src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/eval/builtin_special_test.elvts (about)

     1  //////////
     2  # pragma #
     3  //////////
     4  
     5  ~> pragma unknown-command
     6  Compilation error: need literal =
     7    [tty]:1:23: pragma unknown-command
     8  ~> pragma unknown-command =
     9  Compilation error: need pragma value
    10    [tty]:1:25: pragma unknown-command =
    11  ~> pragma unknown-command x
    12  Compilation error: must be literal =
    13    [tty]:1:24-24: pragma unknown-command x
    14  ~> pragma bad-name = some-value
    15  Compilation error: unknown pragma bad-name
    16    [tty]:1:8-15: pragma bad-name = some-value
    17  ~> pragma unknown-command = bad
    18  Compilation error: invalid value for unknown-command: bad
    19    [tty]:1:26-28: pragma unknown-command = bad
    20  
    21  // Actual effect of the unknown-command pragma is tested along with external
    22  // command resolution in compile_effect_test.elvts.
    23  
    24  ///////
    25  # var #
    26  ///////
    27  
    28  // Interaction between assignment and variable scoping is tested as part of
    29  // closure behavior in compile_value_test.elvts.
    30  
    31  ## declaring without assigning ##
    32  ~> var x
    33     put $x
    34  ▶ $nil
    35  ## Quoted variable name ##
    36  ~> var 'a/b'
    37     put $'a/b'
    38  ▶ $nil
    39  ## declaring one variable whose name ends in ":" ##
    40  ~> var a:
    41  ## declaring a variable whose name ends in "~" initializes it to the builtin nop ##
    42  ~> var cmd~
    43     cmd &ignored-opt ignored-arg
    44     is $cmd~ $nop~
    45  ▶ $true
    46  ## declaring multiple variables ##
    47  ~> var x y
    48     put $x $y
    49  ▶ $nil
    50  ▶ $nil
    51  ## declaring one variable with initial value ##
    52  ~> var x = foo
    53     put $x
    54  ▶ foo
    55  ## declaring multiple variables with initial values ##
    56  ~> var x y = foo bar
    57     put $x $y
    58  ▶ foo
    59  ▶ bar
    60  ## rest variable ##
    61  ~> var x @y z = a b c d
    62     put $x $y $z
    63  ▶ a
    64  ▶ [b c]
    65  ▶ d
    66  ## rest variable with empty RHS ##
    67  ~> var @x =
    68     put $x
    69  ▶ []
    70  ## shadowing ##
    71  ~> var x = old
    72     fn f { put $x }
    73     var x = new
    74     put $x
    75     f
    76  ▶ new
    77  ▶ old
    78  
    79  ## concurrent creation and access ##
    80  // Ensure that there is no race with "go test -race"
    81  ~> var x = 1
    82     put $x | var y = (all)
    83  
    84  ## assignment errors when the RHS errors ##
    85  ~> var x = [][1]
    86  Exception: out of range: index must be from 0 to -1, but is 1
    87    [tty]:1:9-13: var x = [][1]
    88  
    89  ## arity mismatch ##
    90  ~> var x = 1 2
    91  Exception: arity mismatch: assignment right-hand-side must be 1 value, but is 2 values
    92    [tty]:1:1-11: var x = 1 2
    93  ~> var x y = 1
    94  Exception: arity mismatch: assignment right-hand-side must be 2 values, but is 1 value
    95    [tty]:1:1-11: var x y = 1
    96  ~> var x y @z = 1
    97  Exception: arity mismatch: assignment right-hand-side must be 2 or more values, but is 1 value
    98    [tty]:1:1-14: var x y @z = 1
    99  
   100  ## variable name must not be empty ##
   101  ~> var ''
   102  Compilation error: variable name must not be empty
   103    [tty]:1:5-6: var ''
   104  
   105  ## variable name that must be quoted after $ must be quoted ##
   106  ~> var a/b
   107  Compilation error: lvalue must be valid literal variable names
   108    [tty]:1:5-7: var a/b
   109  
   110  ## multiple @ not allowed ##
   111  ~> var x @y @z = a b c d
   112  Compilation error: at most one rest variable is allowed
   113    [tty]:1:10-11: var x @y @z = a b c d
   114  
   115  ## non-local not allowed ##
   116  ~> var ns:a
   117  Compilation error: cannot create variable $ns:a; new variables can only be created in the current scope
   118    [tty]:1:5-8: var ns:a
   119  
   120  ## index not allowed ##
   121  ~> var a[0]
   122  Compilation error: new variable $a must not have indices
   123    [tty]:1:5-8: var a[0]
   124  
   125  ## composite expression not allowed ##
   126  ~> var a'b'
   127  Compilation error: lvalue may not be composite expressions
   128    [tty]:1:5-8: var a'b'
   129  
   130  ## braced lists must not have any indices when used as a lvalue ##
   131  ~> var {a b}[0] = x y
   132  Compilation error: braced list may not have indices when used as lvalue
   133    [tty]:1:5-12: var {a b}[0] = x y
   134  
   135  ///////
   136  # set #
   137  ///////
   138  
   139  ## setting one variable ##
   140  ~> var x
   141     set x = foo
   142     put $x
   143  ▶ foo
   144  
   145  ## empty RHS is allowed ##
   146  ~> var x
   147     set @x =
   148     put $x
   149  ▶ []
   150  
   151  ## variable must already exist ##
   152  ~> set x = foo
   153  Compilation error: cannot find variable $x
   154    [tty]:1:5-5: set x = foo
   155  
   156  ## list element assignment ##
   157  ~> var li = [foo bar]; set li[0] = 233; put $@li
   158  ▶ 233
   159  ▶ bar
   160  
   161  ## variable in list assignment must already be defined ##
   162  // Regression test for b.elv.sh/889
   163  ~> set y[0] = a
   164  Compilation error: cannot find variable $y
   165    [tty]:1:5-8: set y[0] = a
   166  
   167  ## map element assignment ##
   168  ~> var di = [&k=v]
   169     set di[k] = lorem
   170     set di[k2] = ipsum
   171     put $di[k] $di[k2]
   172  ▶ lorem
   173  ▶ ipsum
   174  
   175  ## nested map element assignment ##
   176  ~> var d = [&a=[&b=v]]
   177     put $d[a][b]
   178     set d[a][b] = u
   179     put $d[a][b]
   180  ▶ v
   181  ▶ u
   182  
   183  ## setting a non-exist environment variable ##
   184  //unset-env X
   185  ~> has-env X
   186     set E:X = x
   187     get-env X
   188  ▶ $false
   189  ▶ x
   190  
   191  ## map element assignment errors ##
   192  ~> var li = [foo]; set li[(fail foo)] = bar
   193  Exception: foo
   194    [tty]:1:25-32: var li = [foo]; set li[(fail foo)] = bar
   195  ~> var li = [foo]; set li[0 1] = foo bar
   196  Exception: multi indexing not implemented
   197    [tty]:1:21-27: var li = [foo]; set li[0 1] = foo bar
   198  ~> var li = [[]]; set li[1][2] = bar
   199  Exception: out of range: index must be from 0 to 0, but is 1
   200    [tty]:1:20-27: var li = [[]]; set li[1][2] = bar
   201  
   202  ## assignment to read-only var is a compile-time error ##
   203  ~> set nil = 1
   204  Compilation error: variable $nil is read-only
   205    [tty]:1:5-7: set nil = 1
   206  ~> var a b
   207     set a true b = 1 2 3
   208  Compilation error: variable $true is read-only
   209    [tty]:2:7-10: set a true b = 1 2 3
   210  ~> set @true = 1
   211  Compilation error: variable $true is read-only
   212    [tty]:1:5-9: set @true = 1
   213  ~> var r
   214     set true @r = 1
   215  Compilation error: variable $true is read-only
   216    [tty]:2:5-8: set true @r = 1
   217  ~> var r
   218     set @r true = 1
   219  Compilation error: variable $true is read-only
   220    [tty]:2:8-11: set @r true = 1
   221  
   222  // Error conditions already covered by tests for var above are not repeated.
   223  
   224  ## = is required ##
   225  ~> var x; set x
   226  Compilation error: need = and right-hand-side
   227    [tty]:1:13: var x; set x
   228  
   229  //////////////////////
   230  # error from Var.Set #
   231  //////////////////////
   232  
   233  //add-bad-var bad 0
   234  
   235  ~> set bad = foo
   236  Exception: bad var
   237    [tty]:1:5-7: set bad = foo
   238  ~> var a; set bad @a = foo
   239  Exception: bad var
   240    [tty]:1:12-14: var a; set bad @a = foo
   241  ~> var a; set a @bad = foo
   242  Exception: bad var
   243    [tty]:1:14-17: var a; set a @bad = foo
   244  ~> var a; set @a bad = foo
   245  Exception: bad var
   246    [tty]:1:15-17: var a; set @a bad = foo
   247  
   248  ///////
   249  # tmp #
   250  ///////
   251  
   252  ~> var x = foo
   253     put $x
   254     { tmp x = bar; put $x }
   255     put $x
   256  ▶ foo
   257  ▶ bar
   258  ▶ foo
   259  
   260  ## use outside function ##
   261  ~> var x; tmp x = y
   262  Compilation error: tmp may only be used inside a function
   263    [tty]:1:8-16: var x; tmp x = y
   264  
   265  ## non-existent variable ##
   266  ~> { tmp x = y }
   267  Compilation error: cannot find variable $x
   268    [tty]:1:7-7: { tmp x = y }
   269  
   270  ## used on unset environment variable ##
   271  //unset-env X
   272  ~> has-env X
   273     { tmp E:X = y; put $E:X }
   274     has-env X
   275     put $E:X
   276  ▶ $false
   277  ▶ y
   278  ▶ $false
   279  ▶ ''
   280  
   281  ## used on set environment variable ##
   282  //unset-env X
   283  ~> set-env X x
   284     { tmp E:X = y; put $E:X }
   285     get-env X
   286     put $E:X
   287  ▶ y
   288  ▶ x
   289  ▶ x
   290  
   291  ## error setting ##
   292  //add-bad-var bad 0
   293  ~> { tmp bad = foo }
   294  Exception: bad var
   295    [tty]:1:7-9: { tmp bad = foo }
   296    [tty]:1:1-17: { tmp bad = foo }
   297  
   298  # error restoring #
   299  //add-bad-var bad 1
   300  ~> { tmp bad = foo; put after }
   301  ▶ after
   302  Exception: restore variable: bad var
   303    [tty]:1:7-9: { tmp bad = foo; put after }
   304    [tty]:1:1-28: { tmp bad = foo; put after }
   305  
   306  ///////
   307  # del #
   308  ///////
   309  
   310  ~> var x = 1
   311     del x
   312  
   313  ## variable can't be used after deleted ##
   314  ~> var x = 1
   315     del x
   316     echo $x
   317  Compilation error: variable $x not found
   318    [tty]:3:6-7: echo $x
   319  
   320  ## deleting environment variable ##
   321  //set-env TEST_ENV test_value
   322  ~> has-env TEST_ENV
   323     del E:TEST_ENV
   324     has-env TEST_ENV
   325  ▶ $true
   326  ▶ $false
   327  
   328  ## deleting variable whose name contains special characters ##
   329  ~> var 'a/b' = foo
   330     del 'a/b'
   331  
   332  ## deleting element ##
   333  ~> var x = [&k=v &k2=v2]
   334     del x[k2]
   335     keys $x
   336  ▶ k
   337  ~> var x = [[&k=v &k2=v2]];
   338     del x[0][k2]
   339     keys $x[0]
   340  ▶ k
   341  
   342  ## deleting nonexistent variable ##
   343  ~> del x
   344  Compilation error: no variable $x
   345    [tty]:1:5-5: del x
   346  
   347  ## deleting element of nonexistent variable ##
   348  ~> del x[0]
   349  Compilation error: no variable $x
   350    [tty]:1:5-8: del x[0]
   351  
   352  ## deleting non-local variable ##
   353  ~> var a: = (ns [&b=$nil])
   354     del a:b
   355  Compilation error: only variables in the local scope or E: can be deleted
   356    [tty]:2:5-7: del a:b
   357  
   358  ## variable name given with $ ##
   359  ~> var x = 1
   360     del $x
   361  Compilation error: arguments to del must omit the dollar sign
   362    [tty]:2:5-6: del $x
   363  
   364  ## variable name not given as a single primary expression ##
   365  ~> var ab = 1
   366     del a'b'
   367  Compilation error: arguments to del must be variable or variable elements
   368    [tty]:2:5-8: del a'b'
   369  
   370  ## variable name not a string ##
   371  ~> del [a]
   372  Compilation error: arguments to del must be variable or variable elements
   373    [tty]:1:5-7: del [a]
   374  
   375  ## variable name has sigil ##
   376  ~> var x = []; del @x
   377  Compilation error: arguments to del must be variable or variable elements
   378    [tty]:1:17-18: var x = []; del @x
   379  
   380  ## variable name not quoted when it should be ##
   381  ~> var 'a/b' = foo
   382     del a/b
   383  Compilation error: arguments to del must be variable or variable elements
   384    [tty]:2:5-7: del a/b
   385  
   386  ## index is multiple values ##
   387  ~> var x = [&k1=v1 &k2=v2]
   388     del x[k1 k2]
   389  Exception: index must evaluate to a single value in argument to del
   390    [tty]:2:7-11: del x[k1 k2]
   391  
   392  ## index expression throws ##
   393  ~> var x = [&k]
   394     del x[(fail x)]
   395  Exception: x
   396    [tty]:2:8-13: del x[(fail x)]
   397  
   398  ## value does not support element removal ##
   399  ~> var x = (num 1)
   400     del x[k]
   401  Exception: value does not support element removal
   402    [tty]:2:5-7: del x[k]
   403  // TODO: Fix the stack trace so that it points to "x[k]" instead of "x[k"
   404  
   405  ## intermediate element does not exist ##
   406  ~> var x = [&]
   407     del x[k][0]
   408  Exception: no such key: k
   409    [tty]:2:5-5: del x[k][0]
   410  
   411  ///////
   412  # and #
   413  ///////
   414  
   415  ~> and $true $false
   416  ▶ $false
   417  ~> and a b
   418  ▶ b
   419  ~> and $false b
   420  ▶ $false
   421  ~> and $true b
   422  ▶ b
   423  
   424  ## short circuit ##
   425  ~> var x = a
   426     and $false (x = b)
   427     put $x
   428  ▶ $false
   429  ▶ a
   430  
   431  ## exception propagation ##
   432  ~> and a (fail x)
   433  Exception: x
   434    [tty]:1:8-13: and a (fail x)
   435  
   436  ## output error is bubbled ##
   437  ~> and a >&-
   438  Exception: port does not support value output
   439    [tty]:1:1-9: and a >&-
   440  
   441  //////
   442  # or #
   443  //////
   444  
   445  ~> or $true $false
   446  ▶ $true
   447  ~> or a b
   448  ▶ a
   449  ~> or $false b
   450  ▶ b
   451  ~> or $true b
   452  ▶ $true
   453  
   454  ## short circuit ##
   455  ~> var x = a; or $true (x = b); put $x
   456  ▶ $true
   457  ▶ a
   458  
   459  ## exception ##
   460  ~> or $false (fail x)
   461  Exception: x
   462    [tty]:1:12-17: or $false (fail x)
   463  
   464  ## output error is bubbled ##
   465  ~> or a >&-
   466  Exception: port does not support value output
   467    [tty]:1:1-8: or a >&-
   468  
   469  ////////////
   470  # coalesce #
   471  ////////////
   472  
   473  ~> coalesce a b
   474  ▶ a
   475  ~> coalesce $nil b
   476  ▶ b
   477  ~> coalesce $nil $nil
   478  ▶ $nil
   479  ~> coalesce
   480  ▶ $nil
   481  
   482  ## short circuit ##
   483  ~> coalesce a (fail foo)
   484  ▶ a
   485  
   486  ## exception propagation ##
   487  ~> coalesce $nil (fail foo)
   488  Exception: foo
   489    [tty]:1:16-23: coalesce $nil (fail foo)
   490  
   491  ## output error is bubbled ##
   492  ~> coalesce a >&-
   493  Exception: port does not support value output
   494    [tty]:1:1-14: coalesce a >&-
   495  
   496  ////////////////////////////////
   497  # special forms require thunks #
   498  ////////////////////////////////
   499  
   500  // Regression test for b.elv.sh/1456.
   501  //
   502  // This only tests "for"; the other special forms use the same utility under the
   503  // hood and are not repeated.
   504  
   505  ~> for x [] {|arg| }
   506  Compilation error: for body must not have arguments
   507    [tty]:1:10-17: for x [] {|arg| }
   508  ~> for x [] {|&opt=val| }
   509  Compilation error: for body must not have options
   510    [tty]:1:10-22: for x [] {|&opt=val| }
   511  
   512  //////
   513  # if #
   514  //////
   515  
   516  ~> if true { put then }
   517  ▶ then
   518  ~> if $false { put then } else { put else }
   519  ▶ else
   520  ~> if $false { put 1 } elif $false { put 2 } else { put 3 }
   521  ▶ 3
   522  ~> if $false { put 2 } elif true { put 2 } else { put 3 }
   523  ▶ 2
   524  
   525  ## exception in condition expression ##
   526  ~> if (fail x) { }
   527  Exception: x
   528    [tty]:1:5-10: if (fail x) { }
   529  
   530  ///////
   531  # try #
   532  ///////
   533  
   534  ~> try { nop } catch { put bad } else { put good }
   535  ▶ good
   536  ~> try { fail tr } catch - { put bad } else { put good }
   537  ▶ bad
   538  ~> try { fail tr } finally { put final }
   539  ▶ final
   540  Exception: tr
   541    [tty]:1:7-14: try { fail tr } finally { put final }
   542  ~> try { fail tr } catch { fail ex } finally { put final }
   543  ▶ final
   544  Exception: ex
   545    [tty]:1:25-32: try { fail tr } catch { fail ex } finally { put final }
   546  ~> try { fail tr } catch { put ex } finally { fail final }
   547  ▶ ex
   548  Exception: final
   549    [tty]:1:44-54: try { fail tr } catch { put ex } finally { fail final }
   550  ~> try { fail tr } catch { fail ex } finally { fail final }
   551  Exception: final
   552    [tty]:1:45-55: try { fail tr } catch { fail ex } finally { fail final }
   553  
   554  ## must have catch to use else ##
   555  ~> try { fail tr } else { echo else }
   556  Compilation error: try with an else block requires a catch block
   557    [tty]:1:1-34: try { fail tr } else { echo else }
   558  
   559  ## must have catch or finally ##
   560  ~> try { fail tr }
   561  Compilation error: try must be followed by a catch block or a finally block
   562    [tty]:1:1-15: try { fail tr }
   563  
   564  ## rest variable not allowed ##
   565  ~> try { nop } catch @a { }
   566  Compilation error: rest variable not allowed
   567    [tty]:1:19-20: try { nop } catch @a { }
   568  
   569  ## readonly var as a target for the "catch" clause ##
   570  ~> try { fail reason } catch nil { }
   571  Compilation error: variable $nil is read-only
   572    [tty]:1:27-29: try { fail reason } catch nil { }
   573  
   574  ## quoted var name ##
   575  ~> try { fail hard } catch 'x=' { put $'x='[reason][type] }
   576  ▶ fail
   577  
   578  ## regression test: "try { } catch" is a syntax error, but it should not panic ##
   579  ~> try { } catch
   580  Compilation error: need variable or body
   581    [tty]:1:14: try { } catch
   582  
   583  /////////
   584  # while #
   585  /////////
   586  
   587  ~> var x = (num 0)
   588     while (< $x 4) { put $x; set x = (+ $x 1) }
   589  ▶ (num 0)
   590  ▶ (num 1)
   591  ▶ (num 2)
   592  ▶ (num 3)
   593  
   594  ## break ##
   595  ~> var x = (num 0)
   596     while (< $x 4) { put $x; break }
   597  ▶ (num 0)
   598  
   599  ## continue ##
   600  ~> var x = (num 0)
   601     while (< $x 4) { put $x; set x = (+ $x 1); continue; put bad }
   602  ▶ (num 0)
   603  ▶ (num 1)
   604  ▶ (num 2)
   605  ▶ (num 3)
   606  
   607  ## exception in body ##
   608  ~> var x = 0; while (< $x 4) { fail haha }
   609  Exception: haha
   610    [tty]:1:29-38: var x = 0; while (< $x 4) { fail haha }
   611  
   612  ## exception in condition ##
   613  ~> while (fail x) { }
   614  Exception: x
   615    [tty]:1:8-13: while (fail x) { }
   616  
   617  ## else branch - not taken ##
   618  ~> var x = 0; while (< $x 4) { put $x; set x = (+ $x 1) } else { put bad }
   619  ▶ 0
   620  ▶ (num 1)
   621  ▶ (num 2)
   622  ▶ (num 3)
   623  
   624  ## else branch - taken ##
   625  ~> while $false { put bad } else { put good }
   626  ▶ good
   627  
   628  ///////
   629  # for #
   630  ///////
   631  
   632  ~> for x [tempora mores] { put 'O '$x }
   633  ▶ 'O tempora'
   634  ▶ 'O mores'
   635  
   636  ## break ##
   637  ~> for x [a] { break } else { put $x }
   638  
   639  ## else ##
   640  ~> for x [a] { put $x } else { put $x }
   641  ▶ a
   642  
   643  ## continue ##
   644  ~> for x [a b] { put $x; continue; put $x; }
   645  ▶ a
   646  ▶ b
   647  
   648  ## else ##
   649  ~> for x [] { } else { put else }
   650  ▶ else
   651  ~> for x [a] { } else { put else }
   652  
   653  ## propagating exception ##
   654  ~> for x [a] { fail foo }
   655  Exception: foo
   656    [tty]:1:13-21: for x [a] { fail foo }
   657  
   658  ## more than one iterator ##
   659  ~> for {x,y} [] { }
   660  Compilation error: must be exactly one lvalue
   661    [tty]:1:5-9: for {x,y} [] { }
   662  
   663  ## can't create new variable non-local variable ##
   664  ~> for no-such-namespace:x [a b] { }
   665  Compilation error: cannot create variable $no-such-namespace:x; new variables can only be created in the current scope
   666    [tty]:1:5-23: for no-such-namespace:x [a b] { }
   667  
   668  ## can't use non-existent variable ##
   669  ~> var a: = (ns [&])
   670     for a:b [] { }
   671  Exception: no variable $a:b
   672    [tty]:2:5-7: for a:b [] { }
   673  
   674  ## exception when evaluating iterable ##
   675  ~> for x [][0] { }
   676  Exception: out of range: index must be from 0 to -1, but is 0
   677    [tty]:1:7-11: for x [][0] { }
   678  
   679  ## more than one iterable ##
   680  ~> for x (put a b) { }
   681  Exception: arity mismatch: value being iterated must be 1 value, but is 2 values
   682    [tty]:1:7-15: for x (put a b) { }
   683  
   684  ## non-iterable value ##
   685  ~> for x (num 0) { }
   686  Exception: cannot iterate number
   687    [tty]:1:1-17: for x (num 0) { }
   688  
   689  //////
   690  # fn #
   691  //////
   692  
   693  ~> fn f {|x| put x=$x'.' }; f lorem; f ipsum
   694  ▶ 'x=lorem.'
   695  ▶ 'x=ipsum.'
   696  
   697  ## recursive functions with fn ##
   698  // Regression test for b.elv.sh/1206.
   699  ~> fn f {|n| if (== $n 0) { num 1 } else { * $n (f (- $n 1)) } }; f 3
   700  ▶ (num 6)
   701  
   702  ## swallowing exception thrown by return ##
   703  ~> fn f { put a; return; put b }; f
   704  ▶ a
   705  
   706  ## error when evaluating the lambda ##
   707  ~> fn f {|&opt=(fail x)| }
   708  Exception: x
   709    [tty]:1:14-19: fn f {|&opt=(fail x)| }
   710  
   711  ///////
   712  # use #
   713  ///////
   714  
   715  ## basic usage ##
   716  //tmp-lib-dir
   717  ~> echo 'var name = ipsum' > $lib/lorem.elv
   718  ~> use lorem
   719     put $lorem:name
   720  ▶ ipsum
   721  
   722  ## imports are lexically scoped ##
   723  //tmp-lib-dir
   724  ~> echo 'var name = ipsum' > $lib/lorem.elv
   725  ~> { use lorem }
   726     put $lorem:name
   727  Compilation error: variable $lorem:name not found
   728    [tty]:2:5-15: put $lorem:name
   729  
   730  ## prefers lib dir that appear earlier ##
   731  //two-tmp-lib-dirs
   732  ~> echo 'echo lib1/shadow' > $lib1/shadow.elv
   733  ~> echo 'echo lib2/shadow' > $lib2/shadow.elv
   734  ~> use shadow
   735  lib1/shadow
   736  
   737  ## use of imported variable is captured in upvalue ##
   738  //tmp-lib-dir
   739  ~> echo 'var name = ipsum' > $lib/lorem.elv
   740  ~> use lorem
   741     { put $lorem:name }
   742  ▶ ipsum
   743  
   744  ## use of imported function is also captured in upvalue ##
   745  //tmp-lib-dir
   746  ~> echo 'var name = ipsum; fn put-name { put $name }' > $lib/lorem.elv
   747  ~> { use lorem; { lorem:put-name } }
   748  ▶ ipsum
   749  
   750  ## use of module in subdirectory ##
   751  //tmp-lib-dir
   752  // TODO: Use os:mkdir-all when it's available.
   753  ~> use os
   754     os:mkdir $lib/a
   755     os:mkdir $lib/a/b
   756     echo 'var name = a/b/c' > $lib/a/b/c.elv
   757  ~> use a/b/c
   758     put $c:name
   759  ▶ a/b/c
   760  
   761  ## module is cached after first use ##
   762  //tmp-lib-dir
   763  ~> echo 'put has-init' > $lib/has-init.elv
   764  ~> use has-init
   765  ▶ has-init
   766  ~> use has-init
   767  // Init code is not run again
   768  
   769  ## renaming module ##
   770  //tmp-lib-dir
   771  // TODO: Use os:mkdir-all when it's available.
   772  ~> use os
   773     os:mkdir $lib/a
   774     os:mkdir $lib/a/b
   775     echo 'var name = a/b/c' > $lib/a/b/c.elv
   776  ~> use a/b/c mod
   777     put $mod:name
   778  ▶ a/b/c
   779  
   780  ## modules can be used multiple times with different aliases ##
   781  //tmp-lib-dir
   782  ~> echo 'var name = ipsum' > $lib/lorem.elv
   783  ~> use lorem
   784     use lorem lorem2
   785     put $lorem:name $lorem2:name
   786  ▶ ipsum
   787  ▶ ipsum
   788  
   789  ## variable referencing a module can be shadowed ##
   790  //tmp-lib-dir
   791  // TODO: Use os:mkdir-all when it's available.
   792  ~> use os
   793     os:mkdir $lib/a
   794     os:mkdir $lib/a/b
   795     echo 'var name = c' > $lib/c.elv
   796     echo 'var name = a/b/c' > $lib/a/b/c.elv
   797  ~> use c
   798     put $c:name
   799     use a/b/c
   800     put $c:name
   801  ▶ c
   802  ▶ a/b/c
   803  
   804  ## relative uses ##
   805  //tmp-lib-dir
   806  ~> use os
   807     os:mkdir $lib/a
   808     os:mkdir $lib/a/b
   809     echo 'var name = ipsum' > $lib/lorem.elv
   810     echo 'var name = a/b/c' > $lib/a/b/c.elv
   811     echo 'use ./c; var c = $c:name; use ../../lorem; var lorem = $lorem:name' > $lib/a/b/x.elv
   812  ~> use a/b/x; put $x:c $x:lorem
   813  ▶ a/b/c
   814  ▶ ipsum
   815  
   816  ## relative uses from the REPL ##
   817  // Relative uses from the REPL is relative to the working directory.
   818  //in-temp-dir
   819  ~> echo 'var name = ipsum' > lorem.elv
   820  ~> use ./lorem
   821     put $lorem:name
   822  ▶ ipsum
   823  
   824  ## variables in the REPL scope is invisible from modules ##
   825  //tmp-lib-dir
   826  ~> echo 'put $x' > $lib/put-x.elv
   827  // We have to do this since the exception stack trace contains $lib, which is a
   828  // temporary directory that changes across runs.
   829  //
   830  // TODO: Print the whole error message (but without the filename) when
   831  // exceptions support that level of introspection.
   832  ~> try {
   833       use put-x
   834     } catch e {
   835       echo has exception
   836     }
   837  has exception
   838  
   839  ## invalid UTF-8 in module file ##
   840  //tmp-lib-dir
   841  ~> echo "\xff" > $lib/invalid-utf8.elv
   842  // We have to do this since the exception stack trace contains $lib, which is a
   843  // temporary directory that changes across runs.
   844  //
   845  // TODO: Print the whole error message (but without the filename) when
   846  // exceptions support that level of introspection.
   847  ~> try {
   848       use invalid-utf8
   849     } catch e {
   850       echo has exception
   851     }
   852  has exception
   853  
   854  ## unknown module spec ##
   855  ~> use unknown
   856  Exception: no such module: unknown
   857    [tty]:1:1-11: use unknown
   858  ~> use ./unknown
   859  Exception: no such module: ./unknown
   860    [tty]:1:1-13: use ./unknown
   861  ~> use ../unknown
   862  Exception: no such module: ../unknown
   863    [tty]:1:1-14: use ../unknown
   864  
   865  ## wrong number of arguments ##
   866  ~> use
   867  Compilation error: need module spec
   868    [tty]:1:4: use
   869  ~> use a b c
   870  Compilation error: superfluous arguments
   871    [tty]:1:9-9: use a b c
   872  
   873  ## circular dependency ##
   874  //tmp-lib-dir
   875  ~> echo 'var pre = apre; use b; put $b:pre $b:post; var post = apost' > $lib/a.elv
   876     echo "var pre = bpre; use a; put $a:pre $a:post; var post = bpost" > $lib/b.elv
   877  ~> use a
   878  ▶ apre
   879  ▶ $nil
   880  ▶ bpre
   881  ▶ bpost
   882  
   883  ## importing module triggers check for deprecated features ##
   884  // Regression test for b.elv.sh/1072
   885  //tmp-lib-dir
   886  ~> echo 'a=b nop $a' > $lib/dep.elv
   887  // Only show the first line to avoid showing the file path, which contains $lib
   888  // and changes across runs.
   889  ~> use dep 2>&1 | take 1 | to-lines
   890  Deprecation: the legacy temporary assignment syntax is deprecated; use "tmp" instead
   891  
   892  ## module may mutate REPL namespace ##
   893  // Regression test for b.elv.sh/1225
   894  //tmp-lib-dir
   895  //add-var-in-builtin
   896  ~> echo 'var foo = bar; add-var foo $foo' > $lib/a.elv
   897  ~> use a
   898  ~> keys $a:
   899  ▶ foo
   900  ~> put $foo
   901  ▶ bar