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