blob: 558f23cb4718a1c6456c3e41c7d504e6f76d1f69 [file] [log] [blame]
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001" 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
19func Test_def_basic()
20 def SomeFunc(): string
21 return 'yes'
22 enddef
23 call assert_equal('yes', SomeFunc())
24endfunc
25
26def ReturnString(): string
27 return 'string'
28enddef
29
30def ReturnNumber(): number
31 return 123
32enddef
33
34let g:notNumber = 'string'
35
36def ReturnGlobal(): number
37 return g:notNumber
38enddef
39
40def Test_return_something()
41 assert_equal('string', ReturnString())
42 assert_equal(123, ReturnNumber())
43 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
44enddef
45
46let s:nothing = 0
47def ReturnNothing()
48 s:nothing = 1
49 if true
50 return
51 endif
52 s:nothing = 2
53enddef
54
55def Test_return_nothing()
56 ReturnNothing()
57 assert_equal(1, s:nothing)
58enddef
59
60func Increment()
61 let g:counter += 1
62endfunc
63
64def Test_call_ufunc_count()
65 g:counter = 1
66 Increment()
67 Increment()
68 Increment()
69 " works with and without :call
70 assert_equal(4, g:counter)
71 call assert_equal(4, g:counter)
72 unlet g:counter
73enddef
74
75def MyVarargs(arg: string, ...rest: list<string>): string
76 let res = arg
77 for s in rest
78 res ..= ',' .. s
79 endfor
80 return res
81enddef
82
83def Test_call_varargs()
84 assert_equal('one', MyVarargs('one'))
85 assert_equal('one,two', MyVarargs('one', 'two'))
86 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
87enddef
88
89def MyDefaultArgs(name = 'string'): string
90 return name
91enddef
92
93def Test_call_default_args()
94 assert_equal('string', MyDefaultArgs())
95 assert_equal('one', MyDefaultArgs('one'))
96 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
97
98 call CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef'], 'E1001:')
99enddef
100
101func Test_call_default_args_from_func()
102 call assert_equal('string', MyDefaultArgs())
103 call assert_equal('one', MyDefaultArgs('one'))
104 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
105endfunc
106
107func TakesOneArg(arg)
108 echo a:arg
109endfunc
110
111def Test_call_wrong_args()
112 call CheckDefFailure(['TakesOneArg()'], 'E119:')
113 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
114 call CheckDefFailure(['bufnr(xxx)'], 'E1001:')
115enddef
116
117" Default arg and varargs
118def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
119 let res = one .. ',' .. two
120 for s in rest
121 res ..= ',' .. s
122 endfor
123 return res
124enddef
125
126def Test_call_def_varargs()
127 call assert_fails('call MyDefVarargs()', 'E119:')
128 assert_equal('one,foo', MyDefVarargs('one'))
129 assert_equal('one,two', MyDefVarargs('one', 'two'))
130 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
131enddef
132
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200133" Only varargs
134def MyVarargsOnly(...args: list<string>): string
135 return join(args, ',')
136enddef
137
138def Test_call_varargs_only()
139 assert_equal('', MyVarargsOnly())
140 assert_equal('one', MyVarargsOnly('one'))
141 assert_equal('one,two', MyVarargsOnly('one', 'two'))
142 call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number')
143 call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number')
144enddef
145
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200146def Test_using_var_as_arg()
147 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
148 call assert_fails('so Xdef', 'E1006:')
149 call delete('Xdef')
150enddef
151
152def Test_call_func_defined_later()
153 call assert_equal('one', DefinedLater('one'))
154 call assert_fails('call NotDefined("one")', 'E117:')
155enddef
156
157func DefinedLater(arg)
158 return a:arg
159endfunc
160
161def FuncWithForwardCall()
162 return DefinedEvenLater("yes")
163enddef
164
165def DefinedEvenLater(arg: string): string
166 return arg
167enddef
168
169def Test_error_in_nested_function()
170 " Error in called function requires unwinding the call stack.
171 assert_fails('call FuncWithForwardCall()', 'E1029')
172enddef
173
174def Test_return_type_wrong()
175 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
176 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
177 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
178 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
179
180 CheckScriptFailure(['def Func(): number', 'return', 'enddef'], 'E1003:')
181
182 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
183 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200184 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200185enddef
186
187def Test_arg_type_wrong()
188 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200189 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200190enddef
191
192def Test_vim9script_call()
193 let lines =<< trim END
194 vim9script
195 let var = ''
196 def MyFunc(arg: string)
197 var = arg
198 enddef
199 MyFunc('foobar')
200 assert_equal('foobar', var)
201
202 let str = 'barfoo'
203 str->MyFunc()
204 assert_equal('barfoo', var)
205
206 let g:value = 'value'
207 g:value->MyFunc()
208 assert_equal('value', var)
209
210 let listvar = []
211 def ListFunc(arg: list<number>)
212 listvar = arg
213 enddef
214 [1, 2, 3]->ListFunc()
215 assert_equal([1, 2, 3], listvar)
216
217 let dictvar = {}
218 def DictFunc(arg: dict<number>)
219 dictvar = arg
220 enddef
221 {'a': 1, 'b': 2}->DictFunc()
222 assert_equal(#{a: 1, b: 2}, dictvar)
223 def CompiledDict()
224 {'a': 3, 'b': 4}->DictFunc()
225 enddef
226 CompiledDict()
227 assert_equal(#{a: 3, b: 4}, dictvar)
228
229 #{a: 3, b: 4}->DictFunc()
230 assert_equal(#{a: 3, b: 4}, dictvar)
231
232 ('text')->MyFunc()
233 assert_equal('text', var)
234 ("some")->MyFunc()
235 assert_equal('some', var)
236 END
237 writefile(lines, 'Xcall.vim')
238 source Xcall.vim
239 delete('Xcall.vim')
240enddef
241
242def Test_vim9script_call_fail_decl()
243 let lines =<< trim END
244 vim9script
245 let var = ''
246 def MyFunc(arg: string)
247 let var = 123
248 enddef
249 END
250 writefile(lines, 'Xcall_decl.vim')
251 assert_fails('source Xcall_decl.vim', 'E1054:')
252 delete('Xcall_decl.vim')
253enddef
254
255def Test_vim9script_call_fail_const()
256 let lines =<< trim END
257 vim9script
258 const var = ''
259 def MyFunc(arg: string)
260 var = 'asdf'
261 enddef
262 END
263 writefile(lines, 'Xcall_const.vim')
264 assert_fails('source Xcall_const.vim', 'E46:')
265 delete('Xcall_const.vim')
266enddef
267
268" Test that inside :function a Python function can be defined, :def is not
269" recognized.
270func Test_function_python()
271 CheckFeature python3
272 let py = 'python3'
273 execute py "<< EOF"
274def do_something():
275 return 1
276EOF
277endfunc
278
279def Test_delfunc()
280 let lines =<< trim END
281 vim9script
282 def GoneSoon()
283 echo 'hello'
284 enddef
285
286 def CallGoneSoon()
287 GoneSoon()
288 enddef
289
290 delfunc GoneSoon
291 CallGoneSoon()
292 END
293 writefile(lines, 'XToDelFunc')
294 assert_fails('so XToDelFunc', 'E933')
295 assert_fails('so XToDelFunc', 'E933')
296
297 delete('XToDelFunc')
298enddef
299
300def Test_redef_failure()
301 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
302 so Xdef
303 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
304 so Xdef
305 call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
306 call assert_fails('so Xdef', 'E1027:')
307 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
308 so Xdef
309 call delete('Xdef')
310
311 call assert_equal(0, Func0())
312 call assert_equal('Func1', Func1())
313 call assert_equal('Func2', Func2())
314
315 delfunc! Func0
316 delfunc! Func1
317 delfunc! Func2
318enddef
319
320" Test for internal functions returning different types
321func Test_InternalFuncRetType()
322 let lines =<< trim END
323 def RetFloat(): float
324 return ceil(1.456)
325 enddef
326
327 def RetListAny(): list<any>
328 return items({'k' : 'v'})
329 enddef
330
331 def RetListString(): list<string>
332 return split('a:b:c', ':')
333 enddef
334
335 def RetListDictAny(): list<dict<any>>
336 return getbufinfo()
337 enddef
338
339 def RetDictNumber(): dict<number>
340 return wordcount()
341 enddef
342
343 def RetDictString(): dict<string>
344 return environ()
345 enddef
346 END
347 call writefile(lines, 'Xscript')
348 source Xscript
349
350 call assert_equal(2.0, RetFloat())
351 call assert_equal([['k', 'v']], RetListAny())
352 call assert_equal(['a', 'b', 'c'], RetListString())
353 call assert_notequal([], RetListDictAny())
354 call assert_notequal({}, RetDictNumber())
355 call assert_notequal({}, RetDictString())
356 call delete('Xscript')
357endfunc
358
359" Test for passing too many or too few arguments to internal functions
360func Test_internalfunc_arg_error()
361 let l =<< trim END
362 def! FArgErr(): float
363 return ceil(1.1, 2)
364 enddef
365 END
366 call writefile(l, 'Xinvalidarg')
367 call assert_fails('so Xinvalidarg', 'E118:')
368 let l =<< trim END
369 def! FArgErr(): float
370 return ceil()
371 enddef
372 END
373 call writefile(l, 'Xinvalidarg')
374 call assert_fails('so Xinvalidarg', 'E119:')
375 call delete('Xinvalidarg')
376endfunc
377
378let s:funcResult = 0
379
380def FuncNoArgNoRet()
381 funcResult = 11
382enddef
383
384def FuncNoArgRetNumber(): number
385 funcResult = 22
386 return 1234
387enddef
388
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200389def FuncNoArgRetString(): string
390 funcResult = 45
391 return 'text'
392enddef
393
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200394def FuncOneArgNoRet(arg: number)
395 funcResult = arg
396enddef
397
398def FuncOneArgRetNumber(arg: number): number
399 funcResult = arg
400 return arg
401enddef
402
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200403def FuncOneArgRetString(arg: string): string
404 return arg
405enddef
406
Bram Moolenaar89228602020-04-05 22:14:54 +0200407def FuncOneArgRetAny(arg: any): any
408 return arg
409enddef
410
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200411def Test_func_type()
412 let Ref1: func()
413 funcResult = 0
414 Ref1 = FuncNoArgNoRet
415 Ref1()
416 assert_equal(11, funcResult)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200417
418 let Ref2: func
419 funcResult = 0
420 Ref2 = FuncNoArgNoRet
421 Ref2()
422 assert_equal(11, funcResult)
423
424 funcResult = 0
425 Ref2 = FuncOneArgNoRet
426 Ref2(12)
427 assert_equal(12, funcResult)
428
429 funcResult = 0
430 Ref2 = FuncNoArgRetNumber
431 assert_equal(1234, Ref2())
432 assert_equal(22, funcResult)
433
434 funcResult = 0
435 Ref2 = FuncOneArgRetNumber
436 assert_equal(13, Ref2(13))
437 assert_equal(13, funcResult)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200438enddef
439
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200440def Test_func_type_part()
441 let RefVoid: func: void
442 RefVoid = FuncNoArgNoRet
443 RefVoid = FuncOneArgNoRet
444 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
445 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string')
446
447 let RefAny: func(): any
448 RefAny = FuncNoArgRetNumber
449 RefAny = FuncNoArgRetString
450 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): any but got func()')
451 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1013: type mismatch, expected func(): any but got func(number)')
452
453 let RefNr: func: number
454 RefNr = FuncNoArgRetNumber
455 RefNr = FuncOneArgRetNumber
456 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()')
457 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string')
458
459 let RefStr: func: string
460 RefStr = FuncNoArgRetString
461 RefStr = FuncOneArgRetString
462 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): string but got func()')
463 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got func(): number')
464enddef
465
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200466def Test_func_type_fails()
467 CheckDefFailure(['let ref1: func()'], 'E704:')
468
469 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
470 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)')
471 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number')
472enddef
473
Bram Moolenaar89228602020-04-05 22:14:54 +0200474def Test_func_return_type()
475 let nr: number
476 nr = FuncNoArgRetNumber()
477 assert_equal(1234, nr)
478
479 nr = FuncOneArgRetAny(122)
480 assert_equal(122, nr)
481
482 let str: string
483 str = FuncOneArgRetAny('yes')
484 assert_equal('yes', str)
485
486 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1013: type mismatch, expected string but got number')
487enddef
488
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200489" When using CheckScriptFailure() for the below test, E1010 is generated instead
490" of E1056.
491func Test_E1056_1059()
492 let caught_1056 = 0
493 try
494 def F():
495 return 1
496 enddef
497 catch /E1056:/
498 let caught_1056 = 1
499 endtry
500 call assert_equal(1, caught_1056)
501
502 let caught_1059 = 0
503 try
504 def F5(items : list)
505 echo 'a'
506 enddef
507 catch /E1059:/
508 let caught_1059 = 1
509 endtry
510 call assert_equal(1, caught_1059)
511endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200512
513" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker