1" Test Vim9 assignments
2
3source check.vim
4source vim9.vim
5
6let s:appendToMe = 'xxx'
7let s:addToMe = 111
8let g:existing = 'yes'
9let g:inc_counter = 1
10let $SOME_ENV_VAR = 'some'
11let g:alist = [7]
12let g:adict = #{a: 1}
13let g:astring = 'text'
14
15def Test_assignment_bool()
16  var bool1: bool = true
17  assert_equal(v:true, bool1)
18  var bool2: bool = false
19  assert_equal(v:false, bool2)
20
21  var bool3: bool = 0
22  assert_equal(false, bool3)
23  var bool4: bool = 1
24  assert_equal(true, bool4)
25
26  var bool5: bool = 1 && true
27  assert_equal(true, bool5)
28  var bool6: bool = 0 && 1
29  assert_equal(false, bool6)
30  var bool7: bool = 0 || 1 && true
31  assert_equal(true, bool7)
32
33  var lines =<< trim END
34    vim9script
35    def GetFlag(): bool
36      var flag: bool = 1
37      return flag
38    enddef
39    var flag: bool = GetFlag()
40    assert_equal(true, flag)
41    flag = 0
42    assert_equal(false, flag)
43    flag = 1
44    assert_equal(true, flag)
45    flag = 1 || true
46    assert_equal(true, flag)
47    flag = 1 && false
48    assert_equal(false, flag)
49
50    var cp: bool = &cp
51    var fen: bool = &l:fen
52  END
53  CheckScriptSuccess(lines)
54  CheckDefAndScriptFailure(['var x: bool = 2'], 'E1012:')
55  CheckDefAndScriptFailure(['var x: bool = -1'], 'E1012:')
56  CheckDefAndScriptFailure(['var x: bool = [1]'], 'E1012:')
57  CheckDefAndScriptFailure(['var x: bool = {}'], 'E1012:')
58  CheckDefAndScriptFailure(['var x: bool = "x"'], 'E1012:')
59
60  CheckDefAndScriptFailure(['var x: bool = "x"', '', 'eval 0'], 'E1012:', 1)
61enddef
62
63def Test_syntax()
64  var name = 234
65  var other: list<string> = ['asdf']
66enddef
67
68def Test_assignment()
69  CheckDefFailure(['var x:string'], 'E1069:')
70  CheckDefFailure(['var x:string = "x"'], 'E1069:')
71  CheckDefFailure(['var a:string = "x"'], 'E1069:')
72  CheckDefFailure(['var lambda = () => "lambda"'], 'E704:')
73  CheckScriptFailure(['var x = "x"'], 'E1124:')
74
75  var nr: number = 1234
76  CheckDefFailure(['var nr: number = "asdf"'], 'E1012:')
77
78  var a: number = 6 #comment
79  assert_equal(6, a)
80
81  if has('channel')
82    var chan1: channel
83    assert_equal('fail', ch_status(chan1))
84
85    var job1: job
86    assert_equal('fail', job_status(job1))
87
88    # calling job_start() is in test_vim9_fails.vim, it causes leak reports
89  endif
90  if has('float')
91    var float1: float = 3.4
92  endif
93  var Funky1: func
94  var Funky2: func = function('len')
95  var Party2: func = funcref('g:Test_syntax')
96
97  g:newvar = 'new'  #comment
98  assert_equal('new', g:newvar)
99
100  assert_equal('yes', g:existing)
101  g:existing = 'no'
102  assert_equal('no', g:existing)
103
104  v:char = 'abc'
105  assert_equal('abc', v:char)
106
107  $ENVVAR = 'foobar'
108  assert_equal('foobar', $ENVVAR)
109  $ENVVAR = ''
110
111  var lines =<< trim END
112    vim9script
113    $ENVVAR = 'barfoo'
114    assert_equal('barfoo', $ENVVAR)
115    $ENVVAR = ''
116  END
117  CheckScriptSuccess(lines)
118
119  s:appendToMe ..= 'yyy'
120  assert_equal('xxxyyy', s:appendToMe)
121  s:addToMe += 222
122  assert_equal(333, s:addToMe)
123  s:newVar = 'new'
124  assert_equal('new', s:newVar)
125
126  set ts=7
127  var ts: number = &ts
128  assert_equal(7, ts)
129  &ts += 1
130  assert_equal(8, &ts)
131  &ts -= 3
132  assert_equal(5, &ts)
133  &ts *= 2
134  assert_equal(10, &ts)
135  &ts /= 3
136  assert_equal(3, &ts)
137  set ts=10
138  &ts %= 4
139  assert_equal(2, &ts)
140
141  if has('float')
142    var f100: float = 100.0
143    f100 /= 5
144    assert_equal(20.0, f100)
145
146    var f200: float = 200.0
147    f200 /= 5.0
148    assert_equal(40.0, f200)
149
150    CheckDefFailure(['var nr: number = 200', 'nr /= 5.0'], 'E1012:')
151  endif
152
153  lines =<< trim END
154    &ts = 6
155    &ts += 3
156    assert_equal(9, &ts)
157
158    &l:ts = 6
159    assert_equal(6, &ts)
160    &l:ts += 2
161    assert_equal(8, &ts)
162
163    &g:ts = 6
164    assert_equal(6, &g:ts)
165    &g:ts += 2
166    assert_equal(8, &g:ts)
167
168    &number = true
169    assert_equal(true, &number)
170    &number = 0
171    assert_equal(false, &number)
172    &number = 1
173    assert_equal(true, &number)
174    &number = false
175    assert_equal(false, &number)
176  END
177  CheckDefAndScriptSuccess(lines)
178
179  CheckDefFailure(['&notex += 3'], 'E113:')
180  CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
181  CheckDefFailure(['&ts = [7]'], 'E1012:')
182  CheckDefExecFailure(['&ts = g:alist'], 'E1012: Type mismatch; expected number but got list<number>')
183  CheckDefFailure(['&ts = "xx"'], 'E1012:')
184  CheckDefExecFailure(['&ts = g:astring'], 'E1012: Type mismatch; expected number but got string')
185  CheckDefFailure(['&path += 3'], 'E1012:')
186  CheckDefExecFailure(['&bs = "asdf"'], 'E474:')
187  # test freeing ISN_STOREOPT
188  CheckDefFailure(['&ts = 3', 'var asdf'], 'E1022:')
189  &ts = 8
190
191  lines =<< trim END
192    var save_TI = &t_TI
193    &t_TI = ''
194    assert_equal('', &t_TI)
195    &t_TI = 'xxx'
196    assert_equal('xxx', &t_TI)
197    &t_TI = save_TI
198  END
199  CheckDefAndScriptSuccess(lines)
200
201  CheckDefFailure(['&t_TI = 123'], 'E1012:')
202  CheckScriptFailure(['vim9script', '&t_TI = 123'], 'E928:')
203
204  CheckDefFailure(['var s:var = 123'], 'E1101:')
205  CheckDefFailure(['var s:var: number'], 'E1101:')
206
207  lines =<< trim END
208    vim9script
209    def SomeFunc()
210      s:var = 123
211    enddef
212    defcompile
213  END
214  CheckScriptFailure(lines, 'E1089:')
215
216  g:inc_counter += 1
217  assert_equal(2, g:inc_counter)
218
219  $SOME_ENV_VAR ..= 'more'
220  assert_equal('somemore', $SOME_ENV_VAR)
221  CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1051:')
222  CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1012:')
223
224  lines =<< trim END
225    @c = 'areg'
226    @c ..= 'add'
227    assert_equal('aregadd', @c)
228  END
229  CheckDefAndScriptSuccess(lines)
230
231  CheckDefFailure(['@a += "more"'], 'E1051:')
232  CheckDefFailure(['@a += 123'], 'E1012:')
233
234  v:errmsg = 'none'
235  v:errmsg ..= 'again'
236  assert_equal('noneagain', v:errmsg)
237  CheckDefFailure(['v:errmsg += "more"'], 'E1051:')
238  CheckDefFailure(['v:errmsg += 123'], 'E1012:')
239
240  var text =<< trim END
241    some text
242  END
243enddef
244
245def Test_assign_unpack()
246  var lines =<< trim END
247    var v1: number
248    var v2: number
249    [v1, v2] = [1, 2]
250    assert_equal(1, v1)
251    assert_equal(2, v2)
252  END
253  CheckDefAndScriptSuccess(lines)
254
255  lines =<< trim END
256      var v1: number
257      var v2: number
258      [v1, v2] =
259  END
260  CheckDefFailure(lines, 'E1097:', 5)
261
262  lines =<< trim END
263      var v1: number
264      var v2: number
265      [v1, v2] = xxx
266  END
267  CheckDefFailure(lines, 'E1001:', 3)
268
269  lines =<< trim END
270      var v1: number
271      var v2: number
272      [v1, v2] = popup_clear()
273  END
274  CheckDefFailure(lines, 'E1031:', 3)
275
276  lines =<< trim END
277      [v1, v2] = [1, 2]
278  END
279  CheckDefFailure(lines, 'E1089', 1)
280  CheckScriptFailure(['vim9script'] + lines, 'E1089', 2)
281
282  lines =<< trim END
283      var v1: number
284      var v2: number
285      [v1, v2] = ''
286  END
287  CheckDefFailure(lines, 'E1012: Type mismatch; expected list<any> but got string', 3)
288
289  lines =<< trim END
290    g:values = [false, 0]
291    var x: bool
292    var y: string
293    [x, y] = g:values
294  END
295  CheckDefExecAndScriptFailure(lines, 'E1163: Variable 2: type mismatch, expected string but got number')
296enddef
297
298def Test_assign_linebreak()
299  var nr: number
300  nr =
301      123
302  assert_equal(123, nr)
303
304  var n2: number
305  [nr, n2] =
306     [12, 34]
307  assert_equal(12, nr)
308  assert_equal(34, n2)
309
310  CheckDefFailure(["var x = #"], 'E1097:', 3)
311enddef
312
313def Test_assign_index()
314  # list of list
315  var l1: list<number>
316  l1[0] = 123
317  assert_equal([123], l1)
318
319  var l2: list<list<number>>
320  l2[0] = []
321  l2[0][0] = 123
322  assert_equal([[123]], l2)
323
324  var l3: list<list<list<number>>>
325  l3[0] = []
326  l3[0][0] = []
327  l3[0][0][0] = 123
328  assert_equal([[[123]]], l3)
329
330  var lines =<< trim END
331      var l3: list<list<number>>
332      l3[0] = []
333      l3[0][0] = []
334  END
335  CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got list<unknown>', 3)
336
337  # dict of dict
338  var d1: dict<number>
339  d1.one = 1
340  assert_equal({one: 1}, d1)
341
342  var d2: dict<dict<number>>
343  d2.one = {}
344  d2.one.two = 123
345  assert_equal({one: {two: 123}}, d2)
346
347  var d3: dict<dict<dict<number>>>
348  d3.one = {}
349  d3.one.two = {}
350  d3.one.two.three = 123
351  assert_equal({one: {two: {three: 123}}}, d3)
352
353  lines =<< trim END
354      var d3: dict<dict<number>>
355      d3.one = {}
356      d3.one.two = {}
357  END
358  CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got dict<unknown>', 3)
359
360  lines =<< trim END
361    var lines: list<string>
362    lines['a'] = 'asdf'
363  END
364  CheckDefFailure(lines, 'E1012:', 2)
365
366  lines =<< trim END
367    var lines: string
368    lines[9] = 'asdf'
369  END
370  CheckDefFailure(lines, 'E1141:', 2)
371
372  # list of dict
373  var ld: list<dict<number>>
374  ld[0] = {}
375  ld[0].one = 123
376  assert_equal([{one: 123}], ld)
377
378  lines =<< trim END
379      var ld: list<dict<number>>
380      ld[0] = []
381  END
382  CheckDefFailure(lines, 'E1012: Type mismatch; expected dict<number> but got list<unknown>', 2)
383
384  # dict of list
385  var dl: dict<list<number>>
386  dl.one = []
387  dl.one[0] = 123
388  assert_equal({one: [123]}, dl)
389
390  lines =<< trim END
391      var dl: dict<list<number>>
392      dl.one = {}
393  END
394  CheckDefFailure(lines, 'E1012: Type mismatch; expected list<number> but got dict<unknown>', 2)
395enddef
396
397def Test_extend_list()
398  var lines =<< trim END
399      vim9script
400      var l: list<number>
401      l += [123]
402      assert_equal([123], l)
403  END
404  CheckScriptSuccess(lines)
405
406  lines =<< trim END
407      vim9script
408      var list: list<string>
409      extend(list, ['x'])
410      assert_equal(['x'], list)
411  END
412  CheckScriptSuccess(lines)
413
414  # appending to NULL list from a function
415  lines =<< trim END
416      vim9script
417      var list: list<string>
418      def Func()
419        list += ['a', 'b']
420      enddef
421      Func()
422      assert_equal(['a', 'b'], list)
423  END
424  CheckScriptSuccess(lines)
425  lines =<< trim END
426      vim9script
427      var list: list<string>
428      def Func()
429        extend(list, ['x', 'b'])
430      enddef
431      Func()
432      assert_equal(['x', 'b'], list)
433  END
434  CheckScriptSuccess(lines)
435
436  lines =<< trim END
437      vim9script
438      var l: list<string> = test_null_list()
439      extend(l, ['x'])
440      assert_equal(['x'], l)
441  END
442  CheckScriptSuccess(lines)
443
444  lines =<< trim END
445      vim9script
446      extend(test_null_list(), ['x'])
447  END
448  CheckScriptFailure(lines, 'E1134:', 2)
449enddef
450
451def Test_extend_dict()
452  var lines =<< trim END
453      vim9script
454      var d: dict<number>
455      extend(d, {a: 1})
456      assert_equal({a: 1}, d)
457
458      var d2: dict<number>
459      d2['one'] = 1
460      assert_equal({one: 1}, d2)
461  END
462  CheckScriptSuccess(lines)
463
464  lines =<< trim END
465      vim9script
466      var d: dict<string> = test_null_dict()
467      extend(d, {a: 'x'})
468      assert_equal({a: 'x'}, d)
469  END
470  CheckScriptSuccess(lines)
471
472  lines =<< trim END
473      vim9script
474      extend(test_null_dict(), {a: 'x'})
475  END
476  CheckScriptFailure(lines, 'E1133:', 2)
477enddef
478
479def Test_single_letter_vars()
480  # single letter variables
481  var a: number = 123
482  a = 123
483  assert_equal(123, a)
484  var b: number
485  b = 123
486  assert_equal(123, b)
487  var g: number
488  g = 123
489  assert_equal(123, g)
490  var s: number
491  s = 123
492  assert_equal(123, s)
493  var t: number
494  t = 123
495  assert_equal(123, t)
496  var v: number
497  v = 123
498  assert_equal(123, v)
499  var w: number
500  w = 123
501  assert_equal(123, w)
502enddef
503
504def Test_vim9_single_char_vars()
505  var lines =<< trim END
506      vim9script
507
508      # single character variable declarations work
509      var a: string
510      var b: number
511      var l: list<any>
512      var s: string
513      var t: number
514      var v: number
515      var w: number
516
517      # script-local variables can be used without s: prefix
518      a = 'script-a'
519      b = 111
520      l = [1, 2, 3]
521      s = 'script-s'
522      t = 222
523      v = 333
524      w = 444
525
526      assert_equal('script-a', a)
527      assert_equal(111, b)
528      assert_equal([1, 2, 3], l)
529      assert_equal('script-s', s)
530      assert_equal(222, t)
531      assert_equal(333, v)
532      assert_equal(444, w)
533  END
534  writefile(lines, 'Xsinglechar')
535  source Xsinglechar
536  delete('Xsinglechar')
537enddef
538
539def Test_assignment_list()
540  var list1: list<bool> = [false, true, false]
541  var list2: list<number> = [1, 2, 3]
542  var list3: list<string> = ['sdf', 'asdf']
543  var list4: list<any> = ['yes', true, 1234]
544  var list5: list<blob> = [0z01, 0z02]
545
546  var listS: list<string> = []
547  var listN: list<number> = []
548
549  assert_equal([1, 2, 3], list2)
550  list2[-1] = 99
551  assert_equal([1, 2, 99], list2)
552  list2[-2] = 88
553  assert_equal([1, 88, 99], list2)
554  list2[-3] = 77
555  assert_equal([77, 88, 99], list2)
556  list2 += [100]
557  assert_equal([77, 88, 99, 100], list2)
558
559  list3 += ['end']
560  assert_equal(['sdf', 'asdf', 'end'], list3)
561
562  CheckDefExecFailure(['var ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:')
563  CheckDefExecFailure(['var [v1, v2] = [1, 2]'], 'E1092:')
564
565  # type becomes list<any>
566  var somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
567
568  var lines =<< trim END
569    var d = {dd: test_null_list()}
570    d.dd[0] = 0
571  END
572  CheckDefExecFailure(lines, 'E1147:', 2)
573enddef
574
575def Test_assignment_list_any_index()
576   var l: list<number> = [1, 2]
577  for  [x, y, _]
578  in  [[0, 1, ''], [1, 3, '']]
579      l[x] = l[x] + y
580  endfor
581  assert_equal([2, 5], l)
582enddef
583
584def Test_assignment_list_vim9script()
585  var lines =<< trim END
586    vim9script
587    var v1: number
588    var v2: number
589    var v3: number
590    [v1, v2, v3] = [1, 2, 3]
591    assert_equal([1, 2, 3], [v1, v2, v3])
592  END
593  CheckScriptSuccess(lines)
594enddef
595
596def Test_assignment_dict()
597  var dict1: dict<bool> = {one: false, two: true}
598  var dict2: dict<number> = {one: 1, two: 2}
599  var dict3: dict<string> = {key: 'value'}
600  var dict4: dict<any> = {one: 1, two: '2'}
601  var dict5: dict<blob> = {one: 0z01, two: 0z02}
602
603  # overwrite
604  dict3['key'] = 'another'
605  assert_equal(dict3, {key: 'another'})
606  dict3.key = 'yet another'
607  assert_equal(dict3, {key: 'yet another'})
608
609  # member "any" can also be a dict and assigned to
610  var anydict: dict<any> = {nest: {}, nr: 0}
611  anydict.nest['this'] = 123
612  anydict.nest.that = 456
613  assert_equal({nest: {this: 123, that: 456}, nr: 0}, anydict)
614
615  var lines =<< trim END
616    var dd = {}
617    dd.two = 2
618    assert_equal({two: 2}, dd)
619  END
620  CheckDefAndScriptSuccess(lines)
621
622  lines =<< trim END
623    var d = {dd: {}}
624    d.dd[0] = 2
625    d.dd['x'] = 3
626    d.dd.y = 4
627    assert_equal({dd: {0: 2, x: 3, y: 4}}, d)
628  END
629  CheckDefAndScriptSuccess(lines)
630
631  lines =<< trim END
632    var dd = {one: 1}
633    dd.one) = 2
634  END
635  CheckDefFailure(lines, 'E488:', 2)
636
637  lines =<< trim END
638    var dd = {one: 1}
639    var dd.one = 2
640  END
641  CheckDefAndScriptFailure(lines, 'E1017:', 2)
642
643  # empty key can be used
644  var dd = {}
645  dd[""] = 6
646  assert_equal({['']: 6}, dd)
647
648  # type becomes dict<any>
649  var somedict = rand() > 0 ? {a: 1, b: 2} : {a: 'a', b: 'b'}
650
651  # assignment to script-local dict
652  lines =<< trim END
653    vim9script
654    var test: dict<any> = {}
655    def FillDict(): dict<any>
656      test['a'] = 43
657      return test
658    enddef
659    assert_equal({a: 43}, FillDict())
660  END
661  CheckScriptSuccess(lines)
662
663  lines =<< trim END
664    vim9script
665    var test: dict<any>
666    def FillDict(): dict<any>
667      test['a'] = 43
668      return test
669    enddef
670    FillDict()
671    assert_equal({a: 43}, test)
672  END
673  CheckScriptSuccess(lines)
674
675  # assignment to global dict
676  lines =<< trim END
677    vim9script
678    g:test = {}
679    def FillDict(): dict<any>
680      g:test['a'] = 43
681      return g:test
682    enddef
683    assert_equal({a: 43}, FillDict())
684  END
685  CheckScriptSuccess(lines)
686
687  # assignment to buffer dict
688  lines =<< trim END
689    vim9script
690    b:test = {}
691    def FillDict(): dict<any>
692      b:test['a'] = 43
693      return b:test
694    enddef
695    assert_equal({a: 43}, FillDict())
696  END
697  CheckScriptSuccess(lines)
698
699  lines =<< trim END
700    var d = {dd: test_null_dict()}
701    d.dd[0] = 0
702  END
703  CheckDefExecFailure(lines, 'E1103:', 2)
704
705  lines =<< trim END
706    var d = {dd: 'string'}
707    d.dd[0] = 0
708  END
709  CheckDefExecFailure(lines, 'E1148:', 2)
710enddef
711
712def Test_assignment_local()
713  # Test in a separated file in order not to the current buffer/window/tab is
714  # changed.
715  var script_lines: list<string> =<< trim END
716    let b:existing = 'yes'
717    let w:existing = 'yes'
718    let t:existing = 'yes'
719
720    def Test_assignment_local_internal()
721      b:newvar = 'new'
722      assert_equal('new', b:newvar)
723      assert_equal('yes', b:existing)
724      b:existing = 'no'
725      assert_equal('no', b:existing)
726      b:existing ..= 'NO'
727      assert_equal('noNO', b:existing)
728
729      w:newvar = 'new'
730      assert_equal('new', w:newvar)
731      assert_equal('yes', w:existing)
732      w:existing = 'no'
733      assert_equal('no', w:existing)
734      w:existing ..= 'NO'
735      assert_equal('noNO', w:existing)
736
737      t:newvar = 'new'
738      assert_equal('new', t:newvar)
739      assert_equal('yes', t:existing)
740      t:existing = 'no'
741      assert_equal('no', t:existing)
742      t:existing ..= 'NO'
743      assert_equal('noNO', t:existing)
744    enddef
745    call Test_assignment_local_internal()
746  END
747  CheckScriptSuccess(script_lines)
748enddef
749
750def Test_assignment_default()
751  # Test default values.
752  var thebool: bool
753  assert_equal(v:false, thebool)
754
755  var thenumber: number
756  assert_equal(0, thenumber)
757
758  if has('float')
759    var thefloat: float
760    assert_equal(0.0, thefloat)
761  endif
762
763  var thestring: string
764  assert_equal('', thestring)
765
766  var theblob: blob
767  assert_equal(0z, theblob)
768
769  var Thefunc: func
770  assert_equal(test_null_function(), Thefunc)
771
772  var thelist: list<any>
773  assert_equal([], thelist)
774
775  var thedict: dict<any>
776  assert_equal({}, thedict)
777
778  if has('channel')
779    var thejob: job
780    assert_equal(test_null_job(), thejob)
781
782    var thechannel: channel
783    assert_equal(test_null_channel(), thechannel)
784
785    if has('unix') && executable('cat')
786      # check with non-null job and channel, types must match
787      thejob = job_start("cat ", {})
788      thechannel = job_getchannel(thejob)
789      job_stop(thejob, 'kill')
790    endif
791  endif
792
793  var nr = 1234 | nr = 5678
794  assert_equal(5678, nr)
795enddef
796
797let scriptvar = 'init'
798
799def Test_assignment_var_list()
800  var lines =<< trim END
801      var v1: string
802      var v2: string
803      var vrem: list<string>
804      [v1] = ['aaa']
805      assert_equal('aaa', v1)
806
807      [v1, v2] = ['one', 'two']
808      assert_equal('one', v1)
809      assert_equal('two', v2)
810
811      [v1, v2; vrem] = ['one', 'two']
812      assert_equal('one', v1)
813      assert_equal('two', v2)
814      assert_equal([], vrem)
815
816      [v1, v2; vrem] = ['one', 'two', 'three']
817      assert_equal('one', v1)
818      assert_equal('two', v2)
819      assert_equal(['three'], vrem)
820
821      [&ts, &sw] = [3, 4]
822      assert_equal(3, &ts)
823      assert_equal(4, &sw)
824      set ts=8 sw=4
825
826      [@a, @z] = ['aa', 'zz']
827      assert_equal('aa', @a)
828      assert_equal('zz', @z)
829
830      [$SOME_VAR, $OTHER_VAR] = ['some', 'other']
831      assert_equal('some', $SOME_VAR)
832      assert_equal('other', $OTHER_VAR)
833
834      [g:globalvar, b:bufvar, w:winvar, t:tabvar, v:errmsg] =
835            ['global', 'buf', 'win', 'tab', 'error']
836      assert_equal('global', g:globalvar)
837      assert_equal('buf', b:bufvar)
838      assert_equal('win', w:winvar)
839      assert_equal('tab', t:tabvar)
840      assert_equal('error', v:errmsg)
841      unlet g:globalvar
842  END
843  CheckDefAndScriptSuccess(lines)
844
845  [g:globalvar, s:scriptvar, b:bufvar] = ['global', 'script', 'buf']
846  assert_equal('global', g:globalvar)
847  assert_equal('script', s:scriptvar)
848  assert_equal('buf', b:bufvar)
849
850  lines =<< trim END
851      vim9script
852      var s:scriptvar = 'init'
853      [g:globalvar, s:scriptvar, w:winvar] = ['global', 'script', 'win']
854      assert_equal('global', g:globalvar)
855      assert_equal('script', s:scriptvar)
856      assert_equal('win', w:winvar)
857  END
858  CheckScriptSuccess(lines)
859enddef
860
861def Test_assignment_vim9script()
862  var lines =<< trim END
863    vim9script
864    def Func(): list<number>
865      return [1, 2]
866    enddef
867    var name1: number
868    var name2: number
869    [name1, name2] =
870          Func()
871    assert_equal(1, name1)
872    assert_equal(2, name2)
873    var ll =
874          Func()
875    assert_equal([1, 2], ll)
876
877    @/ = 'text'
878    assert_equal('text', @/)
879    @0 = 'zero'
880    assert_equal('zero', @0)
881    @1 = 'one'
882    assert_equal('one', @1)
883    @9 = 'nine'
884    assert_equal('nine', @9)
885    @- = 'minus'
886    assert_equal('minus', @-)
887    if has('clipboard_working')
888      @* = 'star'
889      assert_equal('star', @*)
890      @+ = 'plus'
891      assert_equal('plus', @+)
892    endif
893
894    var a: number = 123
895    assert_equal(123, a)
896    var s: string = 'yes'
897    assert_equal('yes', s)
898    var b: number = 42
899    assert_equal(42, b)
900    var w: number = 43
901    assert_equal(43, w)
902    var t: number = 44
903    assert_equal(44, t)
904
905    var to_var = 0
906    to_var = 3
907    assert_equal(3, to_var)
908  END
909  CheckScriptSuccess(lines)
910
911  lines =<< trim END
912      vim9script
913      var n: number
914      def Func()
915        n = 'string'
916      enddef
917      defcompile
918  END
919  CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
920enddef
921
922def Mess(): string
923  v:foldstart = 123
924  return 'xxx'
925enddef
926
927def Test_assignment_failure()
928  CheckDefFailure(['var name=234'], 'E1004:')
929  CheckDefFailure(['var name =234'], 'E1004:')
930  CheckDefFailure(['var name= 234'], 'E1004:')
931
932  CheckScriptFailure(['vim9script', 'var name=234'], 'E1004:')
933  CheckScriptFailure(['vim9script', 'var name=234'], "before and after '='")
934  CheckScriptFailure(['vim9script', 'var name =234'], 'E1004:')
935  CheckScriptFailure(['vim9script', 'var name= 234'], 'E1004:')
936  CheckScriptFailure(['vim9script', 'var name = 234', 'name+=234'], 'E1004:')
937  CheckScriptFailure(['vim9script', 'var name = 234', 'name+=234'], "before and after '+='")
938  CheckScriptFailure(['vim9script', 'var name = "x"', 'name..="y"'], 'E1004:')
939  CheckScriptFailure(['vim9script', 'var name = "x"', 'name..="y"'], "before and after '..='")
940
941  CheckDefFailure(['var true = 1'], 'E1034:')
942  CheckDefFailure(['var false = 1'], 'E1034:')
943
944  CheckDefFailure(['[a; b; c] = g:list'], 'E452:')
945  CheckDefExecFailure(['var a: number',
946                       '[a] = test_null_list()'], 'E1093:')
947  CheckDefExecFailure(['var a: number',
948                       '[a] = []'], 'E1093:')
949  CheckDefExecFailure(['var x: number',
950                       'var y: number',
951                       '[x, y] = [1]'], 'E1093:')
952  CheckDefExecFailure(['var x: string',
953                       'var y: string',
954                       '[x, y] = ["x"]'], 'E1093:')
955  CheckDefExecFailure(['var x: number',
956                       'var y: number',
957                       'var z: list<number>',
958                       '[x, y; z] = [1]'], 'E1093:')
959
960  CheckDefFailure(['var somevar'], "E1022:")
961  CheckDefFailure(['var &tabstop = 4'], 'E1052:')
962  CheckDefFailure(['&g:option = 5'], 'E113:')
963  CheckScriptFailure(['vim9script', 'var &tabstop = 4'], 'E1052:')
964
965  CheckDefFailure(['var $VAR = 5'], 'E1016: Cannot declare an environment variable:')
966  CheckScriptFailure(['vim9script', 'var $ENV = "xxx"'], 'E1016:')
967
968  if has('dnd')
969    CheckDefFailure(['var @~ = 5'], 'E1066:')
970  else
971    CheckDefFailure(['var @~ = 5'], 'E354:')
972    CheckDefFailure(['@~ = 5'], 'E354:')
973  endif
974  CheckDefFailure(['var @a = 5'], 'E1066:')
975  CheckDefFailure(['var @/ = "x"'], 'E1066:')
976  CheckScriptFailure(['vim9script', 'var @a = "abc"'], 'E1066:')
977
978  CheckDefFailure(['var g:var = 5'], 'E1016: Cannot declare a global variable:')
979  CheckDefFailure(['var w:var = 5'], 'E1016: Cannot declare a window variable:')
980  CheckDefFailure(['var b:var = 5'], 'E1016: Cannot declare a buffer variable:')
981  CheckDefFailure(['var t:var = 5'], 'E1016: Cannot declare a tab variable:')
982
983  CheckDefFailure(['var anr = 4', 'anr ..= "text"'], 'E1019:')
984  CheckDefFailure(['var xnr += 4'], 'E1020:', 1)
985  CheckScriptFailure(['vim9script', 'var xnr += 4'], 'E1020:')
986  CheckDefFailure(["var xnr = xnr + 1"], 'E1001:', 1)
987  CheckScriptFailure(['vim9script', 'var xnr = xnr + 4'], 'E121:')
988
989  CheckScriptFailure(['vim9script', 'def Func()', 'var dummy = s:notfound', 'enddef', 'defcompile'], 'E1108:')
990
991  CheckDefFailure(['var name: list<string> = [123]'], 'expected list<string> but got list<number>')
992  CheckDefFailure(['var name: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
993
994  CheckDefFailure(['var name: dict<string> = {key: 123}'], 'expected dict<string> but got dict<number>')
995  CheckDefFailure(['var name: dict<number> = {key: "xx"}'], 'expected dict<number> but got dict<string>')
996
997  CheckDefFailure(['var name = feedkeys("0")'], 'E1031:')
998  CheckDefFailure(['var name: number = feedkeys("0")'], 'expected number but got void')
999
1000  CheckDefFailure(['var name: dict <number>'], 'E1068:')
1001  CheckDefFailure(['var name: dict<number'], 'E1009:')
1002
1003  assert_fails('s/^/\=Mess()/n', 'E794:')
1004  CheckDefFailure(['var name: dict<number'], 'E1009:')
1005
1006  CheckDefFailure(['w:foo: number = 10'],
1007                  'E488: Trailing characters: : number = 1')
1008  CheckDefFailure(['t:foo: bool = true'],
1009                  'E488: Trailing characters: : bool = true')
1010  CheckDefFailure(['b:foo: string = "x"'],
1011                  'E488: Trailing characters: : string = "x"')
1012  CheckDefFailure(['g:foo: number = 123'],
1013                  'E488: Trailing characters: : number = 123')
1014enddef
1015
1016def Test_assign_list()
1017  var l: list<string> = []
1018  l[0] = 'value'
1019  assert_equal('value', l[0])
1020
1021  l[1] = 'asdf'
1022  assert_equal('value', l[0])
1023  assert_equal('asdf', l[1])
1024  assert_equal('asdf', l[-1])
1025  assert_equal('value', l[-2])
1026
1027  var nrl: list<number> = []
1028  for i in range(5)
1029    nrl[i] = i
1030  endfor
1031  assert_equal([0, 1, 2, 3, 4], nrl)
1032
1033  CheckDefFailure(["var l: list<number> = ['', true]"], 'E1012: Type mismatch; expected list<number> but got list<any>', 1)
1034  CheckDefFailure(["var l: list<list<number>> = [['', true]]"], 'E1012: Type mismatch; expected list<list<number>> but got list<list<any>>', 1)
1035enddef
1036
1037def Test_assign_dict()
1038  var lines =<< trim END
1039      var d: dict<string> = {}
1040      d['key'] = 'value'
1041      assert_equal('value', d['key'])
1042
1043      d[123] = 'qwerty'
1044      assert_equal('qwerty', d[123])
1045      assert_equal('qwerty', d['123'])
1046
1047      var nrd: dict<number> = {}
1048      for i in range(3)
1049        nrd[i] = i
1050      endfor
1051      assert_equal({0: 0, 1: 1, 2: 2}, nrd)
1052
1053      d.somekey = 'someval'
1054      assert_equal({key: 'value', '123': 'qwerty', somekey: 'someval'}, d)
1055      # unlet d.somekey
1056      # assert_equal({key: 'value', '123': 'qwerty'}, d)
1057  END
1058  CheckDefAndScriptSuccess(lines)
1059
1060  # TODO: move to above once "unlet d.somekey" in :def is implemented
1061  lines =<< trim END
1062      vim9script
1063      var d: dict<string> = {}
1064      d['key'] = 'value'
1065      d.somekey = 'someval'
1066      assert_equal({key: 'value', somekey: 'someval'}, d)
1067      unlet d.somekey
1068      assert_equal({key: 'value'}, d)
1069  END
1070  CheckScriptSuccess(lines)
1071
1072  CheckDefFailure(["var d: dict<number> = {a: '', b: true}"], 'E1012: Type mismatch; expected dict<number> but got dict<any>', 1)
1073  CheckDefFailure(["var d: dict<dict<number>> = {x: {a: '', b: true}}"], 'E1012: Type mismatch; expected dict<dict<number>> but got dict<dict<any>>', 1)
1074enddef
1075
1076def Test_assign_dict_unknown_type()
1077  var lines =<< trim END
1078      vim9script
1079      var mylist = []
1080      mylist += [{one: 'one'}]
1081      def Func()
1082        var dd = mylist[0]
1083        assert_equal('one', dd.one)
1084      enddef
1085      Func()
1086  END
1087  CheckScriptSuccess(lines)
1088
1089  lines =<< trim END
1090      vim9script
1091      var mylist = [[]]
1092      mylist[0] += [{one: 'one'}]
1093      def Func()
1094        var dd = mylist[0][0]
1095        assert_equal('one', dd.one)
1096      enddef
1097      Func()
1098  END
1099  CheckScriptSuccess(lines)
1100enddef
1101
1102def Test_assign_lambda()
1103  # check if assign a lambda to a variable which type is func or any.
1104  var lines =<< trim END
1105      vim9script
1106      var FuncRef = () => 123
1107      assert_equal(123, FuncRef())
1108      var FuncRef_Func: func = () => 123
1109      assert_equal(123, FuncRef_Func())
1110      var FuncRef_Any: any = () => 123
1111      assert_equal(123, FuncRef_Any())
1112      var FuncRef_Number: func(): number = () => 321
1113      assert_equal(321, FuncRef_Number())
1114  END
1115  CheckScriptSuccess(lines)
1116
1117  lines =<< trim END
1118      var Ref: func(number)
1119      Ref = (j) => !j
1120  END
1121  CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(any): bool')
1122
1123  lines =<< trim END
1124      echo filter([1, 2, 3], (_, v: string) => v + 1)
1125  END
1126  CheckDefAndScriptFailure(lines, 'E1051:')
1127enddef
1128
1129def Test_heredoc()
1130  var lines =<< trim END # comment
1131    text
1132  END
1133  assert_equal(['text'], lines)
1134
1135  CheckDefFailure(['var lines =<< trim END X', 'END'], 'E488:')
1136  CheckDefFailure(['var lines =<< trim END " comment', 'END'], 'E488:')
1137
1138  lines =<< trim [END]
1139      def Func()
1140        var&lines =<< trim END
1141        x
1142        x
1143      enddef
1144      defcompile
1145  [END]
1146  CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END')
1147  delfunc! g:Func
1148
1149  lines =<< trim [END]
1150      def Func()
1151        var lines =<< trim END
1152        x
1153        x
1154        x
1155        x
1156        x
1157        x
1158        x
1159        x
1160      enddef
1161      call Func()
1162  [END]
1163  CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END')
1164  delfunc! g:Func
1165enddef
1166
1167def Test_var_func_call()
1168  var lines =<< trim END
1169    vim9script
1170    func GetValue()
1171      if exists('g:count')
1172        let g:count += 1
1173      else
1174        let g:count = 1
1175      endif
1176      return 'this'
1177    endfunc
1178    var val: string = GetValue()
1179    # env var is always a string
1180    var env = $TERM
1181  END
1182  writefile(lines, 'Xfinished')
1183  source Xfinished
1184  # GetValue() is not called during discovery phase
1185  assert_equal(1, g:count)
1186
1187  unlet g:count
1188  delete('Xfinished')
1189enddef
1190
1191def Test_var_missing_type()
1192  var lines =<< trim END
1193    vim9script
1194    var name = g:unknown
1195  END
1196  CheckScriptFailure(lines, 'E121:')
1197
1198  lines =<< trim END
1199    vim9script
1200    var nr: number = 123
1201    var name = nr
1202  END
1203  CheckScriptSuccess(lines)
1204enddef
1205
1206def Test_var_declaration()
1207  var lines =<< trim END
1208    vim9script
1209    var name: string
1210    g:var_uninit = name
1211    name = 'text'
1212    g:var_test = name
1213    # prefixing s: is optional
1214    s:name = 'prefixed'
1215    g:var_prefixed = s:name
1216
1217    const FOO: number = 123
1218    assert_equal(123, FOO)
1219    const FOOS = 'foos'
1220    assert_equal('foos', FOOS)
1221    final FLIST = [1]
1222    assert_equal([1], FLIST)
1223    FLIST[0] = 11
1224    assert_equal([11], FLIST)
1225
1226    const g:FOO: number = 321
1227    assert_equal(321, g:FOO)
1228    const g:FOOS = 'gfoos'
1229    assert_equal('gfoos', g:FOOS)
1230    final g:FLIST = [2]
1231    assert_equal([2], g:FLIST)
1232    g:FLIST[0] = 22
1233    assert_equal([22], g:FLIST)
1234
1235    const w:FOO: number = 46
1236    assert_equal(46, w:FOO)
1237    const w:FOOS = 'wfoos'
1238    assert_equal('wfoos', w:FOOS)
1239    final w:FLIST = [3]
1240    assert_equal([3], w:FLIST)
1241    w:FLIST[0] = 33
1242    assert_equal([33], w:FLIST)
1243
1244    var s:other: number
1245    other = 1234
1246    g:other_var = other
1247
1248    # type is inferred
1249    var s:dict = {['a']: 222}
1250    def GetDictVal(key: any)
1251      g:dict_val = s:dict[key]
1252    enddef
1253    GetDictVal('a')
1254
1255    final adict: dict<string> = {}
1256    def ChangeAdict()
1257      adict.foo = 'foo'
1258    enddef
1259    ChangeAdict()
1260  END
1261  CheckScriptSuccess(lines)
1262  assert_equal('', g:var_uninit)
1263  assert_equal('text', g:var_test)
1264  assert_equal('prefixed', g:var_prefixed)
1265  assert_equal(1234, g:other_var)
1266  assert_equal(222, g:dict_val)
1267
1268  unlet g:var_uninit
1269  unlet g:var_test
1270  unlet g:var_prefixed
1271  unlet g:other_var
1272  unlet g:FOO
1273  unlet g:FOOS
1274  unlet g:FLIST
1275  unlet w:FOO
1276  unlet w:FOOS
1277  unlet w:FLIST
1278enddef
1279
1280def Test_var_declaration_fails()
1281  var lines =<< trim END
1282    vim9script
1283    final var: string
1284  END
1285  CheckScriptFailure(lines, 'E1125:')
1286
1287  lines =<< trim END
1288    vim9script
1289    const g:constvar = 'string'
1290    g:constvar = 'xx'
1291  END
1292  CheckScriptFailure(lines, 'E741:')
1293  unlet g:constvar
1294
1295  lines =<< trim END
1296    vim9script
1297    const cdict: dict<string> = {}
1298    def Change()
1299      cdict.foo = 'foo'
1300    enddef
1301    defcompile
1302  END
1303  CheckScriptFailure(lines, 'E46:')
1304
1305  lines =<< trim END
1306    vim9script
1307    final w:finalvar = [9]
1308    w:finalvar = [8]
1309  END
1310  CheckScriptFailure(lines, 'E1122:')
1311  unlet w:finalvar
1312
1313  lines =<< trim END
1314    vim9script
1315    const var: string
1316  END
1317  CheckScriptFailure(lines, 'E1021:')
1318
1319  lines =<< trim END
1320    vim9script
1321    var 9var: string
1322  END
1323  CheckScriptFailure(lines, 'E475:')
1324
1325  CheckDefFailure(['var foo.bar = 2'], 'E1087:')
1326  CheckDefFailure(['var foo[3] = 2'], 'E1087:')
1327  CheckDefFailure(['const foo: number'], 'E1021:')
1328enddef
1329
1330def Test_var_type_check()
1331  var lines =<< trim END
1332    vim9script
1333    var name: string
1334    name = 1234
1335  END
1336  CheckScriptFailure(lines, 'E1012:')
1337
1338  lines =<< trim END
1339    vim9script
1340    var name:string
1341  END
1342  CheckScriptFailure(lines, 'E1069:')
1343
1344  lines =<< trim END
1345    vim9script
1346    var name: asdf
1347  END
1348  CheckScriptFailure(lines, 'E1010:')
1349
1350  lines =<< trim END
1351    vim9script
1352    var s:l: list<number>
1353    s:l = []
1354  END
1355  CheckScriptSuccess(lines)
1356
1357  lines =<< trim END
1358    vim9script
1359    var s:d: dict<number>
1360    s:d = {}
1361  END
1362  CheckScriptSuccess(lines)
1363enddef
1364
1365let g:dict_number = #{one: 1, two: 2}
1366
1367def Test_var_list_dict_type()
1368  var ll: list<number>
1369  ll = [1, 2, 2, 3, 3, 3]->uniq()
1370  ll->assert_equal([1, 2, 3])
1371
1372  var dd: dict<number>
1373  dd = g:dict_number
1374  dd->assert_equal(g:dict_number)
1375
1376  var lines =<< trim END
1377      var ll: list<number>
1378      ll = [1, 2, 3]->map('"one"')
1379  END
1380  CheckDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string')
1381enddef
1382
1383def Test_cannot_use_let()
1384  CheckDefAndScriptFailure(['let a = 34'], 'E1126:', 1)
1385enddef
1386
1387def Test_unlet()
1388  g:somevar = 'yes'
1389  assert_true(exists('g:somevar'))
1390  unlet g:somevar
1391  assert_false(exists('g:somevar'))
1392  unlet! g:somevar
1393
1394  # also works for script-local variable in legacy Vim script
1395  s:somevar = 'legacy'
1396  assert_true(exists('s:somevar'))
1397  unlet s:somevar
1398  assert_false(exists('s:somevar'))
1399  unlet! s:somevar
1400
1401  CheckDefExecFailure([
1402    'var dd = 111',
1403    'unlet dd',
1404    ], 'E1081:', 2)
1405
1406  # dict unlet
1407  var dd = {a: 1, b: 2, c: 3}
1408  unlet dd['a']
1409  unlet dd.c
1410  assert_equal({b: 2}, dd)
1411
1412  # list unlet
1413  var ll = [1, 2, 3, 4]
1414  unlet ll[1]
1415  unlet ll[-1]
1416  assert_equal([1, 3], ll)
1417
1418  ll = [1, 2, 3, 4]
1419  unlet ll[0 : 1]
1420  assert_equal([3, 4], ll)
1421
1422  ll = [1, 2, 3, 4]
1423  unlet ll[2 : 8]
1424  assert_equal([1, 2], ll)
1425
1426  ll = [1, 2, 3, 4]
1427  unlet ll[-2 : -1]
1428  assert_equal([1, 2], ll)
1429
1430  CheckDefFailure([
1431    'var ll = [1, 2]',
1432    'll[1 : 2] = 7',
1433    ], 'E1165:', 2)
1434  CheckDefFailure([
1435    'var dd = {a: 1}',
1436    'unlet dd["a" : "a"]',
1437    ], 'E1166:', 2)
1438  CheckDefExecFailure([
1439    'unlet g:adict[0 : 1]',
1440    ], 'E1148:', 1)
1441  CheckDefFailure([
1442    'var ll = [1, 2]',
1443    'unlet ll[0:1]',
1444    ], 'E1004:', 2)
1445  CheckDefFailure([
1446    'var ll = [1, 2]',
1447    'unlet ll[0 :1]',
1448    ], 'E1004:', 2)
1449  CheckDefFailure([
1450    'var ll = [1, 2]',
1451    'unlet ll[0: 1]',
1452    ], 'E1004:', 2)
1453
1454  CheckDefFailure([
1455    'var ll = [1, 2]',
1456    'unlet ll["x" : 1]',
1457    ], 'E1012:', 2)
1458  CheckDefFailure([
1459    'var ll = [1, 2]',
1460    'unlet ll[0 : "x"]',
1461    ], 'E1012:', 2)
1462
1463  # list of dict unlet
1464  var dl = [{a: 1, b: 2}, {c: 3}]
1465  unlet dl[0]['b']
1466  assert_equal([{a: 1}, {c: 3}], dl)
1467
1468  CheckDefExecFailure([
1469    'var ll = test_null_list()',
1470    'unlet ll[0]',
1471    ], 'E684:', 2)
1472  CheckDefExecFailure([
1473    'var ll = [1]',
1474    'unlet ll[2]',
1475    ], 'E684:', 2)
1476  CheckDefExecFailure([
1477    'var ll = [1]',
1478    'unlet ll[g:astring]',
1479    ], 'E1012:', 2)
1480  CheckDefExecFailure([
1481    'var dd = test_null_dict()',
1482    'unlet dd["a"]',
1483    ], 'E716:', 2)
1484  CheckDefExecFailure([
1485    'var dd = {a: 1}',
1486    'unlet dd["b"]',
1487    ], 'E716:', 2)
1488  CheckDefExecFailure([
1489    'var dd = {a: 1}',
1490    'unlet dd[g:alist]',
1491    ], 'E1105:', 2)
1492
1493  # can compile unlet before variable exists
1494  g:someDict = {key: 'val'}
1495  var k = 'key'
1496  unlet g:someDict[k]
1497  assert_equal({}, g:someDict)
1498  unlet g:someDict
1499  assert_false(exists('g:someDict'))
1500
1501  CheckScriptFailure([
1502   'vim9script',
1503   'var svar = 123',
1504   'unlet svar',
1505   ], 'E1081:')
1506  CheckScriptFailure([
1507   'vim9script',
1508   'var svar = 123',
1509   'unlet s:svar',
1510   ], 'E1081:')
1511  CheckScriptFailure([
1512   'vim9script',
1513   'var svar = 123',
1514   'def Func()',
1515   '  unlet svar',
1516   'enddef',
1517   'defcompile',
1518   ], 'E1081:')
1519  CheckScriptFailure([
1520   'vim9script',
1521   'var svar = 123',
1522   'func Func()',
1523   '  unlet s:svar',
1524   'endfunc',
1525   'Func()',
1526   ], 'E1081:')
1527  CheckScriptFailure([
1528   'vim9script',
1529   'var svar = 123',
1530   'def Func()',
1531   '  unlet s:svar',
1532   'enddef',
1533   'defcompile',
1534   ], 'E1081:')
1535
1536  writefile(['vim9script', 'export var svar = 1234'], 'XunletExport.vim')
1537  var lines =<< trim END
1538    vim9script
1539    import svar from './XunletExport.vim'
1540    def UnletSvar()
1541      unlet svar
1542    enddef
1543    defcompile
1544  END
1545  CheckScriptFailure(lines, 'E1081:', 1)
1546  delete('XunletExport.vim')
1547
1548  $ENVVAR = 'foobar'
1549  assert_equal('foobar', $ENVVAR)
1550  unlet $ENVVAR
1551  assert_equal('', $ENVVAR)
1552enddef
1553
1554def Test_expr_error_no_assign()
1555  var lines =<< trim END
1556      vim9script
1557      var x = invalid
1558      echo x
1559  END
1560  CheckScriptFailureList(lines, ['E121:', 'E121:'])
1561
1562  lines =<< trim END
1563      vim9script
1564      var x = 1 / 0
1565      echo x
1566  END
1567  CheckScriptFailureList(lines, ['E1154:', 'E121:'])
1568
1569  lines =<< trim END
1570      vim9script
1571      var x = 1 % 0
1572      echo x
1573  END
1574  CheckScriptFailureList(lines, ['E1154:', 'E121:'])
1575enddef
1576
1577
1578def Test_assign_command_modifier()
1579  var lines =<< trim END
1580      var verbose = 0
1581      verbose = 1
1582      assert_equal(1, verbose)
1583      silent verbose = 2
1584      assert_equal(2, verbose)
1585      silent verbose += 2
1586      assert_equal(4, verbose)
1587      silent verbose -= 1
1588      assert_equal(3, verbose)
1589
1590      var topleft = {one: 1}
1591      sandbox topleft.one = 3
1592      assert_equal({one: 3}, topleft)
1593      leftabove topleft[' '] = 4
1594      assert_equal({one: 3, ' ': 4}, topleft)
1595
1596      var x: number
1597      var y: number
1598      silent [x, y] = [1, 2]
1599      assert_equal(1, x)
1600      assert_equal(2, y)
1601  END
1602  CheckDefAndScriptSuccess(lines)
1603enddef
1604
1605
1606" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
1607