src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/mods/os/os_test.elvts (about)

     1  //each:eval use os
     2  //each:in-temp-dir
     3  
     4  ////////////
     5  # os:mkdir #
     6  ////////////
     7  
     8  ~> os:mkdir d
     9     os:is-dir d
    10  ▶ $true
    11  
    12  ## error when directory already exists ##
    13  ~> os:mkdir d
    14     try { os:mkdir d } catch e { os:-is-exist $e }
    15  ▶ $true
    16  
    17  ## &perm ##
    18  //only-on !windows
    19  //umask 0
    20  // TODO: Re-enable this after os:mkdir respects &perm on Windows.
    21  ~> os:mkdir &perm=0o555 d555
    22     printf "%O\n" (os:stat d555)[perm]
    23  0o555
    24  
    25  ## &perm on Unix ##
    26  //only-on unix
    27  //umask 0
    28  // Windows only supports 0o555 and 0o777; test other values on Unix only.
    29  ~> os:mkdir &perm=0o400 d400
    30     printf "%O\n" (os:stat d400)[perm]
    31  0o400
    32  
    33  ////////////////
    34  # os:mkdir-all #
    35  ////////////////
    36  
    37  ~> os:mkdir-all a/b
    38     os:is-dir a
    39     os:is-dir a/b
    40  ▶ $true
    41  ▶ $true
    42  
    43  ## no error if the directory already exists ##
    44  ~> os:mkdir-all a/b
    45  ~> os:mkdir-all a/b
    46  
    47  ## &perm ##
    48  //only-on !windows
    49  //umask 0
    50  ~> os:mkdir-all &perm=0o700 a/b
    51     printf "%O\n" (os:stat a)[perm]
    52     printf "%O\n" (os:stat a/b)[perm]
    53  0o700
    54  0o700
    55  
    56  //////////////
    57  # os:symlink #
    58  //////////////
    59  
    60  //only-if-can-create-symlink
    61  
    62  ~> echo foo > regular
    63  ~> os:symlink regular symlink
    64  ~> slurp < symlink
    65  ▶ "foo\n"
    66  ~> os:eval-symlinks symlink
    67  ▶ regular
    68  
    69  /////////////
    70  # os:remove #
    71  /////////////
    72  
    73  ~> echo > f; os:exists f
    74     os:remove f; os:exists f
    75  ▶ $true
    76  ▶ $false
    77  ~> os:mkdir d; os:exists d
    78     os:remove d; os:exists d
    79  ▶ $true
    80  ▶ $false
    81  
    82  ## can't remove non-empty directory (Unix) ##
    83  //only-on unix
    84  ~> os:mkdir d; echo > d/file
    85     os:remove d
    86  Exception: remove d: directory not empty
    87    [tty]:2:1-11: os:remove d
    88  
    89  ## can't remove non-empty directory (Windows) ##
    90  //only-on windows
    91  // Windows has a different error message.
    92  ~> os:mkdir d; echo > d/file
    93     os:remove d
    94  Exception: remove d: The directory is not empty.
    95    [tty]:2:1-11: os:remove d
    96  
    97  ## can't remove non-existent file ##
    98  ~> try { os:remove d } catch e { os:-is-not-exist $e }
    99  ▶ $true
   100  
   101  ## doesn't take empty string ##
   102  ~> os:remove ""
   103  Exception: bad value: path must be non-empty string, but is empty string
   104    [tty]:1:1-12: os:remove ""
   105  
   106  /////////////////
   107  # os:remove-all #
   108  /////////////////
   109  
   110  ## relative path ##
   111  ~> os:mkdir d; echo > d/file
   112     os:remove-all d; os:exists d
   113  ▶ $false
   114  
   115  ## absolute path ##
   116  ~> os:mkdir d; echo > d/file
   117     os:remove-all $pwd/d; os:exists d
   118  ▶ $false
   119  
   120  ## removing non-existent file is not an error ##
   121  ~> os:remove-all d
   122  
   123  ## doesn't take empty string ##
   124  ~> os:remove-all ""
   125  Exception: bad value: path must be non-empty string, but is empty string
   126    [tty]:1:1-16: os:remove-all ""
   127  
   128  /////////////
   129  # os:rename #
   130  /////////////
   131  
   132  ~> echo > old
   133     os:exists old
   134     os:exists new
   135  ▶ $true
   136  ▶ $false
   137  ~> os:rename old new
   138     os:exists old
   139     os:exists new
   140  ▶ $false
   141  ▶ $true
   142  
   143  ////////////
   144  # os:chmod #
   145  ////////////
   146  
   147  ~> os:mkdir d
   148  ~> os:chmod 0o555 d
   149     printf "%O\n" (os:stat d)[perm]
   150  0o555
   151  ~> os:chmod 0o777 d
   152     printf "%O\n" (os:stat d)[perm]
   153  0o777
   154  
   155  ## Unix ##
   156  //only-on unix
   157  // Windows only supports 0o555 (for read-only files) and 0o777 (for non-readonly
   158  // files) in the perm bits, and no special modes. Test more perm bits and
   159  // special modes on Unix only.
   160  ~> os:mkdir d
   161  ~> os:chmod &special-modes=[setuid setgid sticky] 0o400 d
   162     put (printf "%O" (os:stat d)[perm])
   163     put (os:stat d)[special-modes]
   164  ▶ 0o400
   165  ▶ [setuid setgid sticky]
   166  
   167  ## invalid arguments ##
   168  ~> os:chmod -1 d
   169  Exception: out of range: permission bits must be from 0 to 0o777, but is -1
   170    [tty]:1:1-13: os:chmod -1 d
   171  // TODO: This error should be more informative and point out that it is the
   172  // special modes that should be iterable
   173  ~> os:chmod &special-modes=(num 0) 0 d
   174  Exception: cannot iterate number
   175    [tty]:1:1-35: os:chmod &special-modes=(num 0) 0 d
   176  ~> os:chmod &special-modes=[bad] 0 d
   177  Exception: bad value: special mode must be setuid, setgid or sticky, but is bad
   178    [tty]:1:1-33: os:chmod &special-modes=[bad] 0 d
   179  
   180  ///////////
   181  # os:stat #
   182  ///////////
   183  
   184  // Test basic fields common to all platforms. The perm and special-modes fields
   185  // and already tested alongside os:chmod, so we don't repeat those.
   186  ~> os:mkdir dir
   187  ~> print 123456 > file
   188  ~> put (os:stat file)[name type size]
   189  ▶ file
   190  ▶ regular
   191  ▶ (num 6)
   192  // size exists for directories on all platforms, but the value is
   193  // platform-depedent.
   194  ~> put (os:stat dir)[name type]
   195  ▶ dir
   196  ▶ dir
   197  
   198  ## can't stat non-existent file (Unix) ##
   199  //only-on unix
   200  ~> os:stat non-existent
   201  Exception: lstat non-existent: no such file or directory
   202    [tty]:1:1-20: os:stat non-existent
   203  
   204  ## can't stat non-existent file (Windows) ##
   205  //only-on windows
   206  // Windows has a different error message.
   207  ~> os:stat non-existent
   208  Exception: CreateFile non-existent: The system cannot find the file specified.
   209    [tty]:1:1-20: os:stat non-existent
   210  
   211  ## symlink ##
   212  //only-if-can-create-symlink
   213  ~> echo > regular
   214     os:symlink regular symlink
   215  ~> put (os:stat symlink)[type]
   216  ▶ symlink
   217  ~> put (os:stat &follow-symlink symlink)[type]
   218  ▶ regular
   219  
   220  ## fifo ##
   221  //mkfifo-or-skip fifo
   222  ~> put (os:stat fifo)[type]
   223  ▶ named-pipe
   224  
   225  ## sock on Unix ##
   226  //mksock-or-skip sock
   227  //only-on unix
   228  ~> put (os:stat sock)[type]
   229  ▶ socket
   230  
   231  ## sock on Windows ##
   232  //mksock-or-skip sock
   233  //only-on windows
   234  // Windows does support Unix sockets now, but the type is not reflected in what
   235  // we get from os.Stat.
   236  ~> put (os:stat sock)[type]
   237  ▶ irregular
   238  
   239  ## device ##
   240  //only-on unix
   241  ~> put (os:stat /dev/null)[type]
   242  ▶ char-device
   243  
   244  ## sys on Unix ##
   245  //only-on unix
   246  ~> echo > file
   247     var sys = (os:stat file)[sys]
   248     put $sys[nlink]
   249     and (each {|f| has-key $sys $f} [dev ino uid gid rdev blksize blocks])
   250  ▶ (num 1)
   251  ▶ $true
   252  
   253  ## sys on Windows ##
   254  //only-on windows
   255  //create-windows-special-files-or-skip
   256  ~> has-value (os:stat directory)[sys][file-attributes] directory
   257  ▶ $true
   258  ~> has-value (os:stat readonly)[sys][file-attributes] readonly
   259  ▶ $true
   260  ~> has-value (os:stat hidden)[sys][file-attributes] hidden
   261  ▶ $true
   262  
   263  //////////////////////////////////////////
   264  # os:exists, os:is-dir and os:is-regular #
   265  //////////////////////////////////////////
   266  
   267  ~> os:mkdir d
   268  ~> echo > d/f
   269  ~> os:exists $pwd
   270  ▶ $true
   271  ~> os:is-dir $pwd
   272  ▶ $true
   273  ~> os:is-regular $pwd
   274  ▶ $false
   275  ~> os:exists d
   276  ▶ $true
   277  ~> os:is-dir d
   278  ▶ $true
   279  ~> os:is-regular d
   280  ▶ $false
   281  ~> os:exists d/f
   282  ▶ $true
   283  ~> os:is-dir d/f
   284  ▶ $false
   285  ~> os:is-regular d/f
   286  ▶ $true
   287  ~> os:exists bad
   288  ▶ $false
   289  ~> os:is-dir bad
   290  ▶ $false
   291  ~> os:is-regular bad
   292  ▶ $false
   293  
   294  /////////////////////////
   295  # symbolic link-related #
   296  /////////////////////////
   297  
   298  //only-if-can-create-symlink
   299  // Set up symlinks to test. Each file is named as "s-" plus path relative to the
   300  // test directory root, with / changed to -.
   301  ~> os:mkdir d
   302     echo > d/f
   303     os:symlink f d/s-f   # target is in same directory
   304     os:symlink d s-d     # target is directory
   305     os:symlink d/f s-d-f # target is in subdirectory
   306     os:symlink bad s-bad # target doesn't exist
   307  // These tests can run on Windows, where the output of os:eval-symlinks will use
   308  // \ as the path separator, so we can't rely on the exact output.
   309  ~> use path
   310  // Not symlink
   311  ~> eq (os:eval-symlinks d/f) (path:join d f)
   312  ▶ $true
   313  // Leaf is symlink
   314  ~> eq (os:eval-symlinks d/s-f) (path:join d f)
   315  ▶ $true
   316  // Non-leaf is symlink
   317  ~> eq (os:eval-symlinks s-d/f) (path:join d f)
   318  ▶ $true
   319  ~> os:exists s-d
   320  ▶ $true
   321  ~> os:exists s-d &follow-symlink
   322  ▶ $true
   323  ~> os:exists s-d-f
   324  ▶ $true
   325  ~> os:exists s-d-f &follow-symlink
   326  ▶ $true
   327  ~> os:exists s-bad
   328  ▶ $true
   329  ~> os:exists s-bad &follow-symlink
   330  ▶ $false
   331  ~> os:exists bad
   332  ▶ $false
   333  ~> os:exists bad &follow-symlink
   334  ▶ $false
   335  ~> os:is-dir s-d
   336  ▶ $false
   337  ~> os:is-dir s-d &follow-symlink
   338  ▶ $true
   339  ~> os:is-dir s-d-f
   340  ▶ $false
   341  ~> os:is-dir s-d-f &follow-symlink
   342  ▶ $false
   343  ~> os:is-dir s-bad
   344  ▶ $false
   345  ~> os:is-dir s-bad &follow-symlink
   346  ▶ $false
   347  ~> os:is-dir bad
   348  ▶ $false
   349  ~> os:is-dir bad &follow-symlink
   350  ▶ $false
   351  ~> os:is-regular s-d
   352  ▶ $false
   353  ~> os:is-regular s-d &follow-symlink
   354  ▶ $false
   355  ~> os:is-regular s-d-f
   356  ▶ $false
   357  ~> os:is-regular s-d-f &follow-symlink
   358  ▶ $true
   359  ~> os:is-regular s-bad
   360  ▶ $false
   361  ~> os:is-regular s-bad &follow-symlink
   362  ▶ $false
   363  ~> os:is-regular bad
   364  ▶ $false
   365  ~> os:is-regular bad &follow-symlink
   366  ▶ $false
   367  
   368  ## os:eval-symlinks given non-existent file (Unix) ##
   369  //only-on unix
   370  ~> os:symlink bad s-bad
   371  ~> os:eval-symlinks s-bad
   372  Exception: lstat bad: no such file or directory
   373    [tty]:1:1-22: os:eval-symlinks s-bad
   374  
   375  ## os:eval-symlinks given non-existent file (Windows) ##
   376  // Windows has a different error message.
   377  //only-on windows
   378  ~> os:symlink bad s-bad
   379  ~> os:eval-symlinks s-bad
   380  Exception: CreateFile bad: The system cannot find the file specified.
   381    [tty]:1:1-22: os:eval-symlinks s-bad
   382  
   383  ///////////////
   384  # os:temp-dir #
   385  ///////////////
   386  
   387  //each:eval use re
   388  
   389  // default name template is elvish-*
   390  ~> var x = (os:temp-dir)
   391     os:remove $x
   392     re:match '[/\\]elvish-.*$' $x
   393  ▶ $true
   394  // explicit name template
   395  ~> var x = (os:temp-dir 'x-*.y')
   396     os:remove $x
   397     re:match '[/\\]x-.*\.y$' $x
   398  ▶ $true
   399  
   400  ## create in pwd ##
   401  //in-temp-dir
   402  ~> var x = (os:temp-dir &dir=.)
   403     os:remove $x
   404     re:match '^(\.[/\\])?elvish-.*$' $x
   405  ▶ $true
   406  ~> var x = (os:temp-dir &dir=. 'x-*.y')
   407     os:remove $x
   408     re:match '^(\.[/\\])?x-.*\.y$' $x
   409  ▶ $true
   410  
   411  ## arity check ##
   412  ~> os:temp-dir a b
   413  Exception: arity mismatch: arguments must be 0 to 1 values, but is 2 values
   414    [tty]:1:1-15: os:temp-dir a b
   415  
   416  ////////////////
   417  # os:temp-file #
   418  ////////////////
   419  
   420  //each:eval use re
   421  //each:eval use file
   422  
   423  ~> var f = (os:temp-file)
   424     re:match '[/\\]elvish-.*$' $f[name]
   425     file:close $f
   426     os:remove $f[name]
   427  ▶ $true
   428  ~> var f = (os:temp-file 'x-*.y')
   429     re:match '[/\\]x-.*\.y$' $f[name]
   430     file:close $f
   431     os:remove $f[name]
   432  ▶ $true
   433  
   434  ## create in pwd ##
   435  //in-temp-dir
   436  ~> var f = (os:temp-file &dir=.)
   437     re:match '^(\.[/\\])?elvish-.*$' $f[name]
   438     file:close $f
   439     os:remove $f[name]
   440  ▶ $true
   441  ~> var f = (os:temp-file &dir=. 'x-*.y')
   442     re:match '^(\.[/\\])?x-.*\.y$' $f[name]
   443     file:close $f
   444     os:remove $f[name]
   445  ▶ $true
   446  
   447  ## arity check ##
   448  ~> os:temp-file a b
   449  Exception: arity mismatch: arguments must be 0 to 1 values, but is 2 values
   450    [tty]:1:1-16: os:temp-file a b