1" Test various aspects of the Vim9 script language.
2
3source check.vim
4source view_util.vim
5
6" Check that "lines" inside ":def" results in an "error" message.
7func CheckDefFailure(lines, error)
8  call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef')
9  call assert_fails('so Xdef', a:error, a:lines)
10  call delete('Xdef')
11endfunc
12
13func CheckScriptFailure(lines, error)
14  call writefile(a:lines, 'Xdef')
15  call assert_fails('so Xdef', a:error, a:lines)
16  call delete('Xdef')
17endfunc
18
19def Test_syntax()
20  let var = 234
21  let other: list<string> = ['asdf']
22enddef
23
24func Test_def_basic()
25  def SomeFunc(): string
26    return 'yes'
27  enddef
28  call assert_equal('yes', SomeFunc())
29endfunc
30
31let s:appendToMe = 'xxx'
32let s:addToMe = 111
33let g:existing = 'yes'
34
35def Test_assignment()
36  let bool1: bool = true
37  assert_equal(v:true, bool1)
38  let bool2: bool = false
39  assert_equal(v:false, bool2)
40
41  let list1: list<bool> = [false, true, false]
42  let list2: list<number> = [1, 2, 3]
43  let list3: list<string> = ['sdf', 'asdf']
44  let list4: list<any> = ['yes', true, 1234]
45  let list5: list<blob> = [0z01, 0z02]
46
47  let listS: list<string> = []
48  let listN: list<number> = []
49
50  let dict1: dict<bool> = #{one: false, two: true}
51  let dict2: dict<number> = #{one: 1, two: 2}
52  let dict3: dict<string> = #{key: 'value'}
53  let dict4: dict<any> = #{one: 1, two: '2'}
54  let dict5: dict<blob> = #{one: 0z01, tw: 0z02}
55
56  if has('channel')
57    let chan1: channel
58    let job1: job
59    let job2: job = job_start('willfail')
60  endif
61  if has('float')
62    let float1: float = 3.4
63  endif
64  let funky1: func
65  let funky2: func = function('len')
66  let party1: partial
67  let party2: partial = funcref('Test_syntax')
68
69  " type becomes list<any>
70  let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
71  " type becomes dict<any>
72  let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
73
74  g:newvar = 'new'
75  assert_equal('new', g:newvar)
76
77  assert_equal('yes', g:existing)
78  g:existing = 'no'
79  assert_equal('no', g:existing)
80
81  v:char = 'abc'
82  assert_equal('abc', v:char)
83
84  $ENVVAR = 'foobar'
85  assert_equal('foobar', $ENVVAR)
86  $ENVVAR = ''
87
88  s:appendToMe ..= 'yyy'
89  assert_equal('xxxyyy', s:appendToMe)
90  s:addToMe += 222
91  assert_equal(333, s:addToMe)
92  s:newVar = 'new'
93  assert_equal('new', s:newVar)
94enddef
95
96func Test_assignment_failure()
97  call CheckDefFailure(['let var=234'], 'E1004:')
98  call CheckDefFailure(['let var =234'], 'E1004:')
99  call CheckDefFailure(['let var= 234'], 'E1004:')
100
101  call CheckDefFailure(['let true = 1'], 'E1034:')
102  call CheckDefFailure(['let false = 1'], 'E1034:')
103
104  call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
105  call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
106
107  call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
108  call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
109
110  call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
111  call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
112
113  call CheckDefFailure(['let var: dict <number>'], 'E1007:')
114  call CheckDefFailure(['let var: dict<number'], 'E1009:')
115
116  call CheckDefFailure(['let var: ally'], 'E1010:')
117  call CheckDefFailure(['let var: bram'], 'E1010:')
118  call CheckDefFailure(['let var: cathy'], 'E1010:')
119  call CheckDefFailure(['let var: dom'], 'E1010:')
120  call CheckDefFailure(['let var: freddy'], 'E1010:')
121  call CheckDefFailure(['let var: john'], 'E1010:')
122  call CheckDefFailure(['let var: larry'], 'E1010:')
123  call CheckDefFailure(['let var: ned'], 'E1010:')
124  call CheckDefFailure(['let var: pam'], 'E1010:')
125  call CheckDefFailure(['let var: sam'], 'E1010:')
126  call CheckDefFailure(['let var: vim'], 'E1010:')
127endfunc
128
129func Test_const()
130  call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
131  call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
132  call CheckDefFailure(['const two'], 'E1021:')
133endfunc
134
135def Test_block()
136  let outer = 1
137  {
138    let inner = 2
139    assert_equal(1, outer)
140    assert_equal(2, inner)
141  }
142  assert_equal(1, outer)
143enddef
144
145func Test_block_failure()
146  call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
147endfunc
148
149def ReturnString(): string
150  return 'string'
151enddef
152
153def ReturnNumber(): number
154  return 123
155enddef
156
157let g:notNumber = 'string'
158
159def ReturnGlobal(): number
160  return g:notNumber
161enddef
162
163def Test_return_string()
164  assert_equal('string', ReturnString())
165  assert_equal(123, ReturnNumber())
166  assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
167enddef
168
169func Increment()
170  let g:counter += 1
171endfunc
172
173def Test_call_ufunc_count()
174  g:counter = 1
175  Increment()
176  Increment()
177  Increment()
178  " works with and without :call
179  assert_equal(4, g:counter)
180  call assert_equal(4, g:counter)
181  unlet g:counter
182enddef
183
184def MyVarargs(arg: string, ...rest: list<string>): string
185  let res = arg
186  for s in rest
187    res ..= ',' .. s
188  endfor
189  return res
190enddef
191
192def Test_call_varargs()
193  assert_equal('one', MyVarargs('one'))
194  assert_equal('one,two', MyVarargs('one', 'two'))
195  assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
196enddef
197
198def MyDefaultArgs(name = 'string'): string
199  return name
200enddef
201
202def Test_call_default_args()
203  assert_equal('string', MyDefaultArgs())
204  assert_equal('one', MyDefaultArgs('one'))
205  assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
206enddef
207
208func Test_call_default_args_from_func()
209  call assert_equal('string', MyDefaultArgs())
210  call assert_equal('one', MyDefaultArgs('one'))
211  call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
212endfunc
213
214func TakesOneArg(arg)
215  echo a:arg
216endfunc
217
218def Test_call_wrong_arg_count()
219  call CheckDefFailure(['TakesOneArg()'], 'E119:')
220  call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
221enddef
222
223" Default arg and varargs
224def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
225  let res = one .. ',' .. two
226  for s in rest
227    res ..= ',' .. s
228  endfor
229  return res
230enddef
231
232def Test_call_def_varargs()
233  call assert_fails('call MyDefVarargs()', 'E119:')
234  assert_equal('one,foo', MyDefVarargs('one'))
235  assert_equal('one,two', MyDefVarargs('one', 'two'))
236  assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
237enddef
238
239def Test_using_var_as_arg()
240  call writefile(['def Func(x: number)',  'let x = 234', 'enddef'], 'Xdef')
241  call assert_fails('so Xdef', 'E1006:')
242  call delete('Xdef')
243enddef
244
245def Test_call_func_defined_later()
246  call assert_equal('one', DefinedLater('one'))
247  call assert_fails('call NotDefined("one")', 'E117:')
248enddef
249
250func DefinedLater(arg)
251  return a:arg
252endfunc
253
254def FuncWithForwardCall()
255  return DefinedEvenLater("yes")
256enddef
257
258def DefinedEvenLater(arg: string): string
259  return arg
260enddef
261
262def Test_error_in_nested_function()
263  " Error in called function requires unwinding the call stack.
264  assert_fails('call FuncWithForwardCall()', 'E1029')
265enddef
266
267def Test_return_type_wrong()
268  CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
269  CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
270  CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
271  CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
272enddef
273
274def Test_arg_type_wrong()
275  CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
276enddef
277
278def Test_try_catch()
279  let l = []
280  try
281    add(l, '1')
282    throw 'wrong'
283    add(l, '2')
284  catch
285    add(l, v:exception)
286  finally
287    add(l, '3')
288  endtry
289  assert_equal(['1', 'wrong', '3'], l)
290enddef
291
292def ThrowFromDef()
293  throw 'getout'
294enddef
295
296func CatchInFunc()
297  try
298    call ThrowFromDef()
299  catch
300    let g:thrown_func = v:exception
301  endtry
302endfunc
303
304def CatchInDef()
305  try
306    ThrowFromDef()
307  catch
308    g:thrown_def = v:exception
309  endtry
310enddef
311
312def ReturnFinally(): string
313  try
314    return 'intry'
315  finally
316    g:in_finally = 'finally'
317  endtry
318  return 'end'
319enddef
320
321def Test_try_catch_nested()
322  CatchInFunc()
323  assert_equal('getout', g:thrown_func)
324
325  CatchInDef()
326  assert_equal('getout', g:thrown_def)
327
328  assert_equal('intry', ReturnFinally())
329  assert_equal('finally', g:in_finally)
330enddef
331
332def Test_try_catch_match()
333  let seq = 'a'
334  try
335    throw 'something'
336  catch /nothing/
337    seq ..= 'x'
338  catch /some/
339    seq ..= 'b'
340  catch /asdf/
341    seq ..= 'x'
342  finally
343    seq ..= 'c'
344  endtry
345  assert_equal('abc', seq)
346enddef
347
348let s:export_script_lines =<< trim END
349  vim9script
350  let name: string = 'bob'
351  def Concat(arg: string): string
352    return name .. arg
353  enddef
354  let g:result = Concat('bie')
355  let g:localname = name
356
357  export const CONST = 1234
358  export let exported = 9876
359  export let exp_name = 'John'
360  export def Exported(): string
361    return 'Exported'
362  enddef
363END
364
365def Test_vim9_import_export()
366  let import_script_lines =<< trim END
367    vim9script
368    import {exported, Exported} from './Xexport.vim'
369    g:imported = exported
370    exported += 3
371    g:imported_added = exported
372    g:imported_func = Exported()
373
374    import {exp_name} from './Xexport.vim'
375    g:imported_name = exp_name
376    exp_name ..= ' Doe'
377    g:imported_name_appended = exp_name
378    g:imported_later = exported
379  END
380
381  writefile(import_script_lines, 'Ximport.vim')
382  writefile(s:export_script_lines, 'Xexport.vim')
383
384  source Ximport.vim
385
386  assert_equal('bobbie', g:result)
387  assert_equal('bob', g:localname)
388  assert_equal(9876, g:imported)
389  assert_equal(9879, g:imported_added)
390  assert_equal(9879, g:imported_later)
391  assert_equal('Exported', g:imported_func)
392  assert_equal('John', g:imported_name)
393  assert_equal('John Doe', g:imported_name_appended)
394  assert_false(exists('g:name'))
395
396  unlet g:result
397  unlet g:localname
398  unlet g:imported
399  unlet g:imported_added
400  unlet g:imported_later
401  unlet g:imported_func
402  unlet g:imported_name g:imported_name_appended
403  delete('Ximport.vim')
404
405  let import_in_def_lines =<< trim END
406    vim9script
407    def ImportInDef()
408      import exported from './Xexport.vim'
409      g:imported = exported
410      exported += 7
411      g:imported_added = exported
412    enddef
413    ImportInDef()
414  END
415  writefile(import_in_def_lines, 'Ximport2.vim')
416  source Ximport2.vim
417  " TODO: this should be 9879
418  assert_equal(9876, g:imported)
419  assert_equal(9883, g:imported_added)
420  unlet g:imported
421  unlet g:imported_added
422  delete('Ximport2.vim')
423
424  let import_star_as_lines =<< trim END
425    vim9script
426    import * as Export from './Xexport.vim'
427    def UseExport()
428      g:imported = Export.exported
429    enddef
430    UseExport()
431  END
432  writefile(import_star_as_lines, 'Ximport.vim')
433  source Ximport.vim
434  assert_equal(9883, g:imported)
435
436  let import_star_lines =<< trim END
437    vim9script
438    import * from './Xexport.vim'
439    g:imported = exported
440  END
441  writefile(import_star_lines, 'Ximport.vim')
442  assert_fails('source Ximport.vim', 'E1045:')
443
444  " try to import something that exists but is not exported
445  let import_not_exported_lines =<< trim END
446    vim9script
447    import name from './Xexport.vim'
448  END
449  writefile(import_not_exported_lines, 'Ximport.vim')
450  assert_fails('source Ximport.vim', 'E1049:')
451
452  " try to import something that is already defined
453  let import_already_defined =<< trim END
454    vim9script
455    let exported = 'something'
456    import exported from './Xexport.vim'
457  END
458  writefile(import_already_defined, 'Ximport.vim')
459  assert_fails('source Ximport.vim', 'E1073:')
460
461  " try to import something that is already defined
462  import_already_defined =<< trim END
463    vim9script
464    let exported = 'something'
465    import * as exported from './Xexport.vim'
466  END
467  writefile(import_already_defined, 'Ximport.vim')
468  assert_fails('source Ximport.vim', 'E1073:')
469
470  " try to import something that is already defined
471  import_already_defined =<< trim END
472    vim9script
473    let exported = 'something'
474    import {exported} from './Xexport.vim'
475  END
476  writefile(import_already_defined, 'Ximport.vim')
477  assert_fails('source Ximport.vim', 'E1073:')
478
479  " import a very long name, requires making a copy
480  let import_long_name_lines =<< trim END
481    vim9script
482    import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
483  END
484  writefile(import_long_name_lines, 'Ximport.vim')
485  assert_fails('source Ximport.vim', 'E1048:')
486
487  let import_no_from_lines =<< trim END
488    vim9script
489    import name './Xexport.vim'
490  END
491  writefile(import_no_from_lines, 'Ximport.vim')
492  assert_fails('source Ximport.vim', 'E1070:')
493
494  let import_invalid_string_lines =<< trim END
495    vim9script
496    import name from Xexport.vim
497  END
498  writefile(import_invalid_string_lines, 'Ximport.vim')
499  assert_fails('source Ximport.vim', 'E1071:')
500
501  let import_wrong_name_lines =<< trim END
502    vim9script
503    import name from './XnoExport.vim'
504  END
505  writefile(import_wrong_name_lines, 'Ximport.vim')
506  assert_fails('source Ximport.vim', 'E1053:')
507
508  let import_missing_comma_lines =<< trim END
509    vim9script
510    import {exported name} from './Xexport.vim'
511  END
512  writefile(import_missing_comma_lines, 'Ximport3.vim')
513  assert_fails('source Ximport3.vim', 'E1046:')
514
515  delete('Ximport.vim')
516  delete('Ximport3.vim')
517  delete('Xexport.vim')
518
519  " Check that in a Vim9 script 'cpo' is set to the Vim default.
520  set cpo&vi
521  let cpo_before = &cpo
522  let lines =<< trim END
523    vim9script
524    g:cpo_in_vim9script = &cpo
525  END
526  writefile(lines, 'Xvim9_script')
527  source Xvim9_script
528  assert_equal(cpo_before, &cpo)
529  set cpo&vim
530  assert_equal(&cpo, g:cpo_in_vim9script)
531  delete('Xvim9_script')
532enddef
533
534def Test_vim9script_fails()
535  CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
536  CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
537  CheckScriptFailure(['export let some = 123'], 'E1042:')
538  CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
539  CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
540  CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
541
542  assert_fails('vim9script', 'E1038')
543  assert_fails('export something', 'E1042')
544enddef
545
546def Test_vim9script_call()
547  let lines =<< trim END
548    vim9script
549    let var = ''
550    def MyFunc(arg: string)
551       var = arg
552    enddef
553    MyFunc('foobar')
554    assert_equal('foobar', var)
555
556    let str = 'barfoo'
557    str->MyFunc()
558    assert_equal('barfoo', var)
559
560    let g:value = 'value'
561    g:value->MyFunc()
562    assert_equal('value', var)
563
564    let listvar = []
565    def ListFunc(arg: list<number>)
566       listvar = arg
567    enddef
568    [1, 2, 3]->ListFunc()
569    assert_equal([1, 2, 3], listvar)
570
571    let dictvar = {}
572    def DictFunc(arg: dict<number>)
573       dictvar = arg
574    enddef
575    {'a': 1, 'b': 2}->DictFunc()
576    assert_equal(#{a: 1, b: 2}, dictvar)
577    #{a: 3, b: 4}->DictFunc()
578    assert_equal(#{a: 3, b: 4}, dictvar)
579
580    ('text')->MyFunc()
581    assert_equal('text', var)
582    ("some")->MyFunc()
583    assert_equal('some', var)
584  END
585  writefile(lines, 'Xcall.vim')
586  source Xcall.vim
587  delete('Xcall.vim')
588enddef
589
590def Test_vim9script_call_fail_decl()
591  let lines =<< trim END
592    vim9script
593    let var = ''
594    def MyFunc(arg: string)
595       let var = 123
596    enddef
597  END
598  writefile(lines, 'Xcall_decl.vim')
599  assert_fails('source Xcall_decl.vim', 'E1054:')
600  delete('Xcall_decl.vim')
601enddef
602
603def Test_vim9script_call_fail_const()
604  let lines =<< trim END
605    vim9script
606    const var = ''
607    def MyFunc(arg: string)
608       var = 'asdf'
609    enddef
610  END
611  writefile(lines, 'Xcall_const.vim')
612  assert_fails('source Xcall_const.vim', 'E46:')
613  delete('Xcall_const.vim')
614enddef
615
616def Test_vim9script_reload()
617  let lines =<< trim END
618    vim9script
619    const var = ''
620    let valone = 1234
621    def MyFunc(arg: string)
622       valone = 5678
623    enddef
624  END
625  let morelines =<< trim END
626    let valtwo = 222
627    export def GetValtwo(): number
628      return valtwo
629    enddef
630  END
631  writefile(lines + morelines, 'Xreload.vim')
632  source Xreload.vim
633  source Xreload.vim
634  source Xreload.vim
635
636  let testlines =<< trim END
637    vim9script
638    def TheFunc()
639      import GetValtwo from './Xreload.vim'
640      assert_equal(222, GetValtwo())
641    enddef
642    TheFunc()
643  END
644  writefile(testlines, 'Ximport.vim')
645  source Ximport.vim
646
647  " test that when not using "morelines" valtwo is still defined
648  " need to source Xreload.vim again, import doesn't reload a script
649  writefile(lines, 'Xreload.vim')
650  source Xreload.vim
651  source Ximport.vim
652
653  " cannot declare a var twice
654  lines =<< trim END
655    vim9script
656    let valone = 1234
657    let valone = 5678
658  END
659  writefile(lines, 'Xreload.vim')
660  assert_fails('source Xreload.vim', 'E1041:')
661
662  delete('Xreload.vim')
663  delete('Ximport.vim')
664enddef
665
666def Test_import_absolute()
667  let import_lines = [
668        \ 'vim9script',
669        \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
670        \ 'def UseExported()',
671        \ '  g:imported_abs = exported',
672        \ '  exported = 8888',
673        \ '  g:imported_after = exported',
674        \ 'enddef',
675        \ 'UseExported()',
676        \ 'g:import_disassembled = execute("disass UseExported")',
677        \ ]
678  writefile(import_lines, 'Ximport_abs.vim')
679  writefile(s:export_script_lines, 'Xexport_abs.vim')
680
681  source Ximport_abs.vim
682
683  assert_equal(9876, g:imported_abs)
684  assert_equal(8888, g:imported_after)
685  assert_match('<SNR>\d\+_UseExported.*'
686        \ .. 'g:imported_abs = exported.*'
687        \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
688        \ .. '1 STOREG g:imported_abs.*'
689        \ .. 'exported = 8888.*'
690        \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
691        \ .. 'g:imported_after = exported.*'
692        \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
693        \ .. '5 STOREG g:imported_after.*'
694        \, g:import_disassembled)
695  unlet g:imported_abs
696  unlet g:import_disassembled
697
698  delete('Ximport_abs.vim')
699  delete('Xexport_abs.vim')
700enddef
701
702def Test_import_rtp()
703  let import_lines = [
704        \ 'vim9script',
705        \ 'import exported from "Xexport_rtp.vim"',
706        \ 'g:imported_rtp = exported',
707        \ ]
708  writefile(import_lines, 'Ximport_rtp.vim')
709  mkdir('import')
710  writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
711
712  let save_rtp = &rtp
713  &rtp = getcwd()
714  source Ximport_rtp.vim
715  &rtp = save_rtp
716
717  assert_equal(9876, g:imported_rtp)
718  unlet g:imported_rtp
719
720  delete('Ximport_rtp.vim')
721  delete('import/Xexport_rtp.vim')
722  delete('import', 'd')
723enddef
724
725def Test_fixed_size_list()
726  " will be allocated as one piece of memory, check that changes work
727  let l = [1, 2, 3, 4]
728  l->remove(0)
729  l->add(5)
730  l->insert(99, 1)
731  assert_equal([2, 99, 3, 4, 5], l)
732enddef
733
734" Test that inside :function a Python function can be defined, :def is not
735" recognized.
736func Test_function_python()
737  CheckFeature python3
738  let py = 'python3'
739  execute py "<< EOF"
740def do_something():
741  return 1
742EOF
743endfunc
744
745def IfElse(what: number): string
746  let res = ''
747  if what == 1
748    res = "one"
749  elseif what == 2
750    res = "two"
751  else
752    res = "three"
753  endif
754  return res
755enddef
756
757def Test_if_elseif_else()
758  assert_equal('one', IfElse(1))
759  assert_equal('two', IfElse(2))
760  assert_equal('three', IfElse(3))
761enddef
762
763let g:bool_true = v:true
764let g:bool_false = v:false
765
766def Test_if_const_expr()
767  let res = false
768  if true ? true : false
769    res = true
770  endif
771  assert_equal(true, res)
772
773  res = false
774  if g:bool_true ? true : false
775    res = true
776  endif
777  assert_equal(true, res)
778
779  res = false
780  if true ? g:bool_true : false
781    res = true
782  endif
783  assert_equal(true, res)
784
785  res = false
786  if true ? true : g:bool_false
787    res = true
788  endif
789  assert_equal(true, res)
790
791  res = false
792  if true ? false : true
793    res = true
794  endif
795  assert_equal(false, res)
796
797  res = false
798  if false ? false : true
799    res = true
800  endif
801  assert_equal(true, res)
802
803  res = false
804  if false ? true : false
805    res = true
806  endif
807  assert_equal(false, res)
808
809  res = false
810  if true && true
811    res = true
812  endif
813  assert_equal(true, res)
814
815  res = false
816  if true && false
817    res = true
818  endif
819  assert_equal(false, res)
820
821  res = false
822  if g:bool_true && false
823    res = true
824  endif
825  assert_equal(false, res)
826
827  res = false
828  if true && g:bool_false
829    res = true
830  endif
831  assert_equal(false, res)
832
833  res = false
834  if false && false
835    res = true
836  endif
837  assert_equal(false, res)
838
839  res = false
840  if true || false
841    res = true
842  endif
843  assert_equal(true, res)
844
845  res = false
846  if g:bool_true || false
847    res = true
848  endif
849  assert_equal(true, res)
850
851  res = false
852  if true || g:bool_false
853    res = true
854  endif
855  assert_equal(true, res)
856
857  res = false
858  if false || false
859    res = true
860  endif
861  assert_equal(false, res)
862
863enddef
864
865def Test_delfunc()
866  let lines =<< trim END
867    vim9script
868    def GoneSoon()
869      echo 'hello'
870    enddef
871
872    def CallGoneSoon()
873      GoneSoon()
874    enddef
875
876    delfunc GoneSoon
877    CallGoneSoon()
878  END
879  writefile(lines, 'XToDelFunc')
880  assert_fails('so XToDelFunc', 'E933')
881  assert_fails('so XToDelFunc', 'E933')
882
883  delete('XToDelFunc')
884enddef
885
886def Test_execute_cmd()
887  new
888  setline(1, 'default')
889  execute 'call setline(1, "execute-string")'
890  assert_equal('execute-string', getline(1))
891  let cmd1 = 'call setline(1,'
892  let cmd2 = '"execute-var")'
893  execute cmd1 cmd2
894  assert_equal('execute-var', getline(1))
895  execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
896  assert_equal('execute-var-string', getline(1))
897  let cmd_first = 'call '
898  let cmd_last = 'setline(1, "execute-var-var")'
899  execute cmd_first .. cmd_last
900  assert_equal('execute-var-var', getline(1))
901  bwipe!
902enddef
903
904def Test_echo_cmd()
905  echo 'something'
906  assert_match('^something$', Screenline(&lines))
907
908  let str1 = 'some'
909  let str2 = 'more'
910  echo str1 str2
911  assert_match('^some more$', Screenline(&lines))
912enddef
913
914def Test_for_outside_of_function()
915  let lines =<< trim END
916    vim9script
917    new
918    for var in range(0, 3)
919      append(line('$'), var)
920    endfor
921    assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
922    bwipe!
923  END
924  writefile(lines, 'Xvim9for.vim')
925  source Xvim9for.vim
926  delete('Xvim9for.vim')
927enddef
928
929def Test_while_loop()
930  let result = ''
931  let cnt = 0
932  while cnt < 555
933    if cnt == 3
934      break
935    endif
936    cnt += 1
937    if cnt == 2
938      continue
939    endif
940    result ..= cnt .. '_'
941  endwhile
942  assert_equal('1_3_', result)
943enddef
944
945def Test_substitute_cmd()
946  new
947  setline(1, 'something')
948  :substitute(some(other(
949  assert_equal('otherthing', getline(1))
950  bwipe!
951
952  " also when the context is Vim9 script
953  let lines =<< trim END
954    vim9script
955    new
956    setline(1, 'something')
957    :substitute(some(other(
958    assert_equal('otherthing', getline(1))
959    bwipe!
960  END
961  writefile(lines, 'Xvim9lines')
962  source Xvim9lines
963
964  delete('Xvim9lines')
965enddef
966
967" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
968