1" Test various aspects of the Vim9 script language.
2
3source check.vim
4source view_util.vim
5source vim9.vim
6
7def Test_syntax()
8  let var = 234
9  let other: list<string> = ['asdf']
10enddef
11
12let s:appendToMe = 'xxx'
13let s:addToMe = 111
14let g:existing = 'yes'
15let g:inc_counter = 1
16let $SOME_ENV_VAR = 'some'
17let g:alist = [7]
18let g:astring = 'text'
19
20def Test_assignment()
21  let bool1: bool = true
22  assert_equal(v:true, bool1)
23  let bool2: bool = false
24  assert_equal(v:false, bool2)
25
26  let list1: list<bool> = [false, true, false]
27  let list2: list<number> = [1, 2, 3]
28  let list3: list<string> = ['sdf', 'asdf']
29  let list4: list<any> = ['yes', true, 1234]
30  let list5: list<blob> = [0z01, 0z02]
31
32  let listS: list<string> = []
33  let listN: list<number> = []
34
35  let dict1: dict<bool> = #{one: false, two: true}
36  let dict2: dict<number> = #{one: 1, two: 2}
37  let dict3: dict<string> = #{key: 'value'}
38  let dict4: dict<any> = #{one: 1, two: '2'}
39  let dict5: dict<blob> = #{one: 0z01, tw: 0z02}
40
41  call CheckDefFailure(['let x:string'], 'E1069:')
42  call CheckDefFailure(['let x:string = "x"'], 'E1069:')
43  call CheckDefFailure(['let a:string = "x"'], 'E1069:')
44
45  let a: number = 6
46  assert_equal(6, a)
47
48  if has('channel')
49    let chan1: channel
50    let job1: job
51    let job2: job = job_start('willfail')
52  endif
53  if has('float')
54    let float1: float = 3.4
55  endif
56  let Funky1: func
57  let Funky2: func = function('len')
58  let Party2: func = funcref('g:Test_syntax')
59
60  # type becomes list<any>
61  let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
62  # type becomes dict<any>
63  let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
64
65  g:newvar = 'new'
66  assert_equal('new', g:newvar)
67
68  assert_equal('yes', g:existing)
69  g:existing = 'no'
70  assert_equal('no', g:existing)
71
72  v:char = 'abc'
73  assert_equal('abc', v:char)
74
75  $ENVVAR = 'foobar'
76  assert_equal('foobar', $ENVVAR)
77  $ENVVAR = ''
78
79  s:appendToMe ..= 'yyy'
80  assert_equal('xxxyyy', s:appendToMe)
81  s:addToMe += 222
82  assert_equal(333, s:addToMe)
83  s:newVar = 'new'
84  assert_equal('new', s:newVar)
85
86  set ts=7
87  &ts += 1
88  assert_equal(8, &ts)
89  &ts -= 3
90  assert_equal(5, &ts)
91  &ts *= 2
92  assert_equal(10, &ts)
93  &ts /= 3
94  assert_equal(3, &ts)
95  set ts=10
96  &ts %= 4
97  assert_equal(2, &ts)
98  call CheckDefFailure(['&notex += 3'], 'E113:')
99  call CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
100  call CheckDefFailure(['&ts = [7]'], 'E1013:')
101  call CheckDefExecFailure(['&ts = g:alist'], 'E1029: Expected number but got list')
102  call CheckDefFailure(['&ts = "xx"'], 'E1013:')
103  call CheckDefExecFailure(['&ts = g:astring'], 'E1029: Expected number but got string')
104  call CheckDefFailure(['&path += 3'], 'E1013:')
105  call CheckDefExecFailure(['&bs = "asdf"'], 'E474:')
106  # test freeing ISN_STOREOPT
107  call CheckDefFailure(['&ts = 3', 'let asdf'], 'E1022:')
108  &ts = 8
109
110  g:inc_counter += 1
111  assert_equal(2, g:inc_counter)
112
113  $SOME_ENV_VAR ..= 'more'
114  assert_equal('somemore', $SOME_ENV_VAR)
115  call CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1013:')
116  call CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1013:')
117
118  @a = 'areg'
119  @a ..= 'add'
120  assert_equal('aregadd', @a)
121  call CheckDefFailure(['@a += "more"'], 'E1013:')
122  call CheckDefFailure(['@a += 123'], 'E1013:')
123
124  v:errmsg = 'none'
125  v:errmsg ..= 'again'
126  assert_equal('noneagain', v:errmsg)
127  call CheckDefFailure(['v:errmsg += "more"'], 'E1013:')
128  call CheckDefFailure(['v:errmsg += 123'], 'E1013:')
129enddef
130
131def Test_assignment_local()
132  " Test in a separated file in order not to the current buffer/window/tab is
133  " changed.
134  let script_lines: list<string> =<< trim END
135    let b:existing = 'yes'
136    let w:existing = 'yes'
137    let t:existing = 'yes'
138
139    def Test_assignment_local_internal()
140      b:newvar = 'new'
141      assert_equal('new', b:newvar)
142      assert_equal('yes', b:existing)
143      b:existing = 'no'
144      assert_equal('no', b:existing)
145      b:existing ..= 'NO'
146      assert_equal('noNO', b:existing)
147
148      w:newvar = 'new'
149      assert_equal('new', w:newvar)
150      assert_equal('yes', w:existing)
151      w:existing = 'no'
152      assert_equal('no', w:existing)
153      w:existing ..= 'NO'
154      assert_equal('noNO', w:existing)
155
156      t:newvar = 'new'
157      assert_equal('new', t:newvar)
158      assert_equal('yes', t:existing)
159      t:existing = 'no'
160      assert_equal('no', t:existing)
161      t:existing ..= 'NO'
162      assert_equal('noNO', t:existing)
163    enddef
164    call Test_assignment_local_internal()
165  END
166  call CheckScriptSuccess(script_lines)
167enddef
168
169def Test_assignment_default()
170
171  # Test default values.
172  let thebool: bool
173  assert_equal(v:false, thebool)
174
175  let thenumber: number
176  assert_equal(0, thenumber)
177
178  if has('float')
179    let thefloat: float
180    assert_equal(0.0, thefloat)
181  endif
182
183  let thestring: string
184  assert_equal('', thestring)
185
186  let theblob: blob
187  assert_equal(0z, theblob)
188
189  let Thefunc: func
190  assert_equal(test_null_function(), Thefunc)
191
192  let thelist: list<any>
193  assert_equal([], thelist)
194
195  let thedict: dict<any>
196  assert_equal({}, thedict)
197
198  if has('channel')
199    let thejob: job
200    assert_equal(test_null_job(), thejob)
201
202    let thechannel: channel
203    assert_equal(test_null_channel(), thechannel)
204  endif
205
206  let nr = 1234 | nr = 5678
207  assert_equal(5678, nr)
208enddef
209
210def Mess(): string
211  v:foldstart = 123
212  return 'xxx'
213enddef
214
215def Test_assignment_failure()
216  call CheckDefFailure(['let var=234'], 'E1004:')
217  call CheckDefFailure(['let var =234'], 'E1004:')
218  call CheckDefFailure(['let var= 234'], 'E1004:')
219
220  call CheckDefFailure(['let true = 1'], 'E1034:')
221  call CheckDefFailure(['let false = 1'], 'E1034:')
222
223  call CheckDefFailure(['let [a; b; c] = g:list'], 'E452:')
224
225  call CheckDefFailure(['let somevar'], "E1022:")
226  call CheckDefFailure(['let &option'], 'E1052:')
227  call CheckDefFailure(['&g:option = 5'], 'E113:')
228
229  call CheckDefFailure(['let $VAR = 5'], 'E1065:')
230
231  call CheckDefFailure(['let @~ = 5'], 'E354:')
232  call CheckDefFailure(['let @a = 5'], 'E1066:')
233
234  call CheckDefFailure(['let g:var = 5'], 'E1016:')
235  call CheckDefFailure(['let w:var = 5'], 'E1079:')
236  call CheckDefFailure(['let b:var = 5'], 'E1078:')
237  call CheckDefFailure(['let t:var = 5'], 'E1080:')
238
239  call CheckDefFailure(['let anr = 4', 'anr ..= "text"'], 'E1019:')
240  call CheckDefFailure(['let xnr += 4'], 'E1020:')
241
242  call CheckScriptFailure(['vim9script', 'def Func()', 'let dummy = s:notfound', 'enddef'], 'E1050:')
243
244  call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
245  call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
246
247  call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
248  call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
249
250  call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
251  call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
252
253  call CheckDefFailure(['let var: dict <number>'], 'E1068:')
254  call CheckDefFailure(['let var: dict<number'], 'E1009:')
255
256  call assert_fails('s/^/\=Mess()/n', 'E794:')
257  call CheckDefFailure(['let var: dict<number'], 'E1009:')
258enddef
259
260def Test_unlet()
261  g:somevar = 'yes'
262  assert_true(exists('g:somevar'))
263  unlet g:somevar
264  assert_false(exists('g:somevar'))
265  unlet! g:somevar
266
267  call CheckScriptFailure([
268        'vim9script',
269        'let svar = 123',
270        'unlet svar',
271        ], 'E1081:')
272  call CheckScriptFailure([
273        'vim9script',
274        'let svar = 123',
275        'unlet s:svar',
276        ], 'E1081:')
277  call CheckScriptFailure([
278        'vim9script',
279        'let svar = 123',
280        'def Func()',
281        '  unlet svar',
282        'enddef',
283        ], 'E1081:')
284  call CheckScriptFailure([
285        'vim9script',
286        'let svar = 123',
287        'def Func()',
288        '  unlet s:svar',
289        'enddef',
290        ], 'E1081:')
291
292  $ENVVAR = 'foobar'
293  assert_equal('foobar', $ENVVAR)
294  unlet $ENVVAR
295  assert_equal('', $ENVVAR)
296enddef
297
298def Test_delfunction()
299  " Check function is defined in script namespace
300  CheckScriptSuccess([
301      'vim9script',
302      'func CheckMe()',
303      '  return 123',
304      'endfunc',
305      'assert_equal(123, s:CheckMe())',
306      ])
307
308  " Check function in script namespace cannot be deleted
309  CheckScriptFailure([
310      'vim9script',
311      'func DeleteMe1()',
312      'endfunc',
313      'delfunction DeleteMe1',
314      ], 'E1084:')
315  CheckScriptFailure([
316      'vim9script',
317      'func DeleteMe2()',
318      'endfunc',
319      'def DoThat()',
320      '  delfunction DeleteMe2',
321      'enddef',
322      'DoThat()',
323      ], 'E1084:')
324  CheckScriptFailure([
325      'vim9script',
326      'def DeleteMe3()',
327      'enddef',
328      'delfunction DeleteMe3',
329      ], 'E1084:')
330  CheckScriptFailure([
331      'vim9script',
332      'def DeleteMe4()',
333      'enddef',
334      'def DoThat()',
335      '  delfunction DeleteMe4',
336      'enddef',
337      'DoThat()',
338      ], 'E1084:')
339enddef
340
341func Test_wrong_type()
342  call CheckDefFailure(['let var: list<nothing>'], 'E1010:')
343  call CheckDefFailure(['let var: list<list<nothing>>'], 'E1010:')
344  call CheckDefFailure(['let var: dict<nothing>'], 'E1010:')
345  call CheckDefFailure(['let var: dict<dict<nothing>>'], 'E1010:')
346
347  call CheckDefFailure(['let var: dict<number'], 'E1009:')
348  call CheckDefFailure(['let var: dict<list<number>'], 'E1009:')
349
350  call CheckDefFailure(['let var: ally'], 'E1010:')
351  call CheckDefFailure(['let var: bram'], 'E1010:')
352  call CheckDefFailure(['let var: cathy'], 'E1010:')
353  call CheckDefFailure(['let var: dom'], 'E1010:')
354  call CheckDefFailure(['let var: freddy'], 'E1010:')
355  call CheckDefFailure(['let var: john'], 'E1010:')
356  call CheckDefFailure(['let var: larry'], 'E1010:')
357  call CheckDefFailure(['let var: ned'], 'E1010:')
358  call CheckDefFailure(['let var: pam'], 'E1010:')
359  call CheckDefFailure(['let var: sam'], 'E1010:')
360  call CheckDefFailure(['let var: vim'], 'E1010:')
361
362  call CheckDefFailure(['let Ref: number', 'Ref()'], 'E1085:')
363  call CheckDefFailure(['let Ref: string', 'let res = Ref()'], 'E1085:')
364endfunc
365
366func Test_const()
367  call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
368  call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
369  call CheckDefFailure(['const two'], 'E1021:')
370  call CheckDefFailure(['const &option'], 'E996:')
371endfunc
372
373def Test_block()
374  let outer = 1
375  {
376    let inner = 2
377    assert_equal(1, outer)
378    assert_equal(2, inner)
379  }
380  assert_equal(1, outer)
381enddef
382
383func Test_block_failure()
384  call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
385  call CheckDefFailure(['}'], 'E1025:')
386  call CheckDefFailure(['{', 'echo 1'], 'E1026:')
387endfunc
388
389def Test_cmd_modifier()
390  tab echo '0'
391  call CheckDefFailure(['5tab echo 3'], 'E16:')
392enddef
393
394def Test_try_catch()
395  let l = []
396  try # comment
397    add(l, '1')
398    throw 'wrong'
399    add(l, '2')
400  catch # comment
401    add(l, v:exception)
402  finally # comment
403    add(l, '3')
404  endtry # comment
405  assert_equal(['1', 'wrong', '3'], l)
406enddef
407
408def ThrowFromDef()
409  throw "getout" # comment
410enddef
411
412func CatchInFunc()
413  try
414    call ThrowFromDef()
415  catch
416    let g:thrown_func = v:exception
417  endtry
418endfunc
419
420def CatchInDef()
421  try
422    ThrowFromDef()
423  catch
424    g:thrown_def = v:exception
425  endtry
426enddef
427
428def ReturnFinally(): string
429  try
430    return 'intry'
431  finally
432    g:in_finally = 'finally'
433  endtry
434  return 'end'
435enddef
436
437def Test_try_catch_nested()
438  CatchInFunc()
439  assert_equal('getout', g:thrown_func)
440
441  CatchInDef()
442  assert_equal('getout', g:thrown_def)
443
444  assert_equal('intry', ReturnFinally())
445  assert_equal('finally', g:in_finally)
446enddef
447
448def Test_try_catch_match()
449  let seq = 'a'
450  try
451    throw 'something'
452  catch /nothing/
453    seq ..= 'x'
454  catch /some/
455    seq ..= 'b'
456  catch /asdf/
457    seq ..= 'x'
458  catch ?a\?sdf?
459    seq ..= 'y'
460  finally
461    seq ..= 'c'
462  endtry
463  assert_equal('abc', seq)
464enddef
465
466def Test_try_catch_fails()
467  call CheckDefFailure(['catch'], 'E603:')
468  call CheckDefFailure(['try', 'echo 0', 'catch','catch'], 'E1033:')
469  call CheckDefFailure(['try', 'echo 0', 'catch /pat'], 'E1067:')
470  call CheckDefFailure(['finally'], 'E606:')
471  call CheckDefFailure(['try', 'echo 0', 'finally', 'echo 1', 'finally'], 'E607:')
472  call CheckDefFailure(['endtry'], 'E602:')
473  call CheckDefFailure(['while 1', 'endtry'], 'E170:')
474  call CheckDefFailure(['for i in range(5)', 'endtry'], 'E170:')
475  call CheckDefFailure(['if 2', 'endtry'], 'E171:')
476  call CheckDefFailure(['try', 'echo 1', 'endtry'], 'E1032:')
477
478  call CheckDefFailure(['throw'], 'E1015:')
479  call CheckDefFailure(['throw xxx'], 'E1001:')
480enddef
481
482if has('channel')
483  let someJob = test_null_job()
484
485  def FuncWithError()
486    echomsg g:someJob
487  enddef
488
489  func Test_convert_emsg_to_exception()
490    try
491      call FuncWithError()
492    catch
493      call assert_match('Vim:E908:', v:exception)
494    endtry
495  endfunc
496endif
497
498let s:export_script_lines =<< trim END
499  vim9script
500  let name: string = 'bob'
501  def Concat(arg: string): string
502    return name .. arg
503  enddef
504  g:result = Concat('bie')
505  g:localname = name
506
507  export const CONST = 1234
508  export let exported = 9876
509  export let exp_name = 'John'
510  export def Exported(): string
511    return 'Exported'
512  enddef
513END
514
515def Test_vim9_import_export()
516  let import_script_lines =<< trim END
517    vim9script
518    import {exported, Exported} from './Xexport.vim'
519    g:imported = exported
520    exported += 3
521    g:imported_added = exported
522    g:imported_func = Exported()
523
524    import {exp_name} from './Xexport.vim'
525    g:imported_name = exp_name
526    exp_name ..= ' Doe'
527    g:imported_name_appended = exp_name
528    g:imported_later = exported
529  END
530
531  writefile(import_script_lines, 'Ximport.vim')
532  writefile(s:export_script_lines, 'Xexport.vim')
533
534  source Ximport.vim
535
536  assert_equal('bobbie', g:result)
537  assert_equal('bob', g:localname)
538  assert_equal(9876, g:imported)
539  assert_equal(9879, g:imported_added)
540  assert_equal(9879, g:imported_later)
541  assert_equal('Exported', g:imported_func)
542  assert_equal('John', g:imported_name)
543  assert_equal('John Doe', g:imported_name_appended)
544  assert_false(exists('g:name'))
545
546  unlet g:result
547  unlet g:localname
548  unlet g:imported
549  unlet g:imported_added
550  unlet g:imported_later
551  unlet g:imported_func
552  unlet g:imported_name g:imported_name_appended
553  delete('Ximport.vim')
554
555  let import_in_def_lines =<< trim END
556    vim9script
557    def ImportInDef()
558      import exported from './Xexport.vim'
559      g:imported = exported
560      exported += 7
561      g:imported_added = exported
562    enddef
563    ImportInDef()
564  END
565  writefile(import_in_def_lines, 'Ximport2.vim')
566  source Ximport2.vim
567  " TODO: this should be 9879
568  assert_equal(9876, g:imported)
569  assert_equal(9883, g:imported_added)
570  unlet g:imported
571  unlet g:imported_added
572  delete('Ximport2.vim')
573
574  let import_star_as_lines =<< trim END
575    vim9script
576    import * as Export from './Xexport.vim'
577    def UseExport()
578      g:imported = Export.exported
579    enddef
580    UseExport()
581  END
582  writefile(import_star_as_lines, 'Ximport.vim')
583  source Ximport.vim
584  assert_equal(9883, g:imported)
585
586  let import_star_as_lines_no_dot =<< trim END
587    vim9script
588    import * as Export from './Xexport.vim'
589    def Func()
590      let dummy = 1
591      let imported = Export + dummy
592    enddef
593  END
594  writefile(import_star_as_lines_no_dot, 'Ximport.vim')
595  assert_fails('source Ximport.vim', 'E1060:')
596
597  let import_star_as_lines_dot_space =<< trim END
598    vim9script
599    import * as Export from './Xexport.vim'
600    def Func()
601      let imported = Export . exported
602    enddef
603  END
604  writefile(import_star_as_lines_dot_space, 'Ximport.vim')
605  assert_fails('source Ximport.vim', 'E1074:')
606
607  let import_star_as_lines_missing_name =<< trim END
608    vim9script
609    import * as Export from './Xexport.vim'
610    def Func()
611      let imported = Export.
612    enddef
613  END
614  writefile(import_star_as_lines_missing_name, 'Ximport.vim')
615  assert_fails('source Ximport.vim', 'E1048:')
616
617  let import_star_lines =<< trim END
618    vim9script
619    import * from './Xexport.vim'
620  END
621  writefile(import_star_lines, 'Ximport.vim')
622  assert_fails('source Ximport.vim', 'E1045:')
623
624  " try to import something that exists but is not exported
625  let import_not_exported_lines =<< trim END
626    vim9script
627    import name from './Xexport.vim'
628  END
629  writefile(import_not_exported_lines, 'Ximport.vim')
630  assert_fails('source Ximport.vim', 'E1049:')
631
632  " try to import something that is already defined
633  let import_already_defined =<< trim END
634    vim9script
635    let exported = 'something'
636    import exported from './Xexport.vim'
637  END
638  writefile(import_already_defined, 'Ximport.vim')
639  assert_fails('source Ximport.vim', 'E1073:')
640
641  " try to import something that is already defined
642  import_already_defined =<< trim END
643    vim9script
644    let exported = 'something'
645    import * as exported from './Xexport.vim'
646  END
647  writefile(import_already_defined, 'Ximport.vim')
648  assert_fails('source Ximport.vim', 'E1073:')
649
650  " try to import something that is already defined
651  import_already_defined =<< trim END
652    vim9script
653    let exported = 'something'
654    import {exported} from './Xexport.vim'
655  END
656  writefile(import_already_defined, 'Ximport.vim')
657  assert_fails('source Ximport.vim', 'E1073:')
658
659  " import a very long name, requires making a copy
660  let import_long_name_lines =<< trim END
661    vim9script
662    import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
663  END
664  writefile(import_long_name_lines, 'Ximport.vim')
665  assert_fails('source Ximport.vim', 'E1048:')
666
667  let import_no_from_lines =<< trim END
668    vim9script
669    import name './Xexport.vim'
670  END
671  writefile(import_no_from_lines, 'Ximport.vim')
672  assert_fails('source Ximport.vim', 'E1070:')
673
674  let import_invalid_string_lines =<< trim END
675    vim9script
676    import name from Xexport.vim
677  END
678  writefile(import_invalid_string_lines, 'Ximport.vim')
679  assert_fails('source Ximport.vim', 'E1071:')
680
681  let import_wrong_name_lines =<< trim END
682    vim9script
683    import name from './XnoExport.vim'
684  END
685  writefile(import_wrong_name_lines, 'Ximport.vim')
686  assert_fails('source Ximport.vim', 'E1053:')
687
688  let import_missing_comma_lines =<< trim END
689    vim9script
690    import {exported name} from './Xexport.vim'
691  END
692  writefile(import_missing_comma_lines, 'Ximport3.vim')
693  assert_fails('source Ximport3.vim', 'E1046:')
694
695  delete('Ximport.vim')
696  delete('Ximport3.vim')
697  delete('Xexport.vim')
698
699  " Check that in a Vim9 script 'cpo' is set to the Vim default.
700  set cpo&vi
701  let cpo_before = &cpo
702  let lines =<< trim END
703    vim9script
704    g:cpo_in_vim9script = &cpo
705  END
706  writefile(lines, 'Xvim9_script')
707  source Xvim9_script
708  assert_equal(cpo_before, &cpo)
709  set cpo&vim
710  assert_equal(&cpo, g:cpo_in_vim9script)
711  delete('Xvim9_script')
712enddef
713
714def Test_vim9script_fails()
715  CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
716  CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
717  CheckScriptFailure(['export let some = 123'], 'E1042:')
718  CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
719  CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
720  CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
721
722  assert_fails('vim9script', 'E1038')
723  assert_fails('export something', 'E1043')
724enddef
725
726def Test_vim9script_reload_import()
727  let lines =<< trim END
728    vim9script
729    const var = ''
730    let valone = 1234
731    def MyFunc(arg: string)
732       valone = 5678
733    enddef
734  END
735  let morelines =<< trim END
736    let valtwo = 222
737    export def GetValtwo(): number
738      return valtwo
739    enddef
740  END
741  writefile(lines + morelines, 'Xreload.vim')
742  source Xreload.vim
743  source Xreload.vim
744  source Xreload.vim
745
746  let testlines =<< trim END
747    vim9script
748    def TheFunc()
749      import GetValtwo from './Xreload.vim'
750      assert_equal(222, GetValtwo())
751    enddef
752    TheFunc()
753  END
754  writefile(testlines, 'Ximport.vim')
755  source Ximport.vim
756
757  " Test that when not using "morelines" GetValtwo() and valtwo are still
758  " defined, because import doesn't reload a script.
759  writefile(lines, 'Xreload.vim')
760  source Ximport.vim
761
762  " cannot declare a var twice
763  lines =<< trim END
764    vim9script
765    let valone = 1234
766    let valone = 5678
767  END
768  writefile(lines, 'Xreload.vim')
769  assert_fails('source Xreload.vim', 'E1041:')
770
771  delete('Xreload.vim')
772  delete('Ximport.vim')
773enddef
774
775def Test_vim9script_reload_delfunc()
776  let first_lines =<< trim END
777    vim9script
778    def FuncYes(): string
779      return 'yes'
780    enddef
781  END
782  let withno_lines =<< trim END
783    def FuncNo(): string
784      return 'no'
785    enddef
786    def g:DoCheck(no_exists: bool)
787      assert_equal('yes', FuncYes())
788      assert_equal('no', FuncNo())
789    enddef
790  END
791  let nono_lines =<< trim END
792    def g:DoCheck(no_exists: bool)
793      assert_equal('yes', FuncYes())
794      assert_fails('call FuncNo()', 'E117:')
795    enddef
796  END
797
798  # FuncNo() is defined
799  writefile(first_lines + withno_lines, 'Xreloaded.vim')
800  source Xreloaded.vim
801  g:DoCheck(true)
802
803  # FuncNo() is not redefined
804  writefile(first_lines + nono_lines, 'Xreloaded.vim')
805  source Xreloaded.vim
806  g:DoCheck()
807
808  # FuncNo() is back
809  writefile(first_lines + withno_lines, 'Xreloaded.vim')
810  source Xreloaded.vim
811  g:DoCheck()
812
813  delete('Xreloaded.vim')
814enddef
815
816def Test_vim9script_reload_delvar()
817  # write the script with a script-local variable
818  let lines =<< trim END
819    vim9script
820    let var = 'string'
821  END
822  writefile(lines, 'XreloadVar.vim')
823  source XreloadVar.vim
824
825  # now write the script using the same variable locally - works
826  lines =<< trim END
827    vim9script
828    def Func()
829      let var = 'string'
830    enddef
831  END
832  writefile(lines, 'XreloadVar.vim')
833  source XreloadVar.vim
834
835  delete('XreloadVar.vim')
836enddef
837
838def Test_import_absolute()
839  let import_lines = [
840        'vim9script',
841        'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
842        'def UseExported()',
843        '  g:imported_abs = exported',
844        '  exported = 8888',
845        '  g:imported_after = exported',
846        'enddef',
847        'UseExported()',
848        'g:import_disassembled = execute("disass UseExported")',
849        ]
850  writefile(import_lines, 'Ximport_abs.vim')
851  writefile(s:export_script_lines, 'Xexport_abs.vim')
852
853  source Ximport_abs.vim
854
855  assert_equal(9876, g:imported_abs)
856  assert_equal(8888, g:imported_after)
857  assert_match('<SNR>\d\+_UseExported.*' ..
858          'g:imported_abs = exported.*' ..
859          '0 LOADSCRIPT exported from .*Xexport_abs.vim.*' ..
860          '1 STOREG g:imported_abs.*' ..
861          'exported = 8888.*' ..
862          '3 STORESCRIPT exported in .*Xexport_abs.vim.*' ..
863          'g:imported_after = exported.*' ..
864          '4 LOADSCRIPT exported from .*Xexport_abs.vim.*' ..
865          '5 STOREG g:imported_after.*',
866        g:import_disassembled)
867  unlet g:imported_abs
868  unlet g:import_disassembled
869
870  delete('Ximport_abs.vim')
871  delete('Xexport_abs.vim')
872enddef
873
874def Test_import_rtp()
875  let import_lines = [
876        'vim9script',
877        'import exported from "Xexport_rtp.vim"',
878        'g:imported_rtp = exported',
879        ]
880  writefile(import_lines, 'Ximport_rtp.vim')
881  mkdir('import')
882  writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
883
884  let save_rtp = &rtp
885  &rtp = getcwd()
886  source Ximport_rtp.vim
887  &rtp = save_rtp
888
889  assert_equal(9876, g:imported_rtp)
890  unlet g:imported_rtp
891
892  delete('Ximport_rtp.vim')
893  delete('import', 'rf')
894enddef
895
896def Test_fixed_size_list()
897  " will be allocated as one piece of memory, check that changes work
898  let l = [1, 2, 3, 4]
899  l->remove(0)
900  l->add(5)
901  l->insert(99, 1)
902  assert_equal([2, 99, 3, 4, 5], l)
903enddef
904
905def IfElse(what: number): string
906  let res = ''
907  if what == 1
908    res = "one"
909  elseif what == 2
910    res = "two"
911  else
912    res = "three"
913  endif
914  return res
915enddef
916
917def Test_if_elseif_else()
918  assert_equal('one', IfElse(1))
919  assert_equal('two', IfElse(2))
920  assert_equal('three', IfElse(3))
921enddef
922
923def Test_if_elseif_else_fails()
924  call CheckDefFailure(['elseif true'], 'E582:')
925  call CheckDefFailure(['else'], 'E581:')
926  call CheckDefFailure(['endif'], 'E580:')
927  call CheckDefFailure(['if true', 'elseif xxx'], 'E1001:')
928  call CheckDefFailure(['if true', 'echo 1'], 'E171:')
929enddef
930
931let g:bool_true = v:true
932let g:bool_false = v:false
933
934def Test_if_const_expr()
935  let res = false
936  if true ? true : false
937    res = true
938  endif
939  assert_equal(true, res)
940
941  g:glob = 2
942  if false
943    execute('let g:glob = 3')
944  endif
945  assert_equal(2, g:glob)
946  if true
947    execute('let g:glob = 3')
948  endif
949  assert_equal(3, g:glob)
950
951  res = false
952  if g:bool_true ? true : false
953    res = true
954  endif
955  assert_equal(true, res)
956
957  res = false
958  if true ? g:bool_true : false
959    res = true
960  endif
961  assert_equal(true, res)
962
963  res = false
964  if true ? true : g:bool_false
965    res = true
966  endif
967  assert_equal(true, res)
968
969  res = false
970  if true ? false : true
971    res = true
972  endif
973  assert_equal(false, res)
974
975  res = false
976  if false ? false : true
977    res = true
978  endif
979  assert_equal(true, res)
980
981  res = false
982  if false ? true : false
983    res = true
984  endif
985  assert_equal(false, res)
986
987  res = false
988  if has('xyz') ? true : false
989    res = true
990  endif
991  assert_equal(false, res)
992
993  res = false
994  if true && true
995    res = true
996  endif
997  assert_equal(true, res)
998
999  res = false
1000  if true && false
1001    res = true
1002  endif
1003  assert_equal(false, res)
1004
1005  res = false
1006  if g:bool_true && false
1007    res = true
1008  endif
1009  assert_equal(false, res)
1010
1011  res = false
1012  if true && g:bool_false
1013    res = true
1014  endif
1015  assert_equal(false, res)
1016
1017  res = false
1018  if false && false
1019    res = true
1020  endif
1021  assert_equal(false, res)
1022
1023  res = false
1024  if true || false
1025    res = true
1026  endif
1027  assert_equal(true, res)
1028
1029  res = false
1030  if g:bool_true || false
1031    res = true
1032  endif
1033  assert_equal(true, res)
1034
1035  res = false
1036  if true || g:bool_false
1037    res = true
1038  endif
1039  assert_equal(true, res)
1040
1041  res = false
1042  if false || false
1043    res = true
1044  endif
1045  assert_equal(false, res)
1046enddef
1047
1048def Test_if_const_expr_fails()
1049  call CheckDefFailure(['if "aaa" == "bbb'], 'E114:')
1050  call CheckDefFailure(["if 'aaa' == 'bbb"], 'E115:')
1051  call CheckDefFailure(["if has('aaa'"], 'E110:')
1052  call CheckDefFailure(["if has('aaa') ? true false"], 'E109:')
1053enddef
1054
1055def Test_execute_cmd()
1056  new
1057  setline(1, 'default')
1058  execute 'call setline(1, "execute-string")'
1059  assert_equal('execute-string', getline(1))
1060
1061  execute "call setline(1, 'execute-string')"
1062  assert_equal('execute-string', getline(1))
1063
1064  let cmd1 = 'call setline(1,'
1065  let cmd2 = '"execute-var")'
1066  execute cmd1 cmd2 # comment
1067  assert_equal('execute-var', getline(1))
1068
1069  execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
1070  assert_equal('execute-var-string', getline(1))
1071
1072  let cmd_first = 'call '
1073  let cmd_last = 'setline(1, "execute-var-var")'
1074  execute cmd_first .. cmd_last
1075  assert_equal('execute-var-var', getline(1))
1076  bwipe!
1077
1078  call CheckDefFailure(['execute xxx'], 'E1001:')
1079  call CheckDefFailure(['execute "cmd"# comment'], 'E488:')
1080enddef
1081
1082def Test_echo_cmd()
1083  echo 'some' # comment
1084  echon 'thing'
1085  assert_match('^something$', Screenline(&lines))
1086
1087  echo "some" # comment
1088  echon "thing"
1089  assert_match('^something$', Screenline(&lines))
1090
1091  let str1 = 'some'
1092  let str2 = 'more'
1093  echo str1 str2
1094  assert_match('^some more$', Screenline(&lines))
1095
1096  call CheckDefFailure(['echo "xxx"# comment'], 'E488:')
1097enddef
1098
1099def Test_echomsg_cmd()
1100  echomsg 'some' 'more' # comment
1101  assert_match('^some more$', Screenline(&lines))
1102  echo 'clear'
1103  1messages
1104  assert_match('^some more$', Screenline(&lines))
1105
1106  call CheckDefFailure(['echomsg "xxx"# comment'], 'E488:')
1107enddef
1108
1109def Test_echoerr_cmd()
1110  try
1111    echoerr 'something' 'wrong' # comment
1112  catch
1113    assert_match('something wrong', v:exception)
1114  endtry
1115enddef
1116
1117def Test_for_outside_of_function()
1118  let lines =<< trim END
1119    vim9script
1120    new
1121    for var in range(0, 3)
1122      append(line('$'), var)
1123    endfor
1124    assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
1125    bwipe!
1126  END
1127  writefile(lines, 'Xvim9for.vim')
1128  source Xvim9for.vim
1129  delete('Xvim9for.vim')
1130enddef
1131
1132def Test_for_loop()
1133  let result = ''
1134  for cnt in range(7)
1135    if cnt == 4
1136      break
1137    endif
1138    if cnt == 2
1139      continue
1140    endif
1141    result ..= cnt .. '_'
1142  endfor
1143  assert_equal('0_1_3_', result)
1144enddef
1145
1146def Test_for_loop_fails()
1147  CheckDefFailure(['for # in range(5)'], 'E690:')
1148  CheckDefFailure(['for i In range(5)'], 'E690:')
1149  CheckDefFailure(['let x = 5', 'for x in range(5)'], 'E1023:')
1150  CheckScriptFailure(['def Func(arg: any)', 'for arg in range(5)', 'enddef'], 'E1006:')
1151  CheckDefFailure(['for i in "text"'], 'E1024:')
1152  CheckDefFailure(['for i in xxx'], 'E1001:')
1153  CheckDefFailure(['endfor'], 'E588:')
1154  CheckDefFailure(['for i in range(3)', 'echo 3'], 'E170:')
1155enddef
1156
1157def Test_while_loop()
1158  let result = ''
1159  let cnt = 0
1160  while cnt < 555
1161    if cnt == 3
1162      break
1163    endif
1164    cnt += 1
1165    if cnt == 2
1166      continue
1167    endif
1168    result ..= cnt .. '_'
1169  endwhile
1170  assert_equal('1_3_', result)
1171enddef
1172
1173def Test_while_loop_fails()
1174  CheckDefFailure(['while xxx'], 'E1001:')
1175  CheckDefFailure(['endwhile'], 'E588:')
1176  CheckDefFailure(['continue'], 'E586:')
1177  CheckDefFailure(['if true', 'continue'], 'E586:')
1178  CheckDefFailure(['break'], 'E587:')
1179  CheckDefFailure(['if true', 'break'], 'E587:')
1180  CheckDefFailure(['while 1', 'echo 3'], 'E170:')
1181enddef
1182
1183def Test_interrupt_loop()
1184  let caught = false
1185  let x = 0
1186  try
1187    while 1
1188      x += 1
1189      if x == 100
1190        feedkeys("\<C-C>", 'Lt')
1191      endif
1192    endwhile
1193  catch
1194    caught = true
1195    assert_equal(100, x)
1196  endtry
1197  assert_true(caught, 'should have caught an exception')
1198enddef
1199
1200def Test_automatic_line_continuation()
1201  let mylist = [
1202      'one',
1203      'two',
1204      'three',
1205      ] " comment
1206  assert_equal(['one', 'two', 'three'], mylist)
1207
1208  let mydict = {
1209      'one': 1,
1210      'two': 2,
1211      'three':
1212          3,
1213      } " comment
1214  assert_equal({'one': 1, 'two': 2, 'three': 3}, mydict)
1215  mydict = #{
1216      one: 1,  # comment
1217      two:     # comment
1218           2,  # comment
1219      three: 3 # comment
1220      }
1221  assert_equal(#{one: 1, two: 2, three: 3}, mydict)
1222  mydict = #{
1223      one: 1,
1224      two:
1225           2,
1226      three: 3
1227      }
1228  assert_equal(#{one: 1, two: 2, three: 3}, mydict)
1229
1230  assert_equal(
1231        ['one', 'two', 'three'],
1232        split('one two three')
1233        )
1234enddef
1235
1236def Test_vim9_comment()
1237  CheckScriptSuccess([
1238      'vim9script',
1239      '# something',
1240      ])
1241  CheckScriptFailure([
1242      'vim9script',
1243      ':# something',
1244      ], 'E488:')
1245  CheckScriptFailure([
1246      '# something',
1247      ], 'E488:')
1248  CheckScriptFailure([
1249      ':# something',
1250      ], 'E488:')
1251
1252  { # block start
1253  } # block end
1254  CheckDefFailure([
1255      '{# comment',
1256      ], 'E488:')
1257  CheckDefFailure([
1258      '{',
1259      '}# comment',
1260      ], 'E488:')
1261
1262  echo "yes" # comment
1263  CheckDefFailure([
1264      'echo "yes"# comment',
1265      ], 'E488:')
1266  CheckScriptSuccess([
1267      'vim9script',
1268      'echo "yes" # something',
1269      ])
1270  CheckScriptFailure([
1271      'vim9script',
1272      'echo "yes"# something',
1273      ], 'E121:')
1274  CheckScriptFailure([
1275      'vim9script',
1276      'echo# something',
1277      ], 'E121:')
1278  CheckScriptFailure([
1279      'echo "yes" # something',
1280      ], 'E121:')
1281
1282  exe "echo" # comment
1283  CheckDefFailure([
1284      'exe "echo"# comment',
1285      ], 'E488:')
1286  CheckScriptSuccess([
1287      'vim9script',
1288      'exe "echo" # something',
1289      ])
1290  CheckScriptFailure([
1291      'vim9script',
1292      'exe "echo"# something',
1293      ], 'E121:')
1294  CheckDefFailure([
1295      'exe # comment',
1296      ], 'E1015:')
1297  CheckScriptFailure([
1298      'vim9script',
1299      'exe# something',
1300      ], 'E121:')
1301  CheckScriptFailure([
1302      'exe "echo" # something',
1303      ], 'E121:')
1304
1305  CheckDefFailure([
1306      'try# comment',
1307      '  echo "yes"',
1308      'catch',
1309      'endtry',
1310      ], 'E488:')
1311  CheckScriptFailure([
1312      'vim9script',
1313      'try# comment',
1314      'echo "yes"',
1315      ], 'E488:')
1316  CheckDefFailure([
1317      'try',
1318      '  throw#comment',
1319      'catch',
1320      'endtry',
1321      ], 'E1015:')
1322  CheckDefFailure([
1323      'try',
1324      '  throw "yes"#comment',
1325      'catch',
1326      'endtry',
1327      ], 'E488:')
1328  CheckDefFailure([
1329      'try',
1330      '  echo "yes"',
1331      'catch# comment',
1332      'endtry',
1333      ], 'E488:')
1334  CheckScriptFailure([
1335      'vim9script',
1336      'try',
1337      '  echo "yes"',
1338      'catch# comment',
1339      'endtry',
1340      ], 'E654:')
1341  CheckDefFailure([
1342      'try',
1343      '  echo "yes"',
1344      'catch /pat/# comment',
1345      'endtry',
1346      ], 'E488:')
1347  CheckDefFailure([
1348      'try',
1349      'echo "yes"',
1350      'catch',
1351      'endtry# comment',
1352      ], 'E488:')
1353  CheckScriptFailure([
1354      'vim9script',
1355      'try',
1356      '  echo "yes"',
1357      'catch',
1358      'endtry# comment',
1359      ], 'E600:')
1360
1361  CheckScriptSuccess([
1362      'vim9script',
1363      'hi # comment',
1364      ])
1365  CheckScriptFailure([
1366      'vim9script',
1367      'hi# comment',
1368      ], 'E416:')
1369  CheckScriptSuccess([
1370      'vim9script',
1371      'hi Search # comment',
1372      ])
1373  CheckScriptFailure([
1374      'vim9script',
1375      'hi Search# comment',
1376      ], 'E416:')
1377  CheckScriptSuccess([
1378      'vim9script',
1379      'hi link This Search # comment',
1380      ])
1381  CheckScriptFailure([
1382      'vim9script',
1383      'hi link This That# comment',
1384      ], 'E413:')
1385  CheckScriptSuccess([
1386      'vim9script',
1387      'hi clear This # comment',
1388      'hi clear # comment',
1389      ])
1390  " not tested, because it doesn't give an error but a warning:
1391  " hi clear This# comment',
1392  CheckScriptFailure([
1393      'vim9script',
1394      'hi clear# comment',
1395      ], 'E416:')
1396
1397  CheckScriptSuccess([
1398      'vim9script',
1399      'hi Group term=bold',
1400      'match Group /todo/ # comment',
1401      ])
1402  CheckScriptFailure([
1403      'vim9script',
1404      'hi Group term=bold',
1405      'match Group /todo/# comment',
1406      ], 'E488:')
1407  CheckScriptSuccess([
1408      'vim9script',
1409      'match # comment',
1410      ])
1411  CheckScriptFailure([
1412      'vim9script',
1413      'match# comment',
1414      ], 'E475:')
1415  CheckScriptSuccess([
1416      'vim9script',
1417      'match none # comment',
1418      ])
1419  CheckScriptFailure([
1420      'vim9script',
1421      'match none# comment',
1422      ], 'E475:')
1423
1424  CheckScriptSuccess([
1425      'vim9script',
1426      'menutrans clear # comment',
1427      ])
1428  CheckScriptFailure([
1429      'vim9script',
1430      'menutrans clear# comment text',
1431      ], 'E474:')
1432
1433  CheckScriptSuccess([
1434      'vim9script',
1435      'syntax clear # comment',
1436      ])
1437  CheckScriptFailure([
1438      'vim9script',
1439      'syntax clear# comment text',
1440      ], 'E28:')
1441  CheckScriptSuccess([
1442      'vim9script',
1443      'syntax keyword Word some',
1444      'syntax clear Word # comment',
1445      ])
1446  CheckScriptFailure([
1447      'vim9script',
1448      'syntax keyword Word some',
1449      'syntax clear Word# comment text',
1450      ], 'E28:')
1451
1452  CheckScriptSuccess([
1453      'vim9script',
1454      'syntax list # comment',
1455      ])
1456  CheckScriptFailure([
1457      'vim9script',
1458      'syntax list# comment text',
1459      ], 'E28:')
1460
1461  CheckScriptSuccess([
1462      'vim9script',
1463      'syntax match Word /pat/ oneline # comment',
1464      ])
1465  CheckScriptFailure([
1466      'vim9script',
1467      'syntax match Word /pat/ oneline# comment',
1468      ], 'E475:')
1469
1470  CheckScriptSuccess([
1471      'vim9script',
1472      'syntax keyword Word word # comm[ent',
1473      ])
1474  CheckScriptFailure([
1475      'vim9script',
1476      'syntax keyword Word word# comm[ent',
1477      ], 'E789:')
1478
1479  CheckScriptSuccess([
1480      'vim9script',
1481      'syntax match Word /pat/ # comment',
1482      ])
1483  CheckScriptFailure([
1484      'vim9script',
1485      'syntax match Word /pat/# comment',
1486      ], 'E402:')
1487
1488  CheckScriptSuccess([
1489      'vim9script',
1490      'syntax match Word /pat/ contains=Something # comment',
1491      ])
1492  CheckScriptFailure([
1493      'vim9script',
1494      'syntax match Word /pat/ contains=Something# comment',
1495      ], 'E475:')
1496  CheckScriptFailure([
1497      'vim9script',
1498      'syntax match Word /pat/ contains= # comment',
1499      ], 'E406:')
1500  CheckScriptFailure([
1501      'vim9script',
1502      'syntax match Word /pat/ contains=# comment',
1503      ], 'E475:')
1504
1505  CheckScriptSuccess([
1506      'vim9script',
1507      'syntax region Word start=/pat/ end=/pat/ # comment',
1508      ])
1509  CheckScriptFailure([
1510      'vim9script',
1511      'syntax region Word start=/pat/ end=/pat/# comment',
1512      ], 'E475:')
1513
1514  CheckScriptSuccess([
1515      'vim9script',
1516      'syntax sync # comment',
1517      ])
1518  CheckScriptFailure([
1519      'vim9script',
1520      'syntax sync# comment',
1521      ], 'E404:')
1522  CheckScriptSuccess([
1523      'vim9script',
1524      'syntax sync ccomment # comment',
1525      ])
1526  CheckScriptFailure([
1527      'vim9script',
1528      'syntax sync ccomment# comment',
1529      ], 'E404:')
1530
1531  CheckScriptSuccess([
1532      'vim9script',
1533      'syntax cluster Some contains=Word # comment',
1534      ])
1535  CheckScriptFailure([
1536      'vim9script',
1537      'syntax cluster Some contains=Word# comment',
1538      ], 'E475:')
1539
1540  CheckScriptSuccess([
1541      'vim9script',
1542      'command Echo echo # comment',
1543      'command Echo # comment',
1544      ])
1545  CheckScriptFailure([
1546      'vim9script',
1547      'command Echo echo# comment',
1548      'Echo',
1549      ], 'E121:')
1550  CheckScriptFailure([
1551      'vim9script',
1552      'command Echo# comment',
1553      ], 'E182:')
1554  CheckScriptFailure([
1555      'vim9script',
1556      'command Echo echo',
1557      'command Echo# comment',
1558      ], 'E182:')
1559
1560  CheckScriptSuccess([
1561      'vim9script',
1562      'function # comment',
1563      ])
1564  CheckScriptFailure([
1565      'vim9script',
1566      'function# comment',
1567      ], 'E129:')
1568  CheckScriptSuccess([
1569      'vim9script',
1570      'function CheckScriptSuccess # comment',
1571      ])
1572  CheckScriptFailure([
1573      'vim9script',
1574      'function CheckScriptSuccess# comment',
1575      ], 'E488:')
1576
1577  CheckScriptSuccess([
1578      'vim9script',
1579      'func g:DeleteMeA()',
1580      'endfunc',
1581      'delfunction g:DeleteMeA # comment',
1582      ])
1583  CheckScriptFailure([
1584      'vim9script',
1585      'func g:DeleteMeB()',
1586      'endfunc',
1587      'delfunction g:DeleteMeB# comment',
1588      ], 'E488:')
1589
1590  CheckScriptSuccess([
1591      'vim9script',
1592      'call execute("ls") # comment',
1593      ])
1594  CheckScriptFailure([
1595      'vim9script',
1596      'call execute("ls")# comment',
1597      ], 'E488:')
1598enddef
1599
1600def Test_vim9_comment_gui()
1601  CheckCanRunGui
1602
1603  CheckScriptFailure([
1604      'vim9script',
1605      'gui#comment'
1606      ], 'E499:')
1607  CheckScriptFailure([
1608      'vim9script',
1609      'gui -f#comment'
1610      ], 'E499:')
1611enddef
1612
1613def Test_vim9_comment_not_compiled()
1614  au TabEnter *.vim let g:entered = 1
1615  au TabEnter *.x let g:entered = 2
1616
1617  edit test.vim
1618  doautocmd TabEnter #comment
1619  assert_equal(1, g:entered)
1620
1621  doautocmd TabEnter f.x
1622  assert_equal(2, g:entered)
1623
1624  g:entered = 0
1625  doautocmd TabEnter f.x #comment
1626  assert_equal(2, g:entered)
1627
1628  assert_fails('doautocmd Syntax#comment', 'E216:')
1629
1630  au! TabEnter
1631  unlet g:entered
1632
1633  CheckScriptSuccess([
1634      'vim9script',
1635      'let g:var = 123',
1636      'let w:var = 777',
1637      'unlet g:var w:var # something',
1638      ])
1639
1640  CheckScriptFailure([
1641      'vim9script',
1642      'let g:var = 123',
1643      'unlet g:var# comment1',
1644      ], 'E108:')
1645
1646  CheckScriptFailure([
1647      'let g:var = 123',
1648      'unlet g:var # something',
1649      ], 'E488:')
1650
1651  CheckScriptSuccess([
1652      'vim9script',
1653      'if 1 # comment2',
1654      '  echo "yes"',
1655      'elseif 2 #comment',
1656      '  echo "no"',
1657      'endif',
1658      ])
1659
1660  CheckScriptFailure([
1661      'vim9script',
1662      'if 1# comment3',
1663      '  echo "yes"',
1664      'endif',
1665      ], 'E15:')
1666
1667  CheckScriptFailure([
1668      'vim9script',
1669      'if 0 # comment4',
1670      '  echo "yes"',
1671      'elseif 2#comment',
1672      '  echo "no"',
1673      'endif',
1674      ], 'E15:')
1675
1676  CheckScriptSuccess([
1677      'vim9script',
1678      'let v = 1 # comment5',
1679      ])
1680
1681  CheckScriptFailure([
1682      'vim9script',
1683      'let v = 1# comment6',
1684      ], 'E15:')
1685
1686  CheckScriptFailure([
1687      'vim9script',
1688      'let v:version',
1689      ], 'E1091:')
1690
1691  CheckScriptSuccess([
1692      'vim9script',
1693      'new'
1694      'call setline(1, ["# define pat", "last"])',
1695      '$',
1696      'dsearch /pat/ #comment',
1697      'bwipe!',
1698      ])
1699
1700  CheckScriptFailure([
1701      'vim9script',
1702      'new'
1703      'call setline(1, ["# define pat", "last"])',
1704      '$',
1705      'dsearch /pat/#comment',
1706      'bwipe!',
1707      ], 'E488:')
1708enddef
1709
1710def Test_finish()
1711  let lines =<< trim END
1712    vim9script
1713    let g:res = 'one'
1714    if v:false | finish | endif
1715    let g:res = 'two'
1716    finish
1717    let g:res = 'three'
1718  END
1719  writefile(lines, 'Xfinished')
1720  source Xfinished
1721  assert_equal('two', g:res)
1722
1723  unlet g:res
1724  delete('Xfinished')
1725enddef
1726
1727def Test_let_func_call()
1728  let lines =<< trim END
1729    vim9script
1730    func GetValue()
1731      if exists('g:count')
1732        let g:count += 1
1733      else
1734        let g:count = 1
1735      endif
1736      return 'this'
1737    endfunc
1738    let val: string = GetValue()
1739    " env var is always a string
1740    let env = $TERM
1741  END
1742  writefile(lines, 'Xfinished')
1743  source Xfinished
1744  " GetValue() is not called during discovery phase
1745  assert_equal(1, g:count)
1746
1747  unlet g:count
1748  delete('Xfinished')
1749enddef
1750
1751def Test_let_missing_type()
1752  let lines =<< trim END
1753    vim9script
1754    func GetValue()
1755      return 'this'
1756    endfunc
1757    let val = GetValue()
1758  END
1759  CheckScriptFailure(lines, 'E1091:')
1760
1761  lines =<< trim END
1762    vim9script
1763    func GetValue()
1764      return 'this'
1765    endfunc
1766    let val = [GetValue()]
1767  END
1768  CheckScriptFailure(lines, 'E1091:')
1769
1770  lines =<< trim END
1771    vim9script
1772    func GetValue()
1773      return 'this'
1774    endfunc
1775    let val = {GetValue(): 123}
1776  END
1777  CheckScriptFailure(lines, 'E1091:')
1778
1779  lines =<< trim END
1780    vim9script
1781    func GetValue()
1782      return 'this'
1783    endfunc
1784    let val = {'a': GetValue()}
1785  END
1786  CheckScriptFailure(lines, 'E1091:')
1787
1788  lines =<< trim END
1789    vim9script
1790    let var = g:unknown
1791  END
1792  CheckScriptFailure(lines, 'E1091:')
1793
1794  " TODO: eventually this would work
1795  lines =<< trim END
1796    vim9script
1797    let var = has('eval')
1798  END
1799  CheckScriptFailure(lines, 'E1091:')
1800
1801  " TODO: eventually this would work
1802  lines =<< trim END
1803    vim9script
1804    let var = len('string')
1805  END
1806  CheckScriptFailure(lines, 'E1091:')
1807
1808  lines =<< trim END
1809    vim9script
1810    let nr: number = 123
1811    let var = nr
1812  END
1813  CheckScriptFailure(lines, 'E1091:')
1814enddef
1815
1816def Test_forward_declaration()
1817  let lines =<< trim END
1818    vim9script
1819    g:initVal = GetValue()
1820    def GetValue(): string
1821      return theVal
1822    enddef
1823    let theVal = 'something'
1824    theVal = 'else'
1825    g:laterVal = GetValue()
1826  END
1827  writefile(lines, 'Xforward')
1828  source Xforward
1829  assert_equal('something', g:initVal)
1830  assert_equal('else', g:laterVal)
1831
1832  unlet g:initVal
1833  unlet g:laterVal
1834  delete('Xforward')
1835enddef
1836
1837
1838" Keep this last, it messes up highlighting.
1839def Test_substitute_cmd()
1840  new
1841  setline(1, 'something')
1842  :substitute(some(other(
1843  assert_equal('otherthing', getline(1))
1844  bwipe!
1845
1846  " also when the context is Vim9 script
1847  let lines =<< trim END
1848    vim9script
1849    new
1850    setline(1, 'something')
1851    :substitute(some(other(
1852    assert_equal('otherthing', getline(1))
1853    bwipe!
1854  END
1855  writefile(lines, 'Xvim9lines')
1856  source Xvim9lines
1857
1858  delete('Xvim9lines')
1859enddef
1860
1861" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
1862