blob: 6ae4273b90da8576627a2f29065ccfc02cfad420 [file] [log] [blame]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001" Test various aspects of the Vim9 script language.
2
Bram Moolenaar673660a2020-01-26 16:50:05 +01003source check.vim
4
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005" Check that "lines" inside ":def" results in an "error" message.
6func CheckDefFailure(lines, error)
Bram Moolenaar978d1702020-01-26 17:38:12 +01007 call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01008 call assert_fails('so Xdef', a:error, a:lines)
9 call delete('Xdef')
10endfunc
11
12func CheckScriptFailure(lines, error)
13 call writefile(a:lines, 'Xdef')
14 call assert_fails('so Xdef', a:error, a:lines)
15 call delete('Xdef')
16endfunc
17
18def Test_syntax()
19 let var = 234
20 let other: list<string> = ['asdf']
21enddef
22
23func Test_def_basic()
24 def SomeFunc(): string
25 return 'yes'
26 enddef
27 call assert_equal('yes', SomeFunc())
28endfunc
29
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010030let s:appendToMe = 'xxx'
31let s:addToMe = 111
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010032let g:existing = 'yes'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010033
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010034def Test_assignment()
35 let bool1: bool = true
36 assert_equal(v:true, bool1)
37 let bool2: bool = false
38 assert_equal(v:false, bool2)
39
40 let list1: list<string> = ['sdf', 'asdf']
41 let list2: list<number> = [1, 2, 3]
42
Bram Moolenaar436472f2020-02-20 22:54:43 +010043 let listS: list<string> = []
44 let listN: list<number> = []
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010045
46 let dict1: dict<string> = #{key: 'value'}
47 let dict2: dict<number> = #{one: 1, two: 2}
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010048
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010049 g:newvar = 'new'
50 assert_equal('new', g:newvar)
51
52 assert_equal('yes', g:existing)
53 g:existing = 'no'
54 assert_equal('no', g:existing)
55
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010056 v:char = 'abc'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010057 assert_equal('abc', v:char)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010058
59 $ENVVAR = 'foobar'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010060 assert_equal('foobar', $ENVVAR)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010061 $ENVVAR = ''
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010062
Bram Moolenaarfd1823e2020-02-19 20:23:11 +010063 s:appendToMe ..= 'yyy'
64 assert_equal('xxxyyy', s:appendToMe)
65 s:addToMe += 222
66 assert_equal(333, s:addToMe)
Bram Moolenaar0bbf7222020-02-19 22:31:48 +010067 s:newVar = 'new'
68 assert_equal('new', s:newVar)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010069enddef
70
71func Test_assignment_failure()
72 call CheckDefFailure(['let var=234'], 'E1004:')
73 call CheckDefFailure(['let var =234'], 'E1004:')
74 call CheckDefFailure(['let var= 234'], 'E1004:')
75
76 call CheckDefFailure(['let true = 1'], 'E1034:')
77 call CheckDefFailure(['let false = 1'], 'E1034:')
78
79 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
80 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
81
82 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
83 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
84
85 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
86 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
87endfunc
88
89func Test_const()
90 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
91 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
92 call CheckDefFailure(['const two'], 'E1021:')
93endfunc
94
95def Test_block()
96 let outer = 1
97 {
98 let inner = 2
99 assert_equal(1, outer)
100 assert_equal(2, inner)
101 }
102 assert_equal(1, outer)
103enddef
104
105func Test_block_failure()
106 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
107endfunc
108
109def ReturnString(): string
110 return 'string'
111enddef
112
113def ReturnNumber(): number
114 return 123
115enddef
116
117def Test_return_string()
118 assert_equal('string', ReturnString())
119 assert_equal(123, ReturnNumber())
120enddef
121
122func Increment()
123 let g:counter += 1
124endfunc
125
126def Test_call_ufunc_count()
127 g:counter = 1
128 Increment()
129 Increment()
130 Increment()
131 " works with and without :call
132 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100133 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100134 unlet g:counter
135enddef
136
137def MyVarargs(arg: string, ...rest: list<string>): string
138 let res = arg
139 for s in rest
140 res ..= ',' .. s
141 endfor
142 return res
143enddef
144
145def Test_call_varargs()
146 assert_equal('one', MyVarargs('one'))
147 assert_equal('one,two', MyVarargs('one', 'two'))
148 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
149enddef
150
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100151def MyDefaultArgs(name = 'string'): string
152 return name
153enddef
154
155def Test_call_default_args()
156 assert_equal('string', MyDefaultArgs())
157 assert_equal('one', MyDefaultArgs('one'))
158 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
159enddef
160
161func Test_call_default_args_from_func()
162 call assert_equal('string', MyDefaultArgs())
163 call assert_equal('one', MyDefaultArgs('one'))
164 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
165endfunc
166
167" Default arg and varargs
168def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
169 let res = one .. ',' .. two
170 for s in rest
171 res ..= ',' .. s
172 endfor
173 return res
174enddef
175
176def Test_call_def_varargs()
177 call assert_fails('call MyDefVarargs()', 'E119:')
178 assert_equal('one,foo', MyDefVarargs('one'))
179 assert_equal('one,two', MyDefVarargs('one', 'two'))
180 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
181enddef
182
183
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100184"def Test_call_func_defined_later()
185" call assert_equal('one', DefineLater('one'))
186" call assert_fails('call NotDefined("one")', 'E99:')
187"enddef
188
189func DefineLater(arg)
190 return a:arg
191endfunc
192
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100193def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100194 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
195 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
196 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
197 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100198enddef
199
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100200def Test_arg_type_wrong()
201 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
202enddef
203
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100204def Test_try_catch()
205 let l = []
206 try
207 add(l, '1')
208 throw 'wrong'
209 add(l, '2')
210 catch
211 add(l, v:exception)
212 finally
213 add(l, '3')
214 endtry
215 assert_equal(['1', 'wrong', '3'], l)
216enddef
217
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100218def ThrowFromDef()
219 throw 'getout'
220enddef
221
222func CatchInFunc()
223 try
224 call ThrowFromDef()
225 catch
226 let g:thrown_func = v:exception
227 endtry
228endfunc
229
230def CatchInDef()
231 try
232 ThrowFromDef()
233 catch
234 g:thrown_def = v:exception
235 endtry
236enddef
237
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100238def ReturnFinally(): string
239 try
240 return 'intry'
241 finally
242 g:in_finally = 'finally'
243 endtry
244 return 'end'
245enddef
246
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100247def Test_try_catch_nested()
248 CatchInFunc()
249 assert_equal('getout', g:thrown_func)
250
251 CatchInDef()
252 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100253
254 assert_equal('intry', ReturnFinally())
255 assert_equal('finally', g:in_finally)
256enddef
257
258def Test_try_catch_match()
259 let seq = 'a'
260 try
261 throw 'something'
262 catch /nothing/
263 seq ..= 'x'
264 catch /some/
265 seq ..= 'b'
266 catch /asdf/
267 seq ..= 'x'
268 finally
269 seq ..= 'c'
270 endtry
271 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100272enddef
273
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100274let s:export_script_lines =<< trim END
275 vim9script
276 let name: string = 'bob'
277 def Concat(arg: string): string
278 return name .. arg
279 enddef
280 let g:result = Concat('bie')
281 let g:localname = name
282
283 export const CONST = 1234
284 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100285 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100286 export def Exported(): string
287 return 'Exported'
288 enddef
289END
290
291def Test_vim9script()
292 let import_script_lines =<< trim END
293 vim9script
294 import {exported, Exported} from './Xexport.vim'
295 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100296 exported += 3
297 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100298 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100299
300 import {exp_name} from './Xexport.vim'
301 g:imported_name = exp_name
302 exp_name ..= ' Doe'
303 g:imported_name_appended = exp_name
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100304 END
305
306 writefile(import_script_lines, 'Ximport.vim')
307 writefile(s:export_script_lines, 'Xexport.vim')
308
309 source Ximport.vim
310
311 assert_equal('bobbie', g:result)
312 assert_equal('bob', g:localname)
313 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100314 assert_equal(9879, g:imported_added)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100315 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100316 assert_equal('John', g:imported_name)
317 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100318 assert_false(exists('g:name'))
319
320 unlet g:result
321 unlet g:localname
322 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100323 unlet g:imported_added
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100324 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100325 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100326 delete('Ximport.vim')
327 delete('Xexport.vim')
328
329 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
330 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
331enddef
332
333def Test_vim9script_call()
334 let lines =<< trim END
335 vim9script
336 let var = ''
337 def MyFunc(arg: string)
338 var = arg
339 enddef
340 MyFunc('foobar')
341 assert_equal('foobar', var)
342
343 let str = 'barfoo'
344 str->MyFunc()
345 assert_equal('barfoo', var)
346
347 let g:value = 'value'
348 g:value->MyFunc()
349 assert_equal('value', var)
350
351 let listvar = []
352 def ListFunc(arg: list<number>)
353 listvar = arg
354 enddef
355 [1, 2, 3]->ListFunc()
356 assert_equal([1, 2, 3], listvar)
357
358 let dictvar = {}
359 def DictFunc(arg: dict<number>)
360 dictvar = arg
361 enddef
362 {'a': 1, 'b': 2}->DictFunc()
363 assert_equal(#{a: 1, b: 2}, dictvar)
364 #{a: 3, b: 4}->DictFunc()
365 assert_equal(#{a: 3, b: 4}, dictvar)
366 END
367 writefile(lines, 'Xcall.vim')
368 source Xcall.vim
369 delete('Xcall.vim')
370enddef
371
372def Test_vim9script_call_fail_decl()
373 let lines =<< trim END
374 vim9script
375 let var = ''
376 def MyFunc(arg: string)
377 let var = 123
378 enddef
379 END
380 writefile(lines, 'Xcall_decl.vim')
381 assert_fails('source Xcall_decl.vim', 'E1054:')
382 delete('Xcall_decl.vim')
383enddef
384
385def Test_vim9script_call_fail_const()
386 let lines =<< trim END
387 vim9script
388 const var = ''
389 def MyFunc(arg: string)
390 var = 'asdf'
391 enddef
392 END
393 writefile(lines, 'Xcall_const.vim')
394 assert_fails('source Xcall_const.vim', 'E46:')
395 delete('Xcall_const.vim')
396enddef
397
398def Test_vim9script_reload()
399 let lines =<< trim END
400 vim9script
401 const var = ''
402 let valone = 1234
403 def MyFunc(arg: string)
404 valone = 5678
405 enddef
406 END
407 let morelines =<< trim END
408 let valtwo = 222
409 export def GetValtwo(): number
410 return valtwo
411 enddef
412 END
413 writefile(lines + morelines, 'Xreload.vim')
414 source Xreload.vim
415 source Xreload.vim
416 source Xreload.vim
417
418 let testlines =<< trim END
419 vim9script
420 def TheFunc()
421 import GetValtwo from './Xreload.vim'
422 assert_equal(222, GetValtwo())
423 enddef
424 TheFunc()
425 END
426 writefile(testlines, 'Ximport.vim')
427 source Ximport.vim
428
429 " test that when not using "morelines" valtwo is still defined
430 " need to source Xreload.vim again, import doesn't reload a script
431 writefile(lines, 'Xreload.vim')
432 source Xreload.vim
433 source Ximport.vim
434
435 " cannot declare a var twice
436 lines =<< trim END
437 vim9script
438 let valone = 1234
439 let valone = 5678
440 END
441 writefile(lines, 'Xreload.vim')
442 assert_fails('source Xreload.vim', 'E1041:')
443
444 delete('Xreload.vim')
445 delete('Ximport.vim')
446enddef
447
448def Test_import_absolute()
449 let import_lines = [
450 \ 'vim9script',
451 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100452 \ 'def UseExported()',
453 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100454 \ ' exported = 8888',
455 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100456 \ 'enddef',
457 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100458 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100459 \ ]
460 writefile(import_lines, 'Ximport_abs.vim')
461 writefile(s:export_script_lines, 'Xexport_abs.vim')
462
463 source Ximport_abs.vim
464
465 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100466 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100467 assert_match('<SNR>\d\+_UseExported.*'
468 \ .. 'g:imported_abs = exported.*'
469 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100470 \ .. '1 STOREG g:imported_abs.*'
471 \ .. 'exported = 8888.*'
472 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
473 \ .. 'g:imported_after = exported.*'
474 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
475 \ .. '5 STOREG g:imported_after.*'
476 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100477 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100478 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100479
480 delete('Ximport_abs.vim')
481 delete('Xexport_abs.vim')
482enddef
483
484def Test_import_rtp()
485 let import_lines = [
486 \ 'vim9script',
487 \ 'import exported from "Xexport_rtp.vim"',
488 \ 'g:imported_rtp = exported',
489 \ ]
490 writefile(import_lines, 'Ximport_rtp.vim')
491 mkdir('import')
492 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
493
494 let save_rtp = &rtp
495 &rtp = getcwd()
496 source Ximport_rtp.vim
497 &rtp = save_rtp
498
499 assert_equal(9876, g:imported_rtp)
500 unlet g:imported_rtp
501
502 delete('Ximport_rtp.vim')
503 delete('import/Xexport_rtp.vim')
504 delete('import', 'd')
505enddef
506
507def Test_fixed_size_list()
508 " will be allocated as one piece of memory, check that changes work
509 let l = [1, 2, 3, 4]
510 l->remove(0)
511 l->add(5)
512 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100513 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100514enddef
515
Bram Moolenaar673660a2020-01-26 16:50:05 +0100516" Test that inside :function a Python function can be defined, :def is not
517" recognized.
518func Test_function_python()
519 CheckFeature python3
520 let py = 'python3'
521 execute py "<< EOF"
522def do_something():
523 return 1
524EOF
525endfunc
526
Bram Moolenaar158906c2020-02-06 20:39:45 +0100527def IfElse(what: number): string
528 let res = ''
529 if what == 1
530 res = "one"
531 elseif what == 2
532 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100533 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100534 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100535 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100536 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100537enddef
538
Bram Moolenaar158906c2020-02-06 20:39:45 +0100539def Test_if_elseif_else()
540 assert_equal('one', IfElse(1))
541 assert_equal('two', IfElse(2))
542 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100543enddef
544
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100545def Test_delfunc()
546 let lines =<< trim END
547 vim9script
548 def GoneSoon()
549 echo 'hello'
550 enddef
551
552 def CallGoneSoon()
553 GoneSoon()
554 enddef
555
556 delfunc GoneSoon
557 CallGoneSoon()
558 END
559 writefile(lines, 'XToDelFunc')
560 assert_fails('so XToDelFunc', 'E933')
561 assert_fails('so XToDelFunc', 'E933')
562
563 delete('XToDelFunc')
564enddef
565
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100566
567" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker