blob: 6ff23e95a73d9d0e16038ee6b511f8c88a0916d8 [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 Moolenaar5deeb3f2020-04-05 17:08:17 +020097let s:nothing = 0
98def ReturnNothing()
99 s:nothing = 1
100 if true
101 return
102 endif
103 s:nothing = 2
104enddef
105
106def Test_return_nothing()
107 ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200108 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200109enddef
110
111func Increment()
112 let g:counter += 1
113endfunc
114
115def Test_call_ufunc_count()
116 g:counter = 1
117 Increment()
118 Increment()
119 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200120 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200121 g:counter->assert_equal(4)
122 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200123 unlet g:counter
124enddef
125
126def MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200127 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200128 for s in rest
129 res ..= ',' .. s
130 endfor
131 return res
132enddef
133
134def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200135 MyVarargs('one')->assert_equal('one')
136 MyVarargs('one', 'two')->assert_equal('one,two')
137 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200138enddef
139
140def MyDefaultArgs(name = 'string'): string
141 return name
142enddef
143
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200144def MyDefaultSecond(name: string, second: bool = true): string
145 return second ? name : 'none'
146enddef
147
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200148def Test_call_default_args()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200149 MyDefaultArgs()->assert_equal('string')
150 MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200151 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200152
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200153 MyDefaultSecond('test')->assert_equal('test')
154 MyDefaultSecond('test', true)->assert_equal('test')
155 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200156
Bram Moolenaar822ba242020-05-24 23:00:18 +0200157 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar77072282020-09-16 17:55:40 +0200158 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 +0200159enddef
160
161def Test_nested_function()
162 def Nested(arg: string): string
163 return 'nested ' .. arg
164 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200165 Nested('function')->assert_equal('nested function')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200166
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200167 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
168 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
169
Bram Moolenaar04b12692020-05-04 23:24:44 +0200170 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200171 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
172 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200173
174 CheckDefFailure([
175 'def Outer()',
176 ' def Inner()',
177 ' # comment',
178 ' enddef',
179 ' def Inner()',
180 ' enddef',
181 'enddef'], 'E1073:')
182 CheckDefFailure([
183 'def Outer()',
184 ' def Inner()',
185 ' # comment',
186 ' enddef',
187 ' def! Inner()',
188 ' enddef',
189 'enddef'], 'E1117:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200190enddef
191
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200192func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200193 call MyDefaultArgs()->assert_equal('string')
194 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200195 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200196endfunc
197
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200198def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200199 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200200 vim9script
201 def Outer()
202 def g:Inner(): string
203 return 'inner'
204 enddef
205 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200206 defcompile
207 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200208 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200209 delfunc g:Inner
210 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200211 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200212 delfunc g:Inner
213 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200214 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200215 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200216 END
217 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200218
219 lines =<< trim END
220 vim9script
221 def Outer()
222 def g:Inner(): string
223 return 'inner'
224 enddef
225 enddef
226 defcompile
227 Outer()
228 Outer()
229 END
230 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200231
232 lines =<< trim END
233 vim9script
234 def Func()
235 echo 'script'
236 enddef
237 def Outer()
238 def Func()
239 echo 'inner'
240 enddef
241 enddef
242 defcompile
243 END
244 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200245enddef
246
Bram Moolenaar333894b2020-08-01 18:53:07 +0200247def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200248 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200249 vim9script
250 def g:Func(): string
251 return 'global'
252 enddef
253 def Func(): string
254 return 'local'
255 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200256 g:Func()->assert_equal('global')
257 Func()->assert_equal('local')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200258 END
259 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200260
261 lines =<< trim END
262 vim9script
263 def g:Funcy()
264 echo 'funcy'
265 enddef
266 s:Funcy()
267 END
268 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200269enddef
270
Bram Moolenaar0f769812020-09-12 18:32:34 +0200271def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200272 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200273 vim9script
274 def g:Gfunc(): string
275 return 'global'
276 enddef
277 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200278 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200279 return Gfunc('testing')
280 enddef
281 g:Gfunc()->assert_equal('global')
282 AnotherFunc()->assert_equal(7)
283 delfunc g:Gfunc
284 END
285 CheckScriptSuccess(lines)
286
287 lines =<< trim END
288 vim9script
289 def g:Func(): string
290 return 'global'
291 enddef
292 def AnotherFunc()
293 g:Func = function('len')
294 enddef
295 AnotherFunc()
296 END
297 CheckScriptFailure(lines, 'E705:')
298 delfunc g:Func
299enddef
300
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200301func TakesOneArg(arg)
302 echo a:arg
303endfunc
304
305def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200306 CheckDefFailure(['TakesOneArg()'], 'E119:')
307 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
308 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
309 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200310
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200311 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200312 vim9script
313 def Func(s: string)
314 echo s
315 enddef
316 Func([])
317 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200318 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200319
320 lines =<< trim END
321 vim9script
322 def FuncOne(nr: number)
323 echo nr
324 enddef
325 def FuncTwo()
326 FuncOne()
327 enddef
328 defcompile
329 END
330 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200331 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200332 try
333 source Xscript
334 catch
335 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
336 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
337 didCatch = true
338 endtry
339 assert_true(didCatch)
340
341 lines =<< trim END
342 vim9script
343 def FuncOne(nr: number)
344 echo nr
345 enddef
346 def FuncTwo()
347 FuncOne(1, 2)
348 enddef
349 defcompile
350 END
351 writefile(lines, 'Xscript')
352 didCatch = false
353 try
354 source Xscript
355 catch
356 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
357 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
358 didCatch = true
359 endtry
360 assert_true(didCatch)
361
362 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200363enddef
364
365" Default arg and varargs
366def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200367 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200368 for s in rest
369 res ..= ',' .. s
370 endfor
371 return res
372enddef
373
374def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200375 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200376 MyDefVarargs('one')->assert_equal('one,foo')
377 MyDefVarargs('one', 'two')->assert_equal('one,two')
378 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200379 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200380 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200381 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200382 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200383
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200384 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200385 vim9script
386 def Func(...l: list<string>)
387 echo l
388 enddef
389 Func('a', 'b', 'c')
390 END
391 CheckScriptSuccess(lines)
392
393 lines =<< trim END
394 vim9script
395 def Func(...l: list<string>)
396 echo l
397 enddef
398 Func()
399 END
400 CheckScriptSuccess(lines)
401
402 lines =<< trim END
403 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200404 def Func(...l: any)
405 echo l
406 enddef
407 Func(0)
408 END
409 CheckScriptSuccess(lines)
410
411 lines =<< trim END
412 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200413 def Func(..._l: list<string>)
414 echo _l
415 enddef
416 Func('a', 'b', 'c')
417 END
418 CheckScriptSuccess(lines)
419
420 lines =<< trim END
421 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200422 def Func(...l: list<string>)
423 echo l
424 enddef
425 Func(1, 2, 3)
426 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200427 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200428
429 lines =<< trim END
430 vim9script
431 def Func(...l: list<string>)
432 echo l
433 enddef
434 Func('a', 9)
435 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200436 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200437
438 lines =<< trim END
439 vim9script
440 def Func(...l: list<string>)
441 echo l
442 enddef
443 Func(1, 'a')
444 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200445 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200446enddef
447
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200448def Test_call_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200449 var l = [3, 2, 1]
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200450 call('reverse', [l])
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200451 l->assert_equal([1, 2, 3])
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200452enddef
453
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200454let s:value = ''
455
456def FuncOneDefArg(opt = 'text')
457 s:value = opt
458enddef
459
460def FuncTwoDefArg(nr = 123, opt = 'text'): string
461 return nr .. opt
462enddef
463
464def FuncVarargs(...arg: list<string>): string
465 return join(arg, ',')
466enddef
467
468def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200469 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200470 RefDefArg = FuncOneDefArg
471 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200472 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200473 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200474 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200475
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200476 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200477 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200478 RefDef2Arg()->assert_equal('123text')
479 RefDef2Arg(99)->assert_equal('99text')
480 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200481
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200482 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
483 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200484
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200485 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200486 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200487 RefVarargs()->assert_equal('')
488 RefVarargs('one')->assert_equal('one')
489 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200490
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200491 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
492 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200493enddef
494
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200495" Only varargs
496def MyVarargsOnly(...args: list<string>): string
497 return join(args, ',')
498enddef
499
500def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200501 MyVarargsOnly()->assert_equal('')
502 MyVarargsOnly('one')->assert_equal('one')
503 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200504 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
505 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200506enddef
507
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200508def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200509 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200510 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200511 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200512enddef
513
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200514def DictArg(arg: dict<string>)
515 arg['key'] = 'value'
516enddef
517
518def ListArg(arg: list<string>)
519 arg[0] = 'value'
520enddef
521
522def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200523 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200524 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200525 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200526 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200527 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200528 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200529 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200530
Bram Moolenaard2c61702020-09-06 15:58:36 +0200531 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200532enddef
533
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200534" These argument names are reserved in legacy functions.
535def WithReservedNames(firstline: string, lastline: string): string
536 return firstline .. lastline
537enddef
538
539def Test_argument_names()
540 assert_equal('OK', WithReservedNames('O', 'K'))
541enddef
542
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200543def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200544 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200545 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200546enddef
547
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200548func DefinedLater(arg)
549 return a:arg
550endfunc
551
552def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200553 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200554 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
555 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200556
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200557 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200558 vim9script
559 def RetNumber(): number
560 return 123
561 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200562 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200563 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200564 END
565 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200566
567 lines =<< trim END
568 vim9script
569 def RetNumber(): number
570 return 123
571 enddef
572 def Bar(F: func: number): number
573 return F()
574 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200575 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200576 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200577 END
578 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200579
580 lines =<< trim END
581 vim9script
582 def UseNumber(nr: number)
583 echo nr
584 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200585 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200586 Funcref(123)
587 END
588 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200589
590 lines =<< trim END
591 vim9script
592 def UseNumber(nr: number)
593 echo nr
594 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200595 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200596 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200597 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200598
599 lines =<< trim END
600 vim9script
601 def EchoNr(nr = 34)
602 g:echo = nr
603 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200604 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200605 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200606 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200607 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200608 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200609 END
610 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200611
612 lines =<< trim END
613 vim9script
614 def EchoList(...l: list<number>)
615 g:echo = l
616 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200617 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200618 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200619 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200620 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200621 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200622 END
623 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200624
625 lines =<< trim END
626 vim9script
627 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
628 g:optarg = opt
629 g:listarg = l
630 return nr
631 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200632 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200633 Funcref(10)->assert_equal(10)
634 g:optarg->assert_equal(12)
635 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200636
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200637 Funcref(11, 22)->assert_equal(11)
638 g:optarg->assert_equal(22)
639 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200640
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200641 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
642 g:optarg->assert_equal(18)
643 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200644 END
645 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200646enddef
647
648let SomeFunc = function('len')
649let NotAFunc = 'text'
650
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200651def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200652 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200653 var Ref1: func(bool): string
654 var Ref2: func(bool): number
655 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200656 Ref3 = g:cond ? Ref1 : Ref2
657
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200658 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200659 var Refa1: func(bool): number
660 var Refa2: func(bool, number): number
661 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200662 Refa3 = g:cond ? Refa1 : Refa2
663
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200664 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200665 var Refb1: func(bool, string): number
666 var Refb2: func(string, number): number
667 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200668 Refb3 = g:cond ? Refb1 : Refb2
669enddef
670
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200671def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200672 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200673enddef
674
675def DefinedEvenLater(arg: string): string
676 return arg
677enddef
678
679def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200680 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200681 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200682enddef
683
684def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200685 CheckScriptFailure([
686 'def Func(): number',
687 'return "a"',
688 'enddef',
689 'defcompile'], 'expected number but got string')
690 CheckScriptFailure([
691 'def Func(): string',
692 'return 1',
693 'enddef',
694 'defcompile'], 'expected string but got number')
695 CheckScriptFailure([
696 'def Func(): void',
697 'return "a"',
698 'enddef',
699 'defcompile'],
700 'E1096: Returning a value in a function without a return type')
701 CheckScriptFailure([
702 'def Func()',
703 'return "a"',
704 'enddef',
705 'defcompile'],
706 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200707
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200708 CheckScriptFailure([
709 'def Func(): number',
710 'return',
711 'enddef',
712 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200713
714 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
715 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200716 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200717
718 CheckScriptFailure([
719 'vim9script',
720 'def FuncB()',
721 ' return 123',
722 'enddef',
723 'def FuncA()',
724 ' FuncB()',
725 'enddef',
726 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200727enddef
728
729def Test_arg_type_wrong()
730 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200731 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200732 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200733 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200734enddef
735
736def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200737 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200738 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200739 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200740 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200741 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200742 enddef
743 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200744 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200745
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200746 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200747 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200748 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200749
Bram Moolenaar67979662020-06-20 22:50:47 +0200750 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200751 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200752 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200753
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200754 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200755 def ListFunc(arg: list<number>)
756 listvar = arg
757 enddef
758 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200759 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200760
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200761 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200762 def DictFunc(arg: dict<number>)
763 dictvar = arg
764 enddef
765 {'a': 1, 'b': 2}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200766 dictvar->assert_equal(#{a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200767 def CompiledDict()
768 {'a': 3, 'b': 4}->DictFunc()
769 enddef
770 CompiledDict()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200771 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200772
773 #{a: 3, b: 4}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200774 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200775
776 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200777 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200778 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200779 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200780
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200781 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200782 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200783 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200784 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200785 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200786 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200787
788 def UseString()
789 'xyork'->MyFunc()
790 enddef
791 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200792 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200793
Bram Moolenaar10409562020-07-29 20:00:38 +0200794 def UseString2()
795 "knife"->MyFunc()
796 enddef
797 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200798 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200799
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200800 # prepending a colon makes it a mark
801 new
802 setline(1, ['aaa', 'bbb', 'ccc'])
803 normal! 3Gmt1G
804 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200805 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200806 bwipe!
807
Bram Moolenaare6b53242020-07-01 17:28:33 +0200808 MyFunc(
809 'continued'
810 )
811 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200812 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200813 )
814
815 call MyFunc(
816 'more'
817 ..
818 'lines'
819 )
820 assert_equal(
821 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200822 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200823 END
824 writefile(lines, 'Xcall.vim')
825 source Xcall.vim
826 delete('Xcall.vim')
827enddef
828
829def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200830 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200831 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200832 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200833 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200834 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200835 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200836 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200837 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200838 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200839enddef
840
Bram Moolenaar65b95452020-07-19 14:03:09 +0200841def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200842 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200843 vim9script
844 def MyFunc(arg: string)
845 echo arg
846 enddef
847 MyFunc(1234)
848 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200849 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200850enddef
851
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200852def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200853 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200854 vim9script
855 const var = ''
856 def MyFunc(arg: string)
857 var = 'asdf'
858 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200859 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200860 END
861 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200862 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200863 delete('Xcall_const.vim')
864enddef
865
866" Test that inside :function a Python function can be defined, :def is not
867" recognized.
868func Test_function_python()
869 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200870 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200871 execute py "<< EOF"
872def do_something():
873 return 1
874EOF
875endfunc
876
877def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200878 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200879 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200880 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200881 echo 'hello'
882 enddef
883
884 def CallGoneSoon()
885 GoneSoon()
886 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200887 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200888
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200889 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200890 CallGoneSoon()
891 END
892 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200893 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
894 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200895
896 delete('XToDelFunc')
897enddef
898
899def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200900 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200901 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200902 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200903 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200904 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200905 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200906 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200907 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200908 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200909
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200910 g:Func0()->assert_equal(0)
911 g:Func1()->assert_equal('Func1')
912 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200913
914 delfunc! Func0
915 delfunc! Func1
916 delfunc! Func2
917enddef
918
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200919def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200920 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200921 vim9script
922 func Func(arg)
923 echo a:arg
924 endfunc
925 Func('text')
926 END
927 writefile(lines, 'XVim9Func')
928 so XVim9Func
929
930 delete('XVim9Func')
931enddef
932
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200933" Test for internal functions returning different types
934func Test_InternalFuncRetType()
935 let lines =<< trim END
936 def RetFloat(): float
937 return ceil(1.456)
938 enddef
939
940 def RetListAny(): list<any>
Bram Moolenaar17a836c2020-08-12 17:35:58 +0200941 return items({'k': 'v'})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200942 enddef
943
944 def RetListString(): list<string>
945 return split('a:b:c', ':')
946 enddef
947
948 def RetListDictAny(): list<dict<any>>
949 return getbufinfo()
950 enddef
951
952 def RetDictNumber(): dict<number>
953 return wordcount()
954 enddef
955
956 def RetDictString(): dict<string>
957 return environ()
958 enddef
959 END
960 call writefile(lines, 'Xscript')
961 source Xscript
962
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200963 call RetFloat()->assert_equal(2.0)
964 call RetListAny()->assert_equal([['k', 'v']])
965 call RetListString()->assert_equal(['a', 'b', 'c'])
966 call RetListDictAny()->assert_notequal([])
967 call RetDictNumber()->assert_notequal({})
968 call RetDictString()->assert_notequal({})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200969 call delete('Xscript')
970endfunc
971
972" Test for passing too many or too few arguments to internal functions
973func Test_internalfunc_arg_error()
974 let l =<< trim END
975 def! FArgErr(): float
976 return ceil(1.1, 2)
977 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200978 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200979 END
980 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200981 call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200982 let l =<< trim END
983 def! FArgErr(): float
984 return ceil()
985 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200986 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200987 END
988 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200989 call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200990 call delete('Xinvalidarg')
991endfunc
992
993let s:funcResult = 0
994
995def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200996 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200997enddef
998
999def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001000 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001001 return 1234
1002enddef
1003
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001004def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02001005 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001006 return 'text'
1007enddef
1008
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001009def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001010 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001011enddef
1012
1013def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001014 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001015 return arg
1016enddef
1017
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001018def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001019 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001020enddef
1021
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001022def FuncOneArgRetString(arg: string): string
1023 return arg
1024enddef
1025
Bram Moolenaar89228602020-04-05 22:14:54 +02001026def FuncOneArgRetAny(arg: any): any
1027 return arg
1028enddef
1029
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001030def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001031 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001032 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001033 Ref1 = FuncNoArgNoRet
1034 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001035 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001036
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001037 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001038 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001039 Ref2 = FuncNoArgNoRet
1040 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001041 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001042
Bram Moolenaar53900992020-08-22 19:02:02 +02001043 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001044 Ref2 = FuncOneArgNoRet
1045 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001046 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001047
Bram Moolenaar53900992020-08-22 19:02:02 +02001048 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001049 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001050 Ref2()->assert_equal(1234)
1051 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001052
Bram Moolenaar53900992020-08-22 19:02:02 +02001053 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001054 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001055 Ref2(13)->assert_equal(13)
1056 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001057enddef
1058
Bram Moolenaar9978d472020-07-05 16:01:56 +02001059def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001060 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001061 for n in repeat([1], 3)
1062 res += n
1063 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001064 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001065
1066 res = 0
1067 for n in add([1, 2], 3)
1068 res += n
1069 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001070 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001071enddef
1072
Bram Moolenaar846178a2020-07-05 17:04:13 +02001073def Test_argv_return_type()
1074 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001075 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001076 for name in argv()
1077 res ..= name
1078 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001079 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001080enddef
1081
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001082def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001083 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001084 RefVoid = FuncNoArgNoRet
1085 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001086 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1087 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001088
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001089 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001090 RefAny = FuncNoArgRetNumber
1091 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001092 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1093 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001094
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001095 var RefAnyNoArgs: func: any = RefAny
1096
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001097 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001098 RefNr = FuncNoArgRetNumber
1099 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001100 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1101 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001102
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001103 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001104 RefStr = FuncNoArgRetString
1105 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001106 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1107 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001108enddef
1109
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001110def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001111 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001112
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001113 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1114 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1115 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1116 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1117 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1118 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 +02001119
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001120 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1121 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1122 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:')
1123 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001124enddef
1125
Bram Moolenaar89228602020-04-05 22:14:54 +02001126def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001127 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001128 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001129 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001130
1131 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001132 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001133
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001134 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001135 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001136 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001137
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001138 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001139enddef
1140
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001141def Test_func_common_type()
1142 def FuncOne(n: number): number
1143 return n
1144 enddef
1145 def FuncTwo(s: string): number
1146 return len(s)
1147 enddef
1148 def FuncThree(n: number, s: string): number
1149 return n + len(s)
1150 enddef
1151 var list = [FuncOne, FuncTwo, FuncThree]
1152 assert_equal(8, list[0](8))
1153 assert_equal(4, list[1]('word'))
1154 assert_equal(7, list[2](3, 'word'))
1155enddef
1156
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001157def MultiLine(
1158 arg1: string,
1159 arg2 = 1234,
1160 ...rest: list<string>
1161 ): string
1162 return arg1 .. arg2 .. join(rest, '-')
1163enddef
1164
Bram Moolenaar2c330432020-04-13 14:41:35 +02001165def MultiLineComment(
1166 arg1: string, # comment
1167 arg2 = 1234, # comment
1168 ...rest: list<string> # comment
1169 ): string # comment
1170 return arg1 .. arg2 .. join(rest, '-')
1171enddef
1172
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001173def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001174 MultiLine('text')->assert_equal('text1234')
1175 MultiLine('text', 777)->assert_equal('text777')
1176 MultiLine('text', 777, 'one')->assert_equal('text777one')
1177 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001178enddef
1179
Bram Moolenaar23e03252020-04-12 22:22:31 +02001180func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001181 call MultiLine('text')->assert_equal('text1234')
1182 call MultiLine('text', 777)->assert_equal('text777')
1183 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1184 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001185endfunc
1186
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001187
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001188" When using CheckScriptFailure() for the below test, E1010 is generated instead
1189" of E1056.
1190func Test_E1056_1059()
1191 let caught_1056 = 0
1192 try
1193 def F():
1194 return 1
1195 enddef
1196 catch /E1056:/
1197 let caught_1056 = 1
1198 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001199 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001200
1201 let caught_1059 = 0
1202 try
1203 def F5(items : list)
1204 echo 'a'
1205 enddef
1206 catch /E1059:/
1207 let caught_1059 = 1
1208 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001209 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001210endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001211
Bram Moolenaar015f4262020-05-05 21:25:22 +02001212func DelMe()
1213 echo 'DelMe'
1214endfunc
1215
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001216def Test_error_reporting()
1217 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001218 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001219 " comment
1220 def Func()
1221 # comment
1222 # comment
1223 invalid
1224 enddef
1225 defcompile
1226 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001227 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001228 try
1229 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001230 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001231 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001232 v:exception->assert_match('Invalid command: invalid')
1233 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001234 endtry
1235
1236 # comment lines after the start of the function
1237 lines =<< trim END
1238 " comment
1239 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001240 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001241 # comment
1242 # comment
1243 invalid
1244 enddef
1245 defcompile
1246 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001247 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001248 try
1249 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001250 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001251 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001252 v:exception->assert_match('Invalid command: invalid')
1253 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001254 endtry
1255
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001256 lines =<< trim END
1257 vim9script
1258 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001259 var db = #{foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001260 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001261 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001262 enddef
1263 defcompile
1264 Func()
1265 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001266 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001267 try
1268 source Xdef
1269 assert_report('should have failed')
1270 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001271 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001272 endtry
1273
Bram Moolenaar08052222020-09-14 17:04:31 +02001274 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001275enddef
1276
Bram Moolenaar015f4262020-05-05 21:25:22 +02001277def Test_deleted_function()
1278 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001279 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001280 'delfunc g:DelMe',
1281 'echo RefMe()'], 'E117:')
1282enddef
1283
1284def Test_unknown_function()
1285 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001286 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001287 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001288enddef
1289
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001290def RefFunc(Ref: func(string): string): string
1291 return Ref('more')
1292enddef
1293
1294def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001295 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001296 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001297enddef
1298
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001299def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001300 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001301 g:Ref = {s -> local .. s}
1302enddef
1303
1304def Test_closure_ref_after_return()
1305 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001306 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001307 unlet g:Ref
1308enddef
1309
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001310def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001311 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001312 g:Extend = {s -> local->add(s)}
1313 g:Read = {-> local}
1314enddef
1315
1316def Test_closure_two_refs()
1317 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001318 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001319 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001320 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001321 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001322 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001323
1324 unlet g:Extend
1325 unlet g:Read
1326enddef
1327
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001328def ReadRef(Ref: func(): list<string>): string
1329 return join(Ref(), ' ')
1330enddef
1331
Bram Moolenaar5e654232020-09-16 15:22:00 +02001332def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001333 Ref(add)
1334enddef
1335
1336def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001337 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001338 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001339 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001340 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001341 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001342 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001343
1344 unlet g:Extend
1345 unlet g:Read
1346enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001347
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001348def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001349 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001350 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1351enddef
1352
1353def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001354 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001355 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1356enddef
1357
1358def Test_closure_using_argument()
1359 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001360 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001361
1362 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001363 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001364
1365 unlet g:UseArg
1366 unlet g:UseVararg
1367enddef
1368
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001369def MakeGetAndAppendRefs()
1370 var local = 'a'
1371
1372 def Append(arg: string)
1373 local ..= arg
1374 enddef
1375 g:Append = Append
1376
1377 def Get(): string
1378 return local
1379 enddef
1380 g:Get = Get
1381enddef
1382
1383def Test_closure_append_get()
1384 MakeGetAndAppendRefs()
1385 g:Get()->assert_equal('a')
1386 g:Append('-b')
1387 g:Get()->assert_equal('a-b')
1388 g:Append('-c')
1389 g:Get()->assert_equal('a-b-c')
1390
1391 unlet g:Append
1392 unlet g:Get
1393enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001394
Bram Moolenaar04b12692020-05-04 23:24:44 +02001395def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001396 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001397 def Closure(arg: string): string
1398 return local .. arg
1399 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001400 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001401enddef
1402
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001403func GetResult(Ref)
1404 return a:Ref('some')
1405endfunc
1406
1407def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001408 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001409 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001410 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001411enddef
1412
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001413def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001414 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001415 vim9script
1416 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001417 var name = 0
1418 for i in range(2)
1419 timer_start(0, {-> name})
1420 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001421 enddef
1422 Func()
1423 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001424 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001425enddef
1426
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001427def Test_nested_closure_used()
1428 var lines =<< trim END
1429 vim9script
1430 def Func()
1431 var x = 'hello'
1432 var Closure = {-> x}
1433 g:Myclosure = {-> Closure()}
1434 enddef
1435 Func()
1436 assert_equal('hello', g:Myclosure())
1437 END
1438 CheckScriptSuccess(lines)
1439enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001440
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001441def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001442 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001443 vim9script
1444 def FuncA()
1445 FuncB(0)
1446 enddef
1447 def FuncB(n: number): list<string>
1448 return map([0], {_, v -> n})
1449 enddef
1450 FuncA()
1451 END
1452 CheckScriptFailure(lines, 'E1012:')
1453enddef
1454
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001455def Test_nested_lambda()
1456 var lines =<< trim END
1457 vim9script
1458 def Func()
1459 var x = 4
1460 var Lambda1 = {-> 7}
1461 var Lambda2 = {-> [Lambda1(), x]}
1462 var res = Lambda2()
1463 assert_equal([7, 4], res)
1464 enddef
1465 Func()
1466 END
1467 CheckScriptSuccess(lines)
1468enddef
1469
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001470def Test_sort_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001471 var res: list<number>
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001472 res = [1, 2, 3]->sort()
1473enddef
1474
Bram Moolenaar08e51f42020-09-16 23:23:36 +02001475def Test_sort_argument()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001476 var res = ['b', 'a', 'c']->sort('i')
Bram Moolenaar08e51f42020-09-16 23:23:36 +02001477 res->assert_equal(['a', 'b', 'c'])
1478enddef
1479
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001480def Test_getqflist_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001481 var l = getqflist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001482 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001483
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001484 var d = getqflist(#{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001485 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001486enddef
1487
1488def Test_getloclist_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001489 var l = getloclist(1)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001490 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001491
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001492 var d = getloclist(1, #{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001493 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001494enddef
1495
Bram Moolenaara66ba012020-07-05 18:41:08 +02001496def Test_copy_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001497 var l = copy([1, 2, 3])
1498 var res = 0
Bram Moolenaara66ba012020-07-05 18:41:08 +02001499 for n in l
1500 res += n
1501 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001502 res->assert_equal(6)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001503
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001504 var dl = deepcopy([1, 2, 3])
Bram Moolenaara66ba012020-07-05 18:41:08 +02001505 res = 0
1506 for n in dl
1507 res += n
1508 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001509 res->assert_equal(6)
Bram Moolenaar44b4a242020-09-05 17:18:28 +02001510
1511 dl = deepcopy([1, 2, 3], true)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001512enddef
1513
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001514def Test_extend_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001515 var l = extend([1, 2], [3])
1516 var res = 0
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001517 for n in l
1518 res += n
1519 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001520 res->assert_equal(6)
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001521enddef
1522
Bram Moolenaar2df47312020-09-05 17:30:44 +02001523def Test_garbagecollect()
1524 garbagecollect(true)
1525enddef
1526
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001527def Test_insert_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001528 var l = insert([2, 1], 3)
1529 var res = 0
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001530 for n in l
1531 res += n
1532 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001533 res->assert_equal(6)
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001534enddef
1535
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001536def Test_keys_return_type()
1537 const var: list<string> = #{a: 1, b: 2}->keys()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001538 var->assert_equal(['a', 'b'])
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001539enddef
1540
Bram Moolenaar67627352020-07-05 21:10:24 +02001541def Test_reverse_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001542 var l = reverse([1, 2, 3])
1543 var res = 0
Bram Moolenaar67627352020-07-05 21:10:24 +02001544 for n in l
1545 res += n
1546 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001547 res->assert_equal(6)
Bram Moolenaar67627352020-07-05 21:10:24 +02001548enddef
1549
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001550def Test_remove_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001551 var l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
1552 var res = 0
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001553 for n in l
1554 res += n
1555 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001556 res->assert_equal(3)
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001557enddef
1558
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001559def Test_filter_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001560 var l = filter([1, 2, 3], {-> 1})
1561 var res = 0
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001562 for n in l
1563 res += n
1564 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001565 res->assert_equal(6)
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001566enddef
1567
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001568def Test_bufnr()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001569 var buf = bufnr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001570 bufnr('%')->assert_equal(buf)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001571
1572 buf = bufnr('Xdummy', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001573 buf->assert_notequal(-1)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001574 exe 'bwipe! ' .. buf
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001575enddef
1576
Bram Moolenaarec65d772020-08-20 22:29:12 +02001577def Test_col()
1578 new
1579 setline(1, 'asdf')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001580 col([1, '$'])->assert_equal(5)
Bram Moolenaarec65d772020-08-20 22:29:12 +02001581enddef
1582
Bram Moolenaar24f77502020-09-04 19:50:57 +02001583def Test_char2nr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001584 char2nr('あ', true)->assert_equal(12354)
Bram Moolenaar24f77502020-09-04 19:50:57 +02001585enddef
1586
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001587def Test_getreg_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001588 var s1: string = getreg('"')
1589 var s2: string = getreg('"', 1)
1590 var s3: list<string> = getreg('"', 1, 1)
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001591enddef
1592
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001593def Wrong_dict_key_type(items: list<number>): list<number>
1594 return filter(items, {_, val -> get({val: 1}, 'x')})
1595enddef
1596
1597def Test_wrong_dict_key_type()
Bram Moolenaar5e654232020-09-16 15:22:00 +02001598 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:')
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001599enddef
1600
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001601def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001602 var path: string = empty(dir)
1603 \ ? 'empty'
1604 \ : 'full'
1605 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001606enddef
1607
1608def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001609 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001610enddef
1611
Bram Moolenaar5e654232020-09-16 15:22:00 +02001612def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001613 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001614 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001615 ->toupper()})
1616 ->reverse()
1617 return x
1618enddef
1619
1620def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001621 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001622enddef
1623
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001624func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001625 CheckScreendump
1626
1627 let lines =<< trim END
1628 vim9script
1629 def EchoNothing()
1630 silent echo ''
1631 enddef
1632 defcompile
1633 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001634 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001635
1636 " Check that the balloon shows up after a mouse move
1637 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001638 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001639 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1640
1641 " clean up
1642 call StopVimInTerminal(buf)
1643 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001644endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001645
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001646""""""" builtin functions that behave differently in Vim9
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001647
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001648def Test_bufname()
1649 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001650 bufname('%')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001651 edit OtherFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001652 bufname('#')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001653 close
Bram Moolenaar191929b2020-08-19 21:20:49 +02001654enddef
1655
Bram Moolenaara5d38412020-09-02 21:02:35 +02001656def Test_bufwinid()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001657 var origwin = win_getid()
Bram Moolenaara5d38412020-09-02 21:02:35 +02001658 below split SomeFile
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001659 var SomeFileID = win_getid()
Bram Moolenaara5d38412020-09-02 21:02:35 +02001660 below split OtherFile
1661 below split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001662 bufwinid('SomeFile')->assert_equal(SomeFileID)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001663
1664 win_gotoid(origwin)
1665 only
1666 bwipe SomeFile
1667 bwipe OtherFile
1668enddef
1669
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001670def Test_count()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001671 count('ABC ABC ABC', 'b', true)->assert_equal(3)
1672 count('ABC ABC ABC', 'b', false)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001673enddef
1674
1675def Test_expand()
1676 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001677 expand('%', true, true)->assert_equal(['SomeFile'])
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001678 close
1679enddef
1680
1681def Test_getbufinfo()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001682 var bufinfo = getbufinfo(bufnr())
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001683 getbufinfo('%')->assert_equal(bufinfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001684
1685 edit Xtestfile1
1686 hide edit Xtestfile2
1687 hide enew
1688 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false})
1689 ->len()->assert_equal(3)
1690 bwipe Xtestfile1 Xtestfile2
1691enddef
1692
Bram Moolenaara5d38412020-09-02 21:02:35 +02001693def Test_getbufline()
1694 e SomeFile
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001695 var buf = bufnr()
Bram Moolenaara5d38412020-09-02 21:02:35 +02001696 e #
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001697 var lines = ['aaa', 'bbb', 'ccc']
Bram Moolenaara5d38412020-09-02 21:02:35 +02001698 setbufline(buf, 1, lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001699 getbufline('#', 1, '$')->assert_equal(lines)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001700
1701 bwipe!
1702enddef
1703
1704def Test_getchangelist()
1705 new
1706 setline(1, 'some text')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001707 var changelist = bufnr()->getchangelist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001708 getchangelist('%')->assert_equal(changelist)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001709 bwipe!
1710enddef
1711
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001712def Test_getchar()
Bram Moolenaar636c5d52020-09-05 18:48:57 +02001713 while getchar(0)
1714 endwhile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001715 getchar(true)->assert_equal(0)
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001716enddef
1717
Bram Moolenaard217a872020-09-05 18:31:33 +02001718def Test_getcompletion()
1719 set wildignore=*.vim,*~
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001720 var l = getcompletion('run', 'file', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001721 l->assert_equal([])
Bram Moolenaard217a872020-09-05 18:31:33 +02001722 set wildignore&
1723enddef
1724
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001725def Test_getreg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001726 var lines = ['aaa', 'bbb', 'ccc']
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001727 setreg('a', lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001728 getreg('a', true, true)->assert_equal(lines)
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001729enddef
1730
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001731def Test_glob()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001732 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001733enddef
1734
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001735def Test_globpath()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001736 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001737enddef
1738
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001739def Test_has()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001740 has('eval', true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001741enddef
1742
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001743def Test_hasmapto()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001744 hasmapto('foobar', 'i', true)->assert_equal(0)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001745 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001746 hasmapto('foobar', 'i', true)->assert_equal(1)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001747 iunabbrev foo
1748enddef
1749
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001750def Test_index()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001751 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001752enddef
1753
1754def Test_list2str_str2list_utf8()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001755 var s = "\u3042\u3044"
1756 var l = [0x3042, 0x3044]
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001757 str2list(s, true)->assert_equal(l)
1758 list2str(l, true)->assert_equal(s)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001759enddef
1760
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001761def SID(): number
1762 return expand('<SID>')
1763 ->matchstr('<SNR>\zs\d\+\ze_$')
1764 ->str2nr()
1765enddef
1766
1767def Test_maparg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001768 var lnum = str2nr(expand('<sflnum>'))
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001769 map foo bar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001770 maparg('foo', '', false, true)->assert_equal(#{
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001771 lnum: lnum + 1,
1772 script: 0,
1773 mode: ' ',
1774 silent: 0,
1775 noremap: 0,
1776 lhs: 'foo',
1777 lhsraw: 'foo',
1778 nowait: 0,
1779 expr: 0,
1780 sid: SID(),
1781 rhs: 'bar',
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001782 buffer: 0})
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001783 unmap foo
1784enddef
1785
1786def Test_mapcheck()
1787 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001788 mapcheck('foo', 'i', true)->assert_equal('foobar')
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001789 iunabbrev foo
1790enddef
1791
Bram Moolenaar74273e62020-10-01 21:37:21 +02001792def Test_maparg_mapset()
1793 nnoremap <F3> :echo "hit F3"<CR>
1794 var mapsave = maparg('<F3>', 'n', false, true)
1795 mapset('n', false, mapsave)
1796
1797 nunmap <F3>
1798enddef
1799
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001800def Test_nr2char()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001801 nr2char(97, true)->assert_equal('a')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001802enddef
1803
1804def Test_readdir()
1805 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1806 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
1807enddef
1808
1809def Test_search()
1810 new
1811 setline(1, ['foo', 'bar'])
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001812 var val = 0
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001813 # skip expr returns boolean
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001814 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001815 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001816 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001817 # skip expr returns number, only 0 and 1 are accepted
1818 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001819 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001820 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001821 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001822 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1823 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1824enddef
1825
1826def Test_searchcount()
1827 new
1828 setline(1, "foo bar")
1829 :/foo
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001830 searchcount(#{recompute: true})
1831 ->assert_equal(#{
1832 exact_match: 1,
1833 current: 1,
1834 total: 1,
1835 maxcount: 99,
1836 incomplete: 0})
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001837 bwipe!
1838enddef
1839
1840def Test_searchdecl()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001841 searchdecl('blah', true, true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001842enddef
1843
1844def Test_setbufvar()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001845 setbufvar(bufnr('%'), '&syntax', 'vim')
1846 &syntax->assert_equal('vim')
1847 setbufvar(bufnr('%'), '&ts', 16)
1848 &ts->assert_equal(16)
1849 settabwinvar(1, 1, '&syntax', 'vam')
1850 &syntax->assert_equal('vam')
1851 settabwinvar(1, 1, '&ts', 15)
1852 &ts->assert_equal(15)
1853 setlocal ts=8
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001854
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001855 setbufvar('%', 'myvar', 123)
1856 getbufvar('%', 'myvar')->assert_equal(123)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001857enddef
1858
Bram Moolenaar401f0c02020-09-05 22:37:39 +02001859def Test_setloclist()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001860 var items = [#{filename: '/tmp/file', lnum: 1, valid: true}]
1861 var what = #{items: items}
Bram Moolenaar401f0c02020-09-05 22:37:39 +02001862 setqflist([], ' ', what)
1863 setloclist(0, [], ' ', what)
1864enddef
1865
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001866def Test_setreg()
1867 setreg('a', ['aaa', 'bbb', 'ccc'])
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001868 var reginfo = getreginfo('a')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001869 setreg('a', reginfo)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001870 getreginfo('a')->assert_equal(reginfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001871enddef
1872
Bram Moolenaar7c27f332020-09-05 22:45:55 +02001873def Test_spellsuggest()
1874 if !has('spell')
1875 MissingFeature 'spell'
1876 else
1877 spellsuggest('marrch', 1, true)->assert_equal(['March'])
1878 endif
1879enddef
1880
Bram Moolenaar3986b942020-09-06 16:09:04 +02001881def Test_split()
1882 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
1883enddef
1884
1885def Test_str2nr()
1886 str2nr("1'000'000", 10, true)->assert_equal(1000000)
1887enddef
1888
1889def Test_strchars()
1890 strchars("A\u20dd", true)->assert_equal(1)
1891enddef
1892
Bram Moolenaarad304702020-09-06 18:22:53 +02001893def Test_submatch()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001894 var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
1895 var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()}
1896 var actual = substitute('A123456789', pat, Rep, '')
1897 var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001898 actual->assert_equal(expected)
Bram Moolenaarad304702020-09-06 18:22:53 +02001899enddef
1900
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001901def Test_synID()
1902 new
1903 setline(1, "text")
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001904 synID(1, 1, true)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001905 bwipe!
1906enddef
1907
Bram Moolenaarad304702020-09-06 18:22:53 +02001908def Test_term_gettty()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001909 if !has('terminal')
1910 MissingFeature 'terminal'
1911 else
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001912 var buf = Run_shell_in_terminal({})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001913 term_gettty(buf, true)->assert_notequal('')
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001914 StopShellInTerminal(buf)
1915 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001916enddef
1917
1918def Test_term_start()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001919 if !has('terminal')
1920 MissingFeature 'terminal'
1921 else
1922 botright new
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001923 var winnr = winnr()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001924 term_start(&shell, #{curwin: true})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001925 winnr()->assert_equal(winnr)
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001926 bwipe!
1927 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001928enddef
1929
Bram Moolenaar418155d2020-09-06 18:39:38 +02001930def Test_timer_paused()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001931 var id = timer_start(50, {-> 0})
Bram Moolenaar418155d2020-09-06 18:39:38 +02001932 timer_pause(id, true)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001933 var info = timer_info(id)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001934 info[0]['paused']->assert_equal(1)
Bram Moolenaar418155d2020-09-06 18:39:38 +02001935 timer_stop(id)
1936enddef
1937
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001938def Test_win_splitmove()
1939 split
1940 win_splitmove(1, 2, #{vertical: true, rightbelow: true})
1941 close
1942enddef
1943
1944""""""" end of builtin functions
1945
1946def Fibonacci(n: number): number
1947 if n < 2
1948 return n
1949 else
1950 return Fibonacci(n - 1) + Fibonacci(n - 2)
1951 endif
1952enddef
1953
Bram Moolenaar985116a2020-07-12 17:31:09 +02001954def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001955 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001956enddef
1957
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001958def TreeWalk(dir: string): list<any>
1959 return readdir(dir)->map({_, val ->
1960 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001961 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001962 : val
1963 })
1964enddef
1965
1966def Test_closure_in_map()
1967 mkdir('XclosureDir/tdir', 'p')
1968 writefile(['111'], 'XclosureDir/file1')
1969 writefile(['222'], 'XclosureDir/file2')
1970 writefile(['333'], 'XclosureDir/tdir/file3')
1971
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001972 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001973
1974 delete('XclosureDir', 'rf')
1975enddef
1976
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001977def Test_invalid_function_name()
1978 var lines =<< trim END
1979 vim9script
1980 def s: list<string>
1981 END
1982 CheckScriptFailure(lines, 'E129:')
1983
1984 lines =<< trim END
1985 vim9script
1986 def g: list<string>
1987 END
1988 CheckScriptFailure(lines, 'E129:')
1989
1990 lines =<< trim END
1991 vim9script
1992 def <SID>: list<string>
1993 END
1994 CheckScriptFailure(lines, 'E884:')
1995
1996 lines =<< trim END
1997 vim9script
1998 def F list<string>
1999 END
2000 CheckScriptFailure(lines, 'E488:')
2001enddef
2002
Bram Moolenaara90afb92020-07-15 22:38:56 +02002003def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002004 var Xsetlist = function('setloclist', [0])
Bram Moolenaara90afb92020-07-15 22:38:56 +02002005 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002006 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02002007
2008 Xsetlist = function('setloclist', [0, [], ' '])
2009 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002010 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02002011
2012 Xsetlist = function('setqflist')
2013 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002014 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02002015
2016 Xsetlist = function('setqflist', [[], ' '])
2017 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002018 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02002019
2020 var Len: func: number = function('len', ['word'])
2021 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02002022enddef
2023
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002024def Test_cmd_modifier()
2025 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02002026 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002027enddef
2028
2029def Test_restore_modifiers()
2030 # check that when compiling a :def function command modifiers are not messed
2031 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002032 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002033 vim9script
2034 set eventignore=
2035 autocmd QuickFixCmdPost * copen
2036 def AutocmdsDisabled()
2037 eval 0
2038 enddef
2039 func Func()
2040 noautocmd call s:AutocmdsDisabled()
2041 let g:ei_after = &eventignore
2042 endfunc
2043 Func()
2044 END
2045 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002046 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002047enddef
2048
Bram Moolenaardfa3d552020-09-10 22:05:08 +02002049def StackTop()
2050 eval 1
2051 eval 2
2052 # call not on fourth line
2053 StackBot()
2054enddef
2055
2056def StackBot()
2057 # throw an error
2058 eval [][0]
2059enddef
2060
2061def Test_callstack_def()
2062 try
2063 StackTop()
2064 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002065 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02002066 endtry
2067enddef
2068
Bram Moolenaare8211a32020-10-09 22:04:29 +02002069" Re-using spot for variable used in block
2070def Test_block_scoped_var()
2071 var lines =<< trim END
2072 vim9script
2073 def Func()
2074 var x = ['a', 'b', 'c']
2075 if 1
2076 var y = 'x'
2077 map(x, {-> y})
2078 endif
2079 var z = x
2080 assert_equal(['x', 'x', 'x'], z)
2081 enddef
2082 Func()
2083 END
2084 CheckScriptSuccess(lines)
2085enddef
2086
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002087
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002088" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker