blob: 0e18e4a1b6c98230785cc1cff09a7868c95af7fe [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
43 " TODO: does not work yet
44 " let listS: list<string> = []
45 " let listN: list<number> = []
46
47 let dict1: dict<string> = #{key: 'value'}
48 let dict2: dict<number> = #{one: 1, two: 2}
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010049
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010050 g:newvar = 'new'
51 assert_equal('new', g:newvar)
52
53 assert_equal('yes', g:existing)
54 g:existing = 'no'
55 assert_equal('no', g:existing)
56
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010057 v:char = 'abc'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010058 assert_equal('abc', v:char)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010059
60 $ENVVAR = 'foobar'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010061 assert_equal('foobar', $ENVVAR)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010062 $ENVVAR = ''
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010063
64 appendToMe ..= 'yyy'
65 assert_equal('xxxyyy', appendToMe)
66 addToMe += 222
67 assert_equal(333, addToMe)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010068enddef
69
70func Test_assignment_failure()
71 call CheckDefFailure(['let var=234'], 'E1004:')
72 call CheckDefFailure(['let var =234'], 'E1004:')
73 call CheckDefFailure(['let var= 234'], 'E1004:')
74
75 call CheckDefFailure(['let true = 1'], 'E1034:')
76 call CheckDefFailure(['let false = 1'], 'E1034:')
77
78 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
79 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
80
81 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
82 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
83
84 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
85 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
86endfunc
87
88func Test_const()
89 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
90 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
91 call CheckDefFailure(['const two'], 'E1021:')
92endfunc
93
94def Test_block()
95 let outer = 1
96 {
97 let inner = 2
98 assert_equal(1, outer)
99 assert_equal(2, inner)
100 }
101 assert_equal(1, outer)
102enddef
103
104func Test_block_failure()
105 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
106endfunc
107
108def ReturnString(): string
109 return 'string'
110enddef
111
112def ReturnNumber(): number
113 return 123
114enddef
115
116def Test_return_string()
117 assert_equal('string', ReturnString())
118 assert_equal(123, ReturnNumber())
119enddef
120
121func Increment()
122 let g:counter += 1
123endfunc
124
125def Test_call_ufunc_count()
126 g:counter = 1
127 Increment()
128 Increment()
129 Increment()
130 " works with and without :call
131 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100132 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100133 unlet g:counter
134enddef
135
136def MyVarargs(arg: string, ...rest: list<string>): string
137 let res = arg
138 for s in rest
139 res ..= ',' .. s
140 endfor
141 return res
142enddef
143
144def Test_call_varargs()
145 assert_equal('one', MyVarargs('one'))
146 assert_equal('one,two', MyVarargs('one', 'two'))
147 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
148enddef
149
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100150def MyDefaultArgs(name = 'string'): string
151 return name
152enddef
153
154def Test_call_default_args()
155 assert_equal('string', MyDefaultArgs())
156 assert_equal('one', MyDefaultArgs('one'))
157 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
158enddef
159
160func Test_call_default_args_from_func()
161 call assert_equal('string', MyDefaultArgs())
162 call assert_equal('one', MyDefaultArgs('one'))
163 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
164endfunc
165
166" Default arg and varargs
167def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
168 let res = one .. ',' .. two
169 for s in rest
170 res ..= ',' .. s
171 endfor
172 return res
173enddef
174
175def Test_call_def_varargs()
176 call assert_fails('call MyDefVarargs()', 'E119:')
177 assert_equal('one,foo', MyDefVarargs('one'))
178 assert_equal('one,two', MyDefVarargs('one', 'two'))
179 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
180enddef
181
182
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100183"def Test_call_func_defined_later()
184" call assert_equal('one', DefineLater('one'))
185" call assert_fails('call NotDefined("one")', 'E99:')
186"enddef
187
188func DefineLater(arg)
189 return a:arg
190endfunc
191
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100192def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100193 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
194 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
195 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
196 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100197enddef
198
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100199def Test_arg_type_wrong()
200 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
201enddef
202
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100203def Test_try_catch()
204 let l = []
205 try
206 add(l, '1')
207 throw 'wrong'
208 add(l, '2')
209 catch
210 add(l, v:exception)
211 finally
212 add(l, '3')
213 endtry
214 assert_equal(['1', 'wrong', '3'], l)
215enddef
216
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100217def ThrowFromDef()
218 throw 'getout'
219enddef
220
221func CatchInFunc()
222 try
223 call ThrowFromDef()
224 catch
225 let g:thrown_func = v:exception
226 endtry
227endfunc
228
229def CatchInDef()
230 try
231 ThrowFromDef()
232 catch
233 g:thrown_def = v:exception
234 endtry
235enddef
236
237def Test_try_catch_nested()
238 CatchInFunc()
239 assert_equal('getout', g:thrown_func)
240
241 CatchInDef()
242 assert_equal('getout', g:thrown_def)
243enddef
244
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100245let s:export_script_lines =<< trim END
246 vim9script
247 let name: string = 'bob'
248 def Concat(arg: string): string
249 return name .. arg
250 enddef
251 let g:result = Concat('bie')
252 let g:localname = name
253
254 export const CONST = 1234
255 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100256 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100257 export def Exported(): string
258 return 'Exported'
259 enddef
260END
261
262def Test_vim9script()
263 let import_script_lines =<< trim END
264 vim9script
265 import {exported, Exported} from './Xexport.vim'
266 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100267 exported += 3
268 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100269 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100270
271 import {exp_name} from './Xexport.vim'
272 g:imported_name = exp_name
273 exp_name ..= ' Doe'
274 g:imported_name_appended = exp_name
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100275 END
276
277 writefile(import_script_lines, 'Ximport.vim')
278 writefile(s:export_script_lines, 'Xexport.vim')
279
280 source Ximport.vim
281
282 assert_equal('bobbie', g:result)
283 assert_equal('bob', g:localname)
284 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100285 assert_equal(9879, g:imported_added)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100286 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100287 assert_equal('John', g:imported_name)
288 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100289 assert_false(exists('g:name'))
290
291 unlet g:result
292 unlet g:localname
293 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100294 unlet g:imported_added
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100295 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100296 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100297 delete('Ximport.vim')
298 delete('Xexport.vim')
299
300 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
301 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
302enddef
303
304def Test_vim9script_call()
305 let lines =<< trim END
306 vim9script
307 let var = ''
308 def MyFunc(arg: string)
309 var = arg
310 enddef
311 MyFunc('foobar')
312 assert_equal('foobar', var)
313
314 let str = 'barfoo'
315 str->MyFunc()
316 assert_equal('barfoo', var)
317
318 let g:value = 'value'
319 g:value->MyFunc()
320 assert_equal('value', var)
321
322 let listvar = []
323 def ListFunc(arg: list<number>)
324 listvar = arg
325 enddef
326 [1, 2, 3]->ListFunc()
327 assert_equal([1, 2, 3], listvar)
328
329 let dictvar = {}
330 def DictFunc(arg: dict<number>)
331 dictvar = arg
332 enddef
333 {'a': 1, 'b': 2}->DictFunc()
334 assert_equal(#{a: 1, b: 2}, dictvar)
335 #{a: 3, b: 4}->DictFunc()
336 assert_equal(#{a: 3, b: 4}, dictvar)
337 END
338 writefile(lines, 'Xcall.vim')
339 source Xcall.vim
340 delete('Xcall.vim')
341enddef
342
343def Test_vim9script_call_fail_decl()
344 let lines =<< trim END
345 vim9script
346 let var = ''
347 def MyFunc(arg: string)
348 let var = 123
349 enddef
350 END
351 writefile(lines, 'Xcall_decl.vim')
352 assert_fails('source Xcall_decl.vim', 'E1054:')
353 delete('Xcall_decl.vim')
354enddef
355
356def Test_vim9script_call_fail_const()
357 let lines =<< trim END
358 vim9script
359 const var = ''
360 def MyFunc(arg: string)
361 var = 'asdf'
362 enddef
363 END
364 writefile(lines, 'Xcall_const.vim')
365 assert_fails('source Xcall_const.vim', 'E46:')
366 delete('Xcall_const.vim')
367enddef
368
369def Test_vim9script_reload()
370 let lines =<< trim END
371 vim9script
372 const var = ''
373 let valone = 1234
374 def MyFunc(arg: string)
375 valone = 5678
376 enddef
377 END
378 let morelines =<< trim END
379 let valtwo = 222
380 export def GetValtwo(): number
381 return valtwo
382 enddef
383 END
384 writefile(lines + morelines, 'Xreload.vim')
385 source Xreload.vim
386 source Xreload.vim
387 source Xreload.vim
388
389 let testlines =<< trim END
390 vim9script
391 def TheFunc()
392 import GetValtwo from './Xreload.vim'
393 assert_equal(222, GetValtwo())
394 enddef
395 TheFunc()
396 END
397 writefile(testlines, 'Ximport.vim')
398 source Ximport.vim
399
400 " test that when not using "morelines" valtwo is still defined
401 " need to source Xreload.vim again, import doesn't reload a script
402 writefile(lines, 'Xreload.vim')
403 source Xreload.vim
404 source Ximport.vim
405
406 " cannot declare a var twice
407 lines =<< trim END
408 vim9script
409 let valone = 1234
410 let valone = 5678
411 END
412 writefile(lines, 'Xreload.vim')
413 assert_fails('source Xreload.vim', 'E1041:')
414
415 delete('Xreload.vim')
416 delete('Ximport.vim')
417enddef
418
419def Test_import_absolute()
420 let import_lines = [
421 \ 'vim9script',
422 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100423 \ 'def UseExported()',
424 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100425 \ ' exported = 8888',
426 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100427 \ 'enddef',
428 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100429 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100430 \ ]
431 writefile(import_lines, 'Ximport_abs.vim')
432 writefile(s:export_script_lines, 'Xexport_abs.vim')
433
434 source Ximport_abs.vim
435
436 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100437 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100438 assert_match('<SNR>\d\+_UseExported.*'
439 \ .. 'g:imported_abs = exported.*'
440 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100441 \ .. '1 STOREG g:imported_abs.*'
442 \ .. 'exported = 8888.*'
443 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
444 \ .. 'g:imported_after = exported.*'
445 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
446 \ .. '5 STOREG g:imported_after.*'
447 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100448 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100449 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100450
451 delete('Ximport_abs.vim')
452 delete('Xexport_abs.vim')
453enddef
454
455def Test_import_rtp()
456 let import_lines = [
457 \ 'vim9script',
458 \ 'import exported from "Xexport_rtp.vim"',
459 \ 'g:imported_rtp = exported',
460 \ ]
461 writefile(import_lines, 'Ximport_rtp.vim')
462 mkdir('import')
463 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
464
465 let save_rtp = &rtp
466 &rtp = getcwd()
467 source Ximport_rtp.vim
468 &rtp = save_rtp
469
470 assert_equal(9876, g:imported_rtp)
471 unlet g:imported_rtp
472
473 delete('Ximport_rtp.vim')
474 delete('import/Xexport_rtp.vim')
475 delete('import', 'd')
476enddef
477
478def Test_fixed_size_list()
479 " will be allocated as one piece of memory, check that changes work
480 let l = [1, 2, 3, 4]
481 l->remove(0)
482 l->add(5)
483 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100484 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100485enddef
486
Bram Moolenaar673660a2020-01-26 16:50:05 +0100487" Test that inside :function a Python function can be defined, :def is not
488" recognized.
489func Test_function_python()
490 CheckFeature python3
491 let py = 'python3'
492 execute py "<< EOF"
493def do_something():
494 return 1
495EOF
496endfunc
497
Bram Moolenaar158906c2020-02-06 20:39:45 +0100498def IfElse(what: number): string
499 let res = ''
500 if what == 1
501 res = "one"
502 elseif what == 2
503 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100504 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100505 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100506 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100507 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100508enddef
509
Bram Moolenaar158906c2020-02-06 20:39:45 +0100510def Test_if_elseif_else()
511 assert_equal('one', IfElse(1))
512 assert_equal('two', IfElse(2))
513 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100514enddef
515
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100516def Test_delfunc()
517 let lines =<< trim END
518 vim9script
519 def GoneSoon()
520 echo 'hello'
521 enddef
522
523 def CallGoneSoon()
524 GoneSoon()
525 enddef
526
527 delfunc GoneSoon
528 CallGoneSoon()
529 END
530 writefile(lines, 'XToDelFunc')
531 assert_fails('so XToDelFunc', 'E933')
532 assert_fails('so XToDelFunc', 'E933')
533
534 delete('XToDelFunc')
535enddef
536
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100537
538" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker