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