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