1" Tests for Vim9 script expressions
2
3source check.vim
4source vim9.vim
5
6let g:cond = v:false
7def FuncOne(arg: number): string
8  return 'yes'
9enddef
10def FuncTwo(arg: number): number
11  return 123
12enddef
13
14" test cond ? expr : expr
15def Test_expr1_trinary()
16  var lines =<< trim END
17      assert_equal('one', true ? 'one' : 'two')
18      assert_equal('one', 1 ?
19                            'one' :
20                            'two')
21      if has('float')
22        assert_equal('one', !!0.1 ? 'one' : 'two')
23      endif
24      assert_equal('one', !!'x' ? 'one' : 'two')
25      assert_equal('one', !!'x'
26                            ? 'one'
27                            : 'two')
28      assert_equal('one', !!0z1234 ? 'one' : 'two')
29      assert_equal('one', !![0] ? 'one' : 'two')
30      assert_equal('one', !!{x: 0} ? 'one' : 'two')
31      var name = 1
32      assert_equal('one', name ? 'one' : 'two')
33
34      assert_equal('two', false ? 'one' : 'two')
35      assert_equal('two', 0 ? 'one' : 'two')
36      if has('float')
37        assert_equal('two', !!0.0 ? 'one' : 'two')
38      endif
39      assert_equal('two', !!'' ? 'one' : 'two')
40      assert_equal('two', !!0z ? 'one' : 'two')
41      assert_equal('two', !![] ? 'one' : 'two')
42      assert_equal('two', !!{} ? 'one' : 'two')
43      name = 0
44      assert_equal('two', name ? 'one' : 'two')
45
46      # with constant condition expression is not evaluated
47      assert_equal('one', 1 ? 'one' : xxx)
48
49      var Some: func = function('len')
50      var Other: func = function('winnr')
51      var Res: func = g:atrue ? Some : Other
52      assert_equal(function('len'), Res)
53
54      var RetOne: func(string): number = function('len')
55      var RetTwo: func(string): number = function('winnr')
56      var RetThat: func = g:atrue ? RetOne : RetTwo
57      assert_equal(function('len'), RetThat)
58
59      var X = FuncOne
60      var Y = FuncTwo
61      var Z = g:cond ? FuncOne : FuncTwo
62      assert_equal(123, Z(3))
63  END
64  CheckDefAndScriptSuccess(lines)
65enddef
66
67def Test_expr1_trinary_vimscript()
68  # check line continuation
69  var lines =<< trim END
70      vim9script
71      var name = 1
72      		? 'yes'
73		: 'no'
74      assert_equal('yes', name)
75  END
76  CheckScriptSuccess(lines)
77
78  lines =<< trim END
79      vim9script
80      var name = v:false
81      		? 'yes'
82		: 'no'
83      assert_equal('no', name)
84  END
85  CheckScriptSuccess(lines)
86
87  lines =<< trim END
88      vim9script
89      var name = v:false ?
90      		'yes' :
91		'no'
92      assert_equal('no', name)
93  END
94  CheckScriptSuccess(lines)
95
96  lines =<< trim END
97      vim9script
98      var name = v:false ?  # comment
99      		'yes' :
100                # comment
101		'no' # comment
102      assert_equal('no', name)
103  END
104  CheckScriptSuccess(lines)
105
106  # check white space
107  lines =<< trim END
108      vim9script
109      var name = v:true?1:2
110  END
111  CheckScriptFailure(lines, 'E1004:', 2)
112  lines =<< trim END
113      vim9script
114      var name = v:true? 1 : 2
115  END
116  CheckScriptFailure(lines, 'E1004:', 2)
117  lines =<< trim END
118      vim9script
119      var name = v:true ?1 : 2
120  END
121  CheckScriptFailure(lines, 'E1004:', 2)
122  lines =<< trim END
123      vim9script
124      var name = v:true ? 1: 2
125  END
126  CheckScriptFailure(lines, 'E1004:', 2)
127  lines =<< trim END
128      vim9script
129      var name = v:true ? 1 :2
130  END
131  CheckScriptFailure(lines, 'E1004:', 2)
132
133  lines =<< trim END
134      vim9script
135      var name = 'x' ? 1 : 2
136  END
137  CheckScriptFailure(lines, 'E1135:', 2)
138
139  lines =<< trim END
140      vim9script
141      var name = [] ? 1 : 2
142  END
143  CheckScriptFailure(lines, 'E745:', 2)
144
145  lines =<< trim END
146      vim9script
147      var name = {} ? 1 : 2
148  END
149  CheckScriptFailure(lines, 'E728:', 2)
150
151  # check after failure eval_flags is reset
152  lines =<< trim END
153      vim9script
154      try
155        eval('0 ? 1: 2')
156      catch
157      endtry
158      assert_equal(v:true, eval(string(v:true)))
159  END
160  CheckScriptSuccess(lines)
161
162  lines =<< trim END
163      vim9script
164      try
165        eval('0 ? 1 :2')
166      catch
167      endtry
168      assert_equal(v:true, eval(string(v:true)))
169  END
170  CheckScriptSuccess(lines)
171enddef
172
173func Test_expr1_trinary_fails()
174  call CheckDefFailure(["var x = 1 ? 'one'"], "Missing ':' after '?'", 1)
175
176  let msg = "White space required before and after '?'"
177  call CheckDefFailure(["var x = 1? 'one' : 'two'"], msg, 1)
178  call CheckDefFailure(["var x = 1 ?'one' : 'two'"], msg, 1)
179  call CheckDefFailure(["var x = 1?'one' : 'two'"], msg, 1)
180
181  let msg = "White space required before and after ':'"
182  call CheckDefFailure(["var x = 1 ? 'one': 'two'"], msg, 1)
183  call CheckDefFailure(["var x = 1 ? 'one' :'two'"], msg, 1)
184  call CheckDefFailure(["var x = 1 ? 'one':'two'"], msg, 1)
185
186  call CheckDefFailure(["var x = 'x' ? 'one' : 'two'"], 'E1135:', 1)
187  call CheckDefFailure(["var x = 0z1234 ? 'one' : 'two'"], 'E974:', 1)
188  call CheckDefExecFailure(["var x = [] ? 'one' : 'two'"], 'E745:', 1)
189  call CheckDefExecFailure(["var x = {} ? 'one' : 'two'"], 'E728:', 1)
190
191  call CheckDefExecFailure(["var x = false ? "], 'E1097:', 3)
192  call CheckDefExecFailure(["var x = false ? 'one' : "], 'E1097:', 3)
193
194  call CheckDefExecFailure(["var x = true ? xxx : 'foo'"], 'E1001:', 1)
195  call CheckDefExecFailure(["var x = false ? 'foo' : xxx"], 'E1001:', 1)
196
197  if has('float')
198    call CheckDefFailure(["var x = 0.1 ? 'one' : 'two'"], 'E805:', 1)
199  endif
200
201  " missing argument detected even when common type is used
202  call CheckDefFailure([
203	\ 'var X = FuncOne',
204	\ 'var Y = FuncTwo',
205	\ 'var Z = g:cond ? FuncOne : FuncTwo',
206	\ 'Z()'], 'E119:', 4)
207endfunc
208
209def Test_expr1_falsy()
210  var lines =<< trim END
211      assert_equal(v:true, v:true ?? 456)
212      assert_equal(123, 123 ?? 456)
213      assert_equal('yes', 'yes' ?? 456)
214      assert_equal([1], [1] ?? 456)
215      assert_equal({one: 1}, {one: 1} ?? 456)
216      if has('float')
217        assert_equal(0.1, 0.1 ?? 456)
218      endif
219
220      assert_equal(456, v:false ?? 456)
221      assert_equal(456, 0 ?? 456)
222      assert_equal(456, '' ?? 456)
223      assert_equal(456, [] ?? 456)
224      assert_equal(456, {} ?? 456)
225      if has('float')
226        assert_equal(456, 0.0 ?? 456)
227      endif
228  END
229  CheckDefAndScriptSuccess(lines)
230
231  var msg = "White space required before and after '??'"
232  call CheckDefFailure(["var x = 1?? 'one' : 'two'"], msg, 1)
233  call CheckDefFailure(["var x = 1 ??'one' : 'two'"], msg, 1)
234  call CheckDefFailure(["var x = 1??'one' : 'two'"], msg, 1)
235enddef
236
237def Record(val: any): any
238  g:vals->add(val)
239  return val
240enddef
241
242" test ||
243def Test_expr2()
244  var lines =<< trim END
245      assert_equal(true, 1 || 0)
246      assert_equal(true, 0 ||
247                        0 ||
248                        1)
249      assert_equal(true, 0 ||
250			0 ||
251			!!7)
252      assert_equal(false, 0 || 0)
253      assert_equal(false, 0
254                        || 0)
255      assert_equal(false, 0 || false)
256
257      g:vals = []
258      assert_equal(true, Record(1) || Record(3))
259      assert_equal([1], g:vals)
260
261      g:vals = []
262      assert_equal(true, Record(0) || Record(1))
263      assert_equal([0, 1], g:vals)
264
265      g:vals = []
266      assert_equal(true, Record(0) || Record(true))
267      assert_equal([0, true], g:vals)
268
269      g:vals = []
270      assert_equal(true, Record(0)
271                          || Record(1)
272                          || Record(0))
273      assert_equal([0, 1], g:vals)
274
275      g:vals = []
276      assert_equal(true, Record(0)
277			  || Record(true)
278			  || Record(0))
279      assert_equal([0, true], g:vals)
280
281      g:vals = []
282      assert_equal(true, Record(true) || Record(false))
283      assert_equal([true], g:vals)
284
285      g:vals = []
286      assert_equal(false, Record(0) || Record(false) || Record(0))
287      assert_equal([0, false, 0], g:vals)
288  END
289  CheckDefAndScriptSuccess(lines)
290enddef
291
292def Test_expr2_vimscript()
293  # check line continuation
294  var lines =<< trim END
295      vim9script
296      var name = 0
297      		|| 1
298      assert_equal(true, name)
299  END
300  CheckScriptSuccess(lines)
301
302  lines =<< trim END
303      vim9script
304      var name = v:false
305      		|| v:true
306      		|| v:false
307      assert_equal(v:true, name)
308  END
309  CheckScriptSuccess(lines)
310
311  lines =<< trim END
312      vim9script
313      var name = v:false ||
314      		v:true ||
315		v:false
316      assert_equal(v:true, name)
317  END
318  CheckScriptSuccess(lines)
319
320  lines =<< trim END
321      vim9script
322      var name = v:false || # comment
323                # comment
324      		v:true ||
325                # comment
326		v:false # comment
327      assert_equal(v:true, name)
328  END
329  CheckScriptSuccess(lines)
330
331  # check white space
332  lines =<< trim END
333      vim9script
334      var name = v:true||v:true
335  END
336  CheckScriptFailure(lines, 'E1004:', 2)
337  lines =<< trim END
338      vim9script
339      var name = v:true ||v:true
340  END
341  CheckScriptFailure(lines, 'E1004:', 2)
342  lines =<< trim END
343      vim9script
344      var name = v:true|| v:true
345  END
346  CheckScriptFailure(lines, 'E1004:', 2)
347enddef
348
349def Test_expr2_fails()
350  var msg = "White space required before and after '||'"
351  call CheckDefFailure(["var x = 1||2"], msg, 1)
352  call CheckDefFailure(["var x = 1 ||2"], msg, 1)
353  call CheckDefFailure(["var x = 1|| 2"], msg, 1)
354
355  call CheckDefFailure(["var x = false || "], 'E1097:', 3)
356
357  call CheckDefFailure(["var x = 1 || xxx"], 'E1001:', 1)
358  call CheckDefFailure(["var x = [] || false"], 'E1012:', 1)
359  call CheckDefFailure(["if 'yes' || 0", 'echo 0', 'endif'], 'E1012: Type mismatch; expected bool but got string', 1)
360
361  # TODO: should fail at compile time
362  call CheckDefExecFailure(["var x = 3 || 7"], 'E1023:', 1)
363  call CheckScriptFailure(["vim9script", "var x = 3 || 7"], 'E1023:', 2)
364  call CheckScriptFailure(["vim9script", "var x = [] || false"], 'E745:', 2)
365enddef
366
367" test &&
368def Test_expr3()
369  var lines =<< trim END
370      assert_equal(false, 1 && 0)
371      assert_equal(false, 0 &&
372                    0 &&
373                    1)
374      assert_equal(true, 1
375                        && true
376                        && 1)
377      assert_equal(false, 0 && 0)
378      assert_equal(false, 0 && false)
379      assert_equal(true, 1 && true)
380
381      g:vals = []
382      assert_equal(true, Record(true) && Record(1))
383      assert_equal([true, 1], g:vals)
384
385      g:vals = []
386      assert_equal(true, Record(1) && Record(true))
387      assert_equal([1, true], g:vals)
388
389      g:vals = []
390      assert_equal(false, Record(0) && Record(1))
391      assert_equal([0], g:vals)
392
393      g:vals = []
394      assert_equal(false, Record(0) && Record(1) && Record(0))
395      assert_equal([0], g:vals)
396
397      g:vals = []
398      assert_equal(false, Record(0) && Record(4) && Record(0))
399      assert_equal([0], g:vals)
400
401      g:vals = []
402      assert_equal(false, Record(1) && Record(true) && Record(0))
403      assert_equal([1, true, 0], g:vals)
404  END
405  CheckDefAndScriptSuccess(lines)
406enddef
407
408def Test_expr3_vimscript()
409  # check line continuation
410  var lines =<< trim END
411      vim9script
412      var name = 0
413      		&& 1
414      assert_equal(false, name)
415  END
416  CheckScriptSuccess(lines)
417
418  lines =<< trim END
419      vim9script
420      var name = v:true
421      		&& v:true
422      		&& v:true
423      assert_equal(v:true, name)
424  END
425  CheckScriptSuccess(lines)
426
427  lines =<< trim END
428      vim9script
429      var name = v:true &&
430      		v:true &&
431      		v:true
432      assert_equal(v:true, name)
433  END
434  CheckScriptSuccess(lines)
435
436  lines =<< trim END
437      vim9script
438      var name = v:true &&  # comment
439                # comment
440      		v:true &&
441                # comment
442      		v:true
443      assert_equal(v:true, name)
444  END
445  CheckScriptSuccess(lines)
446
447  # check white space
448  lines =<< trim END
449      vim9script
450      var name = v:true&&v:true
451  END
452  CheckScriptFailure(lines, 'E1004:', 2)
453  lines =<< trim END
454      vim9script
455      var name = v:true &&v:true
456  END
457  CheckScriptFailure(lines, 'E1004:', 2)
458  lines =<< trim END
459      vim9script
460      var name = v:true&& v:true
461  END
462  CheckScriptFailure(lines, 'E1004:', 2)
463enddef
464
465func Test_expr3_fails()
466  let msg = "White space required before and after '&&'"
467  call CheckDefFailure(["var x = 1&&2"], msg, 1)
468  call CheckDefFailure(["var x = 1 &&2"], msg, 1)
469  call CheckDefFailure(["var x = 1&& 2"], msg, 1)
470
471  call CheckDefFailure(["if 'yes' && 0", 'echo 0', 'endif'], 'E1012: Type mismatch; expected bool but got string', 1)
472
473  call CheckDefExecFailure(['assert_equal(false, Record(1) && Record(4) && Record(0))'], 'E1023: Using a Number as a Bool: 4', 1)
474endfunc
475
476" global variables to use for tests with the "any" type
477let atrue = v:true
478let afalse = v:false
479let anone = v:none
480let anull = v:null
481let anint = 10
482let theone = 1
483let thefour = 4
484if has('float')
485  let afloat = 0.1
486endif
487let astring = 'asdf'
488let ablob = 0z01ab
489let alist = [2, 3, 4]
490let adict = #{aaa: 2, bbb: 8}
491
492" test == comperator
493def Test_expr4_equal()
494  var lines =<< trim END
495      var trueVar = true
496      var falseVar = false
497      assert_equal(true, true == true)
498      assert_equal(false, true ==
499                            false)
500      assert_equal(true, true
501                            == trueVar)
502      assert_equal(false, true == falseVar)
503      assert_equal(true, true == g:atrue)
504      assert_equal(false, g:atrue == false)
505
506      assert_equal(true, v:none == v:none)
507      assert_equal(false, v:none == v:null)
508      assert_equal(true, g:anone == v:none)
509      assert_equal(false, v:none == g:anull)
510
511      var nr0 = 0
512      var nr61 = 61
513      assert_equal(false, 2 == 0)
514      assert_equal(false, 2 == nr0)
515      assert_equal(true, 61 == 61)
516      assert_equal(true, 61 == nr61)
517      assert_equal(true, g:anint == 10)
518      assert_equal(false, 61 == g:anint)
519
520      if has('float')
521        var ff = 0.3
522        assert_equal(true, ff == 0.3)
523        assert_equal(false, 0.4 == ff)
524        assert_equal(true, 0.1 == g:afloat)
525        assert_equal(false, g:afloat == 0.3)
526
527        ff = 3.0
528        assert_equal(true, ff == 3)
529        assert_equal(true, 3 == ff)
530        ff = 3.1
531        assert_equal(false, ff == 3)
532        assert_equal(false, 3 == ff)
533      endif
534
535      assert_equal(true, 'abc' == 'abc')
536      assert_equal(false, 'xyz' == 'abc')
537      assert_equal(true, g:astring == 'asdf')
538      assert_equal(false, 'xyz' == g:astring)
539
540      assert_equal(false, 'abc' == 'aBc')
541      assert_equal(false, 'abc' ==# 'aBc')
542      assert_equal(true, 'abc' ==? 'aBc')
543
544      assert_equal(false, 'abc' == 'ABC')
545      set ignorecase
546      assert_equal(false, 'abc' == 'ABC')
547      assert_equal(false, 'abc' ==# 'ABC')
548      assert_equal(true, 'abc' ==? 'ABC')
549      set noignorecase
550
551      var bb = 0z3f
552      assert_equal(true, 0z3f == bb)
553      assert_equal(false, bb == 0z4f)
554      assert_equal(true, g:ablob == 0z01ab)
555      assert_equal(false, 0z3f == g:ablob)
556
557      assert_equal(true, [1, 2, 3] == [1, 2, 3])
558      assert_equal(false, [1, 2, 3] == [2, 3, 1])
559      assert_equal(true, [2, 3, 4] == g:alist)
560      assert_equal(false, g:alist == [2, 3, 1])
561      assert_equal(false, [1, 2, 3] == [])
562      assert_equal(false, [1, 2, 3] == ['1', '2', '3'])
563
564      assert_equal(true, {one: 1, two: 2} == {one: 1, two: 2})
565      assert_equal(false, {one: 1, two: 2} == {one: 2, two: 2})
566      assert_equal(false, {one: 1, two: 2} == {two: 2})
567      assert_equal(false, {one: 1, two: 2} == {})
568      assert_equal(true, g:adict == {bbb: 8, aaa: 2})
569      assert_equal(false, {ccc: 9, aaa: 2} == g:adict)
570
571      assert_equal(true, function('g:Test_expr4_equal') == function('g:Test_expr4_equal'))
572      assert_equal(false, function('g:Test_expr4_equal') == function('g:Test_expr4_is'))
573
574      assert_equal(true, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_equal', [123]))
575      assert_equal(false, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_is', [123]))
576      assert_equal(false, function('g:Test_expr4_equal', [123]) == function('g:Test_expr4_equal', [999]))
577
578      # TODO: this unexpectedly sometimes fails on Appveyor
579      if !has('win32')
580        var OneFunc: func
581        var TwoFunc: func
582        OneFunc = function('len')
583        TwoFunc = function('len')
584        assert_equal(true, OneFunc('abc') == TwoFunc('123'))
585      endif
586  END
587  CheckDefAndScriptSuccess(lines)
588
589  CheckDefFailure(["var x = 'a' == xxx"], 'E1001:', 1)
590  CheckDefFailure(["var x = 'a' == "], 'E1097:', 3)
591
592  CheckDefExecFailure(['var items: any', 'eval 1', 'eval 2', 'if items == []', 'endif'], 'E691:', 4)
593enddef
594
595" test != comperator
596def Test_expr4_notequal()
597  var lines =<< trim END
598      var trueVar = true
599      var falseVar = false
600      assert_equal(false, true != true)
601      assert_equal(true, true !=
602                            false)
603      assert_equal(false, true
604                            != trueVar)
605      assert_equal(true, true != falseVar)
606      assert_equal(false, true != g:atrue)
607      assert_equal(true, g:atrue != false)
608
609      assert_equal(false, v:none != v:none)
610      assert_equal(true, v:none != v:null)
611      assert_equal(false, g:anone != v:none)
612      assert_equal(true, v:none != g:anull)
613
614      var nr55 = 55
615      var nr0 = 55
616      assert_equal(true, 2 != 0)
617      assert_equal(true, 2 != nr0)
618      assert_equal(false, 55 != 55)
619      assert_equal(false, 55 != nr55)
620      assert_equal(false, g:anint != 10)
621      assert_equal(true, 61 != g:anint)
622
623      if has('float')
624        var ff = 0.3
625        assert_equal(false, 0.3 != ff)
626        assert_equal(true, 0.4 != ff)
627        assert_equal(false, 0.1 != g:afloat)
628        assert_equal(true, g:afloat != 0.3)
629
630        ff = 3.0
631        assert_equal(false, ff != 3)
632        assert_equal(false, 3 != ff)
633        ff = 3.1
634        assert_equal(true, ff != 3)
635        assert_equal(true, 3 != ff)
636      endif
637
638      assert_equal(false, 'abc' != 'abc')
639      assert_equal(true, 'xyz' != 'abc')
640      assert_equal(false, g:astring != 'asdf')
641      assert_equal(true, 'xyz' != g:astring)
642
643      assert_equal(true, 'abc' != 'ABC')
644      set ignorecase
645      assert_equal(true, 'abc' != 'ABC')
646      assert_equal(true, 'abc' !=# 'ABC')
647      assert_equal(false, 'abc' !=? 'ABC')
648      set noignorecase
649
650      var bb = 0z3f
651      assert_equal(false, 0z3f != bb)
652      assert_equal(true, bb != 0z4f)
653      assert_equal(false, g:ablob != 0z01ab)
654      assert_equal(true, 0z3f != g:ablob)
655
656      assert_equal(false, [1, 2, 3] != [1, 2, 3])
657      assert_equal(true, [1, 2, 3] != [2, 3, 1])
658      assert_equal(false, [2, 3, 4] != g:alist)
659      assert_equal(true, g:alist != [2, 3, 1])
660      assert_equal(true, [1, 2, 3] != [])
661      assert_equal(true, [1, 2, 3] != ['1', '2', '3'])
662
663      assert_equal(false, {one: 1, two: 2} != {one: 1, two: 2})
664      assert_equal(true, {one: 1, two: 2} != {one: 2, two: 2})
665      assert_equal(true, {one: 1, two: 2} != {two: 2})
666      assert_equal(true, {one: 1, two: 2} != {})
667      assert_equal(false, g:adict != {bbb: 8, aaa: 2})
668      assert_equal(true, {ccc: 9, aaa: 2} != g:adict)
669
670      assert_equal(false, function('g:Test_expr4_equal') != function('g:Test_expr4_equal'))
671      assert_equal(true, function('g:Test_expr4_equal') != function('g:Test_expr4_is'))
672
673      assert_equal(false, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_equal', [123]))
674      assert_equal(true, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_is', [123]))
675      assert_equal(true, function('g:Test_expr4_equal', [123]) != function('g:Test_expr4_equal', [999]))
676  END
677  CheckDefAndScriptSuccess(lines)
678enddef
679
680" test > comperator
681def Test_expr4_greater()
682  var lines =<< trim END
683      assert_true(2 > 0)
684      assert_true(2 >
685                    1)
686      assert_false(2 > 2)
687      assert_false(2 > 3)
688      var nr2 = 2
689      assert_true(nr2 > 0)
690      assert_true(nr2 >
691                    1)
692      assert_false(nr2 > 2)
693      assert_false(nr2
694                        > 3)
695      if has('float')
696        var ff = 2.0
697        assert_true(ff > 0.0)
698        assert_true(ff > 1.0)
699        assert_false(ff > 2.0)
700        assert_false(ff > 3.0)
701      endif
702  END
703  CheckDefAndScriptSuccess(lines)
704enddef
705
706" test >= comperator
707def Test_expr4_greaterequal()
708  var lines =<< trim END
709      assert_true(2 >= 0)
710      assert_true(2 >=
711                            2)
712      assert_false(2 >= 3)
713      var nr2 = 2
714      assert_true(nr2 >= 0)
715      assert_true(nr2 >= 2)
716      assert_false(nr2 >= 3)
717      if has('float')
718        var ff = 2.0
719        assert_true(ff >= 0.0)
720        assert_true(ff >= 2.0)
721        assert_false(ff >= 3.0)
722      endif
723  END
724  CheckDefAndScriptSuccess(lines)
725enddef
726
727" test < comperator
728def Test_expr4_smaller()
729  var lines =<< trim END
730      assert_false(2 < 0)
731      assert_false(2 <
732                            2)
733      assert_true(2
734                    < 3)
735      var nr2 = 2
736      assert_false(nr2 < 0)
737      assert_false(nr2 < 2)
738      assert_true(nr2 < 3)
739      if has('float')
740        var ff = 2.0
741        assert_false(ff < 0.0)
742        assert_false(ff < 2.0)
743        assert_true(ff < 3.0)
744      endif
745  END
746  CheckDefAndScriptSuccess(lines)
747enddef
748
749" test <= comperator
750def Test_expr4_smallerequal()
751  var lines =<< trim END
752      assert_false(2 <= 0)
753      assert_false(2 <=
754                            1)
755      assert_true(2
756                    <= 2)
757      assert_true(2 <= 3)
758      var nr2 = 2
759      assert_false(nr2 <= 0)
760      assert_false(nr2 <= 1)
761      assert_true(nr2 <= 2)
762      assert_true(nr2 <= 3)
763      if has('float')
764        var ff = 2.0
765        assert_false(ff <= 0.0)
766        assert_false(ff <= 1.0)
767        assert_true(ff <= 2.0)
768        assert_true(ff <= 3.0)
769      endif
770  END
771  CheckDefAndScriptSuccess(lines)
772enddef
773
774" test =~ comperator
775def Test_expr4_match()
776  var lines =<< trim END
777      assert_equal(false, '2' =~ '0')
778      assert_equal(false, ''
779                             =~ '0')
780      assert_equal(true, '2' =~
781                            '[0-9]')
782      set ignorecase
783      assert_equal(false, 'abc' =~ 'ABC')
784      assert_equal(false, 'abc' =~# 'ABC')
785      assert_equal(true, 'abc' =~? 'ABC')
786      set noignorecase
787  END
788  CheckDefAndScriptSuccess(lines)
789enddef
790
791" test !~ comperator
792def Test_expr4_nomatch()
793  var lines =<< trim END
794      assert_equal(true, '2' !~ '0')
795      assert_equal(true, ''
796                            !~ '0')
797      assert_equal(false, '2' !~
798                            '[0-9]')
799  END
800  CheckDefAndScriptSuccess(lines)
801enddef
802
803" test is comperator
804def Test_expr4_is()
805  var lines =<< trim END
806      var mylist = [2]
807      assert_false(mylist is [2])
808      var other = mylist
809      assert_true(mylist is
810                    other)
811
812      var myblob = 0z1234
813      assert_false(myblob
814                            is 0z1234)
815      var otherblob = myblob
816      assert_true(myblob is otherblob)
817  END
818  CheckDefAndScriptSuccess(lines)
819enddef
820
821" test isnot comperator
822def Test_expr4_isnot()
823  var lines =<< trim END
824      var mylist = [2]
825      assert_true('2' isnot '0')
826      assert_true(mylist isnot [2])
827      var other = mylist
828      assert_false(mylist isnot
829                            other)
830
831      var myblob = 0z1234
832      assert_true(myblob
833                    isnot 0z1234)
834      var otherblob = myblob
835      assert_false(myblob isnot otherblob)
836  END
837  CheckDefAndScriptSuccess(lines)
838enddef
839
840def RetVoid()
841  var x = 1
842enddef
843
844def Test_expr4_vim9script()
845  # check line continuation
846  var lines =<< trim END
847      vim9script
848      var name = 0
849      		< 1
850      assert_equal(true, name)
851  END
852  CheckScriptSuccess(lines)
853
854  lines =<< trim END
855      vim9script
856      var name = 123
857                # comment
858      		!= 123
859      assert_equal(false, name)
860  END
861  CheckScriptSuccess(lines)
862
863  lines =<< trim END
864      vim9script
865      var name = 123 ==
866      			123
867      assert_equal(true, name)
868  END
869  CheckScriptSuccess(lines)
870
871  lines =<< trim END
872      vim9script
873      var list = [1, 2, 3]
874      var name = list
875      		is list
876      assert_equal(true, name)
877  END
878  CheckScriptSuccess(lines)
879
880  lines =<< trim END
881      vim9script
882      var list = [1, 2, 3]
883      var name = list # comment
884                 # comment
885      		is list
886      assert_equal(true, name)
887  END
888  CheckScriptSuccess(lines)
889
890  lines =<< trim END
891      vim9script
892      var myblob = 0z1234
893      var name = myblob
894      		isnot 0z11
895      assert_equal(true, name)
896  END
897  CheckScriptSuccess(lines)
898
899  # spot check mismatching types
900  lines =<< trim END
901      vim9script
902      echo '' == 0
903  END
904  CheckScriptFailure(lines, 'E1072:', 2)
905
906  lines =<< trim END
907      vim9script
908      echo v:true > v:false
909  END
910  CheckScriptFailure(lines, 'Cannot compare bool with bool', 2)
911
912  lines =<< trim END
913      vim9script
914      echo 123 is 123
915  END
916  CheckScriptFailure(lines, 'Cannot use "is" with number', 2)
917
918  # check missing white space
919  lines =<< trim END
920    vim9script
921    echo 2>3
922  END
923  CheckScriptFailure(lines, 'E1004:', 2)
924  lines =<< trim END
925    vim9script
926    echo 2 >3
927  END
928  CheckScriptFailure(lines, 'E1004:', 2)
929  lines =<< trim END
930    vim9script
931    echo 2> 3
932  END
933  CheckScriptFailure(lines, 'E1004:', 2)
934  lines =<< trim END
935    vim9script
936    echo 2!=3
937  END
938  CheckScriptFailure(lines, 'E1004:', 2)
939  lines =<< trim END
940    vim9script
941    echo 2 !=3
942  END
943  CheckScriptFailure(lines, 'E1004:', 2)
944  lines =<< trim END
945    vim9script
946    echo 2!= 3
947  END
948  CheckScriptFailure(lines, 'E1004:', 2)
949
950  lines =<< trim END
951    vim9script
952    echo len('xxx') == 3
953  END
954  CheckScriptSuccess(lines)
955
956  lines =<< trim END
957    vim9script
958    var line = 'abc'
959    echo line[1] =~ '\w'
960  END
961  CheckScriptSuccess(lines)
962enddef
963
964func Test_expr4_fails()
965  let msg = "White space required before and after '>'"
966  call CheckDefFailure(["var x = 1>2"], msg, 1)
967  call CheckDefFailure(["var x = 1 >2"], msg, 1)
968  call CheckDefFailure(["var x = 1> 2"], msg, 1)
969
970  let msg = "White space required before and after '=='"
971  call CheckDefFailure(["var x = 1==2"], msg, 1)
972  call CheckDefFailure(["var x = 1 ==2"], msg, 1)
973  call CheckDefFailure(["var x = 1== 2"], msg, 1)
974
975  let msg = "White space required before and after 'is'"
976  call CheckDefFailure(["var x = '1'is'2'"], msg, 1)
977  call CheckDefFailure(["var x = '1' is'2'"], msg, 1)
978  call CheckDefFailure(["var x = '1'is '2'"], msg, 1)
979
980  let msg = "White space required before and after 'isnot'"
981  call CheckDefFailure(["var x = '1'isnot'2'"], msg, 1)
982  call CheckDefFailure(["var x = '1' isnot'2'"], msg, 1)
983  call CheckDefFailure(["var x = '1'isnot '2'"], msg, 1)
984
985  call CheckDefFailure(["var x = 1 is# 2"], 'E15:', 1)
986  call CheckDefFailure(["var x = 1 is? 2"], 'E15:', 1)
987  call CheckDefFailure(["var x = 1 isnot# 2"], 'E15:', 1)
988  call CheckDefFailure(["var x = 1 isnot? 2"], 'E15:', 1)
989
990  call CheckDefFailure(["var x = 1 == '2'"], 'Cannot compare number with string', 1)
991  call CheckDefFailure(["var x = '1' == 2"], 'Cannot compare string with number', 1)
992  call CheckDefFailure(["var x = 1 == RetVoid()"], 'Cannot compare number with void', 1)
993  call CheckDefFailure(["var x = RetVoid() == 1"], 'Cannot compare void with number', 1)
994
995  call CheckDefFailure(["var x = true > false"], 'Cannot compare bool with bool', 1)
996  call CheckDefFailure(["var x = true >= false"], 'Cannot compare bool with bool', 1)
997  call CheckDefFailure(["var x = true < false"], 'Cannot compare bool with bool', 1)
998  call CheckDefFailure(["var x = true <= false"], 'Cannot compare bool with bool', 1)
999  call CheckDefFailure(["var x = true =~ false"], 'Cannot compare bool with bool', 1)
1000  call CheckDefFailure(["var x = true !~ false"], 'Cannot compare bool with bool', 1)
1001  call CheckDefFailure(["var x = true is false"], 'Cannot use "is" with bool', 1)
1002  call CheckDefFailure(["var x = true isnot false"], 'Cannot use "isnot" with bool', 1)
1003
1004  call CheckDefFailure(["var x = v:none is v:null"], 'Cannot use "is" with special', 1)
1005  call CheckDefFailure(["var x = v:none isnot v:null"], 'Cannot use "isnot" with special', 1)
1006  call CheckDefFailure(["var x = 123 is 123"], 'Cannot use "is" with number', 1)
1007  call CheckDefFailure(["var x = 123 isnot 123"], 'Cannot use "isnot" with number', 1)
1008  if has('float')
1009    call CheckDefFailure(["var x = 1.3 is 1.3"], 'Cannot use "is" with float', 1)
1010    call CheckDefFailure(["var x = 1.3 isnot 1.3"], 'Cannot use "isnot" with float', 1)
1011  endif
1012
1013  call CheckDefFailure(["var x = 0za1 > 0z34"], 'Cannot compare blob with blob', 1)
1014  call CheckDefFailure(["var x = 0za1 >= 0z34"], 'Cannot compare blob with blob', 1)
1015  call CheckDefFailure(["var x = 0za1 < 0z34"], 'Cannot compare blob with blob', 1)
1016  call CheckDefFailure(["var x = 0za1 <= 0z34"], 'Cannot compare blob with blob', 1)
1017  call CheckDefFailure(["var x = 0za1 =~ 0z34"], 'Cannot compare blob with blob', 1)
1018  call CheckDefFailure(["var x = 0za1 !~ 0z34"], 'Cannot compare blob with blob', 1)
1019
1020  call CheckDefFailure(["var x = [13] > [88]"], 'Cannot compare list with list', 1)
1021  call CheckDefFailure(["var x = [13] >= [88]"], 'Cannot compare list with list', 1)
1022  call CheckDefFailure(["var x = [13] < [88]"], 'Cannot compare list with list', 1)
1023  call CheckDefFailure(["var x = [13] <= [88]"], 'Cannot compare list with list', 1)
1024  call CheckDefFailure(["var x = [13] =~ [88]"], 'Cannot compare list with list', 1)
1025  call CheckDefFailure(["var x = [13] !~ [88]"], 'Cannot compare list with list', 1)
1026
1027  call CheckDefFailure(['var j: job', 'var chan: channel', 'var r = j == chan'], 'Cannot compare job with channel', 3)
1028  call CheckDefFailure(['var j: job', 'var x: list<any>', 'var r = j == x'], 'Cannot compare job with list', 3)
1029  call CheckDefFailure(['var j: job', 'var Xx: func', 'var r = j == Xx'], 'Cannot compare job with func', 3)
1030  call CheckDefFailure(['var j: job', 'var Xx: func', 'var r = j == Xx'], 'Cannot compare job with func', 3)
1031endfunc
1032
1033" test addition, subtraction, concatenation
1034def Test_expr5()
1035  var lines =<< trim END
1036      assert_equal(66, 60 + 6)
1037      assert_equal(70, 60 +
1038                            g:anint)
1039      assert_equal(9, g:thefour
1040                            + 5)
1041      assert_equal(14, g:thefour + g:anint)
1042      assert_equal([1, 2, 3, 4], [1] + g:alist)
1043
1044      assert_equal(54, 60 - 6)
1045      assert_equal(50, 60 -
1046                        g:anint)
1047      assert_equal(-1, g:thefour
1048                            - 5)
1049      assert_equal(-6, g:thefour - g:anint)
1050
1051      assert_equal('hello', 'hel' .. 'lo')
1052      assert_equal('hello 123', 'hello ' ..
1053                                            123)
1054      assert_equal('hello 123', 'hello '
1055                                    ..  123)
1056      assert_equal('123 hello', 123 .. ' hello')
1057      assert_equal('123456', 123 .. 456)
1058
1059      assert_equal('av:true', 'a' .. true)
1060      assert_equal('av:false', 'a' .. false)
1061      assert_equal('av:null', 'a' .. v:null)
1062      assert_equal('av:none', 'a' .. v:none)
1063      if has('float')
1064        assert_equal('a0.123', 'a' .. 0.123)
1065      endif
1066
1067      assert_equal([1, 2, 3, 4], [1, 2] + [3, 4])
1068      assert_equal(0z11223344, 0z1122 + 0z3344)
1069      assert_equal(0z112201ab, 0z1122
1070                                    + g:ablob)
1071      assert_equal(0z01ab3344, g:ablob + 0z3344)
1072      assert_equal(0z01ab01ab, g:ablob + g:ablob)
1073
1074      # concatenate non-constant to constant
1075      var save_path = &path
1076      &path = 'b'
1077      assert_equal('ab', 'a' .. &path)
1078      &path = save_path
1079
1080      @b = 'b'
1081      assert_equal('ab', 'a' .. @b)
1082
1083      $ENVVAR = 'env'
1084      assert_equal('aenv', 'a' .. $ENVVAR)
1085  END
1086  CheckDefAndScriptSuccess(lines)
1087enddef
1088
1089def Test_expr5_vim9script()
1090  # check line continuation
1091  var lines =<< trim END
1092      vim9script
1093      var name = 11
1094      		+ 77
1095		- 22
1096      assert_equal(66, name)
1097  END
1098  CheckScriptSuccess(lines)
1099
1100  lines =<< trim END
1101      vim9script
1102      var name = 11 +
1103		  77 -
1104		  22
1105      assert_equal(66, name)
1106  END
1107  CheckScriptSuccess(lines)
1108
1109  lines =<< trim END
1110      vim9script
1111      var name = 11 +  # comment
1112		  77 -
1113                  # comment
1114		  22
1115      assert_equal(66, name)
1116  END
1117  CheckScriptSuccess(lines)
1118
1119  lines =<< trim END
1120      vim9script
1121      var name = 'one'
1122      		.. 'two'
1123      assert_equal('onetwo', name)
1124  END
1125  CheckScriptSuccess(lines)
1126
1127  lines =<< trim END
1128      vim9script
1129      echo 'abc' is# 'abc'
1130  END
1131  CheckScriptFailure(lines, 'E15:', 2)
1132
1133  lines =<< trim END
1134      vim9script
1135      echo {} - 22
1136  END
1137  CheckScriptFailure(lines, 'E728:', 2)
1138
1139  lines =<< trim END
1140      vim9script
1141      echo [] - 33
1142  END
1143  CheckScriptFailure(lines, 'E745:', 2)
1144
1145  lines =<< trim END
1146      vim9script
1147      echo 0z1234 - 44
1148  END
1149  CheckScriptFailure(lines, 'E974:', 2)
1150
1151  lines =<< trim END
1152      vim9script
1153      echo 'abc' is? 'abc'
1154  END
1155  CheckScriptFailure(lines, 'E15:', 2)
1156
1157  lines =<< trim END
1158      vim9script
1159      echo 'abc' isnot# 'abc'
1160  END
1161  CheckScriptFailure(lines, 'E15:', 2)
1162
1163  lines =<< trim END
1164      vim9script
1165      echo 'abc' isnot? 'abc'
1166  END
1167  CheckScriptFailure(lines, 'E15:', 2)
1168
1169  # check white space
1170  lines =<< trim END
1171      vim9script
1172      echo 5+6
1173  END
1174  CheckScriptFailure(lines, 'E1004:', 2)
1175  lines =<< trim END
1176      vim9script
1177      echo 5 +6
1178  END
1179  CheckScriptFailure(lines, 'E1004:', 2)
1180  lines =<< trim END
1181      vim9script
1182      echo 5+ 6
1183  END
1184  CheckScriptFailure(lines, 'E1004:', 2)
1185
1186  lines =<< trim END
1187      vim9script
1188      echo 'a'..'b'
1189  END
1190  CheckScriptFailure(lines, 'E1004:', 2)
1191  lines =<< trim END
1192      vim9script
1193      echo 'a' ..'b'
1194  END
1195  CheckScriptFailure(lines, 'E1004:', 2)
1196  lines =<< trim END
1197      vim9script
1198      echo 'a'.. 'b'
1199  END
1200  CheckScriptFailure(lines, 'E1004:', 2)
1201
1202  # check invalid string concatenation
1203  lines =<< trim END
1204      vim9script
1205      echo 'a' .. [1]
1206  END
1207  CheckScriptFailure(lines, 'E730:', 2)
1208  lines =<< trim END
1209      vim9script
1210      echo 'a' .. {a: 1}
1211  END
1212  CheckScriptFailure(lines, 'E731:', 2)
1213  lines =<< trim END
1214      vim9script
1215      echo 'a' .. test_void()
1216  END
1217  CheckScriptFailure(lines, 'E908:', 2)
1218  lines =<< trim END
1219      vim9script
1220      echo 'a' .. 0z33
1221  END
1222  CheckScriptFailure(lines, 'E976:', 2)
1223  lines =<< trim END
1224      vim9script
1225      echo 'a' .. function('len')
1226  END
1227  CheckScriptFailure(lines, 'E729:', 2)
1228enddef
1229
1230def Test_expr5_vim9script_channel()
1231  if !has('channel')
1232    MissingFeature 'float'
1233  else
1234    var lines =<< trim END
1235        vim9script
1236        echo 'a' .. test_null_job()
1237    END
1238    CheckScriptFailure(lines, 'E908:', 2)
1239    lines =<< trim END
1240        vim9script
1241        echo 'a' .. test_null_channel()
1242    END
1243    CheckScriptFailure(lines, 'E908:', 2)
1244  endif
1245enddef
1246
1247def Test_expr5_float()
1248  if !has('float')
1249    MissingFeature 'float'
1250  else
1251    var lines =<< trim END
1252        assert_equal(66.0, 60.0 + 6.0)
1253        assert_equal(66.0, 60.0 + 6)
1254        assert_equal(66.0, 60 +
1255                             6.0)
1256        assert_equal(5.1, g:afloat
1257                            + 5)
1258        assert_equal(8.1, 8 + g:afloat)
1259        assert_equal(10.1, g:anint + g:afloat)
1260        assert_equal(10.1, g:afloat + g:anint)
1261
1262        assert_equal(54.0, 60.0 - 6.0)
1263        assert_equal(54.0, 60.0
1264                                - 6)
1265        assert_equal(54.0, 60 - 6.0)
1266        assert_equal(-4.9, g:afloat - 5)
1267        assert_equal(7.9, 8 - g:afloat)
1268        assert_equal(9.9, g:anint - g:afloat)
1269        assert_equal(-9.9, g:afloat - g:anint)
1270    END
1271    CheckDefAndScriptSuccess(lines)
1272  endif
1273enddef
1274
1275func Test_expr5_fails()
1276  let msg = "White space required before and after '+'"
1277  call CheckDefFailure(["var x = 1+2"], msg, 1)
1278  call CheckDefFailure(["var x = 1 +2"], msg, 1)
1279  call CheckDefFailure(["var x = 1+ 2"], msg, 1)
1280
1281  let msg = "White space required before and after '-'"
1282  call CheckDefFailure(["var x = 1-2"], msg, 1)
1283  call CheckDefFailure(["var x = 1 -2"], msg, 1)
1284  call CheckDefFailure(["var x = 1- 2"], msg, 1)
1285
1286  let msg = "White space required before and after '..'"
1287  call CheckDefFailure(["var x = '1'..'2'"], msg, 1)
1288  call CheckDefFailure(["var x = '1' ..'2'"], msg, 1)
1289  call CheckDefFailure(["var x = '1'.. '2'"], msg, 1)
1290
1291  call CheckDefFailure(["var x = 0z1122 + 33"], 'E1051:', 1)
1292  call CheckDefFailure(["var x = 0z1122 + [3]"], 'E1051:', 1)
1293  call CheckDefFailure(["var x = 0z1122 + 'asd'"], 'E1051:', 1)
1294  call CheckDefFailure(["var x = 33 + 0z1122"], 'E1051:', 1)
1295  call CheckDefFailure(["var x = [3] + 0z1122"], 'E1051:', 1)
1296  call CheckDefFailure(["var x = 'asdf' + 0z1122"], 'E1051:', 1)
1297  call CheckDefFailure(["var x = 6 + xxx"], 'E1001:', 1)
1298
1299  call CheckDefFailure(["var x = 'a' .. [1]"], 'E1105:', 1)
1300  call CheckDefFailure(["var x = 'a' .. {a: 1}"], 'E1105:', 1)
1301  call CheckDefFailure(["var x = 'a' .. test_void()"], 'E1105:', 1)
1302  call CheckDefFailure(["var x = 'a' .. 0z32"], 'E1105:', 1)
1303  call CheckDefFailure(["var x = 'a' .. function('len')"], 'E1105:', 1)
1304  call CheckDefFailure(["var x = 'a' .. function('len', ['a'])"], 'E1105:', 1)
1305
1306  call CheckScriptFailure(['vim9script', 'var x = 1 + v:none'], 'E611:', 2)
1307  call CheckScriptFailure(['vim9script', 'var x = 1 + v:null'], 'E611:', 2)
1308  call CheckScriptFailure(['vim9script', 'var x = 1 + v:true'], 'E1138:', 2)
1309  call CheckScriptFailure(['vim9script', 'var x = 1 + v:false'], 'E1138:', 2)
1310  call CheckScriptFailure(['vim9script', 'var x = 1 + true'], 'E1138:', 2)
1311  call CheckScriptFailure(['vim9script', 'var x = 1 + false'], 'E1138:', 2)
1312endfunc
1313
1314func Test_expr5_fails_channel()
1315  CheckFeature channel
1316  call CheckDefFailure(["var x = 'a' .. test_null_job()"], 'E1105:', 1)
1317  call CheckDefFailure(["var x = 'a' .. test_null_channel()"], 'E1105:', 1)
1318endfunc
1319
1320def Test_expr5_list_add()
1321  # concatenating two lists with same member types is OK
1322  var d = {}
1323  for i in ['a'] + ['b']
1324    d = {[i]: 0}
1325  endfor
1326
1327  # concatenating two lists with different member types results in "any"
1328  var lines =<< trim END
1329      var d = {}
1330      for i in ['a'] + [0]
1331        d = {[i]: 0}
1332      endfor
1333  END
1334  CheckDefExecFailure(lines, 'E1012:')
1335enddef
1336
1337" test multiply, divide, modulo
1338def Test_expr6()
1339  var lines =<< trim END
1340      assert_equal(36, 6 * 6)
1341      assert_equal(24, 6 *
1342                            g:thefour)
1343      assert_equal(24, g:thefour
1344                            * 6)
1345      assert_equal(40, g:anint * g:thefour)
1346
1347      assert_equal(10, 60 / 6)
1348      assert_equal(6, 60 /
1349                            g:anint)
1350      assert_equal(1, g:anint / 6)
1351      assert_equal(2, g:anint
1352                            / g:thefour)
1353
1354      assert_equal(5, 11 % 6)
1355      assert_equal(4, g:anint % 6)
1356      assert_equal(3, 13 %
1357                            g:anint)
1358      assert_equal(2, g:anint
1359                            % g:thefour)
1360
1361      assert_equal(4, 6 * 4 / 6)
1362
1363      var x = [2]
1364      var y = [3]
1365      assert_equal(5, x[0] + y[0])
1366      assert_equal(6, x[0] * y[0])
1367      if has('float')
1368        var xf = [2.0]
1369        var yf = [3.0]
1370        assert_equal(5.0, xf[0]
1371                            + yf[0])
1372        assert_equal(6.0, xf[0]
1373                            * yf[0])
1374      endif
1375  END
1376  CheckDefAndScriptSuccess(lines)
1377
1378  CheckDefFailure(["var x = 6 * xxx"], 'E1001:', 1)
1379  CheckDefFailure(["var d = 6 * "], 'E1097:', 3)
1380enddef
1381
1382def Test_expr6_vim9script()
1383  # check line continuation
1384  var lines =<< trim END
1385      vim9script
1386      var name = 11
1387      		* 22
1388		/ 3
1389      assert_equal(80, name)
1390  END
1391  CheckScriptSuccess(lines)
1392
1393  lines =<< trim END
1394      vim9script
1395      var name = 25
1396      		% 10
1397      assert_equal(5, name)
1398  END
1399  CheckScriptSuccess(lines)
1400
1401  lines =<< trim END
1402      vim9script
1403      var name = 25
1404                # comment
1405
1406                # comment
1407      		% 10
1408      assert_equal(5, name)
1409  END
1410  CheckScriptSuccess(lines)
1411
1412  lines =<< trim END
1413      vim9script
1414      var name = 11 *
1415      		22 /
1416		3
1417      assert_equal(80, name)
1418  END
1419  CheckScriptSuccess(lines)
1420
1421  # check white space
1422  lines =<< trim END
1423      vim9script
1424      echo 5*6
1425  END
1426  CheckScriptFailure(lines, 'E1004:', 2)
1427  lines =<< trim END
1428      vim9script
1429      echo 5 *6
1430  END
1431  CheckScriptFailure(lines, 'E1004:', 2)
1432  lines =<< trim END
1433      vim9script
1434      echo 5* 6
1435  END
1436  CheckScriptFailure(lines, 'E1004:', 2)
1437enddef
1438
1439def Test_expr6_float()
1440  if !has('float')
1441    MissingFeature 'float'
1442  else
1443    var lines =<< trim END
1444        assert_equal(36.0, 6.0 * 6)
1445        assert_equal(36.0, 6 *
1446                               6.0)
1447        assert_equal(36.0, 6.0 * 6.0)
1448        assert_equal(1.0, g:afloat * g:anint)
1449
1450        assert_equal(10.0, 60 / 6.0)
1451        assert_equal(10.0, 60.0 /
1452                            6)
1453        assert_equal(10.0, 60.0 / 6.0)
1454        assert_equal(0.01, g:afloat / g:anint)
1455
1456        assert_equal(4.0, 6.0 * 4 / 6)
1457        assert_equal(4.0, 6 *
1458                            4.0 /
1459                            6)
1460        assert_equal(4.0, 6 * 4 / 6.0)
1461        assert_equal(4.0, 6.0 * 4.0 / 6)
1462        assert_equal(4.0, 6 * 4.0 / 6.0)
1463        assert_equal(4.0, 6.0 * 4 / 6.0)
1464        assert_equal(4.0, 6.0 * 4.0 / 6.0)
1465
1466        assert_equal(4.0, 6.0 * 4.0 / 6.0)
1467    END
1468    CheckDefAndScriptSuccess(lines)
1469  endif
1470enddef
1471
1472func Test_expr6_fails()
1473  let msg = "White space required before and after '*'"
1474  call CheckDefFailure(["var x = 1*2"], msg, 1)
1475  call CheckDefFailure(["var x = 1 *2"], msg, 1)
1476  call CheckDefFailure(["var x = 1* 2"], msg, 1)
1477
1478  let msg = "White space required before and after '/'"
1479  call CheckDefFailure(["var x = 1/2"], msg, 1)
1480  call CheckDefFailure(["var x = 1 /2"], msg, 1)
1481  call CheckDefFailure(["var x = 1/ 2"], msg, 1)
1482
1483  let msg = "White space required before and after '%'"
1484  call CheckDefFailure(["var x = 1%2"], msg, 1)
1485  call CheckDefFailure(["var x = 1 %2"], msg, 1)
1486  call CheckDefFailure(["var x = 1% 2"], msg, 1)
1487
1488  call CheckDefFailure(["var x = '1' * '2'"], 'E1036:', 1)
1489  call CheckDefFailure(["var x = '1' / '2'"], 'E1036:', 1)
1490  call CheckDefFailure(["var x = '1' % '2'"], 'E1035:', 1)
1491
1492  call CheckDefFailure(["var x = 0z01 * 0z12"], 'E1036:', 1)
1493  call CheckDefFailure(["var x = 0z01 / 0z12"], 'E1036:', 1)
1494  call CheckDefFailure(["var x = 0z01 % 0z12"], 'E1035:', 1)
1495
1496  call CheckDefFailure(["var x = [1] * [2]"], 'E1036:', 1)
1497  call CheckDefFailure(["var x = [1] / [2]"], 'E1036:', 1)
1498  call CheckDefFailure(["var x = [1] % [2]"], 'E1035:', 1)
1499
1500  call CheckDefFailure(["var x = {one: 1} * {two: 2}"], 'E1036:', 1)
1501  call CheckDefFailure(["var x = {one: 1} / {two: 2}"], 'E1036:', 1)
1502  call CheckDefFailure(["var x = {one: 1} % {two: 2}"], 'E1035:', 1)
1503
1504  call CheckDefFailure(["var x = 0xff[1]"], 'E1107:', 1)
1505  if has('float')
1506    call CheckDefFailure(["var x = 0.7[1]"], 'E1107:', 1)
1507  endif
1508endfunc
1509
1510func Test_expr6_float_fails()
1511  CheckFeature float
1512  call CheckDefFailure(["var x = 1.0 % 2"], 'E1035:', 1)
1513endfunc
1514
1515" define here to use old style parsing
1516if has('float')
1517  let g:float_zero = 0.0
1518  let g:float_neg = -9.8
1519  let g:float_big = 9.9e99
1520endif
1521let g:blob_empty = 0z
1522let g:blob_one = 0z01
1523let g:blob_long = 0z0102.0304
1524
1525let g:string_empty = ''
1526let g:string_short = 'x'
1527let g:string_long = 'abcdefghijklm'
1528let g:string_special = "ab\ncd\ref\ekk"
1529
1530let g:special_true = v:true
1531let g:special_false = v:false
1532let g:special_null = v:null
1533let g:special_none = v:none
1534
1535let g:list_empty = []
1536let g:list_mixed = [1, 'b', v:false]
1537
1538let g:dict_empty = {}
1539let g:dict_one = #{one: 1}
1540
1541let $TESTVAR = 'testvar'
1542
1543" type casts
1544def Test_expr7t()
1545  var ls: list<string> = ['a', <string>g:string_empty]
1546  var ln: list<number> = [<number>g:anint, <number>g:thefour]
1547  var nr = <number>234
1548  assert_equal(234, nr)
1549
1550  CheckDefFailure(["var x = <nr>123"], 'E1010:', 1)
1551  CheckDefFailure(["var x = <number>"], 'E1097:', 3)
1552  CheckDefFailure(["var x = <number >123"], 'E1068:', 1)
1553  CheckDefFailure(["var x = <number 123"], 'E1104:', 1)
1554enddef
1555
1556" test low level expression
1557def Test_expr7_number()
1558  # number constant
1559  var lines =<< trim END
1560      assert_equal(0, 0)
1561      assert_equal(654, 0654)
1562
1563      assert_equal(6, 0x6)
1564      assert_equal(15, 0xf)
1565      assert_equal(255, 0xff)
1566  END
1567  CheckDefAndScriptSuccess(lines)
1568enddef
1569
1570def Test_expr7_float()
1571  # float constant
1572  if !has('float')
1573    MissingFeature 'float'
1574  else
1575    var lines =<< trim END
1576        assert_equal(g:float_zero, .0)
1577        assert_equal(g:float_zero, 0.0)
1578        assert_equal(g:float_neg, -9.8)
1579        assert_equal(g:float_big, 9.9e99)
1580    END
1581    CheckDefAndScriptSuccess(lines)
1582  endif
1583enddef
1584
1585def Test_expr7_blob()
1586  # blob constant
1587  var lines =<< trim END
1588      assert_equal(g:blob_empty, 0z)
1589      assert_equal(g:blob_one, 0z01)
1590      assert_equal(g:blob_long, 0z0102.0304)
1591  END
1592  CheckDefAndScriptSuccess(lines)
1593
1594  CheckDefFailure(["var x = 0z123"], 'E973:', 1)
1595enddef
1596
1597def Test_expr7_string()
1598  # string constant
1599  var lines =<< trim END
1600      assert_equal(g:string_empty, '')
1601      assert_equal(g:string_empty, "")
1602      assert_equal(g:string_short, 'x')
1603      assert_equal(g:string_short, "x")
1604      assert_equal(g:string_long, 'abcdefghijklm')
1605      assert_equal(g:string_long, "abcdefghijklm")
1606      assert_equal(g:string_special, "ab\ncd\ref\ekk")
1607  END
1608  CheckDefAndScriptSuccess(lines)
1609
1610  CheckDefFailure(['var x = "abc'], 'E114:', 1)
1611  CheckDefFailure(["var x = 'abc"], 'E115:', 1)
1612enddef
1613
1614def Test_expr7_vimvar()
1615  var old: list<string> = v:oldfiles
1616  var compl: dict<any> = v:completed_item
1617
1618  CheckDefFailure(["var old: list<number> = v:oldfiles"], 'E1012: Type mismatch; expected list<number> but got list<string>', 1)
1619  new
1620  exec "normal! afoo fo\<C-N>\<Esc>"
1621  CheckDefExecFailure(["var old: dict<number> = v:completed_item"], 'E1012: Type mismatch; expected dict<number> but got dict<string>', 1)
1622  bwipe!
1623enddef
1624
1625def Test_expr7_special()
1626  # special constant
1627  var lines =<< trim END
1628      assert_equal(g:special_true, true)
1629      assert_equal(g:special_false, false)
1630      assert_equal(g:special_true, v:true)
1631      assert_equal(g:special_false, v:false)
1632      assert_equal(v:true, true)
1633      assert_equal(v:false, false)
1634
1635      assert_equal(true, !false)
1636      assert_equal(false, !true)
1637      assert_equal(true, !0)
1638      assert_equal(false, !1)
1639      assert_equal(false, !!false)
1640      assert_equal(true, !!true)
1641      assert_equal(false, !!0)
1642      assert_equal(true, !!1)
1643
1644      var t = true
1645      var f = false
1646      assert_equal(true, t)
1647      assert_equal(false, f)
1648
1649      assert_equal(g:special_null, v:null)
1650      assert_equal(g:special_none, v:none)
1651  END
1652  CheckDefAndScriptSuccess(lines)
1653
1654  CheckDefFailure(['v:true = true'], 'E46:', 1)
1655  CheckDefFailure(['v:true = false'], 'E46:', 1)
1656  CheckDefFailure(['v:false = true'], 'E46:', 1)
1657  CheckDefFailure(['v:null = 11'], 'E46:', 1)
1658  CheckDefFailure(['v:none = 22'], 'E46:', 1)
1659enddef
1660
1661def Test_expr7_list()
1662  # list
1663  var lines =<< trim END
1664      assert_equal(g:list_empty, [])
1665      assert_equal(g:list_empty, [  ])
1666
1667      var numbers: list<number> = [1, 2, 3]
1668      numbers = [1]
1669      numbers = []
1670
1671      var strings: list<string> = ['a', 'b', 'c']
1672      strings = ['x']
1673      strings = []
1674
1675      var mixed: list<any> = [1, 'b', false,]
1676      assert_equal(g:list_mixed, mixed)
1677      assert_equal('b', mixed[1])
1678
1679      echo [1,
1680            2] [3,
1681                    4]
1682
1683      var llstring: list<list<string>> = [['text'], []]
1684      llstring = [[], ['text']]
1685      llstring = [[], []]
1686  END
1687  CheckDefAndScriptSuccess(lines)
1688
1689  var rangelist: list<number> = range(3)
1690  g:rangelist = range(3)
1691  CheckDefExecFailure(["var x: list<string> = g:rangelist"], 'E1012: Type mismatch; expected list<string> but got list<number>', 1)
1692
1693  CheckDefFailure(["var x = 1234[3]"], 'E1107:', 1)
1694  CheckDefExecFailure(["var x = g:anint[3]"], 'E1062:', 1)
1695
1696  CheckDefFailure(["var x = g:list_mixed[xxx]"], 'E1001:', 1)
1697
1698  CheckDefFailure(["var x = [1,2,3]"], 'E1069:', 1)
1699  CheckDefFailure(["var x = [1 ,2, 3]"], 'E1068:', 1)
1700
1701  CheckDefExecFailure(["echo 1", "var x = [][0]", "echo 3"], 'E684:', 2)
1702
1703  CheckDefExecFailure(["var x = g:list_mixed['xx']"], 'E1012:', 1)
1704  CheckDefFailure(["var x = g:list_mixed["], 'E1097:', 3)
1705  CheckDefFailure(["var x = g:list_mixed[0"], 'E1097:', 3)
1706  CheckDefExecFailure(["var x = g:list_empty[3]"], 'E684:', 1)
1707  CheckDefExecFailure(["var l: list<number> = [234, 'x']"], 'E1012:', 1)
1708  CheckDefExecFailure(["var l: list<number> = ['x', 234]"], 'E1012:', 1)
1709  CheckDefExecFailure(["var l: list<string> = [234, 'x']"], 'E1012:', 1)
1710  CheckDefExecFailure(["var l: list<string> = ['x', 123]"], 'E1012:', 1)
1711
1712  lines =<< trim END
1713      vim9script
1714      var datalist: list<string>
1715      def Main()
1716        datalist += ['x'.
1717      enddef
1718      Main()
1719  END
1720  CheckScriptFailure(lines, 'E1127:')
1721enddef
1722
1723def Test_expr7_list_vim9script()
1724  var lines =<< trim END
1725      vim9script
1726      var l = [
1727		11,
1728		22,
1729		]
1730      assert_equal([11, 22], l)
1731
1732      echo [1,
1733	    2] [3,
1734		    4]
1735
1736      echo [1, # comment
1737            # comment
1738	    2] [3,
1739            # comment
1740		    4]
1741  END
1742  CheckScriptSuccess(lines)
1743
1744  lines =<< trim END
1745      vim9script
1746      var l = [11,
1747		22]
1748      assert_equal([11, 22], l)
1749  END
1750  CheckScriptSuccess(lines)
1751
1752  lines =<< trim END
1753      vim9script
1754      var l = [11,22]
1755  END
1756  CheckScriptFailure(lines, 'E1069:', 2)
1757
1758  lines =<< trim END
1759      vim9script
1760      var l = [11 , 22]
1761  END
1762  CheckScriptFailure(lines, 'E1068:', 2)
1763
1764  lines =<< trim END
1765    vim9script
1766    var l: list<number> = [234, 'x']
1767  END
1768  CheckScriptFailure(lines, 'E1012:', 2)
1769  lines =<< trim END
1770    vim9script
1771    var l: list<number> = ['x', 234]
1772  END
1773  CheckScriptFailure(lines, 'E1012:', 2)
1774  lines =<< trim END
1775    vim9script
1776    var l: list<string> = ['x', 234]
1777  END
1778  CheckScriptFailure(lines, 'E1012:', 2)
1779  lines =<< trim END
1780    vim9script
1781    var l: list<string> = [234, 'x']
1782  END
1783  CheckScriptFailure(lines, 'E1012:', 2)
1784
1785  lines =<< trim END
1786      vim9script
1787      def Failing()
1788        job_stop()
1789      enddef
1790      var list = [Failing]
1791  END
1792  if has('channel')
1793    CheckScriptFailure(lines, 'E119:', 1)
1794  else
1795    CheckScriptFailure(lines, 'E117:', 1)
1796  endif
1797enddef
1798
1799def LambdaWithComments(): func
1800  return {x ->
1801            # some comment
1802            x == 1
1803            # some comment
1804            ||
1805            x == 2
1806        }
1807enddef
1808
1809def LambdaUsingArg(x: number): func
1810  return {->
1811            # some comment
1812            x == 1
1813            # some comment
1814            ||
1815            x == 2
1816        }
1817enddef
1818
1819def Test_expr7_lambda()
1820  var lines =<< trim END
1821      var La = { -> 'result'}
1822      assert_equal('result', La())
1823      assert_equal([1, 3, 5], [1, 2, 3]->map({key, val -> key + val}))
1824
1825      # line continuation inside lambda with "cond ? expr : expr" works
1826      var ll = range(3)
1827      map(ll, {k, v -> v % 2 ? {
1828                ['111']: 111 } : {}
1829            })
1830      assert_equal([{}, {111: 111}, {}], ll)
1831
1832      ll = range(3)
1833      map(ll, {k, v -> v == 8 || v
1834                    == 9
1835                    || v % 2 ? 111 : 222
1836            })
1837      assert_equal([222, 111, 222], ll)
1838
1839      ll = range(3)
1840      map(ll, {k, v -> v != 8 && v
1841                    != 9
1842                    && v % 2 == 0 ? 111 : 222
1843            })
1844      assert_equal([111, 222, 111], ll)
1845
1846      var dl = [{key: 0}, {key: 22}]->filter({ _, v -> v['key'] })
1847      assert_equal([{key: 22}], dl)
1848
1849      dl = [{key: 12}, {['foo']: 34}]
1850      assert_equal([{key: 12}], filter(dl,
1851            {_, v -> has_key(v, 'key') ? v['key'] == 12 : 0}))
1852
1853      assert_equal(false, LambdaWithComments()(0))
1854      assert_equal(true, LambdaWithComments()(1))
1855      assert_equal(true, LambdaWithComments()(2))
1856      assert_equal(false, LambdaWithComments()(3))
1857
1858      assert_equal(false, LambdaUsingArg(0)())
1859      assert_equal(true, LambdaUsingArg(1)())
1860
1861      var res = map([1, 2, 3], {i: number, v: number -> i + v})
1862      assert_equal([1, 3, 5], res)
1863  END
1864  CheckDefAndScriptSuccess(lines)
1865
1866  CheckDefFailure(["filter([1, 2], {k,v -> 1})"], 'E1069:', 1)
1867  # error is in first line of the lambda
1868  CheckDefFailure(["var L = {a -> a + b}"], 'E1001:', 0)
1869
1870  assert_equal('xxxyyy', 'xxx'->{a, b -> a .. b}('yyy'))
1871
1872  CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x')"],
1873        'E1106: One argument too many')
1874  CheckDefExecFailure(["var s = 'asdf'->{a -> a}('x', 'y')"],
1875        'E1106: 2 arguments too many')
1876  CheckDefFailure(["echo 'asdf'->{a -> a}(x)"], 'E1001:', 1)
1877
1878  CheckDefSuccess(['var Fx = {a -> {k1: 0,', ' k2: 1}}'])
1879  CheckDefFailure(['var Fx = {a -> {k1: 0', ' k2: 1}}'], 'E722:', 2)
1880  CheckDefFailure(['var Fx = {a -> {k1: 0,', ' k2 1}}'], 'E720:', 2)
1881
1882  CheckDefSuccess(['var Fx = {a -> [0,', ' 1]}'])
1883  CheckDefFailure(['var Fx = {a -> [0', ' 1]}'], 'E696:', 2)
1884enddef
1885
1886def Test_expr7_lambda_vim9script()
1887  var lines =<< trim END
1888      vim9script
1889      var v = 10->{a ->
1890	    a
1891	      + 2
1892	  }()
1893      assert_equal(12, v)
1894  END
1895  CheckScriptSuccess(lines)
1896
1897  # nested lambda with line breaks
1898  lines =<< trim END
1899      vim9script
1900      search('"', 'cW', 0, 0, {->
1901	synstack('.', col('.'))
1902	->map({_, v -> synIDattr(v, 'name')})->len()})
1903  END
1904  CheckScriptSuccess(lines)
1905enddef
1906
1907def Test_epxr7_funcref()
1908  var lines =<< trim END
1909      def RetNumber(): number
1910        return 123
1911      enddef
1912      var FuncRef = RetNumber
1913      assert_equal(123, FuncRef())
1914  END
1915  CheckDefAndScriptSuccess(lines)
1916enddef
1917
1918let g:test_space_dict = {'': 'empty', ' ': 'space'}
1919let g:test_hash_dict = #{one: 1, two: 2}
1920
1921def Test_expr7_dict()
1922  # dictionary
1923  var lines =<< trim END
1924      assert_equal(g:dict_empty, {})
1925      assert_equal(g:dict_empty, {  })
1926      assert_equal(g:dict_one, {['one']: 1})
1927      var key = 'one'
1928      var val = 1
1929      assert_equal(g:dict_one, {[key]: val})
1930
1931      var numbers: dict<number> = {a: 1, b: 2, c: 3}
1932      numbers = {a: 1}
1933      numbers = {}
1934
1935      var strings: dict<string> = {a: 'a', b: 'b', c: 'c'}
1936      strings = {a: 'x'}
1937      strings = {}
1938
1939      var dash = {xx-x: 8}
1940      assert_equal({['xx-x']: 8}, dash)
1941
1942      var dnr = {8: 8}
1943      assert_equal({['8']: 8}, dnr)
1944
1945      var mixed: dict<any> = {a: 'a', b: 42}
1946      mixed = {a: 'x'}
1947      mixed = {a: 234}
1948      mixed = {}
1949
1950      var dictlist: dict<list<string>> = {absent: [], present: ['hi']}
1951      dictlist = {absent: ['hi'], present: []}
1952      dictlist = {absent: [], present: []}
1953
1954      var dictdict: dict<dict<string>> = {one: {a: 'text'}, two: {}}
1955      dictdict = {one: {}, two: {a: 'text'}}
1956      dictdict = {one: {}, two: {}}
1957
1958      assert_equal({['']: 0}, {[matchstr('string', 'wont match')]: 0})
1959
1960      assert_equal(g:test_space_dict, {['']: 'empty', [' ']: 'space'})
1961      assert_equal(g:test_hash_dict, {one: 1, two: 2})
1962
1963      assert_equal({['a a']: 1, ['b/c']: 2}, {'a a': 1, "b/c": 2})
1964  END
1965  CheckDefAndScriptSuccess(lines)
1966
1967  # legacy syntax doesn't work
1968  CheckDefFailure(["var x = #{key: 8}"], 'E1097:', 3)
1969  CheckDefFailure(["var x = 'a' .. #{a: 1}"], 'E1097:', 3)
1970
1971  CheckDefFailure(["var x = {a:8}"], 'E1069:', 1)
1972  CheckDefFailure(["var x = {a : 8}"], 'E1059:', 1)
1973  CheckDefFailure(["var x = {a :8}"], 'E1059:', 1)
1974  CheckDefFailure(["var x = {a: 8 , b: 9}"], 'E1068:', 1)
1975  CheckDefFailure(["var x = {a: 1,b: 2}"], 'E1069:', 1)
1976
1977  CheckDefFailure(["var x = {xxx}"], 'E720:', 1)
1978  CheckDefFailure(["var x = {xxx: 1", "var y = 2"], 'E722:', 2)
1979  CheckDefFailure(["var x = {xxx: 1,"], 'E723:', 2)
1980  CheckDefFailure(["var x = {['a']: xxx}"], 'E1001:', 1)
1981  CheckDefFailure(["var x = {a: 1, a: 2}"], 'E721:', 1)
1982  CheckDefExecFailure(["var x = g:anint.member"], 'E715:', 1)
1983  CheckDefExecFailure(["var x = g:dict_empty.member"], 'E716:', 1)
1984
1985  CheckDefExecFailure(['var x: dict<number> = {a: 234, b: "1"}'], 'E1012:', 1)
1986  CheckDefExecFailure(['var x: dict<number> = {a: "x", b: 134}'], 'E1012:', 1)
1987  CheckDefExecFailure(['var x: dict<string> = {a: 234, b: "1"}'], 'E1012:', 1)
1988  CheckDefExecFailure(['var x: dict<string> = {a: "x", b: 134}'], 'E1012:', 1)
1989
1990  CheckDefFailure(['var x = ({'], 'E723:', 2)
1991  CheckDefExecFailure(['{}[getftype("file")]'], 'E716: Key not present in Dictionary: ""', 1)
1992
1993  # no automatic conversion from number to string
1994  lines =<< trim END
1995      var n = 123
1996      var d = {[n]: 1}
1997  END
1998  CheckDefFailure(lines, 'E1012:', 2)
1999  CheckScriptFailure(['vim9script'] + lines, 'E928:', 3)
2000enddef
2001
2002def Test_expr7_dict_vim9script()
2003  var lines =<< trim END
2004      vim9script
2005      var d = {
2006		['one']:
2007		   1,
2008		['two']: 2,
2009		   }
2010      assert_equal({one: 1, two: 2}, d)
2011
2012      d = {  # comment
2013		['one']:
2014                # comment
2015
2016		   1,
2017                # comment
2018                # comment
2019		['two']: 2,
2020		   }
2021      assert_equal({one: 1, two: 2}, d)
2022  END
2023  CheckScriptSuccess(lines)
2024
2025  lines =<< trim END
2026      vim9script
2027      var d = { ["one"]: "one", ["two"]: "two", }
2028      assert_equal({one: 'one', two: 'two'}, d)
2029  END
2030  CheckScriptSuccess(lines)
2031
2032  lines =<< trim END
2033      vim9script
2034      var d = {one: 1,
2035		two: 2,
2036	       }
2037      assert_equal({one: 1, two: 2}, d)
2038  END
2039  CheckScriptSuccess(lines)
2040
2041  lines =<< trim END
2042      vim9script
2043      var d = {one:1, two: 2}
2044  END
2045  CheckScriptFailure(lines, 'E1069:', 2)
2046
2047  lines =<< trim END
2048      vim9script
2049      var d = {one: 1,two: 2}
2050  END
2051  CheckScriptFailure(lines, 'E1069:', 2)
2052
2053  lines =<< trim END
2054      vim9script
2055      var d = {one : 1}
2056  END
2057  CheckScriptFailure(lines, 'E1059:', 2)
2058
2059  lines =<< trim END
2060      vim9script
2061      var d = {one:1}
2062  END
2063  CheckScriptFailure(lines, 'E1069:', 2)
2064
2065  lines =<< trim END
2066      vim9script
2067      var d = {one: 1 , two: 2}
2068  END
2069  CheckScriptFailure(lines, 'E1068:', 2)
2070
2071  lines =<< trim END
2072    vim9script
2073    var l: dict<number> = {a: 234, b: 'x'}
2074  END
2075  CheckScriptFailure(lines, 'E1012:', 2)
2076  lines =<< trim END
2077    vim9script
2078    var l: dict<number> = {a: 'x', b: 234}
2079  END
2080  CheckScriptFailure(lines, 'E1012:', 2)
2081  lines =<< trim END
2082    vim9script
2083    var l: dict<string> = {a: 'x', b: 234}
2084  END
2085  CheckScriptFailure(lines, 'E1012:', 2)
2086  lines =<< trim END
2087    vim9script
2088    var l: dict<string> = {a: 234, b: 'x'}
2089  END
2090  CheckScriptFailure(lines, 'E1012:', 2)
2091
2092  lines =<< trim END
2093    vim9script
2094    var d = {['a']: 234, ['b': 'x'}
2095  END
2096  CheckScriptFailure(lines, 'E1139:', 2)
2097  lines =<< trim END
2098    vim9script
2099    def Func()
2100      var d = {['a']: 234, ['b': 'x'}
2101    enddef
2102    defcompile
2103  END
2104  CheckScriptFailure(lines, 'E1139:', 1)
2105  lines =<< trim END
2106    vim9script
2107    var d = {'a':
2108  END
2109  CheckScriptFailure(lines, 'E15:', 2)
2110  lines =<< trim END
2111    vim9script
2112    def Func()
2113      var d = {'a':
2114    enddef
2115    defcompile
2116  END
2117  CheckScriptFailure(lines, 'E723:', 1)
2118
2119  lines =<< trim END
2120      vim9script
2121      def Failing()
2122        job_stop()
2123      enddef
2124      var dict = {name: Failing}
2125  END
2126  if has('channel')
2127    CheckScriptFailure(lines, 'E119:', 1)
2128  else
2129    CheckScriptFailure(lines, 'E117:', 1)
2130  endif
2131enddef
2132
2133let g:oneString = 'one'
2134
2135def Test_expr_member()
2136  assert_equal(1, g:dict_one.one)
2137  var d: dict<number> = g:dict_one
2138  assert_equal(1, d['one'])
2139  assert_equal(1, d[
2140		  'one'
2141		  ])
2142  assert_equal(1, d
2143  	.one)
2144  d = {1: 1, _: 2}
2145  assert_equal(1, d
2146  	.1)
2147  assert_equal(2, d
2148  	._)
2149
2150  # getting the one member should clear the dict after getting the item
2151  assert_equal('one', {one: 'one'}.one)
2152  assert_equal('one', {one: 'one'}[g:oneString])
2153
2154  CheckDefFailure(["var x = g:dict_one.#$!"], 'E1002:', 1)
2155  CheckDefExecFailure(["var d: dict<any>", "echo d['a']"], 'E716:', 2)
2156  CheckDefExecFailure(["var d: dict<number>", "d = g:list_empty"], 'E1012: Type mismatch; expected dict<number> but got list<unknown>', 2)
2157enddef
2158
2159def Test_expr7_any_index_slice()
2160  var lines =<< trim END
2161    # getting the one member should clear the list only after getting the item
2162    assert_equal('bbb', ['aaa', 'bbb', 'ccc'][1])
2163
2164    # string is permissive, index out of range accepted
2165    g:teststring = 'abcdef'
2166    assert_equal('b', g:teststring[1])
2167    assert_equal('', g:teststring[-1])
2168    assert_equal('', g:teststring[99])
2169
2170    assert_equal('b', g:teststring[1:1])
2171    assert_equal('bcdef', g:teststring[1:])
2172    assert_equal('abcd', g:teststring[:3])
2173    assert_equal('cdef', g:teststring[-4:])
2174    assert_equal('abcdef', g:teststring[-9:])
2175    assert_equal('abcd', g:teststring[:-3])
2176    assert_equal('', g:teststring[:-9])
2177
2178    # blob index cannot be out of range
2179    g:testblob = 0z01ab
2180    assert_equal(0x01, g:testblob[0])
2181    assert_equal(0xab, g:testblob[1])
2182    assert_equal(0xab, g:testblob[-1])
2183    assert_equal(0x01, g:testblob[-2])
2184
2185    # blob slice accepts out of range
2186    assert_equal(0z01ab, g:testblob[0:1])
2187    assert_equal(0z01, g:testblob[0:0])
2188    assert_equal(0z01, g:testblob[-2:-2])
2189    assert_equal(0zab, g:testblob[1:1])
2190    assert_equal(0zab, g:testblob[-1:-1])
2191    assert_equal(0z, g:testblob[2:2])
2192    assert_equal(0z, g:testblob[0:-3])
2193
2194    # list index cannot be out of range
2195    g:testlist = [0, 1, 2, 3]
2196    assert_equal(0, g:testlist[0])
2197    assert_equal(1, g:testlist[1])
2198    assert_equal(3, g:testlist[3])
2199    assert_equal(3, g:testlist[-1])
2200    assert_equal(0, g:testlist[-4])
2201    assert_equal(1, g:testlist[g:theone])
2202
2203    # list slice accepts out of range
2204    assert_equal([0], g:testlist[0:0])
2205    assert_equal([3], g:testlist[3:3])
2206    assert_equal([0, 1], g:testlist[0:1])
2207    assert_equal([0, 1, 2, 3], g:testlist[0:3])
2208    assert_equal([0, 1, 2, 3], g:testlist[0:9])
2209    assert_equal([], g:testlist[-1:1])
2210    assert_equal([1], g:testlist[-3:1])
2211    assert_equal([0, 1], g:testlist[-4:1])
2212    assert_equal([0, 1], g:testlist[-9:1])
2213    assert_equal([1, 2, 3], g:testlist[1:-1])
2214    assert_equal([1], g:testlist[1:-3])
2215    assert_equal([], g:testlist[1:-4])
2216    assert_equal([], g:testlist[1:-9])
2217
2218    g:testdict = {a: 1, b: 2}
2219    assert_equal(1, g:testdict['a'])
2220    assert_equal(2, g:testdict['b'])
2221  END
2222
2223  CheckDefSuccess(lines)
2224  CheckScriptSuccess(['vim9script'] + lines)
2225
2226  CheckDefExecFailure(['echo g:testblob[2]'], 'E979:', 1)
2227  CheckScriptFailure(['vim9script', 'echo g:testblob[2]'], 'E979:', 2)
2228  CheckDefExecFailure(['echo g:testblob[-3]'], 'E979:', 1)
2229  CheckScriptFailure(['vim9script', 'echo g:testblob[-3]'], 'E979:', 2)
2230
2231  CheckDefExecFailure(['echo g:testlist[4]'], 'E684:', 1)
2232  CheckScriptFailure(['vim9script', 'echo g:testlist[4]'], 'E684:', 2)
2233  CheckDefExecFailure(['echo g:testlist[-5]'], 'E684:', 1)
2234  CheckScriptFailure(['vim9script', 'echo g:testlist[-5]'], 'E684:', 2)
2235
2236  CheckDefExecFailure(['echo g:testdict["a":"b"]'], 'E719:', 1)
2237  CheckScriptFailure(['vim9script', 'echo g:testdict["a":"b"]'], 'E719:', 2)
2238  CheckDefExecFailure(['echo g:testdict[1]'], 'E716:', 1)
2239  CheckScriptFailure(['vim9script', 'echo g:testdict[1]'], 'E716:', 2)
2240
2241  unlet g:teststring
2242  unlet g:testblob
2243  unlet g:testlist
2244enddef
2245
2246def Test_expr_member_vim9script()
2247  var lines =<< trim END
2248      vim9script
2249      var d = {one:
2250      		'one',
2251		two: 'two',
2252		1: 1,
2253		_: 2}
2254      assert_equal('one', d.one)
2255      assert_equal('one', d
2256                            .one)
2257      assert_equal(1, d
2258                            .1)
2259      assert_equal(2, d
2260                            ._)
2261      assert_equal('one', d[
2262			    'one'
2263			    ])
2264  END
2265  CheckScriptSuccess(lines)
2266
2267  lines =<< trim END
2268      vim9script
2269      var l = [1,
2270		  2,
2271		  3, 4
2272		  ]
2273      assert_equal(2, l[
2274			    1
2275			    ])
2276      assert_equal([2, 3], l[1 : 2])
2277      assert_equal([1, 2, 3], l[
2278				:
2279				2
2280				])
2281      assert_equal([3, 4], l[
2282				2
2283				:
2284				])
2285  END
2286  CheckScriptSuccess(lines)
2287enddef
2288
2289def Test_expr7_option()
2290  # option
2291  set ts=11
2292  assert_equal(11, &ts)
2293  &ts = 9
2294  assert_equal(9, &ts)
2295  set ts=8
2296  set grepprg=some\ text
2297  assert_equal('some text', &grepprg)
2298  &grepprg = test_null_string()
2299  assert_equal('', &grepprg)
2300  set grepprg&
2301enddef
2302
2303def Test_expr7_environment()
2304  # environment variable
2305  assert_equal('testvar', $TESTVAR)
2306  assert_equal('', $ASDF_ASD_XXX)
2307
2308  CheckDefFailure(["var x = $$$"], 'E1002:', 1)
2309enddef
2310
2311def Test_expr7_register()
2312  @a = 'register a'
2313  assert_equal('register a', @a)
2314
2315  var fname = expand('%')
2316  assert_equal(fname, @%)
2317
2318  feedkeys(":echo 'some'\<CR>", "xt")
2319  assert_equal("echo 'some'", @:)
2320
2321  normal axyz
2322  assert_equal("xyz", @.)
2323  CheckDefFailure(["@. = 'yes'"], 'E354:', 1)
2324
2325  @/ = 'slash'
2326  assert_equal('slash', @/)
2327
2328  @= = 'equal'
2329  assert_equal('equal', @=)
2330enddef
2331
2332def Test_expr7_namespace()
2333  g:some_var = 'some'
2334  assert_equal('some', get(g:, 'some_var'))
2335  assert_equal('some', get(g:, 'some_var', 'xxx'))
2336  assert_equal('xxx', get(g:, 'no_var', 'xxx'))
2337  unlet g:some_var
2338
2339  b:some_var = 'some'
2340  assert_equal('some', get(b:, 'some_var'))
2341  assert_equal('some', get(b:, 'some_var', 'xxx'))
2342  assert_equal('xxx', get(b:, 'no_var', 'xxx'))
2343  unlet b:some_var
2344
2345  w:some_var = 'some'
2346  assert_equal('some', get(w:, 'some_var'))
2347  assert_equal('some', get(w:, 'some_var', 'xxx'))
2348  assert_equal('xxx', get(w:, 'no_var', 'xxx'))
2349  unlet w:some_var
2350
2351  t:some_var = 'some'
2352  assert_equal('some', get(t:, 'some_var'))
2353  assert_equal('some', get(t:, 'some_var', 'xxx'))
2354  assert_equal('xxx', get(t:, 'no_var', 'xxx'))
2355  unlet t:some_var
2356enddef
2357
2358def Test_expr7_parens()
2359  # (expr)
2360  assert_equal(4, (6 * 4) / 6)
2361  assert_equal(0, 6 * ( 4 / 6 ))
2362
2363  assert_equal(6, +6)
2364  assert_equal(-6, -6)
2365  assert_equal(6, --6)
2366  assert_equal(6, -+-6)
2367  assert_equal(-6, ---6)
2368  assert_equal(false, !-3)
2369  assert_equal(true, !+-+0)
2370enddef
2371
2372def Test_expr7_parens_vim9script()
2373  var lines =<< trim END
2374      vim9script
2375      var s = (
2376		'one'
2377		..
2378		'two'
2379		)
2380      assert_equal('onetwo', s)
2381  END
2382  CheckScriptSuccess(lines)
2383enddef
2384
2385def Test_expr7_negate_add()
2386  assert_equal(-99, -99)
2387  assert_equal(-99, - 99)
2388  assert_equal(99, --99)
2389  assert_equal(99, -- 99)
2390  assert_equal(99, - - 99)
2391  assert_equal(99, +99)
2392  assert_equal(-99, -+99)
2393  assert_equal(-99, -+ 99)
2394  assert_equal(-99, - +99)
2395  assert_equal(-99, - + 99)
2396  assert_equal(-99, +-99)
2397  assert_equal(-99, + -99)
2398  assert_equal(-99, + - 99)
2399
2400  var nr = 88
2401  assert_equal(-88, -nr)
2402  assert_equal(-88, - nr)
2403  assert_equal(-88, - +nr)
2404  assert_equal(88, -- nr)
2405  assert_equal(88, + nr)
2406  assert_equal(88, --+ nr)
2407  assert_equal(88, - - nr)
2408enddef
2409
2410def Echo(arg: any): string
2411  return arg
2412enddef
2413
2414def s:Echo4Arg(arg: any): string
2415  return arg
2416enddef
2417
2418def Test_expr7_call()
2419  var lines =<< trim END
2420      assert_equal('yes', 'yes'->Echo())
2421      assert_equal(true, !range(5)->empty())
2422      assert_equal([0, 1, 2], --3->range())
2423  END
2424  CheckDefAndScriptSuccess(lines)
2425
2426  assert_equal('yes', 'yes'
2427                        ->s:Echo4Arg())
2428
2429  CheckDefFailure(["var x = 'yes'->Echo"], 'E107:', 1)
2430  CheckScriptFailure([
2431   "vim9script",
2432   "var x = substitute ('x', 'x', 'x', 'x')"
2433   ], 'E121:', 2)
2434  CheckDefFailure(["var Ref = function('len' [1, 2])"], 'E1123:', 1)
2435
2436  var auto_lines =<< trim END
2437      def g:some#func(): string
2438	return 'found'
2439      enddef
2440  END
2441  mkdir('Xruntime/autoload', 'p')
2442  writefile(auto_lines, 'Xruntime/autoload/some.vim')
2443  var save_rtp = &rtp
2444  &rtp = getcwd() .. '/Xruntime,' .. &rtp
2445  assert_equal('found', g:some#func())
2446  assert_equal('found', some#func())
2447
2448  &rtp = save_rtp
2449  delete('Xruntime', 'rf')
2450enddef
2451
2452
2453def Test_expr7_not()
2454  var lines =<< trim END
2455      assert_equal(true, !'')
2456      assert_equal(true, ![])
2457      assert_equal(false, !'asdf')
2458      assert_equal(false, ![2])
2459      assert_equal(true, !!'asdf')
2460      assert_equal(true, !![2])
2461
2462      assert_equal(true, ! false)
2463      assert_equal(true, !! true)
2464      assert_equal(true, ! ! true)
2465      assert_equal(true, !!! false)
2466      assert_equal(true, ! ! ! false)
2467
2468      g:true = true
2469      g:false = false
2470      assert_equal(true, ! g:false)
2471      assert_equal(true, !! g:true)
2472      assert_equal(true, ! ! g:true)
2473      assert_equal(true, !!! g:false)
2474      assert_equal(true, ! ! ! g:false)
2475      unlet g:true
2476      unlet g:false
2477
2478      assert_equal(true, !test_null_partial())
2479      assert_equal(false, !{-> 'yes'})
2480
2481      assert_equal(true, !test_null_dict())
2482      assert_equal(true, !{})
2483      assert_equal(false, !{yes: 'no'})
2484
2485      if has('channel')
2486	assert_equal(true, !test_null_job())
2487	assert_equal(true, !test_null_channel())
2488      endif
2489
2490      assert_equal(true, !test_null_blob())
2491      assert_equal(true, !0z)
2492      assert_equal(false, !0z01)
2493
2494      assert_equal(true, !test_void())
2495      assert_equal(true, !test_unknown())
2496
2497      assert_equal(false, ![1, 2, 3]->reverse())
2498      assert_equal(true, ![]->reverse())
2499  END
2500  CheckDefAndScriptSuccess(lines)
2501enddef
2502
2503func Test_expr7_fails()
2504  call CheckDefFailure(["var x = (12"], "E110:", 1)
2505
2506  call CheckDefFailure(["var x = -'xx'"], "E1030:", 1)
2507  call CheckDefFailure(["var x = +'xx'"], "E1030:", 1)
2508  call CheckDefFailure(["var x = -0z12"], "E974:", 1)
2509  call CheckDefExecFailure(["var x = -[8]"], "E39:", 1)
2510  call CheckDefExecFailure(["var x = -{a: 1}"], "E39:", 1)
2511
2512  call CheckDefFailure(["var x = @"], "E1002:", 1)
2513  call CheckDefFailure(["var x = @<"], "E354:", 1)
2514
2515  call CheckDefFailure(["var x = [1, 2"], "E697:", 2)
2516  call CheckDefFailure(["var x = [notfound]"], "E1001:", 1)
2517
2518  call CheckDefFailure(["var x = { -> 123) }"], "E451:", 1)
2519  call CheckDefFailure(["var x = 123->{x -> x + 5) }"], "E451:", 1)
2520
2521  call CheckDefFailure(["var x = &notexist"], 'E113:', 1)
2522  call CheckDefFailure(["&grepprg = [343]"], 'E1012:', 1)
2523
2524  call CheckDefExecFailure(["echo s:doesnt_exist"], 'E121:', 1)
2525  call CheckDefExecFailure(["echo g:doesnt_exist"], 'E121:', 1)
2526
2527  call CheckDefFailure(["echo a:somevar"], 'E1075:', 1)
2528  call CheckDefFailure(["echo l:somevar"], 'E1075:', 1)
2529  call CheckDefFailure(["echo x:somevar"], 'E1075:', 1)
2530
2531  call CheckDefExecFailure(["var x = +g:astring"], 'E1030:', 1)
2532  call CheckDefExecFailure(["var x = +g:ablob"], 'E974:', 1)
2533  call CheckDefExecFailure(["var x = +g:alist"], 'E745:', 1)
2534  call CheckDefExecFailure(["var x = +g:adict"], 'E728:', 1)
2535
2536  call CheckDefFailure(["var x = ''", "var y = x.memb"], 'E715:', 2)
2537
2538  call CheckDefFailure(["'yes'->", "Echo()"], 'E488: Trailing characters: ->', 1)
2539
2540  call CheckDefExecFailure(["[1, 2->len()"], 'E697:', 2)
2541  call CheckDefExecFailure(["{a: 1->len()"], 'E451:', 1)
2542  call CheckDefExecFailure(["{['a']: 1->len()"], 'E723:', 2)
2543endfunc
2544
2545let g:Funcrefs = [function('add')]
2546
2547func CallMe(arg)
2548  return a:arg
2549endfunc
2550
2551func CallMe2(one, two)
2552  return a:one .. a:two
2553endfunc
2554
2555def Test_expr7_trailing()
2556  # user function call
2557  assert_equal(123, g:CallMe(123))
2558  assert_equal(123, g:CallMe(  123))
2559  assert_equal(123, g:CallMe(123  ))
2560  assert_equal('yesno', g:CallMe2('yes', 'no'))
2561  assert_equal('yesno', g:CallMe2( 'yes', 'no' ))
2562  assert_equal('nothing', g:CallMe('nothing'))
2563
2564  # partial call
2565  var Part = function('g:CallMe')
2566  assert_equal('yes', Part('yes'))
2567
2568  # funcref call, using list index
2569  var l = []
2570  g:Funcrefs[0](l, 2)
2571  assert_equal([2], l)
2572
2573  # method call
2574  l = [2, 5, 6]
2575  l->map({k, v -> k + v})
2576  assert_equal([2, 6, 8], l)
2577
2578  # lambda method call
2579  l = [2, 5]
2580  l->{l -> add(l, 8)}()
2581  assert_equal([2, 5, 8], l)
2582
2583  # dict member
2584  var d = {key: 123}
2585  assert_equal(123, d.key)
2586enddef
2587
2588def Test_expr7_string_subscript()
2589  var lines =<< trim END
2590    var text = 'abcdef'
2591    assert_equal('', text[-1])
2592    assert_equal('a', text[0])
2593    assert_equal('e', text[4])
2594    assert_equal('f', text[5])
2595    assert_equal('', text[6])
2596
2597    text = 'ábçdëf'
2598    assert_equal('', text[-999])
2599    assert_equal('', text[-1])
2600    assert_equal('á', text[0])
2601    assert_equal('b', text[1])
2602    assert_equal('ç', text[2])
2603    assert_equal('d', text[3])
2604    assert_equal('ë', text[4])
2605    assert_equal('f', text[5])
2606    assert_equal('', text[6])
2607    assert_equal('', text[999])
2608
2609    assert_equal('ábçdëf', text[0:-1])
2610    assert_equal('ábçdëf', text[0 :-1])
2611    assert_equal('ábçdëf', text[0: -1])
2612    assert_equal('ábçdëf', text[0 : -1])
2613    assert_equal('ábçdëf', text[0
2614                  :-1])
2615    assert_equal('ábçdëf', text[0:
2616                  -1])
2617    assert_equal('ábçdëf', text[0 : -1
2618                  ])
2619    assert_equal('bçdëf', text[1:-1])
2620    assert_equal('çdëf', text[2:-1])
2621    assert_equal('dëf', text[3:-1])
2622    assert_equal('ëf', text[4:-1])
2623    assert_equal('f', text[5:-1])
2624    assert_equal('', text[6:-1])
2625    assert_equal('', text[999:-1])
2626
2627    assert_equal('ábçd', text[:3])
2628    assert_equal('bçdëf', text[1:])
2629    assert_equal('ábçdëf', text[:])
2630  END
2631  CheckDefSuccess(lines)
2632  CheckScriptSuccess(['vim9script'] + lines)
2633
2634  lines =<< trim END
2635      var d = 'asdf'[1:
2636  END
2637  CheckDefFailure(lines, 'E1097:', 3)
2638  lines =<< trim END
2639      var d = 'asdf'[1:xxx]
2640  END
2641  CheckDefFailure(lines, 'E1001:', 1)
2642  lines =<< trim END
2643      var d = 'asdf'[1:2
2644  END
2645  CheckDefFailure(lines, 'E1097:', 3)
2646  lines =<< trim END
2647      var d = 'asdf'[1:2
2648      echo d
2649  END
2650  CheckDefFailure(lines, 'E111:', 2)
2651  lines =<< trim END
2652      var d = 'asdf'['1']
2653      echo d
2654  END
2655  CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
2656  lines =<< trim END
2657      var d = 'asdf'['1':2]
2658      echo d
2659  END
2660  CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
2661  lines =<< trim END
2662      var d = 'asdf'[1:'2']
2663      echo d
2664  END
2665  CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got string', 1)
2666enddef
2667
2668def Test_expr7_list_subscript()
2669  var lines =<< trim END
2670    var list = [0, 1, 2, 3, 4]
2671    assert_equal(0, list[0])
2672    assert_equal(4, list[4])
2673    assert_equal(4, list[-1])
2674    assert_equal(0, list[-5])
2675
2676    assert_equal([0, 1, 2, 3, 4], list[0:4])
2677    assert_equal([0, 1, 2, 3, 4], list[:])
2678    assert_equal([1, 2, 3, 4], list[1:])
2679    assert_equal([2, 3, 4], list[2:-1])
2680    assert_equal([4], list[4:-1])
2681    assert_equal([], list[5:-1])
2682    assert_equal([], list[999:-1])
2683    assert_equal([1, 2, 3, 4], list[g:theone:g:thefour])
2684
2685    assert_equal([0, 1, 2, 3], list[0:3])
2686    assert_equal([0], list[0:0])
2687    assert_equal([0, 1, 2, 3, 4], list[0:-1])
2688    assert_equal([0, 1, 2], list[0:-3])
2689    assert_equal([0], list[0:-5])
2690    assert_equal([], list[0:-6])
2691    assert_equal([], list[0:-99])
2692  END
2693  CheckDefSuccess(lines)
2694  CheckScriptSuccess(['vim9script'] + lines)
2695
2696  lines = ['var l = [0, 1, 2]', 'echo l[g:astring : g:theone]']
2697  CheckDefExecFailure(lines, 'E1012:')
2698  CheckScriptFailure(['vim9script'] + lines, 'E1030:', 3)
2699enddef
2700
2701def Test_expr7_dict_subscript()
2702  var lines =<< trim END
2703      vim9script
2704      var l = [{lnum: 2}, {lnum: 1}]
2705      var res = l[0].lnum > l[1].lnum
2706      assert_true(res)
2707  END
2708  CheckScriptSuccess(lines)
2709enddef
2710
2711def Test_expr7_subscript_linebreak()
2712  var range = range(
2713  		3)
2714  var l = range
2715	->map('string(v:key)')
2716  assert_equal(['0', '1', '2'], l)
2717
2718  l = range
2719  	->map('string(v:key)')
2720  assert_equal(['0', '1', '2'], l)
2721
2722  l = range # comment
2723  	->map('string(v:key)')
2724  assert_equal(['0', '1', '2'], l)
2725
2726  l = range
2727
2728  	->map('string(v:key)')
2729  assert_equal(['0', '1', '2'], l)
2730
2731  l = range
2732	# comment
2733  	->map('string(v:key)')
2734  assert_equal(['0', '1', '2'], l)
2735
2736  assert_equal('1', l[
2737	1])
2738
2739  var d = {one: 33}
2740  assert_equal(33, d.
2741	one)
2742enddef
2743
2744def Test_expr7_method_call()
2745  new
2746  setline(1, ['first', 'last'])
2747  'second'->append(1)
2748  "third"->append(2)
2749  assert_equal(['first', 'second', 'third', 'last'], getline(1, '$'))
2750  bwipe!
2751
2752  var bufnr = bufnr()
2753  var loclist = [{bufnr: bufnr, lnum: 42, col: 17, text: 'wrong'}]
2754  loclist->setloclist(0)
2755  assert_equal([{bufnr: bufnr,
2756  		lnum: 42,
2757		col: 17,
2758		text: 'wrong',
2759		pattern: '',
2760		valid: 1,
2761		vcol: 0,
2762		nr: 0,
2763		type: '',
2764		module: ''}
2765		], getloclist(0))
2766
2767  var result: bool = get({n: 0}, 'n', 0)
2768  assert_equal(false, result)
2769enddef
2770
2771func Test_expr7_trailing_fails()
2772  call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)}'], 'E107:', 2)
2773  call CheckDefFailure(['var l = [2]', 'l->{l -> add(l, 8)} ()'], 'E274:', 2)
2774endfunc
2775
2776func Test_expr_fails()
2777  call CheckDefFailure(["var x = '1'is2"], 'E488:', 1)
2778  call CheckDefFailure(["var x = '1'isnot2"], 'E488:', 1)
2779
2780  call CheckDefFailure(["CallMe ('yes')"], 'E476:', 1)
2781  call CheckScriptFailure(["CallMe ('yes')"], 'E492:', 1)
2782  call CheckDefAndScriptFailure(["CallMe2('yes','no')"], 'E1069:', 1)
2783  call CheckDefFailure(["CallMe2('yes' , 'no')"], 'E1068:', 1)
2784
2785  call CheckDefFailure(["v:nosuch += 3"], 'E1001:', 1)
2786  call CheckDefFailure(["var v:statusmsg = ''"], 'E1016: Cannot declare a v: variable:', 1)
2787  call CheckDefFailure(["var asdf = v:nosuch"], 'E1001:', 1)
2788
2789  call CheckDefFailure(["echo len('asdf'"], 'E110:', 2)
2790  call CheckDefFailure(["echo Func0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789()"], 'E1011:', 1)
2791  call CheckDefFailure(["echo doesnotexist()"], 'E117:', 1)
2792endfunc
2793
2794" vim: shiftwidth=2 sts=2 expandtab
2795