1" Test various aspects of the Vim9 script language.
2
3source check.vim
4source term_util.vim
5source view_util.vim
6source vim9.vim
7
8def Test_syntax()
9  let var = 234
10  let other: list<string> = ['asdf']
11enddef
12
13let s:appendToMe = 'xxx'
14let s:addToMe = 111
15let g:existing = 'yes'
16let g:inc_counter = 1
17let $SOME_ENV_VAR = 'some'
18let g:alist = [7]
19let g:astring = 'text'
20let g:anumber = 123
21
22def Test_assignment()
23  let bool1: bool = true
24  assert_equal(v:true, bool1)
25  let bool2: bool = false
26  assert_equal(v:false, bool2)
27
28  call CheckDefFailure(['let x:string'], 'E1069:')
29  call CheckDefFailure(['let x:string = "x"'], 'E1069:')
30  call CheckDefFailure(['let a:string = "x"'], 'E1069:')
31
32  let nr: number = 1234
33  call CheckDefFailure(['let nr: number = "asdf"'], 'E1013:')
34
35  let a: number = 6 #comment
36  assert_equal(6, a)
37
38  if has('channel')
39    let chan1: channel
40    let job1: job
41    let job2: job = job_start('willfail')
42  endif
43  if has('float')
44    let float1: float = 3.4
45  endif
46  let Funky1: func
47  let Funky2: func = function('len')
48  let Party2: func = funcref('g:Test_syntax')
49
50  g:newvar = 'new'  #comment
51  assert_equal('new', g:newvar)
52
53  assert_equal('yes', g:existing)
54  g:existing = 'no'
55  assert_equal('no', g:existing)
56
57  v:char = 'abc'
58  assert_equal('abc', v:char)
59
60  $ENVVAR = 'foobar'
61  assert_equal('foobar', $ENVVAR)
62  $ENVVAR = ''
63
64  let lines =<< trim END
65    vim9script
66    $ENVVAR = 'barfoo'
67    assert_equal('barfoo', $ENVVAR)
68    $ENVVAR = ''
69  END
70  call CheckScriptSuccess(lines)
71
72  s:appendToMe ..= 'yyy'
73  assert_equal('xxxyyy', s:appendToMe)
74  s:addToMe += 222
75  assert_equal(333, s:addToMe)
76  s:newVar = 'new'
77  assert_equal('new', s:newVar)
78
79  set ts=7
80  &ts += 1
81  assert_equal(8, &ts)
82  &ts -= 3
83  assert_equal(5, &ts)
84  &ts *= 2
85  assert_equal(10, &ts)
86  &ts /= 3
87  assert_equal(3, &ts)
88  set ts=10
89  &ts %= 4
90  assert_equal(2, &ts)
91
92  lines =<< trim END
93    vim9script
94    &ts = 6
95    &ts += 3
96    assert_equal(9, &ts)
97  END
98  call CheckScriptSuccess(lines)
99
100  call CheckDefFailure(['&notex += 3'], 'E113:')
101  call CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
102  call CheckDefFailure(['&ts = [7]'], 'E1013:')
103  call CheckDefExecFailure(['&ts = g:alist'], 'E1029: Expected number but got list')
104  call CheckDefFailure(['&ts = "xx"'], 'E1013:')
105  call CheckDefExecFailure(['&ts = g:astring'], 'E1029: Expected number but got string')
106  call CheckDefFailure(['&path += 3'], 'E1013:')
107  call CheckDefExecFailure(['&bs = "asdf"'], 'E474:')
108  # test freeing ISN_STOREOPT
109  call CheckDefFailure(['&ts = 3', 'let asdf'], 'E1022:')
110  &ts = 8
111
112  call CheckDefFailure(['let s:var = 123'], 'E1101:')
113  call CheckDefFailure(['let s:var: number'], 'E1101:')
114
115  g:inc_counter += 1
116  assert_equal(2, g:inc_counter)
117
118  $SOME_ENV_VAR ..= 'more'
119  assert_equal('somemore', $SOME_ENV_VAR)
120  call CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1013:')
121  call CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1013:')
122
123  @a = 'areg'
124  @a ..= 'add'
125  assert_equal('aregadd', @a)
126  call CheckDefFailure(['@a += "more"'], 'E1013:')
127  call CheckDefFailure(['@a += 123'], 'E1013:')
128
129  lines =<< trim END
130    vim9script
131    @c = 'areg'
132    @c ..= 'add'
133    assert_equal('aregadd', @c)
134  END
135  call CheckScriptSuccess(lines)
136
137  v:errmsg = 'none'
138  v:errmsg ..= 'again'
139  assert_equal('noneagain', v:errmsg)
140  call CheckDefFailure(['v:errmsg += "more"'], 'E1013:')
141  call CheckDefFailure(['v:errmsg += 123'], 'E1013:')
142
143  # single letter variables
144  a = 123
145  assert_equal(123, a)
146  let b: number
147  b = 123
148  assert_equal(123, b)
149  let g: number
150  g = 123
151  assert_equal(123, g)
152  let s: number
153  s = 123
154  assert_equal(123, s)
155  let t: number
156  t = 123
157  assert_equal(123, t)
158  let v: number
159  v = 123
160  assert_equal(123, v)
161  let w: number
162  w = 123
163  assert_equal(123, w)
164enddef
165
166def Test_vim9_single_char_vars()
167  let lines =<< trim END
168      vim9script
169
170      # single character variable declarations work
171      let a: string
172      let b: number
173      let l: list<any>
174      let s: string
175      let t: number
176      let v: number
177      let w: number
178
179      # script-local variables can be used without s: prefix
180      a = 'script-a'
181      b = 111
182      l = [1, 2, 3]
183      s = 'script-s'
184      t = 222
185      v = 333
186      w = 444
187
188      assert_equal('script-a', a)
189      assert_equal(111, b)
190      assert_equal([1, 2, 3], l)
191      assert_equal('script-s', s)
192      assert_equal(222, t)
193      assert_equal(333, v)
194      assert_equal(444, w)
195  END
196  writefile(lines, 'Xsinglechar')
197  source Xsinglechar
198  delete('Xsinglechar')
199enddef
200
201def Test_assignment_list()
202  let list1: list<bool> = [false, true, false]
203  let list2: list<number> = [1, 2, 3]
204  let list3: list<string> = ['sdf', 'asdf']
205  let list4: list<any> = ['yes', true, 1234]
206  let list5: list<blob> = [0z01, 0z02]
207
208  let listS: list<string> = []
209  let listN: list<number> = []
210
211  assert_equal([1, 2, 3], list2)
212  list2[-1] = 99
213  assert_equal([1, 2, 99], list2)
214  list2[-2] = 88
215  assert_equal([1, 88, 99], list2)
216  list2[-3] = 77
217  assert_equal([77, 88, 99], list2)
218  call CheckDefExecFailure(['let ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:')
219  call CheckDefExecFailure(['let [v1, v2] = [1, 2]'], 'E1092:')
220
221  # type becomes list<any>
222  let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
223enddef
224
225def Test_assignment_list_vim9script()
226  let lines =<< trim END
227    vim9script
228    let v1: number
229    let v2: number
230    let v3: number
231    [v1, v2, v3] = [1, 2, 3]
232    assert_equal([1, 2, 3], [v1, v2, v3])
233  END
234  call CheckScriptSuccess(lines)
235enddef
236
237def Test_assignment_dict()
238  let dict1: dict<bool> = #{one: false, two: true}
239  let dict2: dict<number> = #{one: 1, two: 2}
240  let dict3: dict<string> = #{key: 'value'}
241  let dict4: dict<any> = #{one: 1, two: '2'}
242  let dict5: dict<blob> = #{one: 0z01, two: 0z02}
243
244  # overwrite
245  dict3['key'] = 'another'
246
247  call CheckDefExecFailure(['let dd = {}', 'dd[""] = 6'], 'E713:')
248
249  # type becomes dict<any>
250  let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
251enddef
252
253def Test_assignment_local()
254  # Test in a separated file in order not to the current buffer/window/tab is
255  # changed.
256  let script_lines: list<string> =<< trim END
257    let b:existing = 'yes'
258    let w:existing = 'yes'
259    let t:existing = 'yes'
260
261    def Test_assignment_local_internal()
262      b:newvar = 'new'
263      assert_equal('new', b:newvar)
264      assert_equal('yes', b:existing)
265      b:existing = 'no'
266      assert_equal('no', b:existing)
267      b:existing ..= 'NO'
268      assert_equal('noNO', b:existing)
269
270      w:newvar = 'new'
271      assert_equal('new', w:newvar)
272      assert_equal('yes', w:existing)
273      w:existing = 'no'
274      assert_equal('no', w:existing)
275      w:existing ..= 'NO'
276      assert_equal('noNO', w:existing)
277
278      t:newvar = 'new'
279      assert_equal('new', t:newvar)
280      assert_equal('yes', t:existing)
281      t:existing = 'no'
282      assert_equal('no', t:existing)
283      t:existing ..= 'NO'
284      assert_equal('noNO', t:existing)
285    enddef
286    call Test_assignment_local_internal()
287  END
288  call CheckScriptSuccess(script_lines)
289enddef
290
291def Test_assignment_default()
292
293  # Test default values.
294  let thebool: bool
295  assert_equal(v:false, thebool)
296
297  let thenumber: number
298  assert_equal(0, thenumber)
299
300  if has('float')
301    let thefloat: float
302    assert_equal(0.0, thefloat)
303  endif
304
305  let thestring: string
306  assert_equal('', thestring)
307
308  let theblob: blob
309  assert_equal(0z, theblob)
310
311  let Thefunc: func
312  assert_equal(test_null_function(), Thefunc)
313
314  let thelist: list<any>
315  assert_equal([], thelist)
316
317  let thedict: dict<any>
318  assert_equal({}, thedict)
319
320  if has('channel')
321    let thejob: job
322    assert_equal(test_null_job(), thejob)
323
324    let thechannel: channel
325    assert_equal(test_null_channel(), thechannel)
326
327    if has('unix') && executable('cat')
328      # check with non-null job and channel, types must match
329      thejob = job_start("cat ", #{})
330      thechannel = job_getchannel(thejob)
331      job_stop(thejob, 'kill')
332    endif
333  endif
334
335  let nr = 1234 | nr = 5678
336  assert_equal(5678, nr)
337enddef
338
339def Test_assignment_var_list()
340  let v1: string
341  let v2: string
342  let vrem: list<string>
343  [v1] = ['aaa']
344  assert_equal('aaa', v1)
345
346  [v1, v2] = ['one', 'two']
347  assert_equal('one', v1)
348  assert_equal('two', v2)
349
350  [v1, v2; vrem] = ['one', 'two']
351  assert_equal('one', v1)
352  assert_equal('two', v2)
353  assert_equal([], vrem)
354
355  [v1, v2; vrem] = ['one', 'two', 'three']
356  assert_equal('one', v1)
357  assert_equal('two', v2)
358  assert_equal(['three'], vrem)
359enddef
360
361def Test_assignment_vim9script()
362  let lines =<< trim END
363    vim9script
364    def Func(): list<number>
365      return [1, 2]
366    enddef
367    let var1: number
368    let var2: number
369    [var1, var2] =
370          Func()
371    assert_equal(1, var1)
372    assert_equal(2, var2)
373    let ll =
374          Func()
375    assert_equal([1, 2], ll)
376  END
377  CheckScriptSuccess(lines)
378enddef
379
380def Mess(): string
381  v:foldstart = 123
382  return 'xxx'
383enddef
384
385def Test_assignment_failure()
386  call CheckDefFailure(['let var=234'], 'E1004:')
387  call CheckDefFailure(['let var =234'], 'E1004:')
388  call CheckDefFailure(['let var= 234'], 'E1004:')
389
390  call CheckScriptFailure(['vim9script', 'let var=234'], 'E1004:')
391  call CheckScriptFailure(['vim9script', 'let var=234'], "before and after '='")
392  call CheckScriptFailure(['vim9script', 'let var =234'], 'E1004:')
393  call CheckScriptFailure(['vim9script', 'let var= 234'], 'E1004:')
394  call CheckScriptFailure(['vim9script', 'let var = 234', 'var+=234'], 'E1004:')
395  call CheckScriptFailure(['vim9script', 'let var = 234', 'var+=234'], "before and after '+='")
396  call CheckScriptFailure(['vim9script', 'let var = "x"', 'var..="y"'], 'E1004:')
397  call CheckScriptFailure(['vim9script', 'let var = "x"', 'var..="y"'], "before and after '..='")
398
399  call CheckDefFailure(['let true = 1'], 'E1034:')
400  call CheckDefFailure(['let false = 1'], 'E1034:')
401
402  call CheckDefFailure(['[a; b; c] = g:list'], 'E452:')
403  call CheckDefExecFailure(['let a: number',
404                            '[a] = test_null_list()'], 'E1093:')
405  call CheckDefExecFailure(['let a: number',
406                            '[a] = []'], 'E1093:')
407  call CheckDefExecFailure(['let x: number',
408                            'let y: number',
409                            '[x, y] = [1]'], 'E1093:')
410  call CheckDefExecFailure(['let x: number',
411                            'let y: number',
412                            'let z: list<number>',
413                            '[x, y; z] = [1]'], 'E1093:')
414
415  call CheckDefFailure(['let somevar'], "E1022:")
416  call CheckDefFailure(['let &option'], 'E1052:')
417  call CheckDefFailure(['&g:option = 5'], 'E113:')
418
419  call CheckDefFailure(['let $VAR = 5'], 'E1016: Cannot declare an environment variable:')
420
421  call CheckDefFailure(['let @~ = 5'], 'E354:')
422  call CheckDefFailure(['let @a = 5'], 'E1066:')
423
424  call CheckDefFailure(['let g:var = 5'], 'E1016: Cannot declare a global variable:')
425  call CheckDefFailure(['let w:var = 5'], 'E1016: Cannot declare a window variable:')
426  call CheckDefFailure(['let b:var = 5'], 'E1016: Cannot declare a buffer variable:')
427  call CheckDefFailure(['let t:var = 5'], 'E1016: Cannot declare a tab variable:')
428
429  call CheckDefFailure(['let anr = 4', 'anr ..= "text"'], 'E1019:')
430  call CheckDefFailure(['let xnr += 4'], 'E1020:')
431
432  call CheckScriptFailure(['vim9script', 'def Func()', 'let dummy = s:notfound', 'enddef', 'defcompile'], 'E1050:')
433
434  call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
435  call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
436
437  call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
438  call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
439
440  call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
441  call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
442
443  call CheckDefFailure(['let var: dict <number>'], 'E1068:')
444  call CheckDefFailure(['let var: dict<number'], 'E1009:')
445
446  call assert_fails('s/^/\=Mess()/n', 'E794:')
447  call CheckDefFailure(['let var: dict<number'], 'E1009:')
448
449  call CheckDefFailure(['w:foo: number = 10'],
450                       'E488: Trailing characters: : number = 1')
451  call CheckDefFailure(['t:foo: bool = true'],
452                       'E488: Trailing characters: : bool = true')
453  call CheckDefFailure(['b:foo: string = "x"'],
454                       'E488: Trailing characters: : string = "x"')
455  call CheckDefFailure(['g:foo: number = 123'],
456                       'E488: Trailing characters: : number = 123')
457enddef
458
459def Test_unlet()
460  g:somevar = 'yes'
461  assert_true(exists('g:somevar'))
462  unlet g:somevar
463  assert_false(exists('g:somevar'))
464  unlet! g:somevar
465
466  call CheckScriptFailure([
467        'vim9script',
468        'let svar = 123',
469        'unlet svar',
470        ], 'E1081:')
471  call CheckScriptFailure([
472        'vim9script',
473        'let svar = 123',
474        'unlet s:svar',
475        ], 'E1081:')
476  call CheckScriptFailure([
477        'vim9script',
478        'let svar = 123',
479        'def Func()',
480        '  unlet svar',
481        'enddef',
482        'defcompile',
483        ], 'E1081:')
484  call CheckScriptFailure([
485        'vim9script',
486        'let svar = 123',
487        'def Func()',
488        '  unlet s:svar',
489        'enddef',
490        'defcompile',
491        ], 'E1081:')
492
493  $ENVVAR = 'foobar'
494  assert_equal('foobar', $ENVVAR)
495  unlet $ENVVAR
496  assert_equal('', $ENVVAR)
497enddef
498
499def Test_delfunction()
500  # Check function is defined in script namespace
501  CheckScriptSuccess([
502      'vim9script',
503      'func CheckMe()',
504      '  return 123',
505      'endfunc',
506      'assert_equal(123, s:CheckMe())',
507      ])
508
509  # Check function in script namespace cannot be deleted
510  CheckScriptFailure([
511      'vim9script',
512      'func DeleteMe1()',
513      'endfunc',
514      'delfunction DeleteMe1',
515      ], 'E1084:')
516  CheckScriptFailure([
517      'vim9script',
518      'func DeleteMe2()',
519      'endfunc',
520      'def DoThat()',
521      '  delfunction DeleteMe2',
522      'enddef',
523      'DoThat()',
524      ], 'E1084:')
525  CheckScriptFailure([
526      'vim9script',
527      'def DeleteMe3()',
528      'enddef',
529      'delfunction DeleteMe3',
530      ], 'E1084:')
531  CheckScriptFailure([
532      'vim9script',
533      'def DeleteMe4()',
534      'enddef',
535      'def DoThat()',
536      '  delfunction DeleteMe4',
537      'enddef',
538      'DoThat()',
539      ], 'E1084:')
540
541  # Check that global :def function can be replaced and deleted
542  let lines =<< trim END
543      vim9script
544      def g:Global(): string
545        return "yes"
546      enddef
547      assert_equal("yes", g:Global())
548      def! g:Global(): string
549        return "no"
550      enddef
551      assert_equal("no", g:Global())
552      delfunc g:Global
553      assert_false(exists('*g:Global'))
554  END
555  CheckScriptSuccess(lines)
556
557  # Check that global function can be replaced by a :def function and deleted
558  lines =<< trim END
559      vim9script
560      func g:Global()
561        return "yes"
562      endfunc
563      assert_equal("yes", g:Global())
564      def! g:Global(): string
565        return "no"
566      enddef
567      assert_equal("no", g:Global())
568      delfunc g:Global
569      assert_false(exists('*g:Global'))
570  END
571  CheckScriptSuccess(lines)
572
573  # Check that global :def function can be replaced by a function and deleted
574  lines =<< trim END
575      vim9script
576      def g:Global(): string
577        return "yes"
578      enddef
579      assert_equal("yes", g:Global())
580      func! g:Global()
581        return "no"
582      endfunc
583      assert_equal("no", g:Global())
584      delfunc g:Global
585      assert_false(exists('*g:Global'))
586  END
587  CheckScriptSuccess(lines)
588enddef
589
590func Test_wrong_type()
591  call CheckDefFailure(['let var: list<nothing>'], 'E1010:')
592  call CheckDefFailure(['let var: list<list<nothing>>'], 'E1010:')
593  call CheckDefFailure(['let var: dict<nothing>'], 'E1010:')
594  call CheckDefFailure(['let var: dict<dict<nothing>>'], 'E1010:')
595
596  call CheckDefFailure(['let var: dict<number'], 'E1009:')
597  call CheckDefFailure(['let var: dict<list<number>'], 'E1009:')
598
599  call CheckDefFailure(['let var: ally'], 'E1010:')
600  call CheckDefFailure(['let var: bram'], 'E1010:')
601  call CheckDefFailure(['let var: cathy'], 'E1010:')
602  call CheckDefFailure(['let var: dom'], 'E1010:')
603  call CheckDefFailure(['let var: freddy'], 'E1010:')
604  call CheckDefFailure(['let var: john'], 'E1010:')
605  call CheckDefFailure(['let var: larry'], 'E1010:')
606  call CheckDefFailure(['let var: ned'], 'E1010:')
607  call CheckDefFailure(['let var: pam'], 'E1010:')
608  call CheckDefFailure(['let var: sam'], 'E1010:')
609  call CheckDefFailure(['let var: vim'], 'E1010:')
610
611  call CheckDefFailure(['let Ref: number', 'Ref()'], 'E1085:')
612  call CheckDefFailure(['let Ref: string', 'let res = Ref()'], 'E1085:')
613endfunc
614
615func Test_const()
616  call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
617  call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
618  call CheckDefFailure(['const two'], 'E1021:')
619  call CheckDefFailure(['const &option'], 'E996:')
620endfunc
621
622def Test_range_no_colon()
623  call CheckDefFailure(['%s/a/b/'], 'E1050:')
624  call CheckDefFailure(['+ s/a/b/'], 'E1050:')
625  call CheckDefFailure(['- s/a/b/'], 'E1050:')
626  call CheckDefFailure(['. s/a/b/'], 'E1050:')
627enddef
628
629
630def Test_block()
631  let outer = 1
632  {
633    let inner = 2
634    assert_equal(1, outer)
635    assert_equal(2, inner)
636  }
637  assert_equal(1, outer)
638enddef
639
640func Test_block_failure()
641  call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
642  call CheckDefFailure(['}'], 'E1025:')
643  call CheckDefFailure(['{', 'echo 1'], 'E1026:')
644endfunc
645
646def Test_cmd_modifier()
647  tab echo '0'
648  call CheckDefFailure(['5tab echo 3'], 'E16:')
649enddef
650
651func g:NoSuchFunc()
652  echo 'none'
653endfunc
654
655def Test_try_catch()
656  let l = []
657  try # comment
658    add(l, '1')
659    throw 'wrong'
660    add(l, '2')
661  catch # comment
662    add(l, v:exception)
663  finally # comment
664    add(l, '3')
665  endtry # comment
666  assert_equal(['1', 'wrong', '3'], l)
667
668  l = []
669  try
670    try
671      add(l, '1')
672      throw 'wrong'
673      add(l, '2')
674    catch /right/
675      add(l, v:exception)
676    endtry
677  catch /wrong/
678    add(l, 'caught')
679  finally
680    add(l, 'finally')
681  endtry
682  assert_equal(['1', 'caught', 'finally'], l)
683
684  let n: number
685  try
686    n = l[3]
687  catch /E684:/
688    n = 99
689  endtry
690  assert_equal(99, n)
691
692  try
693    n = g:astring[3]
694  catch /E714:/
695    n = 77
696  endtry
697  assert_equal(77, n)
698
699  try
700    n = l[g:astring]
701  catch /E39:/
702    n = 77
703  endtry
704  assert_equal(77, n)
705
706  try
707    n = s:does_not_exist
708  catch /E121:/
709    n = 111
710  endtry
711  assert_equal(111, n)
712
713  try
714    n = g:does_not_exist
715  catch /E121:/
716    n = 121
717  endtry
718  assert_equal(121, n)
719
720  let d = #{one: 1}
721  try
722    n = d[g:astring]
723  catch /E716:/
724    n = 222
725  endtry
726  assert_equal(222, n)
727
728  try
729    n = -g:astring
730  catch /E39:/
731    n = 233
732  endtry
733  assert_equal(233, n)
734
735  try
736    n = +g:astring
737  catch /E1030:/
738    n = 244
739  endtry
740  assert_equal(244, n)
741
742  try
743    n = +g:alist
744  catch /E745:/
745    n = 255
746  endtry
747  assert_equal(255, n)
748
749  let nd: dict<any>
750  try
751    nd = {g:anumber: 1}
752  catch /E1029:/
753    n = 266
754  endtry
755  assert_equal(266, n)
756
757  try
758    [n] = [1, 2, 3]
759  catch /E1093:/
760    n = 277
761  endtry
762  assert_equal(277, n)
763
764  try
765    &ts = g:astring
766  catch /E1029:/
767    n = 288
768  endtry
769  assert_equal(288, n)
770
771  try
772    &backspace = 'asdf'
773  catch /E474:/
774    n = 299
775  endtry
776  assert_equal(299, n)
777
778  l = [1]
779  try
780    l[3] = 3
781  catch /E684:/
782    n = 300
783  endtry
784  assert_equal(300, n)
785
786  try
787    d[''] = 3
788  catch /E713:/
789    n = 311
790  endtry
791  assert_equal(311, n)
792
793  try
794    unlet g:does_not_exist
795  catch /E108:/
796    n = 322
797  endtry
798  assert_equal(322, n)
799
800  try
801    d = {'text': 1, g:astring: 2}
802  catch /E721:/
803    n = 333
804  endtry
805  assert_equal(333, n)
806
807  try
808    l = DeletedFunc()
809  catch /E933:/
810    n = 344
811  endtry
812  assert_equal(344, n)
813
814  try
815    echo len(v:true)
816  catch /E701:/
817    n = 355
818  endtry
819  assert_equal(355, n)
820
821  let P = function('g:NoSuchFunc')
822  delfunc g:NoSuchFunc
823  try
824    echo P()
825  catch /E117:/
826    n = 366
827  endtry
828  assert_equal(366, n)
829
830  try
831    echo g:NoSuchFunc()
832  catch /E117:/
833    n = 377
834  endtry
835  assert_equal(377, n)
836
837  try
838    echo g:alist + 4
839  catch /E745:/
840    n = 388
841  endtry
842  assert_equal(388, n)
843
844  try
845    echo 4 + g:alist
846  catch /E745:/
847    n = 399
848  endtry
849  assert_equal(399, n)
850
851  try
852    echo g:alist.member
853  catch /E715:/
854    n = 400
855  endtry
856  assert_equal(400, n)
857
858  try
859    echo d.member
860  catch /E716:/
861    n = 411
862  endtry
863  assert_equal(411, n)
864enddef
865
866def DeletedFunc(): list<any>
867  return ['delete me']
868enddef
869defcompile
870delfunc DeletedFunc
871
872def ThrowFromDef()
873  throw "getout" # comment
874enddef
875
876func CatchInFunc()
877  try
878    call ThrowFromDef()
879  catch
880    let g:thrown_func = v:exception
881  endtry
882endfunc
883
884def CatchInDef()
885  try
886    ThrowFromDef()
887  catch
888    g:thrown_def = v:exception
889  endtry
890enddef
891
892def ReturnFinally(): string
893  try
894    return 'intry'
895  finally
896    g:in_finally = 'finally'
897  endtry
898  return 'end'
899enddef
900
901def Test_try_catch_nested()
902  CatchInFunc()
903  assert_equal('getout', g:thrown_func)
904
905  CatchInDef()
906  assert_equal('getout', g:thrown_def)
907
908  assert_equal('intry', ReturnFinally())
909  assert_equal('finally', g:in_finally)
910enddef
911
912def Test_try_catch_match()
913  let seq = 'a'
914  try
915    throw 'something'
916  catch /nothing/
917    seq ..= 'x'
918  catch /some/
919    seq ..= 'b'
920  catch /asdf/
921    seq ..= 'x'
922  catch ?a\?sdf?
923    seq ..= 'y'
924  finally
925    seq ..= 'c'
926  endtry
927  assert_equal('abc', seq)
928enddef
929
930def Test_try_catch_fails()
931  call CheckDefFailure(['catch'], 'E603:')
932  call CheckDefFailure(['try', 'echo 0', 'catch', 'catch'], 'E1033:')
933  call CheckDefFailure(['try', 'echo 0', 'catch /pat'], 'E1067:')
934  call CheckDefFailure(['finally'], 'E606:')
935  call CheckDefFailure(['try', 'echo 0', 'finally', 'echo 1', 'finally'], 'E607:')
936  call CheckDefFailure(['endtry'], 'E602:')
937  call CheckDefFailure(['while 1', 'endtry'], 'E170:')
938  call CheckDefFailure(['for i in range(5)', 'endtry'], 'E170:')
939  call CheckDefFailure(['if 2', 'endtry'], 'E171:')
940  call CheckDefFailure(['try', 'echo 1', 'endtry'], 'E1032:')
941
942  call CheckDefFailure(['throw'], 'E1015:')
943  call CheckDefFailure(['throw xxx'], 'E1001:')
944enddef
945
946def Test_throw_vimscript()
947  # only checks line continuation
948  let lines =<< trim END
949      vim9script
950      try
951        throw 'one'
952              .. 'two'
953      catch
954        assert_equal('onetwo', v:exception)
955      endtry
956  END
957  CheckScriptSuccess(lines)
958enddef
959
960def Test_cexpr_vimscript()
961  # only checks line continuation
962  set errorformat=File\ %f\ line\ %l
963  let lines =<< trim END
964      vim9script
965      cexpr 'File'
966                .. ' someFile' ..
967                   ' line 19'
968      assert_equal(19, getqflist()[0].lnum)
969  END
970  CheckScriptSuccess(lines)
971  set errorformat&
972enddef
973
974def Test_list_vimscript()
975  # checks line continuation and comments
976  let lines =<< trim END
977      vim9script
978      let mylist = [
979            'one',
980            # comment
981            'two', # empty line follows
982
983            'three',
984            ]
985      assert_equal(['one', 'two', 'three'], mylist)
986  END
987  CheckScriptSuccess(lines)
988enddef
989
990if has('channel')
991  let someJob = test_null_job()
992
993  def FuncWithError()
994    echomsg g:someJob
995  enddef
996
997  func Test_convert_emsg_to_exception()
998    try
999      call FuncWithError()
1000    catch
1001      call assert_match('Vim:E908:', v:exception)
1002    endtry
1003  endfunc
1004endif
1005
1006let s:export_script_lines =<< trim END
1007  vim9script
1008  let name: string = 'bob'
1009  def Concat(arg: string): string
1010    return name .. arg
1011  enddef
1012  g:result = Concat('bie')
1013  g:localname = name
1014
1015  export const CONST = 1234
1016  export let exported = 9876
1017  export let exp_name = 'John'
1018  export def Exported(): string
1019    return 'Exported'
1020  enddef
1021END
1022
1023def Test_vim9_import_export()
1024  let import_script_lines =<< trim END
1025    vim9script
1026    import {exported, Exported} from './Xexport.vim'
1027    g:imported = exported
1028    exported += 3
1029    g:imported_added = exported
1030    g:imported_func = Exported()
1031
1032    def GetExported(): string
1033      let local_dict = #{ref: Exported}
1034      return local_dict.ref()
1035    enddef
1036    g:funcref_result = GetExported()
1037
1038    import {exp_name} from './Xexport.vim'
1039    g:imported_name = exp_name
1040    exp_name ..= ' Doe'
1041    g:imported_name_appended = exp_name
1042    g:imported_later = exported
1043  END
1044
1045  writefile(import_script_lines, 'Ximport.vim')
1046  writefile(s:export_script_lines, 'Xexport.vim')
1047
1048  source Ximport.vim
1049
1050  assert_equal('bobbie', g:result)
1051  assert_equal('bob', g:localname)
1052  assert_equal(9876, g:imported)
1053  assert_equal(9879, g:imported_added)
1054  assert_equal(9879, g:imported_later)
1055  assert_equal('Exported', g:imported_func)
1056  assert_equal('Exported', g:funcref_result)
1057  assert_equal('John', g:imported_name)
1058  assert_equal('John Doe', g:imported_name_appended)
1059  assert_false(exists('g:name'))
1060
1061  unlet g:result
1062  unlet g:localname
1063  unlet g:imported
1064  unlet g:imported_added
1065  unlet g:imported_later
1066  unlet g:imported_func
1067  unlet g:imported_name g:imported_name_appended
1068  delete('Ximport.vim')
1069
1070  # similar, with line breaks
1071  let import_line_break_script_lines =<< trim END
1072    vim9script
1073    import {
1074        exported,
1075        Exported,
1076        }
1077        from
1078        './Xexport.vim'
1079    g:imported = exported
1080    exported += 5
1081    g:imported_added = exported
1082    g:imported_func = Exported()
1083  END
1084  writefile(import_line_break_script_lines, 'Ximport_lbr.vim')
1085  source Ximport_lbr.vim
1086
1087  assert_equal(9876, g:imported)
1088  assert_equal(9881, g:imported_added)
1089  assert_equal('Exported', g:imported_func)
1090
1091  # exported script not sourced again
1092  assert_false(exists('g:result'))
1093  unlet g:imported
1094  unlet g:imported_added
1095  unlet g:imported_func
1096  delete('Ximport_lbr.vim')
1097
1098  # import inside :def function
1099  let import_in_def_lines =<< trim END
1100    vim9script
1101    def ImportInDef()
1102      import exported from './Xexport.vim'
1103      g:imported = exported
1104      exported += 7
1105      g:imported_added = exported
1106    enddef
1107    ImportInDef()
1108  END
1109  writefile(import_in_def_lines, 'Ximport2.vim')
1110  source Ximport2.vim
1111  # TODO: this should be 9879
1112  assert_equal(9876, g:imported)
1113  assert_equal(9883, g:imported_added)
1114  unlet g:imported
1115  unlet g:imported_added
1116  delete('Ximport2.vim')
1117
1118  let import_star_as_lines =<< trim END
1119    vim9script
1120    import * as Export from './Xexport.vim'
1121    def UseExport()
1122      g:imported = Export.exported
1123    enddef
1124    UseExport()
1125  END
1126  writefile(import_star_as_lines, 'Ximport.vim')
1127  source Ximport.vim
1128  assert_equal(9883, g:imported)
1129
1130  let import_star_as_lines_no_dot =<< trim END
1131    vim9script
1132    import * as Export from './Xexport.vim'
1133    def Func()
1134      let dummy = 1
1135      let imported = Export + dummy
1136    enddef
1137    defcompile
1138  END
1139  writefile(import_star_as_lines_no_dot, 'Ximport.vim')
1140  assert_fails('source Ximport.vim', 'E1060:')
1141
1142  let import_star_as_lines_dot_space =<< trim END
1143    vim9script
1144    import * as Export from './Xexport.vim'
1145    def Func()
1146      let imported = Export . exported
1147    enddef
1148    defcompile
1149  END
1150  writefile(import_star_as_lines_dot_space, 'Ximport.vim')
1151  assert_fails('source Ximport.vim', 'E1074:')
1152
1153  let import_star_as_lines_missing_name =<< trim END
1154    vim9script
1155    import * as Export from './Xexport.vim'
1156    def Func()
1157      let imported = Export.
1158    enddef
1159    defcompile
1160  END
1161  writefile(import_star_as_lines_missing_name, 'Ximport.vim')
1162  assert_fails('source Ximport.vim', 'E1048:')
1163
1164  let import_star_as_lbr_lines =<< trim END
1165    vim9script
1166    import *
1167        as Export
1168        from
1169        './Xexport.vim'
1170    def UseExport()
1171      g:imported = Export.exported
1172    enddef
1173    UseExport()
1174  END
1175  writefile(import_star_as_lbr_lines, 'Ximport.vim')
1176  source Ximport.vim
1177  assert_equal(9883, g:imported)
1178
1179  let import_star_lines =<< trim END
1180    vim9script
1181    import * from './Xexport.vim'
1182  END
1183  writefile(import_star_lines, 'Ximport.vim')
1184  assert_fails('source Ximport.vim', 'E1045:')
1185
1186  # try to import something that exists but is not exported
1187  let import_not_exported_lines =<< trim END
1188    vim9script
1189    import name from './Xexport.vim'
1190  END
1191  writefile(import_not_exported_lines, 'Ximport.vim')
1192  assert_fails('source Ximport.vim', 'E1049:')
1193
1194  # try to import something that is already defined
1195  let import_already_defined =<< trim END
1196    vim9script
1197    let exported = 'something'
1198    import exported from './Xexport.vim'
1199  END
1200  writefile(import_already_defined, 'Ximport.vim')
1201  assert_fails('source Ximport.vim', 'E1073:')
1202
1203  # try to import something that is already defined
1204  import_already_defined =<< trim END
1205    vim9script
1206    let exported = 'something'
1207    import * as exported from './Xexport.vim'
1208  END
1209  writefile(import_already_defined, 'Ximport.vim')
1210  assert_fails('source Ximport.vim', 'E1073:')
1211
1212  # try to import something that is already defined
1213  import_already_defined =<< trim END
1214    vim9script
1215    let exported = 'something'
1216    import {exported} from './Xexport.vim'
1217  END
1218  writefile(import_already_defined, 'Ximport.vim')
1219  assert_fails('source Ximport.vim', 'E1073:')
1220
1221  # import a very long name, requires making a copy
1222  let import_long_name_lines =<< trim END
1223    vim9script
1224    import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
1225  END
1226  writefile(import_long_name_lines, 'Ximport.vim')
1227  assert_fails('source Ximport.vim', 'E1048:')
1228
1229  let import_no_from_lines =<< trim END
1230    vim9script
1231    import name './Xexport.vim'
1232  END
1233  writefile(import_no_from_lines, 'Ximport.vim')
1234  assert_fails('source Ximport.vim', 'E1070:')
1235
1236  let import_invalid_string_lines =<< trim END
1237    vim9script
1238    import name from Xexport.vim
1239  END
1240  writefile(import_invalid_string_lines, 'Ximport.vim')
1241  assert_fails('source Ximport.vim', 'E1071:')
1242
1243  let import_wrong_name_lines =<< trim END
1244    vim9script
1245    import name from './XnoExport.vim'
1246  END
1247  writefile(import_wrong_name_lines, 'Ximport.vim')
1248  assert_fails('source Ximport.vim', 'E1053:')
1249
1250  let import_missing_comma_lines =<< trim END
1251    vim9script
1252    import {exported name} from './Xexport.vim'
1253  END
1254  writefile(import_missing_comma_lines, 'Ximport3.vim')
1255  assert_fails('source Ximport3.vim', 'E1046:')
1256
1257  delete('Ximport.vim')
1258  delete('Ximport3.vim')
1259  delete('Xexport.vim')
1260
1261  # Check that in a Vim9 script 'cpo' is set to the Vim default.
1262  set cpo&vi
1263  let cpo_before = &cpo
1264  let lines =<< trim END
1265    vim9script
1266    g:cpo_in_vim9script = &cpo
1267  END
1268  writefile(lines, 'Xvim9_script')
1269  source Xvim9_script
1270  assert_equal(cpo_before, &cpo)
1271  set cpo&vim
1272  assert_equal(&cpo, g:cpo_in_vim9script)
1273  delete('Xvim9_script')
1274enddef
1275
1276def Test_vim9script_fails()
1277  CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
1278  CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
1279  CheckScriptFailure(['export let some = 123'], 'E1042:')
1280  CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1048:')
1281  CheckScriptFailure(['vim9script', 'export let g:some'], 'E1022:')
1282  CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
1283
1284  CheckScriptFailure(['vim9script', 'let str: string', 'str = 1234'], 'E1013:')
1285  CheckScriptFailure(['vim9script', 'const str = "asdf"', 'str = "xxx"'], 'E46:')
1286
1287  assert_fails('vim9script', 'E1038')
1288  assert_fails('export something', 'E1043')
1289enddef
1290
1291func Test_import_fails_without_script()
1292  CheckRunVimInTerminal
1293
1294  " call indirectly to avoid compilation error for missing functions
1295  call Run_Test_import_fails_on_command_line()
1296endfunc
1297
1298def Run_Test_import_fails_on_command_line()
1299  let export =<< trim END
1300    vim9script
1301    export def Foo(): number
1302        return 0
1303    enddef
1304  END
1305  writefile(export, 'Xexport.vim')
1306
1307  let buf = RunVimInTerminal('-c "import Foo from ''./Xexport.vim''"', #{
1308                rows: 6, wait_for_ruler: 0})
1309  WaitForAssert({-> assert_match('^E1094:', term_getline(buf, 5))})
1310
1311  delete('Xexport.vim')
1312  StopVimInTerminal(buf)
1313enddef
1314
1315def Test_vim9script_reload_import()
1316  let lines =<< trim END
1317    vim9script
1318    const var = ''
1319    let valone = 1234
1320    def MyFunc(arg: string)
1321       valone = 5678
1322    enddef
1323  END
1324  let morelines =<< trim END
1325    let valtwo = 222
1326    export def GetValtwo(): number
1327      return valtwo
1328    enddef
1329  END
1330  writefile(lines + morelines, 'Xreload.vim')
1331  source Xreload.vim
1332  source Xreload.vim
1333  source Xreload.vim
1334
1335  let testlines =<< trim END
1336    vim9script
1337    def TheFunc()
1338      import GetValtwo from './Xreload.vim'
1339      assert_equal(222, GetValtwo())
1340    enddef
1341    TheFunc()
1342  END
1343  writefile(testlines, 'Ximport.vim')
1344  source Ximport.vim
1345
1346  # Test that when not using "morelines" GetValtwo() and valtwo are still
1347  # defined, because import doesn't reload a script.
1348  writefile(lines, 'Xreload.vim')
1349  source Ximport.vim
1350
1351  # cannot declare a var twice
1352  lines =<< trim END
1353    vim9script
1354    let valone = 1234
1355    let valone = 5678
1356  END
1357  writefile(lines, 'Xreload.vim')
1358  assert_fails('source Xreload.vim', 'E1041:')
1359
1360  delete('Xreload.vim')
1361  delete('Ximport.vim')
1362enddef
1363
1364" Not exported function that is referenced needs to be accessed by the
1365" script-local name.
1366def Test_vim9script_funcref()
1367  let sortlines =<< trim END
1368      vim9script
1369      def Compare(i1: number, i2: number): number
1370        return i2 - i1
1371      enddef
1372
1373      export def FastSort(): list<number>
1374        return range(5)->sort(Compare)
1375      enddef
1376  END
1377  writefile(sortlines, 'Xsort.vim')
1378
1379  let lines =<< trim END
1380    vim9script
1381    import FastSort from './Xsort.vim'
1382    def Test()
1383      g:result = FastSort()
1384    enddef
1385    Test()
1386  END
1387  writefile(lines, 'Xscript.vim')
1388
1389  source Xscript.vim
1390  assert_equal([4, 3, 2, 1, 0], g:result)
1391
1392  unlet g:result
1393  delete('Xsort.vim')
1394  delete('Xscript.vim')
1395enddef
1396
1397" Check that when searcing for "FilterFunc" it doesn't find the import in the
1398" script where FastFilter() is called from.
1399def Test_vim9script_funcref_other_script()
1400  let filterLines =<< trim END
1401    vim9script
1402    export def FilterFunc(idx: number, val: number): bool
1403      return idx % 2 == 1
1404    enddef
1405    export def FastFilter(): list<number>
1406      return range(10)->filter('FilterFunc')
1407    enddef
1408  END
1409  writefile(filterLines, 'Xfilter.vim')
1410
1411  let lines =<< trim END
1412    vim9script
1413    import {FilterFunc, FastFilter} from './Xfilter.vim'
1414    def Test()
1415      let x: list<number> = FastFilter()
1416    enddef
1417    Test()
1418  END
1419  writefile(lines, 'Ximport.vim')
1420  assert_fails('source Ximport.vim', 'E121:')
1421
1422  delete('Xfilter.vim')
1423  delete('Ximport.vim')
1424enddef
1425
1426def Test_vim9script_reload_delfunc()
1427  let first_lines =<< trim END
1428    vim9script
1429    def FuncYes(): string
1430      return 'yes'
1431    enddef
1432  END
1433  let withno_lines =<< trim END
1434    def FuncNo(): string
1435      return 'no'
1436    enddef
1437    def g:DoCheck(no_exists: bool)
1438      assert_equal('yes', FuncYes())
1439      assert_equal('no', FuncNo())
1440    enddef
1441  END
1442  let nono_lines =<< trim END
1443    def g:DoCheck(no_exists: bool)
1444      assert_equal('yes', FuncYes())
1445      assert_fails('call FuncNo()', 'E117:')
1446    enddef
1447  END
1448
1449  # FuncNo() is defined
1450  writefile(first_lines + withno_lines, 'Xreloaded.vim')
1451  source Xreloaded.vim
1452  g:DoCheck(true)
1453
1454  # FuncNo() is not redefined
1455  writefile(first_lines + nono_lines, 'Xreloaded.vim')
1456  source Xreloaded.vim
1457  g:DoCheck()
1458
1459  # FuncNo() is back
1460  writefile(first_lines + withno_lines, 'Xreloaded.vim')
1461  source Xreloaded.vim
1462  g:DoCheck()
1463
1464  delete('Xreloaded.vim')
1465enddef
1466
1467def Test_vim9script_reload_delvar()
1468  # write the script with a script-local variable
1469  let lines =<< trim END
1470    vim9script
1471    let var = 'string'
1472  END
1473  writefile(lines, 'XreloadVar.vim')
1474  source XreloadVar.vim
1475
1476  # now write the script using the same variable locally - works
1477  lines =<< trim END
1478    vim9script
1479    def Func()
1480      let var = 'string'
1481    enddef
1482  END
1483  writefile(lines, 'XreloadVar.vim')
1484  source XreloadVar.vim
1485
1486  delete('XreloadVar.vim')
1487enddef
1488
1489def Test_import_absolute()
1490  let import_lines = [
1491        'vim9script',
1492        'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
1493        'def UseExported()',
1494        '  g:imported_abs = exported',
1495        '  exported = 8888',
1496        '  g:imported_after = exported',
1497        'enddef',
1498        'UseExported()',
1499        'g:import_disassembled = execute("disass UseExported")',
1500        ]
1501  writefile(import_lines, 'Ximport_abs.vim')
1502  writefile(s:export_script_lines, 'Xexport_abs.vim')
1503
1504  source Ximport_abs.vim
1505
1506  assert_equal(9876, g:imported_abs)
1507  assert_equal(8888, g:imported_after)
1508  assert_match('<SNR>\d\+_UseExported.*' ..
1509          'g:imported_abs = exported.*' ..
1510          '0 LOADSCRIPT exported from .*Xexport_abs.vim.*' ..
1511          '1 STOREG g:imported_abs.*' ..
1512          'exported = 8888.*' ..
1513          '3 STORESCRIPT exported in .*Xexport_abs.vim.*' ..
1514          'g:imported_after = exported.*' ..
1515          '4 LOADSCRIPT exported from .*Xexport_abs.vim.*' ..
1516          '5 STOREG g:imported_after.*',
1517        g:import_disassembled)
1518  unlet g:imported_abs
1519  unlet g:import_disassembled
1520
1521  delete('Ximport_abs.vim')
1522  delete('Xexport_abs.vim')
1523enddef
1524
1525def Test_import_rtp()
1526  let import_lines = [
1527        'vim9script',
1528        'import exported from "Xexport_rtp.vim"',
1529        'g:imported_rtp = exported',
1530        ]
1531  writefile(import_lines, 'Ximport_rtp.vim')
1532  mkdir('import')
1533  writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
1534
1535  let save_rtp = &rtp
1536  &rtp = getcwd()
1537  source Ximport_rtp.vim
1538  &rtp = save_rtp
1539
1540  assert_equal(9876, g:imported_rtp)
1541  unlet g:imported_rtp
1542
1543  delete('Ximport_rtp.vim')
1544  delete('import', 'rf')
1545enddef
1546
1547def Test_import_compile_error()
1548  let export_lines = [
1549        'vim9script',
1550        'export def ExpFunc(): string',
1551        '  return notDefined',
1552        'enddef',
1553        ]
1554  writefile(export_lines, 'Xexported.vim')
1555
1556  let import_lines = [
1557        'vim9script',
1558        'import ExpFunc from "./Xexported.vim"',
1559        'def ImpFunc()',
1560        '  echo ExpFunc()',
1561        'enddef',
1562        'defcompile',
1563        ]
1564  writefile(import_lines, 'Ximport.vim')
1565
1566  try
1567    source Ximport.vim
1568  catch /E1001/
1569    # Error should be fore the Xexported.vim file.
1570    assert_match('E1001: variable not found: notDefined', v:exception)
1571    assert_match('function <SNR>\d\+_ImpFunc\[1\]..<SNR>\d\+_ExpFunc, line 1', v:throwpoint)
1572  endtry
1573
1574  delete('Xexported.vim')
1575  delete('Ximport.vim')
1576enddef
1577
1578def Test_fixed_size_list()
1579  # will be allocated as one piece of memory, check that changes work
1580  let l = [1, 2, 3, 4]
1581  l->remove(0)
1582  l->add(5)
1583  l->insert(99, 1)
1584  assert_equal([2, 99, 3, 4, 5], l)
1585enddef
1586
1587def Test_no_insert_xit()
1588  call CheckDefExecFailure(['x = 1'], 'E1100:')
1589  call CheckDefExecFailure(['a = 1'], 'E1100:')
1590  call CheckDefExecFailure(['i = 1'], 'E1100:')
1591  call CheckDefExecFailure(['c = 1'], 'E1100:')
1592
1593  CheckScriptFailure(['vim9script', 'x = 1'], 'E1100:')
1594  CheckScriptFailure(['vim9script', 'a = 1'], 'E488:')
1595  CheckScriptFailure(['vim9script', 'a'], 'E1100:')
1596  CheckScriptFailure(['vim9script', 'i = 1'], 'E488:')
1597  CheckScriptFailure(['vim9script', 'i'], 'E1100:')
1598  CheckScriptFailure(['vim9script', 'c = 1'], 'E488:')
1599  CheckScriptFailure(['vim9script', 'c'], 'E1100:')
1600enddef
1601
1602def IfElse(what: number): string
1603  let res = ''
1604  if what == 1
1605    res = "one"
1606  elseif what == 2
1607    res = "two"
1608  else
1609    res = "three"
1610  endif
1611  return res
1612enddef
1613
1614def Test_if_elseif_else()
1615  assert_equal('one', IfElse(1))
1616  assert_equal('two', IfElse(2))
1617  assert_equal('three', IfElse(3))
1618enddef
1619
1620def Test_if_elseif_else_fails()
1621  call CheckDefFailure(['elseif true'], 'E582:')
1622  call CheckDefFailure(['else'], 'E581:')
1623  call CheckDefFailure(['endif'], 'E580:')
1624  call CheckDefFailure(['if true', 'elseif xxx'], 'E1001:')
1625  call CheckDefFailure(['if true', 'echo 1'], 'E171:')
1626enddef
1627
1628let g:bool_true = v:true
1629let g:bool_false = v:false
1630
1631def Test_if_const_expr()
1632  let res = false
1633  if true ? true : false
1634    res = true
1635  endif
1636  assert_equal(true, res)
1637
1638  g:glob = 2
1639  if false
1640    execute('g:glob = 3')
1641  endif
1642  assert_equal(2, g:glob)
1643  if true
1644    execute('g:glob = 3')
1645  endif
1646  assert_equal(3, g:glob)
1647
1648  res = false
1649  if g:bool_true ? true : false
1650    res = true
1651  endif
1652  assert_equal(true, res)
1653
1654  res = false
1655  if true ? g:bool_true : false
1656    res = true
1657  endif
1658  assert_equal(true, res)
1659
1660  res = false
1661  if true ? true : g:bool_false
1662    res = true
1663  endif
1664  assert_equal(true, res)
1665
1666  res = false
1667  if true ? false : true
1668    res = true
1669  endif
1670  assert_equal(false, res)
1671
1672  res = false
1673  if false ? false : true
1674    res = true
1675  endif
1676  assert_equal(true, res)
1677
1678  res = false
1679  if false ? true : false
1680    res = true
1681  endif
1682  assert_equal(false, res)
1683
1684  res = false
1685  if has('xyz') ? true : false
1686    res = true
1687  endif
1688  assert_equal(false, res)
1689
1690  res = false
1691  if true && true
1692    res = true
1693  endif
1694  assert_equal(true, res)
1695
1696  res = false
1697  if true && false
1698    res = true
1699  endif
1700  assert_equal(false, res)
1701
1702  res = false
1703  if g:bool_true && false
1704    res = true
1705  endif
1706  assert_equal(false, res)
1707
1708  res = false
1709  if true && g:bool_false
1710    res = true
1711  endif
1712  assert_equal(false, res)
1713
1714  res = false
1715  if false && false
1716    res = true
1717  endif
1718  assert_equal(false, res)
1719
1720  res = false
1721  if true || false
1722    res = true
1723  endif
1724  assert_equal(true, res)
1725
1726  res = false
1727  if g:bool_true || false
1728    res = true
1729  endif
1730  assert_equal(true, res)
1731
1732  res = false
1733  if true || g:bool_false
1734    res = true
1735  endif
1736  assert_equal(true, res)
1737
1738  res = false
1739  if false || false
1740    res = true
1741  endif
1742  assert_equal(false, res)
1743enddef
1744
1745def Test_if_const_expr_fails()
1746  call CheckDefFailure(['if "aaa" == "bbb'], 'E114:')
1747  call CheckDefFailure(["if 'aaa' == 'bbb"], 'E115:')
1748  call CheckDefFailure(["if has('aaa'"], 'E110:')
1749  call CheckDefFailure(["if has('aaa') ? true false"], 'E109:')
1750enddef
1751
1752def RunNested(i: number): number
1753  let x: number = 0
1754  if i % 2
1755    if 1
1756      # comment
1757    else
1758      # comment
1759    endif
1760    x += 1
1761  else
1762    x += 1000
1763  endif
1764  return x
1765enddef
1766
1767def Test_nested_if()
1768  assert_equal(1, RunNested(1))
1769  assert_equal(1000, RunNested(2))
1770enddef
1771
1772def Test_execute_cmd()
1773  new
1774  setline(1, 'default')
1775  execute 'call setline(1, "execute-string")'
1776  assert_equal('execute-string', getline(1))
1777
1778  execute "call setline(1, 'execute-string')"
1779  assert_equal('execute-string', getline(1))
1780
1781  let cmd1 = 'call setline(1,'
1782  let cmd2 = '"execute-var")'
1783  execute cmd1 cmd2 # comment
1784  assert_equal('execute-var', getline(1))
1785
1786  execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
1787  assert_equal('execute-var-string', getline(1))
1788
1789  let cmd_first = 'call '
1790  let cmd_last = 'setline(1, "execute-var-var")'
1791  execute cmd_first .. cmd_last
1792  assert_equal('execute-var-var', getline(1))
1793  bwipe!
1794
1795  let n = true
1796  execute 'echomsg' (n ? '"true"' : '"no"')
1797  assert_match('^true$', Screenline(&lines))
1798
1799  call CheckDefFailure(['execute xxx'], 'E1001:')
1800  call CheckDefFailure(['execute "cmd"# comment'], 'E488:')
1801enddef
1802
1803def Test_execute_cmd_vimscript()
1804  # only checks line continuation
1805  let lines =<< trim END
1806      vim9script
1807      execute 'g:someVar'
1808                .. ' = ' ..
1809                   '28'
1810      assert_equal(28, g:someVar)
1811      unlet g:someVar
1812  END
1813  CheckScriptSuccess(lines)
1814enddef
1815
1816def Test_echo_cmd()
1817  echo 'some' # comment
1818  echon 'thing'
1819  assert_match('^something$', Screenline(&lines))
1820
1821  echo "some" # comment
1822  echon "thing"
1823  assert_match('^something$', Screenline(&lines))
1824
1825  let str1 = 'some'
1826  let str2 = 'more'
1827  echo str1 str2
1828  assert_match('^some more$', Screenline(&lines))
1829
1830  call CheckDefFailure(['echo "xxx"# comment'], 'E488:')
1831enddef
1832
1833def Test_echomsg_cmd()
1834  echomsg 'some' 'more' # comment
1835  assert_match('^some more$', Screenline(&lines))
1836  echo 'clear'
1837  :1messages
1838  assert_match('^some more$', Screenline(&lines))
1839
1840  call CheckDefFailure(['echomsg "xxx"# comment'], 'E488:')
1841enddef
1842
1843def Test_echomsg_cmd_vimscript()
1844  # only checks line continuation
1845  let lines =<< trim END
1846      vim9script
1847      echomsg 'here'
1848                .. ' is ' ..
1849                   'a message'
1850      assert_match('^here is a message$', Screenline(&lines))
1851  END
1852  CheckScriptSuccess(lines)
1853enddef
1854
1855def Test_echoerr_cmd()
1856  try
1857    echoerr 'something' 'wrong' # comment
1858  catch
1859    assert_match('something wrong', v:exception)
1860  endtry
1861enddef
1862
1863def Test_echoerr_cmd_vimscript()
1864  # only checks line continuation
1865  let lines =<< trim END
1866      vim9script
1867      try
1868        echoerr 'this'
1869                .. ' is ' ..
1870                   'wrong'
1871      catch
1872        assert_match('this is wrong', v:exception)
1873      endtry
1874  END
1875  CheckScriptSuccess(lines)
1876enddef
1877
1878def Test_for_outside_of_function()
1879  let lines =<< trim END
1880    vim9script
1881    new
1882    for var in range(0, 3)
1883      append(line('$'), var)
1884    endfor
1885    assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
1886    bwipe!
1887  END
1888  writefile(lines, 'Xvim9for.vim')
1889  source Xvim9for.vim
1890  delete('Xvim9for.vim')
1891enddef
1892
1893def Test_for_loop()
1894  let result = ''
1895  for cnt in range(7)
1896    if cnt == 4
1897      break
1898    endif
1899    if cnt == 2
1900      continue
1901    endif
1902    result ..= cnt .. '_'
1903  endfor
1904  assert_equal('0_1_3_', result)
1905
1906  let concat = ''
1907  for str in eval('["one", "two"]')
1908    concat ..= str
1909  endfor
1910  assert_equal('onetwo', concat)
1911enddef
1912
1913def Test_for_loop_fails()
1914  CheckDefFailure(['for # in range(5)'], 'E690:')
1915  CheckDefFailure(['for i In range(5)'], 'E690:')
1916  CheckDefFailure(['let x = 5', 'for x in range(5)'], 'E1023:')
1917  CheckScriptFailure(['def Func(arg: any)', 'for arg in range(5)', 'enddef', 'defcompile'], 'E1006:')
1918  CheckDefFailure(['for i in "text"'], 'E1013:')
1919  CheckDefFailure(['for i in xxx'], 'E1001:')
1920  CheckDefFailure(['endfor'], 'E588:')
1921  CheckDefFailure(['for i in range(3)', 'echo 3'], 'E170:')
1922enddef
1923
1924def Test_while_loop()
1925  let result = ''
1926  let cnt = 0
1927  while cnt < 555
1928    if cnt == 3
1929      break
1930    endif
1931    cnt += 1
1932    if cnt == 2
1933      continue
1934    endif
1935    result ..= cnt .. '_'
1936  endwhile
1937  assert_equal('1_3_', result)
1938enddef
1939
1940def Test_while_loop_fails()
1941  CheckDefFailure(['while xxx'], 'E1001:')
1942  CheckDefFailure(['endwhile'], 'E588:')
1943  CheckDefFailure(['continue'], 'E586:')
1944  CheckDefFailure(['if true', 'continue'], 'E586:')
1945  CheckDefFailure(['break'], 'E587:')
1946  CheckDefFailure(['if true', 'break'], 'E587:')
1947  CheckDefFailure(['while 1', 'echo 3'], 'E170:')
1948enddef
1949
1950def Test_interrupt_loop()
1951  let caught = false
1952  let x = 0
1953  try
1954    while 1
1955      x += 1
1956      if x == 100
1957        feedkeys("\<C-C>", 'Lt')
1958      endif
1959    endwhile
1960  catch
1961    caught = true
1962    assert_equal(100, x)
1963  endtry
1964  assert_true(caught, 'should have caught an exception')
1965enddef
1966
1967def Test_automatic_line_continuation()
1968  let mylist = [
1969      'one',
1970      'two',
1971      'three',
1972      ] # comment
1973  assert_equal(['one', 'two', 'three'], mylist)
1974
1975  let mydict = {
1976      'one': 1,
1977      'two': 2,
1978      'three':
1979          3,
1980      } # comment
1981  assert_equal({'one': 1, 'two': 2, 'three': 3}, mydict)
1982  mydict = #{
1983      one: 1,  # comment
1984      two:     # comment
1985           2,  # comment
1986      three: 3 # comment
1987      }
1988  assert_equal(#{one: 1, two: 2, three: 3}, mydict)
1989  mydict = #{
1990      one: 1,
1991      two:
1992           2,
1993      three: 3
1994      }
1995  assert_equal(#{one: 1, two: 2, three: 3}, mydict)
1996
1997  assert_equal(
1998        ['one', 'two', 'three'],
1999        split('one two three')
2000        )
2001enddef
2002
2003def Test_vim9_comment()
2004  CheckScriptSuccess([
2005      'vim9script',
2006      '# something',
2007      ])
2008  CheckScriptFailure([
2009      'vim9script',
2010      ':# something',
2011      ], 'E488:')
2012  CheckScriptFailure([
2013      '# something',
2014      ], 'E488:')
2015  CheckScriptFailure([
2016      ':# something',
2017      ], 'E488:')
2018
2019  { # block start
2020  } # block end
2021  CheckDefFailure([
2022      '{# comment',
2023      ], 'E488:')
2024  CheckDefFailure([
2025      '{',
2026      '}# comment',
2027      ], 'E488:')
2028
2029  echo "yes" # comment
2030  CheckDefFailure([
2031      'echo "yes"# comment',
2032      ], 'E488:')
2033  CheckScriptSuccess([
2034      'vim9script',
2035      'echo "yes" # something',
2036      ])
2037  CheckScriptFailure([
2038      'vim9script',
2039      'echo "yes"# something',
2040      ], 'E121:')
2041  CheckScriptFailure([
2042      'vim9script',
2043      'echo# something',
2044      ], 'E121:')
2045  CheckScriptFailure([
2046      'echo "yes" # something',
2047      ], 'E121:')
2048
2049  exe "echo" # comment
2050  CheckDefFailure([
2051      'exe "echo"# comment',
2052      ], 'E488:')
2053  CheckScriptSuccess([
2054      'vim9script',
2055      'exe "echo" # something',
2056      ])
2057  CheckScriptFailure([
2058      'vim9script',
2059      'exe "echo"# something',
2060      ], 'E121:')
2061  CheckDefFailure([
2062      'exe # comment',
2063      ], 'E1015:')
2064  CheckScriptFailure([
2065      'vim9script',
2066      'exe# something',
2067      ], 'E121:')
2068  CheckScriptFailure([
2069      'exe "echo" # something',
2070      ], 'E121:')
2071
2072  CheckDefFailure([
2073      'try# comment',
2074      '  echo "yes"',
2075      'catch',
2076      'endtry',
2077      ], 'E488:')
2078  CheckScriptFailure([
2079      'vim9script',
2080      'try# comment',
2081      'echo "yes"',
2082      ], 'E488:')
2083  CheckDefFailure([
2084      'try',
2085      '  throw#comment',
2086      'catch',
2087      'endtry',
2088      ], 'E1015:')
2089  CheckDefFailure([
2090      'try',
2091      '  throw "yes"#comment',
2092      'catch',
2093      'endtry',
2094      ], 'E488:')
2095  CheckDefFailure([
2096      'try',
2097      '  echo "yes"',
2098      'catch# comment',
2099      'endtry',
2100      ], 'E488:')
2101  CheckScriptFailure([
2102      'vim9script',
2103      'try',
2104      '  echo "yes"',
2105      'catch# comment',
2106      'endtry',
2107      ], 'E654:')
2108  CheckDefFailure([
2109      'try',
2110      '  echo "yes"',
2111      'catch /pat/# comment',
2112      'endtry',
2113      ], 'E488:')
2114  CheckDefFailure([
2115      'try',
2116      'echo "yes"',
2117      'catch',
2118      'endtry# comment',
2119      ], 'E488:')
2120  CheckScriptFailure([
2121      'vim9script',
2122      'try',
2123      '  echo "yes"',
2124      'catch',
2125      'endtry# comment',
2126      ], 'E488:')
2127
2128  CheckScriptSuccess([
2129      'vim9script',
2130      'hi # comment',
2131      ])
2132  CheckScriptFailure([
2133      'vim9script',
2134      'hi# comment',
2135      ], 'E416:')
2136  CheckScriptSuccess([
2137      'vim9script',
2138      'hi Search # comment',
2139      ])
2140  CheckScriptFailure([
2141      'vim9script',
2142      'hi Search# comment',
2143      ], 'E416:')
2144  CheckScriptSuccess([
2145      'vim9script',
2146      'hi link This Search # comment',
2147      ])
2148  CheckScriptFailure([
2149      'vim9script',
2150      'hi link This That# comment',
2151      ], 'E413:')
2152  CheckScriptSuccess([
2153      'vim9script',
2154      'hi clear This # comment',
2155      'hi clear # comment',
2156      ])
2157  # not tested, because it doesn't give an error but a warning:
2158  # hi clear This# comment',
2159  CheckScriptFailure([
2160      'vim9script',
2161      'hi clear# comment',
2162      ], 'E416:')
2163
2164  CheckScriptSuccess([
2165      'vim9script',
2166      'hi Group term=bold',
2167      'match Group /todo/ # comment',
2168      ])
2169  CheckScriptFailure([
2170      'vim9script',
2171      'hi Group term=bold',
2172      'match Group /todo/# comment',
2173      ], 'E488:')
2174  CheckScriptSuccess([
2175      'vim9script',
2176      'match # comment',
2177      ])
2178  CheckScriptFailure([
2179      'vim9script',
2180      'match# comment',
2181      ], 'E475:')
2182  CheckScriptSuccess([
2183      'vim9script',
2184      'match none # comment',
2185      ])
2186  CheckScriptFailure([
2187      'vim9script',
2188      'match none# comment',
2189      ], 'E475:')
2190
2191  CheckScriptSuccess([
2192      'vim9script',
2193      'menutrans clear # comment',
2194      ])
2195  CheckScriptFailure([
2196      'vim9script',
2197      'menutrans clear# comment text',
2198      ], 'E474:')
2199
2200  CheckScriptSuccess([
2201      'vim9script',
2202      'syntax clear # comment',
2203      ])
2204  CheckScriptFailure([
2205      'vim9script',
2206      'syntax clear# comment text',
2207      ], 'E28:')
2208  CheckScriptSuccess([
2209      'vim9script',
2210      'syntax keyword Word some',
2211      'syntax clear Word # comment',
2212      ])
2213  CheckScriptFailure([
2214      'vim9script',
2215      'syntax keyword Word some',
2216      'syntax clear Word# comment text',
2217      ], 'E28:')
2218
2219  CheckScriptSuccess([
2220      'vim9script',
2221      'syntax list # comment',
2222      ])
2223  CheckScriptFailure([
2224      'vim9script',
2225      'syntax list# comment text',
2226      ], 'E28:')
2227
2228  CheckScriptSuccess([
2229      'vim9script',
2230      'syntax match Word /pat/ oneline # comment',
2231      ])
2232  CheckScriptFailure([
2233      'vim9script',
2234      'syntax match Word /pat/ oneline# comment',
2235      ], 'E475:')
2236
2237  CheckScriptSuccess([
2238      'vim9script',
2239      'syntax keyword Word word # comm[ent',
2240      ])
2241  CheckScriptFailure([
2242      'vim9script',
2243      'syntax keyword Word word# comm[ent',
2244      ], 'E789:')
2245
2246  CheckScriptSuccess([
2247      'vim9script',
2248      'syntax match Word /pat/ # comment',
2249      ])
2250  CheckScriptFailure([
2251      'vim9script',
2252      'syntax match Word /pat/# comment',
2253      ], 'E402:')
2254
2255  CheckScriptSuccess([
2256      'vim9script',
2257      'syntax match Word /pat/ contains=Something # comment',
2258      ])
2259  CheckScriptFailure([
2260      'vim9script',
2261      'syntax match Word /pat/ contains=Something# comment',
2262      ], 'E475:')
2263  CheckScriptFailure([
2264      'vim9script',
2265      'syntax match Word /pat/ contains= # comment',
2266      ], 'E406:')
2267  CheckScriptFailure([
2268      'vim9script',
2269      'syntax match Word /pat/ contains=# comment',
2270      ], 'E475:')
2271
2272  CheckScriptSuccess([
2273      'vim9script',
2274      'syntax region Word start=/pat/ end=/pat/ # comment',
2275      ])
2276  CheckScriptFailure([
2277      'vim9script',
2278      'syntax region Word start=/pat/ end=/pat/# comment',
2279      ], 'E402:')
2280
2281  CheckScriptSuccess([
2282      'vim9script',
2283      'syntax sync # comment',
2284      ])
2285  CheckScriptFailure([
2286      'vim9script',
2287      'syntax sync# comment',
2288      ], 'E404:')
2289  CheckScriptSuccess([
2290      'vim9script',
2291      'syntax sync ccomment # comment',
2292      ])
2293  CheckScriptFailure([
2294      'vim9script',
2295      'syntax sync ccomment# comment',
2296      ], 'E404:')
2297
2298  CheckScriptSuccess([
2299      'vim9script',
2300      'syntax cluster Some contains=Word # comment',
2301      ])
2302  CheckScriptFailure([
2303      'vim9script',
2304      'syntax cluster Some contains=Word# comment',
2305      ], 'E475:')
2306
2307  CheckScriptSuccess([
2308      'vim9script',
2309      'command Echo echo # comment',
2310      'command Echo # comment',
2311      ])
2312  CheckScriptFailure([
2313      'vim9script',
2314      'command Echo echo# comment',
2315      'Echo',
2316      ], 'E121:')
2317  CheckScriptFailure([
2318      'vim9script',
2319      'command Echo# comment',
2320      ], 'E182:')
2321  CheckScriptFailure([
2322      'vim9script',
2323      'command Echo echo',
2324      'command Echo# comment',
2325      ], 'E182:')
2326
2327  CheckScriptSuccess([
2328      'vim9script',
2329      'function # comment',
2330      ])
2331  CheckScriptFailure([
2332      'vim9script',
2333      'function " comment',
2334      ], 'E129:')
2335  CheckScriptFailure([
2336      'vim9script',
2337      'function# comment',
2338      ], 'E129:')
2339  CheckScriptSuccess([
2340      'vim9script',
2341      'function CheckScriptSuccess # comment',
2342      ])
2343  CheckScriptFailure([
2344      'vim9script',
2345      'function CheckScriptSuccess# comment',
2346      ], 'E488:')
2347
2348  CheckScriptSuccess([
2349      'vim9script',
2350      'func g:DeleteMeA()',
2351      'endfunc',
2352      'delfunction g:DeleteMeA # comment',
2353      ])
2354  CheckScriptFailure([
2355      'vim9script',
2356      'func g:DeleteMeB()',
2357      'endfunc',
2358      'delfunction g:DeleteMeB# comment',
2359      ], 'E488:')
2360
2361  CheckScriptSuccess([
2362      'vim9script',
2363      'call execute("ls") # comment',
2364      ])
2365  CheckScriptFailure([
2366      'vim9script',
2367      'call execute("ls")# comment',
2368      ], 'E488:')
2369
2370  CheckScriptFailure([
2371      'def Test() " comment',
2372      'enddef',
2373      ], 'E488:')
2374  CheckScriptFailure([
2375      'vim9script',
2376      'def Test() " comment',
2377      'enddef',
2378      ], 'E488:')
2379
2380  CheckScriptSuccess([
2381      'func Test() " comment',
2382      'endfunc',
2383      ])
2384  CheckScriptSuccess([
2385      'vim9script',
2386      'func Test() " comment',
2387      'endfunc',
2388      ])
2389
2390  CheckScriptSuccess([
2391      'def Test() # comment',
2392      'enddef',
2393      ])
2394  CheckScriptFailure([
2395      'func Test() # comment',
2396      'endfunc',
2397      ], 'E488:')
2398enddef
2399
2400def Test_vim9_comment_gui()
2401  CheckCanRunGui
2402
2403  CheckScriptFailure([
2404      'vim9script',
2405      'gui#comment'
2406      ], 'E499:')
2407  CheckScriptFailure([
2408      'vim9script',
2409      'gui -f#comment'
2410      ], 'E499:')
2411enddef
2412
2413def Test_vim9_comment_not_compiled()
2414  au TabEnter *.vim g:entered = 1
2415  au TabEnter *.x g:entered = 2
2416
2417  edit test.vim
2418  doautocmd TabEnter #comment
2419  assert_equal(1, g:entered)
2420
2421  doautocmd TabEnter f.x
2422  assert_equal(2, g:entered)
2423
2424  g:entered = 0
2425  doautocmd TabEnter f.x #comment
2426  assert_equal(2, g:entered)
2427
2428  assert_fails('doautocmd Syntax#comment', 'E216:')
2429
2430  au! TabEnter
2431  unlet g:entered
2432
2433  CheckScriptSuccess([
2434      'vim9script',
2435      'g:var = 123',
2436      'b:var = 456',
2437      'w:var = 777',
2438      't:var = 888',
2439      'unlet g:var w:var # something',
2440      ])
2441
2442  CheckScriptFailure([
2443      'vim9script',
2444      'let g:var = 123',
2445      ], 'E1016: Cannot declare a global variable:')
2446
2447  CheckScriptFailure([
2448      'vim9script',
2449      'let b:var = 123',
2450      ], 'E1016: Cannot declare a buffer variable:')
2451
2452  CheckScriptFailure([
2453      'vim9script',
2454      'let w:var = 123',
2455      ], 'E1016: Cannot declare a window variable:')
2456
2457  CheckScriptFailure([
2458      'vim9script',
2459      'let t:var = 123',
2460      ], 'E1016: Cannot declare a tab variable:')
2461
2462  CheckScriptFailure([
2463      'vim9script',
2464      'let v:version = 123',
2465      ], 'E1016: Cannot declare a v: variable:')
2466
2467  CheckScriptFailure([
2468      'vim9script',
2469      'let $VARIABLE = "text"',
2470      ], 'E1016: Cannot declare an environment variable:')
2471
2472  CheckScriptFailure([
2473      'vim9script',
2474      'g:var = 123',
2475      'unlet g:var# comment1',
2476      ], 'E108:')
2477
2478  CheckScriptFailure([
2479      'let g:var = 123',
2480      'unlet g:var # something',
2481      ], 'E488:')
2482
2483  CheckScriptSuccess([
2484      'vim9script',
2485      'if 1 # comment2',
2486      '  echo "yes"',
2487      'elseif 2 #comment',
2488      '  echo "no"',
2489      'endif',
2490      ])
2491
2492  CheckScriptFailure([
2493      'vim9script',
2494      'if 1# comment3',
2495      '  echo "yes"',
2496      'endif',
2497      ], 'E15:')
2498
2499  CheckScriptFailure([
2500      'vim9script',
2501      'if 0 # comment4',
2502      '  echo "yes"',
2503      'elseif 2#comment',
2504      '  echo "no"',
2505      'endif',
2506      ], 'E15:')
2507
2508  CheckScriptSuccess([
2509      'vim9script',
2510      'let v = 1 # comment5',
2511      ])
2512
2513  CheckScriptFailure([
2514      'vim9script',
2515      'let v = 1# comment6',
2516      ], 'E15:')
2517
2518  CheckScriptSuccess([
2519      'vim9script',
2520      'new'
2521      'call setline(1, ["# define pat", "last"])',
2522      ':$',
2523      'dsearch /pat/ #comment',
2524      'bwipe!',
2525      ])
2526
2527  CheckScriptFailure([
2528      'vim9script',
2529      'new'
2530      'call setline(1, ["# define pat", "last"])',
2531      ':$',
2532      'dsearch /pat/#comment',
2533      'bwipe!',
2534      ], 'E488:')
2535
2536  CheckScriptFailure([
2537      'vim9script',
2538      'func! SomeFunc()',
2539      ], 'E477:')
2540enddef
2541
2542def Test_finish()
2543  let lines =<< trim END
2544    vim9script
2545    g:res = 'one'
2546    if v:false | finish | endif
2547    g:res = 'two'
2548    finish
2549    g:res = 'three'
2550  END
2551  writefile(lines, 'Xfinished')
2552  source Xfinished
2553  assert_equal('two', g:res)
2554
2555  unlet g:res
2556  delete('Xfinished')
2557enddef
2558
2559def Test_let_func_call()
2560  let lines =<< trim END
2561    vim9script
2562    func GetValue()
2563      if exists('g:count')
2564        let g:count += 1
2565      else
2566        let g:count = 1
2567      endif
2568      return 'this'
2569    endfunc
2570    let val: string = GetValue()
2571    # env var is always a string
2572    let env = $TERM
2573  END
2574  writefile(lines, 'Xfinished')
2575  source Xfinished
2576  # GetValue() is not called during discovery phase
2577  assert_equal(1, g:count)
2578
2579  unlet g:count
2580  delete('Xfinished')
2581enddef
2582
2583def Test_let_missing_type()
2584  let lines =<< trim END
2585    vim9script
2586    let var = g:unknown
2587  END
2588  CheckScriptFailure(lines, 'E121:')
2589
2590  lines =<< trim END
2591    vim9script
2592    let nr: number = 123
2593    let var = nr
2594  END
2595  CheckScriptSuccess(lines)
2596enddef
2597
2598def Test_let_declaration()
2599  let lines =<< trim END
2600    vim9script
2601    let var: string
2602    g:var_uninit = var
2603    var = 'text'
2604    g:var_test = var
2605    # prefixing s: is optional
2606    s:var = 'prefixed'
2607    g:var_prefixed = s:var
2608
2609    let s:other: number
2610    other = 1234
2611    g:other_var = other
2612  END
2613  CheckScriptSuccess(lines)
2614  assert_equal('', g:var_uninit)
2615  assert_equal('text', g:var_test)
2616  assert_equal('prefixed', g:var_prefixed)
2617  assert_equal(1234, g:other_var)
2618
2619  unlet g:var_uninit
2620  unlet g:var_test
2621  unlet g:var_prefixed
2622  unlet g:other_var
2623enddef
2624
2625def Test_let_declaration_fails()
2626  let lines =<< trim END
2627    vim9script
2628    const var: string
2629  END
2630  CheckScriptFailure(lines, 'E1021:')
2631
2632  lines =<< trim END
2633    vim9script
2634    let 9var: string
2635  END
2636  CheckScriptFailure(lines, 'E475:')
2637enddef
2638
2639def Test_let_type_check()
2640  let lines =<< trim END
2641    vim9script
2642    let var: string
2643    var = 1234
2644  END
2645  CheckScriptFailure(lines, 'E1013:')
2646
2647  lines =<< trim END
2648    vim9script
2649    let var:string
2650  END
2651  CheckScriptFailure(lines, 'E1069:')
2652
2653  lines =<< trim END
2654    vim9script
2655    let var: asdf
2656  END
2657  CheckScriptFailure(lines, 'E1010:')
2658enddef
2659
2660def Test_forward_declaration()
2661  let lines =<< trim END
2662    vim9script
2663    def GetValue(): string
2664      return theVal
2665    enddef
2666    let theVal = 'something'
2667    g:initVal = GetValue()
2668    theVal = 'else'
2669    g:laterVal = GetValue()
2670  END
2671  writefile(lines, 'Xforward')
2672  source Xforward
2673  assert_equal('something', g:initVal)
2674  assert_equal('else', g:laterVal)
2675
2676  unlet g:initVal
2677  unlet g:laterVal
2678  delete('Xforward')
2679enddef
2680
2681def Test_source_vim9_from_legacy()
2682  let legacy_lines =<< trim END
2683    source Xvim9_script.vim
2684
2685    call assert_false(exists('local'))
2686    call assert_false(exists('exported'))
2687    call assert_false(exists('s:exported'))
2688    call assert_equal('global', global)
2689    call assert_equal('global', g:global)
2690
2691    " imported variable becomes script-local
2692    import exported from './Xvim9_script.vim'
2693    call assert_equal('exported', s:exported)
2694    call assert_false(exists('exported'))
2695
2696    " imported function becomes script-local
2697    import GetText from './Xvim9_script.vim'
2698    call assert_equal('text', s:GetText())
2699    call assert_false(exists('*GetText'))
2700  END
2701  writefile(legacy_lines, 'Xlegacy_script.vim')
2702
2703  let vim9_lines =<< trim END
2704    vim9script
2705    let local = 'local'
2706    g:global = 'global'
2707    export let exported = 'exported'
2708    export def GetText(): string
2709       return 'text'
2710    enddef
2711  END
2712  writefile(vim9_lines, 'Xvim9_script.vim')
2713
2714  source Xlegacy_script.vim
2715
2716  assert_equal('global', g:global)
2717  unlet g:global
2718
2719  delete('Xlegacy_script.vim')
2720  delete('Xvim9_script.vim')
2721enddef
2722
2723def Test_vim9_copen()
2724  # this was giving an error for setting w:quickfix_title
2725  copen
2726  quit
2727enddef
2728
2729" test using a vim9script that is auto-loaded from an autocmd
2730def Test_vim9_autoload()
2731  let lines =<< trim END
2732     vim9script
2733     def foo#test()
2734         echomsg getreg('"')
2735     enddef
2736  END
2737
2738  mkdir('Xdir/autoload', 'p')
2739  writefile(lines, 'Xdir/autoload/foo.vim')
2740  let save_rtp = &rtp
2741  exe 'set rtp^=' .. getcwd() .. '/Xdir'
2742  augroup test
2743    autocmd TextYankPost * call foo#test()
2744  augroup END
2745
2746  normal Y
2747
2748  augroup test
2749    autocmd!
2750  augroup END
2751  delete('Xdir', 'rf')
2752  &rtp = save_rtp
2753enddef
2754
2755" Keep this last, it messes up highlighting.
2756def Test_substitute_cmd()
2757  new
2758  setline(1, 'something')
2759  :substitute(some(other(
2760  assert_equal('otherthing', getline(1))
2761  bwipe!
2762
2763  # also when the context is Vim9 script
2764  let lines =<< trim END
2765    vim9script
2766    new
2767    setline(1, 'something')
2768    :substitute(some(other(
2769    assert_equal('otherthing', getline(1))
2770    bwipe!
2771  END
2772  writefile(lines, 'Xvim9lines')
2773  source Xvim9lines
2774
2775  delete('Xvim9lines')
2776enddef
2777
2778" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
2779