@@ -270,4 +270,159 @@ describe("fs module", () => {
270270 } ) ;
271271 } ) ;
272272 } ) ;
273+
274+ describe ( "symlink" , ( ) => {
275+ it ( "symlink a file and read/write to it" , done => {
276+ fs . mkdir ( "/symlink" , ( ) => {
277+ fs . writeFile ( "/symlink/a.txt" , "hello" , ( ) => {
278+ fs . symlink ( "/symlink/a.txt" , "/symlink/b.txt" , ( ) => {
279+ fs . readFile ( "/symlink/b.txt" , "utf8" , ( err , data ) => {
280+ expect ( err ) . toBe ( null )
281+ expect ( data ) . toBe ( "hello" )
282+ fs . writeFile ( "/symlink/b.txt" , "world" , ( ) => {
283+ fs . readFile ( "/symlink/a.txt" , "utf8" , ( err , data ) => {
284+ expect ( err ) . toBe ( null )
285+ expect ( data ) . toBe ( "world" ) ;
286+ done ( ) ;
287+ } )
288+ } )
289+ } ) ;
290+ } ) ;
291+ } ) ;
292+ } ) ;
293+ } ) ;
294+ it ( "symlink a file and read/write to it (relative)" , done => {
295+ fs . mkdir ( "/symlink" , ( ) => {
296+ fs . writeFile ( "/symlink/a.txt" , "hello" , ( ) => {
297+ fs . symlink ( "a.txt" , "/symlink/b.txt" , ( ) => {
298+ fs . readFile ( "/symlink/b.txt" , "utf8" , ( err , data ) => {
299+ expect ( err ) . toBe ( null )
300+ expect ( data ) . toBe ( "hello" )
301+ fs . writeFile ( "/symlink/b.txt" , "world" , ( ) => {
302+ fs . readFile ( "/symlink/a.txt" , "utf8" , ( err , data ) => {
303+ expect ( err ) . toBe ( null )
304+ expect ( data ) . toBe ( "world" ) ;
305+ done ( ) ;
306+ } )
307+ } )
308+ } ) ;
309+ } ) ;
310+ } ) ;
311+ } ) ;
312+ } ) ;
313+ it ( "symlink a directory and read/write to it" , done => {
314+ fs . mkdir ( "/symlink" , ( ) => {
315+ fs . mkdir ( "/symlink/a" , ( ) => {
316+ fs . writeFile ( "/symlink/a/file.txt" , "data" , ( ) => {
317+ fs . symlink ( "/symlink/a" , "/symlink/b" , ( ) => {
318+ fs . readdir ( "/symlink/b" , ( err , data ) => {
319+ expect ( err ) . toBe ( null )
320+ expect ( data . includes ( "file.txt" ) ) . toBe ( true ) ;
321+ fs . readFile ( "/symlink/b/file.txt" , "utf8" , ( err , data ) => {
322+ expect ( err ) . toBe ( null )
323+ expect ( data ) . toBe ( "data" )
324+ fs . writeFile ( "/symlink/b/file2.txt" , "world" , ( ) => {
325+ fs . readFile ( "/symlink/a/file2.txt" , "utf8" , ( err , data ) => {
326+ expect ( err ) . toBe ( null ) ;
327+ expect ( data ) . toBe ( "world" ) ;
328+ done ( ) ;
329+ } )
330+ } )
331+ } ) ;
332+ } ) ;
333+ } ) ;
334+ } ) ;
335+ } ) ;
336+ } ) ;
337+ } ) ;
338+ it ( "symlink a directory and read/write to it (relative)" , done => {
339+ fs . mkdir ( "/symlink" , ( ) => {
340+ fs . mkdir ( "/symlink/a" , ( ) => {
341+ fs . mkdir ( "/symlink/b" , ( ) => {
342+ fs . writeFile ( "/symlink/a/file.txt" , "data" , ( ) => {
343+ fs . symlink ( "../a" , "/symlink/b/c" , ( ) => {
344+ fs . readdir ( "/symlink/b/c" , ( err , data ) => {
345+ expect ( err ) . toBe ( null )
346+ expect ( data . includes ( "file.txt" ) ) . toBe ( true ) ;
347+ fs . readFile ( "/symlink/b/c/file.txt" , "utf8" , ( err , data ) => {
348+ expect ( err ) . toBe ( null )
349+ expect ( data ) . toBe ( "data" )
350+ fs . writeFile ( "/symlink/b/c/file2.txt" , "world" , ( ) => {
351+ fs . readFile ( "/symlink/a/file2.txt" , "utf8" , ( err , data ) => {
352+ expect ( err ) . toBe ( null ) ;
353+ expect ( data ) . toBe ( "world" ) ;
354+ done ( ) ;
355+ } )
356+ } )
357+ } ) ;
358+ } ) ;
359+ } ) ;
360+ } ) ;
361+ } ) ;
362+ } ) ;
363+ } ) ;
364+ } ) ;
365+ it ( "unlink doesn't follow symlinks" , done => {
366+ fs . mkdir ( "/symlink" , ( ) => {
367+ fs . mkdir ( "/symlink/del" , ( ) => {
368+ fs . writeFile ( "/symlink/del/file.txt" , "data" , ( ) => {
369+ fs . symlink ( "/symlink/del/file.txt" , "/symlink/del/file2.txt" , ( ) => {
370+ fs . readdir ( "/symlink/del" , ( err , data ) => {
371+ expect ( err ) . toBe ( null )
372+ expect ( data . includes ( "file.txt" ) ) . toBe ( true )
373+ expect ( data . includes ( "file2.txt" ) ) . toBe ( true )
374+ fs . unlink ( "/symlink/del/file2.txt" , ( err , data ) => {
375+ expect ( err ) . toBe ( null )
376+ fs . readdir ( "/symlink/del" , ( err , data ) => {
377+ expect ( err ) . toBe ( null )
378+ expect ( data . includes ( "file.txt" ) ) . toBe ( true )
379+ expect ( data . includes ( "file2.txt" ) ) . toBe ( false )
380+ done ( ) ;
381+ } ) ;
382+ } ) ;
383+ } ) ;
384+ } ) ;
385+ } ) ;
386+ } ) ;
387+ } ) ;
388+ } ) ;
389+ it ( "lstat doesn't follow symlinks" , done => {
390+ fs . mkdir ( "/symlink" , ( ) => {
391+ fs . mkdir ( "/symlink/lstat" , ( ) => {
392+ fs . writeFile ( "/symlink/lstat/file.txt" , "data" , ( ) => {
393+ fs . symlink ( "/symlink/lstat/file.txt" , "/symlink/lstat/file2.txt" , ( ) => {
394+ fs . stat ( "/symlink/lstat/file2.txt" , ( err , stat ) => {
395+ expect ( err ) . toBe ( null )
396+ expect ( stat . isFile ( ) ) . toBe ( true )
397+ expect ( stat . isSymbolicLink ( ) ) . toBe ( false )
398+ fs . lstat ( "/symlink/lstat/file2.txt" , ( err , stat ) => {
399+ expect ( err ) . toBe ( null )
400+ expect ( stat . isFile ( ) ) . toBe ( false )
401+ expect ( stat . isSymbolicLink ( ) ) . toBe ( true )
402+ done ( ) ;
403+ } ) ;
404+ } ) ;
405+ } ) ;
406+ } ) ;
407+ } ) ;
408+ } ) ;
409+ } ) ;
410+ } ) ;
411+
412+ describe ( "readlink" , ( ) => {
413+ it ( "readlink returns the target path" , done => {
414+ fs . mkdir ( "/readlink" , ( ) => {
415+ fs . writeFile ( "/readlink/a.txt" , "hello" , ( ) => {
416+ fs . symlink ( "/readlink/a.txt" , "/readlink/b.txt" , ( ) => {
417+ fs . readlink ( "/readlink/b.txt" , "utf8" , ( err , data ) => {
418+ expect ( err ) . toBe ( null )
419+ expect ( data ) . toBe ( "/readlink/a.txt" )
420+ done ( ) ;
421+ } ) ;
422+ } ) ;
423+ } ) ;
424+ } ) ;
425+ } ) ;
426+ } ) ;
427+
273428} ) ;
0 commit comments