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_dict_with_op()
1103  var lines =<< trim END
1104    vim9script
1105    var ds: dict<string> = {a: 'x'}
1106    ds['a'] ..= 'y'
1107    ds.a ..= 'z'
1108    assert_equal('xyz', ds.a)
1109
1110    var dn: dict<number> = {a: 9}
1111    dn['a'] += 2
1112    assert_equal(11, dn.a)
1113    dn.a += 2
1114    assert_equal(13, dn.a)
1115
1116    dn['a'] -= 3
1117    assert_equal(10, dn.a)
1118    dn.a -= 2
1119    assert_equal(8, dn.a)
1120
1121    dn['a'] *= 2
1122    assert_equal(16, dn.a)
1123    dn.a *= 2
1124    assert_equal(32, dn.a)
1125
1126    dn['a'] /= 3
1127    assert_equal(10, dn.a)
1128    dn.a /= 2
1129    assert_equal(5, dn.a)
1130
1131    dn['a'] %= 3
1132    assert_equal(2, dn.a)
1133    dn.a %= 6
1134    assert_equal(2, dn.a)
1135  END
1136  # TODO: this should also work with a :def function
1137  CheckScriptSuccess(lines)
1138enddef
1139
1140def Test_assign_lambda()
1141  # check if assign a lambda to a variable which type is func or any.
1142  var lines =<< trim END
1143      vim9script
1144      var FuncRef = () => 123
1145      assert_equal(123, FuncRef())
1146      var FuncRef_Func: func = () => 123
1147      assert_equal(123, FuncRef_Func())
1148      var FuncRef_Any: any = () => 123
1149      assert_equal(123, FuncRef_Any())
1150      var FuncRef_Number: func(): number = () => 321
1151      assert_equal(321, FuncRef_Number())
1152  END
1153  CheckScriptSuccess(lines)
1154
1155  lines =<< trim END
1156      var Ref: func(number)
1157      Ref = (j) => !j
1158  END
1159  CheckDefAndScriptFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(any): bool')
1160
1161  lines =<< trim END
1162      echo filter([1, 2, 3], (_, v: string) => v + 1)
1163  END
1164  CheckDefAndScriptFailure(lines, 'E1051:')
1165enddef
1166
1167def Test_heredoc()
1168  var lines =<< trim END # comment
1169    text
1170  END
1171  assert_equal(['text'], lines)
1172
1173  CheckDefFailure(['var lines =<< trim END X', 'END'], 'E488:')
1174  CheckDefFailure(['var lines =<< trim END " comment', 'END'], 'E488:')
1175
1176  lines =<< trim [END]
1177      def Func()
1178        var&lines =<< trim END
1179        x
1180        x
1181      enddef
1182      defcompile
1183  [END]
1184  CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END')
1185  delfunc! g:Func
1186
1187  lines =<< trim [END]
1188      def Func()
1189        var lines =<< trim END
1190        x
1191        x
1192        x
1193        x
1194        x
1195        x
1196        x
1197        x
1198      enddef
1199      call Func()
1200  [END]
1201  CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END')
1202  delfunc! g:Func
1203enddef
1204
1205def Test_var_func_call()
1206  var lines =<< trim END
1207    vim9script
1208    func GetValue()
1209      if exists('g:count')
1210        let g:count += 1
1211      else
1212        let g:count = 1
1213      endif
1214      return 'this'
1215    endfunc
1216    var val: string = GetValue()
1217    # env var is always a string
1218    var env = $TERM
1219  END
1220  writefile(lines, 'Xfinished')
1221  source Xfinished
1222  # GetValue() is not called during discovery phase
1223  assert_equal(1, g:count)
1224
1225  unlet g:count
1226  delete('Xfinished')
1227enddef
1228
1229def Test_var_missing_type()
1230  var lines =<< trim END
1231    vim9script
1232    var name = g:unknown
1233  END
1234  CheckScriptFailure(lines, 'E121:')
1235
1236  lines =<< trim END
1237    vim9script
1238    var nr: number = 123
1239    var name = nr
1240  END
1241  CheckScriptSuccess(lines)
1242enddef
1243
1244def Test_var_declaration()
1245  var lines =<< trim END
1246    vim9script
1247    var name: string
1248    g:var_uninit = name
1249    name = 'text'
1250    g:var_test = name
1251    # prefixing s: is optional
1252    s:name = 'prefixed'
1253    g:var_prefixed = s:name
1254
1255    const FOO: number = 123
1256    assert_equal(123, FOO)
1257    const FOOS = 'foos'
1258    assert_equal('foos', FOOS)
1259    final FLIST = [1]
1260    assert_equal([1], FLIST)
1261    FLIST[0] = 11
1262    assert_equal([11], FLIST)
1263
1264    const g:FOO: number = 321
1265    assert_equal(321, g:FOO)
1266    const g:FOOS = 'gfoos'
1267    assert_equal('gfoos', g:FOOS)
1268    final g:FLIST = [2]
1269    assert_equal([2], g:FLIST)
1270    g:FLIST[0] = 22
1271    assert_equal([22], g:FLIST)
1272
1273    const w:FOO: number = 46
1274    assert_equal(46, w:FOO)
1275    const w:FOOS = 'wfoos'
1276    assert_equal('wfoos', w:FOOS)
1277    final w:FLIST = [3]
1278    assert_equal([3], w:FLIST)
1279    w:FLIST[0] = 33
1280    assert_equal([33], w:FLIST)
1281
1282    var s:other: number
1283    other = 1234
1284    g:other_var = other
1285
1286    # type is inferred
1287    var s:dict = {['a']: 222}
1288    def GetDictVal(key: any)
1289      g:dict_val = s:dict[key]
1290    enddef
1291    GetDictVal('a')
1292
1293    final adict: dict<string> = {}
1294    def ChangeAdict()
1295      adict.foo = 'foo'
1296    enddef
1297    ChangeAdict()
1298  END
1299  CheckScriptSuccess(lines)
1300  assert_equal('', g:var_uninit)
1301  assert_equal('text', g:var_test)
1302  assert_equal('prefixed', g:var_prefixed)
1303  assert_equal(1234, g:other_var)
1304  assert_equal(222, g:dict_val)
1305
1306  unlet g:var_uninit
1307  unlet g:var_test
1308  unlet g:var_prefixed
1309  unlet g:other_var
1310  unlet g:FOO
1311  unlet g:FOOS
1312  unlet g:FLIST
1313  unlet w:FOO
1314  unlet w:FOOS
1315  unlet w:FLIST
1316enddef
1317
1318def Test_var_declaration_fails()
1319  var lines =<< trim END
1320    vim9script
1321    final var: string
1322  END
1323  CheckScriptFailure(lines, 'E1125:')
1324
1325  lines =<< trim END
1326    vim9script
1327    const g:constvar = 'string'
1328    g:constvar = 'xx'
1329  END
1330  CheckScriptFailure(lines, 'E741:')
1331  unlet g:constvar
1332
1333  lines =<< trim END
1334    vim9script
1335    const cdict: dict<string> = {}
1336    def Change()
1337      cdict.foo = 'foo'
1338    enddef
1339    defcompile
1340  END
1341  CheckScriptFailure(lines, 'E46:')
1342
1343  lines =<< trim END
1344    vim9script
1345    final w:finalvar = [9]
1346    w:finalvar = [8]
1347  END
1348  CheckScriptFailure(lines, 'E1122:')
1349  unlet w:finalvar
1350
1351  lines =<< trim END
1352    vim9script
1353    const var: string
1354  END
1355  CheckScriptFailure(lines, 'E1021:')
1356
1357  lines =<< trim END
1358    vim9script
1359    var 9var: string
1360  END
1361  CheckScriptFailure(lines, 'E475:')
1362
1363  CheckDefFailure(['var foo.bar = 2'], 'E1087:')
1364  CheckDefFailure(['var foo[3] = 2'], 'E1087:')
1365  CheckDefFailure(['const foo: number'], 'E1021:')
1366enddef
1367
1368def Test_var_type_check()
1369  var lines =<< trim END
1370    vim9script
1371    var name: string
1372    name = 1234
1373  END
1374  CheckScriptFailure(lines, 'E1012:')
1375
1376  lines =<< trim END
1377    vim9script
1378    var name:string
1379  END
1380  CheckScriptFailure(lines, 'E1069:')
1381
1382  lines =<< trim END
1383    vim9script
1384    var name: asdf
1385  END
1386  CheckScriptFailure(lines, 'E1010:')
1387
1388  lines =<< trim END
1389    vim9script
1390    var s:l: list<number>
1391    s:l = []
1392  END
1393  CheckScriptSuccess(lines)
1394
1395  lines =<< trim END
1396    vim9script
1397    var s:d: dict<number>
1398    s:d = {}
1399  END
1400  CheckScriptSuccess(lines)
1401enddef
1402
1403let g:dict_number = #{one: 1, two: 2}
1404
1405def Test_var_list_dict_type()
1406  var ll: list<number>
1407  ll = [1, 2, 2, 3, 3, 3]->uniq()
1408  ll->assert_equal([1, 2, 3])
1409
1410  var dd: dict<number>
1411  dd = g:dict_number
1412  dd->assert_equal(g:dict_number)
1413
1414  var lines =<< trim END
1415      var ll: list<number>
1416      ll = [1, 2, 3]->map('"one"')
1417  END
1418  CheckDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string')
1419enddef
1420
1421def Test_cannot_use_let()
1422  CheckDefAndScriptFailure(['let a = 34'], 'E1126:', 1)
1423enddef
1424
1425def Test_unlet()
1426  g:somevar = 'yes'
1427  assert_true(exists('g:somevar'))
1428  unlet g:somevar
1429  assert_false(exists('g:somevar'))
1430  unlet! g:somevar
1431
1432  # also works for script-local variable in legacy Vim script
1433  s:somevar = 'legacy'
1434  assert_true(exists('s:somevar'))
1435  unlet s:somevar
1436  assert_false(exists('s:somevar'))
1437  unlet! s:somevar
1438
1439  CheckDefExecFailure([
1440    'var dd = 111',
1441    'unlet dd',
1442    ], 'E1081:', 2)
1443
1444  # dict unlet
1445  var dd = {a: 1, b: 2, c: 3}
1446  unlet dd['a']
1447  unlet dd.c
1448  assert_equal({b: 2}, dd)
1449
1450  # list unlet
1451  var ll = [1, 2, 3, 4]
1452  unlet ll[1]
1453  unlet ll[-1]
1454  assert_equal([1, 3], ll)
1455
1456  ll = [1, 2, 3, 4]
1457  unlet ll[0 : 1]
1458  assert_equal([3, 4], ll)
1459
1460  ll = [1, 2, 3, 4]
1461  unlet ll[2 : 8]
1462  assert_equal([1, 2], ll)
1463
1464  ll = [1, 2, 3, 4]
1465  unlet ll[-2 : -1]
1466  assert_equal([1, 2], ll)
1467
1468  CheckDefFailure([
1469    'var ll = [1, 2]',
1470    'll[1 : 2] = 7',
1471    ], 'E1165:', 2)
1472  CheckDefFailure([
1473    'var dd = {a: 1}',
1474    'unlet dd["a" : "a"]',
1475    ], 'E1166:', 2)
1476  CheckDefExecFailure([
1477    'unlet g:adict[0 : 1]',
1478    ], 'E1148:', 1)
1479  CheckDefFailure([
1480    'var ll = [1, 2]',
1481    'unlet ll[0:1]',
1482    ], 'E1004:', 2)
1483  CheckDefFailure([
1484    'var ll = [1, 2]',
1485    'unlet ll[0 :1]',
1486    ], 'E1004:', 2)
1487  CheckDefFailure([
1488    'var ll = [1, 2]',
1489    'unlet ll[0: 1]',
1490    ], 'E1004:', 2)
1491
1492  CheckDefFailure([
1493    'var ll = [1, 2]',
1494    'unlet ll["x" : 1]',
1495    ], 'E1012:', 2)
1496  CheckDefFailure([
1497    'var ll = [1, 2]',
1498    'unlet ll[0 : "x"]',
1499    ], 'E1012:', 2)
1500
1501  # list of dict unlet
1502  var dl = [{a: 1, b: 2}, {c: 3}]
1503  unlet dl[0]['b']
1504  assert_equal([{a: 1}, {c: 3}], dl)
1505
1506  CheckDefExecFailure([
1507    'var ll = test_null_list()',
1508    'unlet ll[0]',
1509    ], 'E684:', 2)
1510  CheckDefExecFailure([
1511    'var ll = [1]',
1512    'unlet ll[2]',
1513    ], 'E684:', 2)
1514  CheckDefExecFailure([
1515    'var ll = [1]',
1516    'unlet ll[g:astring]',
1517    ], 'E1012:', 2)
1518  CheckDefExecFailure([
1519    'var dd = test_null_dict()',
1520    'unlet dd["a"]',
1521    ], 'E716:', 2)
1522  CheckDefExecFailure([
1523    'var dd = {a: 1}',
1524    'unlet dd["b"]',
1525    ], 'E716:', 2)
1526  CheckDefExecFailure([
1527    'var dd = {a: 1}',
1528    'unlet dd[g:alist]',
1529    ], 'E1105:', 2)
1530
1531  # can compile unlet before variable exists
1532  g:someDict = {key: 'val'}
1533  var k = 'key'
1534  unlet g:someDict[k]
1535  assert_equal({}, g:someDict)
1536  unlet g:someDict
1537  assert_false(exists('g:someDict'))
1538
1539  CheckScriptFailure([
1540   'vim9script',
1541   'var svar = 123',
1542   'unlet svar',
1543   ], 'E1081:')
1544  CheckScriptFailure([
1545   'vim9script',
1546   'var svar = 123',
1547   'unlet s:svar',
1548   ], 'E1081:')
1549  CheckScriptFailure([
1550   'vim9script',
1551   'var svar = 123',
1552   'def Func()',
1553   '  unlet svar',
1554   'enddef',
1555   'defcompile',
1556   ], 'E1081:')
1557  CheckScriptFailure([
1558   'vim9script',
1559   'var svar = 123',
1560   'func Func()',
1561   '  unlet s:svar',
1562   'endfunc',
1563   'Func()',
1564   ], 'E1081:')
1565  CheckScriptFailure([
1566   'vim9script',
1567   'var svar = 123',
1568   'def Func()',
1569   '  unlet s:svar',
1570   'enddef',
1571   'defcompile',
1572   ], 'E1081:')
1573
1574  writefile(['vim9script', 'export var svar = 1234'], 'XunletExport.vim')
1575  var lines =<< trim END
1576    vim9script
1577    import svar from './XunletExport.vim'
1578    def UnletSvar()
1579      unlet svar
1580    enddef
1581    defcompile
1582  END
1583  CheckScriptFailure(lines, 'E1081:', 1)
1584  delete('XunletExport.vim')
1585
1586  $ENVVAR = 'foobar'
1587  assert_equal('foobar', $ENVVAR)
1588  unlet $ENVVAR
1589  assert_equal('', $ENVVAR)
1590enddef
1591
1592def Test_expr_error_no_assign()
1593  var lines =<< trim END
1594      vim9script
1595      var x = invalid
1596      echo x
1597  END
1598  CheckScriptFailureList(lines, ['E121:', 'E121:'])
1599
1600  lines =<< trim END
1601      vim9script
1602      var x = 1 / 0
1603      echo x
1604  END
1605  CheckScriptFailureList(lines, ['E1154:', 'E121:'])
1606
1607  lines =<< trim END
1608      vim9script
1609      var x = 1 % 0
1610      echo x
1611  END
1612  CheckScriptFailureList(lines, ['E1154:', 'E121:'])
1613enddef
1614
1615
1616def Test_assign_command_modifier()
1617  var lines =<< trim END
1618      var verbose = 0
1619      verbose = 1
1620      assert_equal(1, verbose)
1621      silent verbose = 2
1622      assert_equal(2, verbose)
1623      silent verbose += 2
1624      assert_equal(4, verbose)
1625      silent verbose -= 1
1626      assert_equal(3, verbose)
1627
1628      var topleft = {one: 1}
1629      sandbox topleft.one = 3
1630      assert_equal({one: 3}, topleft)
1631      leftabove topleft[' '] = 4
1632      assert_equal({one: 3, ' ': 4}, topleft)
1633
1634      var x: number
1635      var y: number
1636      silent [x, y] = [1, 2]
1637      assert_equal(1, x)
1638      assert_equal(2, y)
1639  END
1640  CheckDefAndScriptSuccess(lines)
1641enddef
1642
1643
1644" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
1645