blob: cc6af6a86a789c9ac7c242644566cd759f5b6d1e [file] [log] [blame]
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001" Test various aspects of the Vim9 script language.
2
3source check.vim
Bram Moolenaarad304702020-09-06 18:22:53 +02004source term_util.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02005source view_util.vim
Bram Moolenaar04b12692020-05-04 23:24:44 +02006source vim9.vim
Bram Moolenaar47e7d702020-07-05 18:18:42 +02007source screendump.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02008
9func Test_def_basic()
10 def SomeFunc(): string
11 return 'yes'
12 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020013 call SomeFunc()->assert_equal('yes')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020014endfunc
15
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020016func Test_compiling_error()
17 " use a terminal to see the whole error message
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020018 CheckRunVimInTerminal
19
Bram Moolenaar2b9b17e2020-10-13 18:38:11 +020020 call TestCompilingError()
21endfunc
22
23def TestCompilingError()
Bram Moolenaarf4e8cdd2020-10-12 22:07:13 +020024 var lines =<< trim END
25 vim9script
26 def Fails()
27 echo nothing
28 enddef
29 defcompile
30 END
31 call writefile(lines, 'XTest_compile_error')
32 var buf = RunVimInTerminal('-S XTest_compile_error',
33 #{rows: 10, wait_for_ruler: 0})
34 var text = ''
35 for loop in range(100)
36 text = ''
37 for i in range(1, 9)
38 text ..= term_getline(buf, i)
39 endfor
40 if text =~ 'Error detected'
41 break
42 endif
43 sleep 20m
44 endfor
45 assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing', text)
46
47 # clean up
48 call StopVimInTerminal(buf)
49 call delete('XTest_compile_error')
50enddef
51
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020052def ReturnString(): string
53 return 'string'
54enddef
55
56def ReturnNumber(): number
57 return 123
58enddef
59
60let g:notNumber = 'string'
61
62def ReturnGlobal(): number
63 return g:notNumber
64enddef
65
66def Test_return_something()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020067 ReturnString()->assert_equal('string')
68 ReturnNumber()->assert_equal(123)
Bram Moolenaar5e654232020-09-16 15:22:00 +020069 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020070enddef
71
Bram Moolenaarefd88552020-06-18 20:50:10 +020072def Test_missing_return()
73 CheckDefFailure(['def Missing(): number',
74 ' if g:cond',
75 ' echo "no return"',
76 ' else',
77 ' return 0',
78 ' endif'
79 'enddef'], 'E1027:')
80 CheckDefFailure(['def Missing(): number',
81 ' if g:cond',
82 ' return 1',
83 ' else',
84 ' echo "no return"',
85 ' endif'
86 'enddef'], 'E1027:')
87 CheckDefFailure(['def Missing(): number',
88 ' if g:cond',
89 ' return 1',
90 ' else',
91 ' return 2',
92 ' endif'
93 ' return 3'
94 'enddef'], 'E1095:')
95enddef
96
Bram Moolenaar403dc312020-10-17 19:29:51 +020097def Test_return_bool()
98 var lines =<< trim END
99 vim9script
100 def MenuFilter(id: number, key: string): bool
101 return popup_filter_menu(id, key)
102 enddef
103 def YesnoFilter(id: number, key: string): bool
104 return popup_filter_yesno(id, key)
105 enddef
106 defcompile
107 END
108 CheckScriptSuccess(lines)
109enddef
110
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200111let s:nothing = 0
112def ReturnNothing()
113 s:nothing = 1
114 if true
115 return
116 endif
117 s:nothing = 2
118enddef
119
120def Test_return_nothing()
121 ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200122 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200123enddef
124
125func Increment()
126 let g:counter += 1
127endfunc
128
129def Test_call_ufunc_count()
130 g:counter = 1
131 Increment()
132 Increment()
133 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200134 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200135 g:counter->assert_equal(4)
136 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200137 unlet g:counter
138enddef
139
140def MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200141 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200142 for s in rest
143 res ..= ',' .. s
144 endfor
145 return res
146enddef
147
148def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200149 MyVarargs('one')->assert_equal('one')
150 MyVarargs('one', 'two')->assert_equal('one,two')
151 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200152enddef
153
154def MyDefaultArgs(name = 'string'): string
155 return name
156enddef
157
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200158def MyDefaultSecond(name: string, second: bool = true): string
159 return second ? name : 'none'
160enddef
161
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200162def Test_call_default_args()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200163 MyDefaultArgs()->assert_equal('string')
164 MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200165 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200166
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200167 MyDefaultSecond('test')->assert_equal('test')
168 MyDefaultSecond('test', true)->assert_equal('test')
169 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200170
Bram Moolenaar822ba242020-05-24 23:00:18 +0200171 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar77072282020-09-16 17:55:40 +0200172 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200173enddef
174
175def Test_nested_function()
176 def Nested(arg: string): string
177 return 'nested ' .. arg
178 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200179 Nested('function')->assert_equal('nested function')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200180
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200181 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
182 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
183
Bram Moolenaar04b12692020-05-04 23:24:44 +0200184 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200185 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
186 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200187
188 CheckDefFailure([
189 'def Outer()',
190 ' def Inner()',
191 ' # comment',
192 ' enddef',
193 ' def Inner()',
194 ' enddef',
195 'enddef'], 'E1073:')
196 CheckDefFailure([
197 'def Outer()',
198 ' def Inner()',
199 ' # comment',
200 ' enddef',
201 ' def! Inner()',
202 ' enddef',
203 'enddef'], 'E1117:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200204enddef
205
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200206func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200207 call MyDefaultArgs()->assert_equal('string')
208 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200209 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200210endfunc
211
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200212def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200213 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200214 vim9script
215 def Outer()
216 def g:Inner(): string
217 return 'inner'
218 enddef
219 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200220 defcompile
221 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200222 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200223 delfunc g:Inner
224 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200225 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200226 delfunc g:Inner
227 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200228 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200229 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200230 END
231 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200232
233 lines =<< trim END
234 vim9script
235 def Outer()
236 def g:Inner(): string
237 return 'inner'
238 enddef
239 enddef
240 defcompile
241 Outer()
242 Outer()
243 END
244 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200245
246 lines =<< trim END
247 vim9script
248 def Func()
249 echo 'script'
250 enddef
251 def Outer()
252 def Func()
253 echo 'inner'
254 enddef
255 enddef
256 defcompile
257 END
258 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200259enddef
260
Bram Moolenaar333894b2020-08-01 18:53:07 +0200261def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200262 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200263 vim9script
264 def g:Func(): string
265 return 'global'
266 enddef
267 def Func(): string
268 return 'local'
269 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200270 g:Func()->assert_equal('global')
271 Func()->assert_equal('local')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200272 END
273 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200274
275 lines =<< trim END
276 vim9script
277 def g:Funcy()
278 echo 'funcy'
279 enddef
280 s:Funcy()
281 END
282 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200283enddef
284
Bram Moolenaar0f769812020-09-12 18:32:34 +0200285def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200286 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200287 vim9script
288 def g:Gfunc(): string
289 return 'global'
290 enddef
291 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200292 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200293 return Gfunc('testing')
294 enddef
295 g:Gfunc()->assert_equal('global')
296 AnotherFunc()->assert_equal(7)
297 delfunc g:Gfunc
298 END
299 CheckScriptSuccess(lines)
300
301 lines =<< trim END
302 vim9script
303 def g:Func(): string
304 return 'global'
305 enddef
306 def AnotherFunc()
307 g:Func = function('len')
308 enddef
309 AnotherFunc()
310 END
311 CheckScriptFailure(lines, 'E705:')
312 delfunc g:Func
313enddef
314
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200315func TakesOneArg(arg)
316 echo a:arg
317endfunc
318
319def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200320 CheckDefFailure(['TakesOneArg()'], 'E119:')
321 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
322 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
323 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200324
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200325 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200326 vim9script
327 def Func(s: string)
328 echo s
329 enddef
330 Func([])
331 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200332 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200333
334 lines =<< trim END
335 vim9script
336 def FuncOne(nr: number)
337 echo nr
338 enddef
339 def FuncTwo()
340 FuncOne()
341 enddef
342 defcompile
343 END
344 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200345 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200346 try
347 source Xscript
348 catch
349 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
350 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
351 didCatch = true
352 endtry
353 assert_true(didCatch)
354
355 lines =<< trim END
356 vim9script
357 def FuncOne(nr: number)
358 echo nr
359 enddef
360 def FuncTwo()
361 FuncOne(1, 2)
362 enddef
363 defcompile
364 END
365 writefile(lines, 'Xscript')
366 didCatch = false
367 try
368 source Xscript
369 catch
370 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
371 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
372 didCatch = true
373 endtry
374 assert_true(didCatch)
375
376 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200377enddef
378
379" Default arg and varargs
380def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200381 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200382 for s in rest
383 res ..= ',' .. s
384 endfor
385 return res
386enddef
387
388def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200389 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200390 MyDefVarargs('one')->assert_equal('one,foo')
391 MyDefVarargs('one', 'two')->assert_equal('one,two')
392 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200393 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200394 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200395 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200396 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200397
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200398 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200399 vim9script
400 def Func(...l: list<string>)
401 echo l
402 enddef
403 Func('a', 'b', 'c')
404 END
405 CheckScriptSuccess(lines)
406
407 lines =<< trim END
408 vim9script
409 def Func(...l: list<string>)
410 echo l
411 enddef
412 Func()
413 END
414 CheckScriptSuccess(lines)
415
416 lines =<< trim END
417 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200418 def Func(...l: any)
419 echo l
420 enddef
421 Func(0)
422 END
423 CheckScriptSuccess(lines)
424
425 lines =<< trim END
426 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200427 def Func(..._l: list<string>)
428 echo _l
429 enddef
430 Func('a', 'b', 'c')
431 END
432 CheckScriptSuccess(lines)
433
434 lines =<< trim END
435 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200436 def Func(...l: list<string>)
437 echo l
438 enddef
439 Func(1, 2, 3)
440 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200441 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200442
443 lines =<< trim END
444 vim9script
445 def Func(...l: list<string>)
446 echo l
447 enddef
448 Func('a', 9)
449 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200450 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200451
452 lines =<< trim END
453 vim9script
454 def Func(...l: list<string>)
455 echo l
456 enddef
457 Func(1, 'a')
458 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200459 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200460enddef
461
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200462def Test_call_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200463 var l = [3, 2, 1]
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200464 call('reverse', [l])
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200465 l->assert_equal([1, 2, 3])
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200466enddef
467
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200468let s:value = ''
469
470def FuncOneDefArg(opt = 'text')
471 s:value = opt
472enddef
473
474def FuncTwoDefArg(nr = 123, opt = 'text'): string
475 return nr .. opt
476enddef
477
478def FuncVarargs(...arg: list<string>): string
479 return join(arg, ',')
480enddef
481
482def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200483 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200484 RefDefArg = FuncOneDefArg
485 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200486 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200487 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200488 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200489
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200490 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200491 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200492 RefDef2Arg()->assert_equal('123text')
493 RefDef2Arg(99)->assert_equal('99text')
494 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200495
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200496 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
497 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200498
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200499 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200500 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200501 RefVarargs()->assert_equal('')
502 RefVarargs('one')->assert_equal('one')
503 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200504
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200505 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
506 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200507enddef
508
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200509" Only varargs
510def MyVarargsOnly(...args: list<string>): string
511 return join(args, ',')
512enddef
513
514def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200515 MyVarargsOnly()->assert_equal('')
516 MyVarargsOnly('one')->assert_equal('one')
517 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200518 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
519 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200520enddef
521
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200522def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200523 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200524 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200525 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200526enddef
527
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200528def DictArg(arg: dict<string>)
529 arg['key'] = 'value'
530enddef
531
532def ListArg(arg: list<string>)
533 arg[0] = 'value'
534enddef
535
536def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200537 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200538 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200539 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200540 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200541 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200542 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200543 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200544
Bram Moolenaard2c61702020-09-06 15:58:36 +0200545 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200546enddef
547
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200548" These argument names are reserved in legacy functions.
549def WithReservedNames(firstline: string, lastline: string): string
550 return firstline .. lastline
551enddef
552
553def Test_argument_names()
554 assert_equal('OK', WithReservedNames('O', 'K'))
555enddef
556
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200557def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200558 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200559 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200560enddef
561
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200562func DefinedLater(arg)
563 return a:arg
564endfunc
565
566def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200567 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200568 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
569 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200570
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200571 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200572 vim9script
573 def RetNumber(): number
574 return 123
575 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200576 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200577 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200578 END
579 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200580
581 lines =<< trim END
582 vim9script
583 def RetNumber(): number
584 return 123
585 enddef
586 def Bar(F: func: number): number
587 return F()
588 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200589 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200590 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200591 END
592 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200593
594 lines =<< trim END
595 vim9script
596 def UseNumber(nr: number)
597 echo nr
598 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200599 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200600 Funcref(123)
601 END
602 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200603
604 lines =<< trim END
605 vim9script
606 def UseNumber(nr: number)
607 echo nr
608 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200609 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200610 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200611 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200612
613 lines =<< trim END
614 vim9script
615 def EchoNr(nr = 34)
616 g:echo = nr
617 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200618 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200619 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200620 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200621 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200622 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200623 END
624 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200625
626 lines =<< trim END
627 vim9script
628 def EchoList(...l: list<number>)
629 g:echo = l
630 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200631 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200632 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200633 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200634 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200635 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200636 END
637 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200638
639 lines =<< trim END
640 vim9script
641 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
642 g:optarg = opt
643 g:listarg = l
644 return nr
645 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200646 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200647 Funcref(10)->assert_equal(10)
648 g:optarg->assert_equal(12)
649 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200650
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200651 Funcref(11, 22)->assert_equal(11)
652 g:optarg->assert_equal(22)
653 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200654
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200655 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
656 g:optarg->assert_equal(18)
657 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200658 END
659 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200660enddef
661
662let SomeFunc = function('len')
663let NotAFunc = 'text'
664
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200665def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200666 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200667 var Ref1: func(bool): string
668 var Ref2: func(bool): number
669 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200670 Ref3 = g:cond ? Ref1 : Ref2
671
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200672 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200673 var Refa1: func(bool): number
674 var Refa2: func(bool, number): number
675 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200676 Refa3 = g:cond ? Refa1 : Refa2
677
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200678 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200679 var Refb1: func(bool, string): number
680 var Refb2: func(string, number): number
681 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200682 Refb3 = g:cond ? Refb1 : Refb2
683enddef
684
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200685def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200686 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200687enddef
688
689def DefinedEvenLater(arg: string): string
690 return arg
691enddef
692
693def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200694 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200695 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200696enddef
697
698def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200699 CheckScriptFailure([
700 'def Func(): number',
701 'return "a"',
702 'enddef',
703 'defcompile'], 'expected number but got string')
704 CheckScriptFailure([
705 'def Func(): string',
706 'return 1',
707 'enddef',
708 'defcompile'], 'expected string but got number')
709 CheckScriptFailure([
710 'def Func(): void',
711 'return "a"',
712 'enddef',
713 'defcompile'],
714 'E1096: Returning a value in a function without a return type')
715 CheckScriptFailure([
716 'def Func()',
717 'return "a"',
718 'enddef',
719 'defcompile'],
720 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200721
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200722 CheckScriptFailure([
723 'def Func(): number',
724 'return',
725 'enddef',
726 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200727
728 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
729 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200730 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200731
732 CheckScriptFailure([
733 'vim9script',
734 'def FuncB()',
735 ' return 123',
736 'enddef',
737 'def FuncA()',
738 ' FuncB()',
739 'enddef',
740 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200741enddef
742
743def Test_arg_type_wrong()
744 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200745 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200746 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200747 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200748enddef
749
750def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200751 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200752 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200753 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200754 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200755 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200756 enddef
757 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200758 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200759
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200760 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200761 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200762 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200763
Bram Moolenaar67979662020-06-20 22:50:47 +0200764 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200765 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200766 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200767
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200768 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200769 def ListFunc(arg: list<number>)
770 listvar = arg
771 enddef
772 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200773 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200774
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200775 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200776 def DictFunc(arg: dict<number>)
777 dictvar = arg
778 enddef
779 {'a': 1, 'b': 2}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200780 dictvar->assert_equal(#{a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200781 def CompiledDict()
782 {'a': 3, 'b': 4}->DictFunc()
783 enddef
784 CompiledDict()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200785 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200786
787 #{a: 3, b: 4}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200788 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200789
790 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200791 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200792 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200793 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200794
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200795 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200796 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200797 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200798 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200799 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200800 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200801
802 def UseString()
803 'xyork'->MyFunc()
804 enddef
805 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200806 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200807
Bram Moolenaar10409562020-07-29 20:00:38 +0200808 def UseString2()
809 "knife"->MyFunc()
810 enddef
811 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200812 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200813
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200814 # prepending a colon makes it a mark
815 new
816 setline(1, ['aaa', 'bbb', 'ccc'])
817 normal! 3Gmt1G
818 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200819 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200820 bwipe!
821
Bram Moolenaare6b53242020-07-01 17:28:33 +0200822 MyFunc(
823 'continued'
824 )
825 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200826 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200827 )
828
829 call MyFunc(
830 'more'
831 ..
832 'lines'
833 )
834 assert_equal(
835 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200836 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200837 END
838 writefile(lines, 'Xcall.vim')
839 source Xcall.vim
840 delete('Xcall.vim')
841enddef
842
843def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200844 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200845 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200846 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200847 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200848 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200849 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200850 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200851 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200852 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200853enddef
854
Bram Moolenaar65b95452020-07-19 14:03:09 +0200855def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200856 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200857 vim9script
858 def MyFunc(arg: string)
859 echo arg
860 enddef
861 MyFunc(1234)
862 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200863 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200864enddef
865
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200866def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200867 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200868 vim9script
869 const var = ''
870 def MyFunc(arg: string)
871 var = 'asdf'
872 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200873 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200874 END
875 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200876 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200877 delete('Xcall_const.vim')
878enddef
879
880" Test that inside :function a Python function can be defined, :def is not
881" recognized.
882func Test_function_python()
883 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200884 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200885 execute py "<< EOF"
886def do_something():
887 return 1
888EOF
889endfunc
890
891def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200892 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200893 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200894 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200895 echo 'hello'
896 enddef
897
898 def CallGoneSoon()
899 GoneSoon()
900 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200901 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200902
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200903 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200904 CallGoneSoon()
905 END
906 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200907 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
908 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200909
910 delete('XToDelFunc')
911enddef
912
913def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200914 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200915 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200916 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200917 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200918 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200919 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200920 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200921 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200922 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200923
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200924 g:Func0()->assert_equal(0)
925 g:Func1()->assert_equal('Func1')
926 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200927
928 delfunc! Func0
929 delfunc! Func1
930 delfunc! Func2
931enddef
932
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200933def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200934 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200935 vim9script
936 func Func(arg)
937 echo a:arg
938 endfunc
939 Func('text')
940 END
941 writefile(lines, 'XVim9Func')
942 so XVim9Func
943
944 delete('XVim9Func')
945enddef
946
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200947" Test for internal functions returning different types
948func Test_InternalFuncRetType()
949 let lines =<< trim END
950 def RetFloat(): float
951 return ceil(1.456)
952 enddef
953
954 def RetListAny(): list<any>
Bram Moolenaar17a836c2020-08-12 17:35:58 +0200955 return items({'k': 'v'})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200956 enddef
957
958 def RetListString(): list<string>
959 return split('a:b:c', ':')
960 enddef
961
962 def RetListDictAny(): list<dict<any>>
963 return getbufinfo()
964 enddef
965
966 def RetDictNumber(): dict<number>
967 return wordcount()
968 enddef
969
970 def RetDictString(): dict<string>
971 return environ()
972 enddef
973 END
974 call writefile(lines, 'Xscript')
975 source Xscript
976
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200977 call RetFloat()->assert_equal(2.0)
978 call RetListAny()->assert_equal([['k', 'v']])
979 call RetListString()->assert_equal(['a', 'b', 'c'])
980 call RetListDictAny()->assert_notequal([])
981 call RetDictNumber()->assert_notequal({})
982 call RetDictString()->assert_notequal({})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200983 call delete('Xscript')
984endfunc
985
986" Test for passing too many or too few arguments to internal functions
987func Test_internalfunc_arg_error()
988 let l =<< trim END
989 def! FArgErr(): float
990 return ceil(1.1, 2)
991 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200992 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200993 END
994 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200995 call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200996 let l =<< trim END
997 def! FArgErr(): float
998 return ceil()
999 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +02001000 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001001 END
1002 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +02001003 call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001004 call delete('Xinvalidarg')
1005endfunc
1006
1007let s:funcResult = 0
1008
1009def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +02001010 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001011enddef
1012
1013def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001014 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001015 return 1234
1016enddef
1017
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001018def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02001019 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001020 return 'text'
1021enddef
1022
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001023def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001024 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001025enddef
1026
1027def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001028 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001029 return arg
1030enddef
1031
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001032def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001033 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001034enddef
1035
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001036def FuncOneArgRetString(arg: string): string
1037 return arg
1038enddef
1039
Bram Moolenaar89228602020-04-05 22:14:54 +02001040def FuncOneArgRetAny(arg: any): any
1041 return arg
1042enddef
1043
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001044def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001045 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001046 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001047 Ref1 = FuncNoArgNoRet
1048 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001049 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001050
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001051 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001052 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001053 Ref2 = FuncNoArgNoRet
1054 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001055 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001056
Bram Moolenaar53900992020-08-22 19:02:02 +02001057 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001058 Ref2 = FuncOneArgNoRet
1059 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001060 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001061
Bram Moolenaar53900992020-08-22 19:02:02 +02001062 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001063 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001064 Ref2()->assert_equal(1234)
1065 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001066
Bram Moolenaar53900992020-08-22 19:02:02 +02001067 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001068 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001069 Ref2(13)->assert_equal(13)
1070 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001071enddef
1072
Bram Moolenaar9978d472020-07-05 16:01:56 +02001073def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001074 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001075 for n in repeat([1], 3)
1076 res += n
1077 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001078 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001079
1080 res = 0
1081 for n in add([1, 2], 3)
1082 res += n
1083 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001084 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001085enddef
1086
Bram Moolenaar846178a2020-07-05 17:04:13 +02001087def Test_argv_return_type()
1088 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001089 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001090 for name in argv()
1091 res ..= name
1092 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001093 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001094enddef
1095
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001096def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001097 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001098 RefVoid = FuncNoArgNoRet
1099 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001100 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1101 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001102
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001103 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001104 RefAny = FuncNoArgRetNumber
1105 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001106 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1107 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001108
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001109 var RefAnyNoArgs: func: any = RefAny
1110
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001111 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001112 RefNr = FuncNoArgRetNumber
1113 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001114 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1115 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001116
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001117 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001118 RefStr = FuncNoArgRetString
1119 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001120 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1121 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001122enddef
1123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001124def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001125 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001126
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001127 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1128 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1129 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1130 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1131 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1132 CheckDefFailure(['var Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)')
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001133
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001134 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1135 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1136 CheckDefFailure(['var RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E1005:')
1137 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001138enddef
1139
Bram Moolenaar89228602020-04-05 22:14:54 +02001140def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001141 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001142 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001143 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001144
1145 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001146 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001147
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001148 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001149 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001150 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001151
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001152 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001153enddef
1154
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001155def Test_func_common_type()
1156 def FuncOne(n: number): number
1157 return n
1158 enddef
1159 def FuncTwo(s: string): number
1160 return len(s)
1161 enddef
1162 def FuncThree(n: number, s: string): number
1163 return n + len(s)
1164 enddef
1165 var list = [FuncOne, FuncTwo, FuncThree]
1166 assert_equal(8, list[0](8))
1167 assert_equal(4, list[1]('word'))
1168 assert_equal(7, list[2](3, 'word'))
1169enddef
1170
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001171def MultiLine(
1172 arg1: string,
1173 arg2 = 1234,
1174 ...rest: list<string>
1175 ): string
1176 return arg1 .. arg2 .. join(rest, '-')
1177enddef
1178
Bram Moolenaar2c330432020-04-13 14:41:35 +02001179def MultiLineComment(
1180 arg1: string, # comment
1181 arg2 = 1234, # comment
1182 ...rest: list<string> # comment
1183 ): string # comment
1184 return arg1 .. arg2 .. join(rest, '-')
1185enddef
1186
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001187def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001188 MultiLine('text')->assert_equal('text1234')
1189 MultiLine('text', 777)->assert_equal('text777')
1190 MultiLine('text', 777, 'one')->assert_equal('text777one')
1191 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001192enddef
1193
Bram Moolenaar23e03252020-04-12 22:22:31 +02001194func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001195 call MultiLine('text')->assert_equal('text1234')
1196 call MultiLine('text', 777)->assert_equal('text777')
1197 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1198 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001199endfunc
1200
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001201
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001202" When using CheckScriptFailure() for the below test, E1010 is generated instead
1203" of E1056.
1204func Test_E1056_1059()
1205 let caught_1056 = 0
1206 try
1207 def F():
1208 return 1
1209 enddef
1210 catch /E1056:/
1211 let caught_1056 = 1
1212 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001213 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001214
1215 let caught_1059 = 0
1216 try
1217 def F5(items : list)
1218 echo 'a'
1219 enddef
1220 catch /E1059:/
1221 let caught_1059 = 1
1222 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001223 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001224endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001225
Bram Moolenaar015f4262020-05-05 21:25:22 +02001226func DelMe()
1227 echo 'DelMe'
1228endfunc
1229
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001230def Test_error_reporting()
1231 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001232 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001233 " comment
1234 def Func()
1235 # comment
1236 # comment
1237 invalid
1238 enddef
1239 defcompile
1240 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001241 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001242 try
1243 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001244 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001245 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001246 v:exception->assert_match('Invalid command: invalid')
1247 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001248 endtry
1249
1250 # comment lines after the start of the function
1251 lines =<< trim END
1252 " comment
1253 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001254 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001255 # comment
1256 # comment
1257 invalid
1258 enddef
1259 defcompile
1260 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001261 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001262 try
1263 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001264 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001265 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001266 v:exception->assert_match('Invalid command: invalid')
1267 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001268 endtry
1269
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001270 lines =<< trim END
1271 vim9script
1272 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001273 var db = #{foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001274 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001275 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001276 enddef
1277 defcompile
1278 Func()
1279 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001280 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001281 try
1282 source Xdef
1283 assert_report('should have failed')
1284 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001285 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001286 endtry
1287
Bram Moolenaar08052222020-09-14 17:04:31 +02001288 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001289enddef
1290
Bram Moolenaar015f4262020-05-05 21:25:22 +02001291def Test_deleted_function()
1292 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001293 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001294 'delfunc g:DelMe',
1295 'echo RefMe()'], 'E117:')
1296enddef
1297
1298def Test_unknown_function()
1299 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001300 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001301 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001302enddef
1303
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001304def RefFunc(Ref: func(string): string): string
1305 return Ref('more')
1306enddef
1307
1308def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001309 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001310 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001311enddef
1312
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001313def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001314 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001315 g:Ref = {s -> local .. s}
1316enddef
1317
1318def Test_closure_ref_after_return()
1319 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001320 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001321 unlet g:Ref
1322enddef
1323
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001324def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001325 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001326 g:Extend = {s -> local->add(s)}
1327 g:Read = {-> local}
1328enddef
1329
1330def Test_closure_two_refs()
1331 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001332 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001333 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001334 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001335 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001336 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001337
1338 unlet g:Extend
1339 unlet g:Read
1340enddef
1341
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001342def ReadRef(Ref: func(): list<string>): string
1343 return join(Ref(), ' ')
1344enddef
1345
Bram Moolenaar5e654232020-09-16 15:22:00 +02001346def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001347 Ref(add)
1348enddef
1349
1350def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001351 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001352 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001353 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001354 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001355 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001356 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001357
1358 unlet g:Extend
1359 unlet g:Read
1360enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001361
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001362def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001363 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001364 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1365enddef
1366
1367def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001368 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001369 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1370enddef
1371
1372def Test_closure_using_argument()
1373 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001374 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001375
1376 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001377 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001378
1379 unlet g:UseArg
1380 unlet g:UseVararg
1381enddef
1382
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001383def MakeGetAndAppendRefs()
1384 var local = 'a'
1385
1386 def Append(arg: string)
1387 local ..= arg
1388 enddef
1389 g:Append = Append
1390
1391 def Get(): string
1392 return local
1393 enddef
1394 g:Get = Get
1395enddef
1396
1397def Test_closure_append_get()
1398 MakeGetAndAppendRefs()
1399 g:Get()->assert_equal('a')
1400 g:Append('-b')
1401 g:Get()->assert_equal('a-b')
1402 g:Append('-c')
1403 g:Get()->assert_equal('a-b-c')
1404
1405 unlet g:Append
1406 unlet g:Get
1407enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001408
Bram Moolenaar04b12692020-05-04 23:24:44 +02001409def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001410 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001411 def Closure(arg: string): string
1412 return local .. arg
1413 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001414 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001415enddef
1416
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001417func GetResult(Ref)
1418 return a:Ref('some')
1419endfunc
1420
1421def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001422 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001423 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001424 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001425enddef
1426
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001427def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001428 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001429 vim9script
1430 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001431 var name = 0
1432 for i in range(2)
1433 timer_start(0, {-> name})
1434 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001435 enddef
1436 Func()
1437 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001438 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001439enddef
1440
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001441def Test_nested_closure_used()
1442 var lines =<< trim END
1443 vim9script
1444 def Func()
1445 var x = 'hello'
1446 var Closure = {-> x}
1447 g:Myclosure = {-> Closure()}
1448 enddef
1449 Func()
1450 assert_equal('hello', g:Myclosure())
1451 END
1452 CheckScriptSuccess(lines)
1453enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001454
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001455def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001456 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001457 vim9script
1458 def FuncA()
1459 FuncB(0)
1460 enddef
1461 def FuncB(n: number): list<string>
1462 return map([0], {_, v -> n})
1463 enddef
1464 FuncA()
1465 END
1466 CheckScriptFailure(lines, 'E1012:')
1467enddef
1468
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001469def Test_nested_lambda()
1470 var lines =<< trim END
1471 vim9script
1472 def Func()
1473 var x = 4
1474 var Lambda1 = {-> 7}
1475 var Lambda2 = {-> [Lambda1(), x]}
1476 var res = Lambda2()
1477 assert_equal([7, 4], res)
1478 enddef
1479 Func()
1480 END
1481 CheckScriptSuccess(lines)
1482enddef
1483
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001484def Test_sort_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001485 var res: list<number>
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001486 res = [1, 2, 3]->sort()
1487enddef
1488
Bram Moolenaar08e51f42020-09-16 23:23:36 +02001489def Test_sort_argument()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001490 var res = ['b', 'a', 'c']->sort('i')
Bram Moolenaar08e51f42020-09-16 23:23:36 +02001491 res->assert_equal(['a', 'b', 'c'])
1492enddef
1493
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001494def Test_getqflist_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001495 var l = getqflist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001496 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001497
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001498 var d = getqflist(#{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001499 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001500enddef
1501
1502def Test_getloclist_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001503 var l = getloclist(1)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001504 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001505
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001506 var d = getloclist(1, #{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001507 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001508enddef
1509
Bram Moolenaara66ba012020-07-05 18:41:08 +02001510def Test_copy_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001511 var l = copy([1, 2, 3])
1512 var res = 0
Bram Moolenaara66ba012020-07-05 18:41:08 +02001513 for n in l
1514 res += n
1515 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001516 res->assert_equal(6)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001517
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001518 var dl = deepcopy([1, 2, 3])
Bram Moolenaara66ba012020-07-05 18:41:08 +02001519 res = 0
1520 for n in dl
1521 res += n
1522 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001523 res->assert_equal(6)
Bram Moolenaar44b4a242020-09-05 17:18:28 +02001524
1525 dl = deepcopy([1, 2, 3], true)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001526enddef
1527
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001528def Test_extend_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001529 var l = extend([1, 2], [3])
1530 var res = 0
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001531 for n in l
1532 res += n
1533 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001534 res->assert_equal(6)
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001535enddef
1536
Bram Moolenaar2df47312020-09-05 17:30:44 +02001537def Test_garbagecollect()
1538 garbagecollect(true)
1539enddef
1540
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001541def Test_insert_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001542 var l = insert([2, 1], 3)
1543 var res = 0
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001544 for n in l
1545 res += n
1546 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001547 res->assert_equal(6)
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001548enddef
1549
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001550def Test_keys_return_type()
1551 const var: list<string> = #{a: 1, b: 2}->keys()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001552 var->assert_equal(['a', 'b'])
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001553enddef
1554
Bram Moolenaar67627352020-07-05 21:10:24 +02001555def Test_reverse_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001556 var l = reverse([1, 2, 3])
1557 var res = 0
Bram Moolenaar67627352020-07-05 21:10:24 +02001558 for n in l
1559 res += n
1560 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001561 res->assert_equal(6)
Bram Moolenaar67627352020-07-05 21:10:24 +02001562enddef
1563
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001564def Test_remove_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001565 var l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
1566 var res = 0
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001567 for n in l
1568 res += n
1569 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001570 res->assert_equal(3)
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001571enddef
1572
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001573def Test_filter_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001574 var l = filter([1, 2, 3], {-> 1})
1575 var res = 0
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001576 for n in l
1577 res += n
1578 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001579 res->assert_equal(6)
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001580enddef
1581
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001582def Test_bufnr()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001583 var buf = bufnr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001584 bufnr('%')->assert_equal(buf)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001585
1586 buf = bufnr('Xdummy', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001587 buf->assert_notequal(-1)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001588 exe 'bwipe! ' .. buf
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001589enddef
1590
Bram Moolenaarec65d772020-08-20 22:29:12 +02001591def Test_col()
1592 new
1593 setline(1, 'asdf')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001594 col([1, '$'])->assert_equal(5)
Bram Moolenaarec65d772020-08-20 22:29:12 +02001595enddef
1596
Bram Moolenaar24f77502020-09-04 19:50:57 +02001597def Test_char2nr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001598 char2nr('あ', true)->assert_equal(12354)
Bram Moolenaar24f77502020-09-04 19:50:57 +02001599enddef
1600
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001601def Test_getreg_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001602 var s1: string = getreg('"')
1603 var s2: string = getreg('"', 1)
1604 var s3: list<string> = getreg('"', 1, 1)
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001605enddef
1606
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001607def Wrong_dict_key_type(items: list<number>): list<number>
1608 return filter(items, {_, val -> get({val: 1}, 'x')})
1609enddef
1610
1611def Test_wrong_dict_key_type()
Bram Moolenaar5e654232020-09-16 15:22:00 +02001612 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:')
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001613enddef
1614
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001615def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001616 var path: string = empty(dir)
1617 \ ? 'empty'
1618 \ : 'full'
1619 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001620enddef
1621
1622def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001623 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001624enddef
1625
Bram Moolenaar5e654232020-09-16 15:22:00 +02001626def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001627 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001628 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001629 ->toupper()})
1630 ->reverse()
1631 return x
1632enddef
1633
1634def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001635 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001636enddef
1637
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001638func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001639 CheckScreendump
1640
1641 let lines =<< trim END
1642 vim9script
1643 def EchoNothing()
1644 silent echo ''
1645 enddef
1646 defcompile
1647 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001648 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001649
1650 " Check that the balloon shows up after a mouse move
1651 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001652 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001653 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1654
1655 " clean up
1656 call StopVimInTerminal(buf)
1657 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001658endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001659
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001660""""""" builtin functions that behave differently in Vim9
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001661
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001662def Test_bufname()
1663 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001664 bufname('%')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001665 edit OtherFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001666 bufname('#')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001667 close
Bram Moolenaar191929b2020-08-19 21:20:49 +02001668enddef
1669
Bram Moolenaara5d38412020-09-02 21:02:35 +02001670def Test_bufwinid()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001671 var origwin = win_getid()
Bram Moolenaara5d38412020-09-02 21:02:35 +02001672 below split SomeFile
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001673 var SomeFileID = win_getid()
Bram Moolenaara5d38412020-09-02 21:02:35 +02001674 below split OtherFile
1675 below split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001676 bufwinid('SomeFile')->assert_equal(SomeFileID)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001677
1678 win_gotoid(origwin)
1679 only
1680 bwipe SomeFile
1681 bwipe OtherFile
1682enddef
1683
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001684def Test_count()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001685 count('ABC ABC ABC', 'b', true)->assert_equal(3)
1686 count('ABC ABC ABC', 'b', false)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001687enddef
1688
1689def Test_expand()
1690 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001691 expand('%', true, true)->assert_equal(['SomeFile'])
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001692 close
1693enddef
1694
1695def Test_getbufinfo()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001696 var bufinfo = getbufinfo(bufnr())
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001697 getbufinfo('%')->assert_equal(bufinfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001698
1699 edit Xtestfile1
1700 hide edit Xtestfile2
1701 hide enew
1702 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false})
1703 ->len()->assert_equal(3)
1704 bwipe Xtestfile1 Xtestfile2
1705enddef
1706
Bram Moolenaara5d38412020-09-02 21:02:35 +02001707def Test_getbufline()
1708 e SomeFile
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001709 var buf = bufnr()
Bram Moolenaara5d38412020-09-02 21:02:35 +02001710 e #
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001711 var lines = ['aaa', 'bbb', 'ccc']
Bram Moolenaara5d38412020-09-02 21:02:35 +02001712 setbufline(buf, 1, lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001713 getbufline('#', 1, '$')->assert_equal(lines)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001714
1715 bwipe!
1716enddef
1717
1718def Test_getchangelist()
1719 new
1720 setline(1, 'some text')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001721 var changelist = bufnr()->getchangelist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001722 getchangelist('%')->assert_equal(changelist)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001723 bwipe!
1724enddef
1725
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001726def Test_getchar()
Bram Moolenaar636c5d52020-09-05 18:48:57 +02001727 while getchar(0)
1728 endwhile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001729 getchar(true)->assert_equal(0)
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001730enddef
1731
Bram Moolenaard217a872020-09-05 18:31:33 +02001732def Test_getcompletion()
1733 set wildignore=*.vim,*~
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001734 var l = getcompletion('run', 'file', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001735 l->assert_equal([])
Bram Moolenaard217a872020-09-05 18:31:33 +02001736 set wildignore&
1737enddef
1738
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001739def Test_getreg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001740 var lines = ['aaa', 'bbb', 'ccc']
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001741 setreg('a', lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001742 getreg('a', true, true)->assert_equal(lines)
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001743enddef
1744
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001745def Test_glob()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001746 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001747enddef
1748
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001749def Test_globpath()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001750 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001751enddef
1752
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001753def Test_has()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001754 has('eval', true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001755enddef
1756
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001757def Test_hasmapto()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001758 hasmapto('foobar', 'i', true)->assert_equal(0)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001759 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001760 hasmapto('foobar', 'i', true)->assert_equal(1)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001761 iunabbrev foo
1762enddef
1763
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001764def Test_index()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001765 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001766enddef
1767
1768def Test_list2str_str2list_utf8()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001769 var s = "\u3042\u3044"
1770 var l = [0x3042, 0x3044]
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001771 str2list(s, true)->assert_equal(l)
1772 list2str(l, true)->assert_equal(s)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001773enddef
1774
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001775def SID(): number
1776 return expand('<SID>')
1777 ->matchstr('<SNR>\zs\d\+\ze_$')
1778 ->str2nr()
1779enddef
1780
1781def Test_maparg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001782 var lnum = str2nr(expand('<sflnum>'))
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001783 map foo bar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001784 maparg('foo', '', false, true)->assert_equal(#{
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001785 lnum: lnum + 1,
1786 script: 0,
1787 mode: ' ',
1788 silent: 0,
1789 noremap: 0,
1790 lhs: 'foo',
1791 lhsraw: 'foo',
1792 nowait: 0,
1793 expr: 0,
1794 sid: SID(),
1795 rhs: 'bar',
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001796 buffer: 0})
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001797 unmap foo
1798enddef
1799
1800def Test_mapcheck()
1801 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001802 mapcheck('foo', 'i', true)->assert_equal('foobar')
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001803 iunabbrev foo
1804enddef
1805
Bram Moolenaar74273e62020-10-01 21:37:21 +02001806def Test_maparg_mapset()
1807 nnoremap <F3> :echo "hit F3"<CR>
1808 var mapsave = maparg('<F3>', 'n', false, true)
1809 mapset('n', false, mapsave)
1810
1811 nunmap <F3>
1812enddef
1813
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001814def Test_nr2char()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001815 nr2char(97, true)->assert_equal('a')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001816enddef
1817
1818def Test_readdir()
1819 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1820 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
1821enddef
1822
1823def Test_search()
1824 new
1825 setline(1, ['foo', 'bar'])
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001826 var val = 0
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001827 # skip expr returns boolean
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001828 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001829 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001830 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001831 # skip expr returns number, only 0 and 1 are accepted
1832 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001833 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001834 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001835 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001836 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1837 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1838enddef
1839
1840def Test_searchcount()
1841 new
1842 setline(1, "foo bar")
1843 :/foo
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001844 searchcount(#{recompute: true})
1845 ->assert_equal(#{
1846 exact_match: 1,
1847 current: 1,
1848 total: 1,
1849 maxcount: 99,
1850 incomplete: 0})
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001851 bwipe!
1852enddef
1853
1854def Test_searchdecl()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001855 searchdecl('blah', true, true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001856enddef
1857
1858def Test_setbufvar()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001859 setbufvar(bufnr('%'), '&syntax', 'vim')
1860 &syntax->assert_equal('vim')
1861 setbufvar(bufnr('%'), '&ts', 16)
1862 &ts->assert_equal(16)
1863 settabwinvar(1, 1, '&syntax', 'vam')
1864 &syntax->assert_equal('vam')
1865 settabwinvar(1, 1, '&ts', 15)
1866 &ts->assert_equal(15)
1867 setlocal ts=8
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001868
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001869 setbufvar('%', 'myvar', 123)
1870 getbufvar('%', 'myvar')->assert_equal(123)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001871enddef
1872
Bram Moolenaar401f0c02020-09-05 22:37:39 +02001873def Test_setloclist()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001874 var items = [#{filename: '/tmp/file', lnum: 1, valid: true}]
1875 var what = #{items: items}
Bram Moolenaar401f0c02020-09-05 22:37:39 +02001876 setqflist([], ' ', what)
1877 setloclist(0, [], ' ', what)
1878enddef
1879
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001880def Test_setreg()
1881 setreg('a', ['aaa', 'bbb', 'ccc'])
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001882 var reginfo = getreginfo('a')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001883 setreg('a', reginfo)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001884 getreginfo('a')->assert_equal(reginfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001885enddef
1886
Bram Moolenaar7c27f332020-09-05 22:45:55 +02001887def Test_spellsuggest()
1888 if !has('spell')
1889 MissingFeature 'spell'
1890 else
1891 spellsuggest('marrch', 1, true)->assert_equal(['March'])
1892 endif
1893enddef
1894
Bram Moolenaar3986b942020-09-06 16:09:04 +02001895def Test_split()
1896 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
1897enddef
1898
1899def Test_str2nr()
1900 str2nr("1'000'000", 10, true)->assert_equal(1000000)
1901enddef
1902
1903def Test_strchars()
1904 strchars("A\u20dd", true)->assert_equal(1)
1905enddef
1906
Bram Moolenaarad304702020-09-06 18:22:53 +02001907def Test_submatch()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001908 var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
1909 var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()}
1910 var actual = substitute('A123456789', pat, Rep, '')
1911 var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001912 actual->assert_equal(expected)
Bram Moolenaarad304702020-09-06 18:22:53 +02001913enddef
1914
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001915def Test_synID()
1916 new
1917 setline(1, "text")
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001918 synID(1, 1, true)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001919 bwipe!
1920enddef
1921
Bram Moolenaarad304702020-09-06 18:22:53 +02001922def Test_term_gettty()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001923 if !has('terminal')
1924 MissingFeature 'terminal'
1925 else
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001926 var buf = Run_shell_in_terminal({})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001927 term_gettty(buf, true)->assert_notequal('')
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001928 StopShellInTerminal(buf)
1929 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001930enddef
1931
1932def Test_term_start()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001933 if !has('terminal')
1934 MissingFeature 'terminal'
1935 else
1936 botright new
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001937 var winnr = winnr()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001938 term_start(&shell, #{curwin: true})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001939 winnr()->assert_equal(winnr)
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001940 bwipe!
1941 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001942enddef
1943
Bram Moolenaar418155d2020-09-06 18:39:38 +02001944def Test_timer_paused()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001945 var id = timer_start(50, {-> 0})
Bram Moolenaar418155d2020-09-06 18:39:38 +02001946 timer_pause(id, true)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001947 var info = timer_info(id)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001948 info[0]['paused']->assert_equal(1)
Bram Moolenaar418155d2020-09-06 18:39:38 +02001949 timer_stop(id)
1950enddef
1951
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001952def Test_win_splitmove()
1953 split
1954 win_splitmove(1, 2, #{vertical: true, rightbelow: true})
1955 close
1956enddef
1957
1958""""""" end of builtin functions
1959
1960def Fibonacci(n: number): number
1961 if n < 2
1962 return n
1963 else
1964 return Fibonacci(n - 1) + Fibonacci(n - 2)
1965 endif
1966enddef
1967
Bram Moolenaar985116a2020-07-12 17:31:09 +02001968def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001969 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001970enddef
1971
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001972def TreeWalk(dir: string): list<any>
1973 return readdir(dir)->map({_, val ->
1974 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001975 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001976 : val
1977 })
1978enddef
1979
1980def Test_closure_in_map()
1981 mkdir('XclosureDir/tdir', 'p')
1982 writefile(['111'], 'XclosureDir/file1')
1983 writefile(['222'], 'XclosureDir/file2')
1984 writefile(['333'], 'XclosureDir/tdir/file3')
1985
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001986 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001987
1988 delete('XclosureDir', 'rf')
1989enddef
1990
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001991def Test_invalid_function_name()
1992 var lines =<< trim END
1993 vim9script
1994 def s: list<string>
1995 END
1996 CheckScriptFailure(lines, 'E129:')
1997
1998 lines =<< trim END
1999 vim9script
2000 def g: list<string>
2001 END
2002 CheckScriptFailure(lines, 'E129:')
2003
2004 lines =<< trim END
2005 vim9script
2006 def <SID>: list<string>
2007 END
2008 CheckScriptFailure(lines, 'E884:')
2009
2010 lines =<< trim END
2011 vim9script
2012 def F list<string>
2013 END
2014 CheckScriptFailure(lines, 'E488:')
2015enddef
2016
Bram Moolenaara90afb92020-07-15 22:38:56 +02002017def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002018 var Xsetlist = function('setloclist', [0])
Bram Moolenaara90afb92020-07-15 22:38:56 +02002019 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002020 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02002021
2022 Xsetlist = function('setloclist', [0, [], ' '])
2023 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002024 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02002025
2026 Xsetlist = function('setqflist')
2027 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002028 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02002029
2030 Xsetlist = function('setqflist', [[], ' '])
2031 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002032 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002033
2034 var Len: func: number = function('len', ['word'])
2035 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02002036enddef
2037
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002038def Test_cmd_modifier()
2039 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02002040 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002041enddef
2042
2043def Test_restore_modifiers()
2044 # check that when compiling a :def function command modifiers are not messed
2045 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002046 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002047 vim9script
2048 set eventignore=
2049 autocmd QuickFixCmdPost * copen
2050 def AutocmdsDisabled()
2051 eval 0
2052 enddef
2053 func Func()
2054 noautocmd call s:AutocmdsDisabled()
2055 let g:ei_after = &eventignore
2056 endfunc
2057 Func()
2058 END
2059 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002060 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002061enddef
2062
Bram Moolenaardfa3d552020-09-10 22:05:08 +02002063def StackTop()
2064 eval 1
2065 eval 2
2066 # call not on fourth line
2067 StackBot()
2068enddef
2069
2070def StackBot()
2071 # throw an error
2072 eval [][0]
2073enddef
2074
2075def Test_callstack_def()
2076 try
2077 StackTop()
2078 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002079 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02002080 endtry
2081enddef
2082
Bram Moolenaare8211a32020-10-09 22:04:29 +02002083" Re-using spot for variable used in block
2084def Test_block_scoped_var()
2085 var lines =<< trim END
2086 vim9script
2087 def Func()
2088 var x = ['a', 'b', 'c']
2089 if 1
2090 var y = 'x'
2091 map(x, {-> y})
2092 endif
2093 var z = x
2094 assert_equal(['x', 'x', 'x'], z)
2095 enddef
2096 Func()
2097 END
2098 CheckScriptSuccess(lines)
2099enddef
2100
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002101
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002102" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker