blob: 4329754c390b11a0c75e536529211de1d9304500 [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 Moolenaarf4e8cdd2020-10-12 22:07:13 +020016def Test_compiling_error()
17 # use a terminal to see the whole error message
18 CheckRunVimInTerminal
19
20 var lines =<< trim END
21 vim9script
22 def Fails()
23 echo nothing
24 enddef
25 defcompile
26 END
27 call writefile(lines, 'XTest_compile_error')
28 var buf = RunVimInTerminal('-S XTest_compile_error',
29 #{rows: 10, wait_for_ruler: 0})
30 var text = ''
31 for loop in range(100)
32 text = ''
33 for i in range(1, 9)
34 text ..= term_getline(buf, i)
35 endfor
36 if text =~ 'Error detected'
37 break
38 endif
39 sleep 20m
40 endfor
41 assert_match('Error detected while compiling command line.*Fails.*Variable not found: nothing', text)
42
43 # clean up
44 call StopVimInTerminal(buf)
45 call delete('XTest_compile_error')
46enddef
47
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020048def ReturnString(): string
49 return 'string'
50enddef
51
52def ReturnNumber(): number
53 return 123
54enddef
55
56let g:notNumber = 'string'
57
58def ReturnGlobal(): number
59 return g:notNumber
60enddef
61
62def Test_return_something()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020063 ReturnString()->assert_equal('string')
64 ReturnNumber()->assert_equal(123)
Bram Moolenaar5e654232020-09-16 15:22:00 +020065 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020066enddef
67
Bram Moolenaarefd88552020-06-18 20:50:10 +020068def Test_missing_return()
69 CheckDefFailure(['def Missing(): number',
70 ' if g:cond',
71 ' echo "no return"',
72 ' else',
73 ' return 0',
74 ' endif'
75 'enddef'], 'E1027:')
76 CheckDefFailure(['def Missing(): number',
77 ' if g:cond',
78 ' return 1',
79 ' else',
80 ' echo "no return"',
81 ' endif'
82 'enddef'], 'E1027:')
83 CheckDefFailure(['def Missing(): number',
84 ' if g:cond',
85 ' return 1',
86 ' else',
87 ' return 2',
88 ' endif'
89 ' return 3'
90 'enddef'], 'E1095:')
91enddef
92
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020093let s:nothing = 0
94def ReturnNothing()
95 s:nothing = 1
96 if true
97 return
98 endif
99 s:nothing = 2
100enddef
101
102def Test_return_nothing()
103 ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200104 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200105enddef
106
107func Increment()
108 let g:counter += 1
109endfunc
110
111def Test_call_ufunc_count()
112 g:counter = 1
113 Increment()
114 Increment()
115 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200116 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200117 g:counter->assert_equal(4)
118 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200119 unlet g:counter
120enddef
121
122def MyVarargs(arg: string, ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200123 var res = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200124 for s in rest
125 res ..= ',' .. s
126 endfor
127 return res
128enddef
129
130def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200131 MyVarargs('one')->assert_equal('one')
132 MyVarargs('one', 'two')->assert_equal('one,two')
133 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200134enddef
135
136def MyDefaultArgs(name = 'string'): string
137 return name
138enddef
139
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200140def MyDefaultSecond(name: string, second: bool = true): string
141 return second ? name : 'none'
142enddef
143
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200144def Test_call_default_args()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200145 MyDefaultArgs()->assert_equal('string')
146 MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200147 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200148
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200149 MyDefaultSecond('test')->assert_equal('test')
150 MyDefaultSecond('test', true)->assert_equal('test')
151 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200152
Bram Moolenaar822ba242020-05-24 23:00:18 +0200153 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
Bram Moolenaar77072282020-09-16 17:55:40 +0200154 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 +0200155enddef
156
157def Test_nested_function()
158 def Nested(arg: string): string
159 return 'nested ' .. arg
160 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200161 Nested('function')->assert_equal('nested function')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200162
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200163 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
164 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
165
Bram Moolenaar04b12692020-05-04 23:24:44 +0200166 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200167 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
168 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200169
170 CheckDefFailure([
171 'def Outer()',
172 ' def Inner()',
173 ' # comment',
174 ' enddef',
175 ' def Inner()',
176 ' enddef',
177 'enddef'], 'E1073:')
178 CheckDefFailure([
179 'def Outer()',
180 ' def Inner()',
181 ' # comment',
182 ' enddef',
183 ' def! Inner()',
184 ' enddef',
185 'enddef'], 'E1117:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200186enddef
187
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200188func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200189 call MyDefaultArgs()->assert_equal('string')
190 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200191 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200192endfunc
193
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200194def Test_nested_global_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200195 var lines =<< trim END
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200196 vim9script
197 def Outer()
198 def g:Inner(): string
199 return 'inner'
200 enddef
201 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200202 defcompile
203 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200204 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200205 delfunc g:Inner
206 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200207 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200208 delfunc g:Inner
209 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200210 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200211 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200212 END
213 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200214
215 lines =<< trim END
216 vim9script
217 def Outer()
218 def g:Inner(): string
219 return 'inner'
220 enddef
221 enddef
222 defcompile
223 Outer()
224 Outer()
225 END
226 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200227
228 lines =<< trim END
229 vim9script
230 def Func()
231 echo 'script'
232 enddef
233 def Outer()
234 def Func()
235 echo 'inner'
236 enddef
237 enddef
238 defcompile
239 END
240 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200241enddef
242
Bram Moolenaar333894b2020-08-01 18:53:07 +0200243def Test_global_local_function()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200244 var lines =<< trim END
Bram Moolenaar333894b2020-08-01 18:53:07 +0200245 vim9script
246 def g:Func(): string
247 return 'global'
248 enddef
249 def Func(): string
250 return 'local'
251 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200252 g:Func()->assert_equal('global')
253 Func()->assert_equal('local')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200254 END
255 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200256
257 lines =<< trim END
258 vim9script
259 def g:Funcy()
260 echo 'funcy'
261 enddef
262 s:Funcy()
263 END
264 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200265enddef
266
Bram Moolenaar0f769812020-09-12 18:32:34 +0200267def Test_local_function_shadows_global()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200268 var lines =<< trim END
Bram Moolenaar0f769812020-09-12 18:32:34 +0200269 vim9script
270 def g:Gfunc(): string
271 return 'global'
272 enddef
273 def AnotherFunc(): number
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200274 var Gfunc = function('len')
Bram Moolenaar0f769812020-09-12 18:32:34 +0200275 return Gfunc('testing')
276 enddef
277 g:Gfunc()->assert_equal('global')
278 AnotherFunc()->assert_equal(7)
279 delfunc g:Gfunc
280 END
281 CheckScriptSuccess(lines)
282
283 lines =<< trim END
284 vim9script
285 def g:Func(): string
286 return 'global'
287 enddef
288 def AnotherFunc()
289 g:Func = function('len')
290 enddef
291 AnotherFunc()
292 END
293 CheckScriptFailure(lines, 'E705:')
294 delfunc g:Func
295enddef
296
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200297func TakesOneArg(arg)
298 echo a:arg
299endfunc
300
301def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200302 CheckDefFailure(['TakesOneArg()'], 'E119:')
303 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
304 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
305 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200306
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200307 var lines =<< trim END
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200308 vim9script
309 def Func(s: string)
310 echo s
311 enddef
312 Func([])
313 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200314 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaarb185a402020-09-18 22:42:00 +0200315
316 lines =<< trim END
317 vim9script
318 def FuncOne(nr: number)
319 echo nr
320 enddef
321 def FuncTwo()
322 FuncOne()
323 enddef
324 defcompile
325 END
326 writefile(lines, 'Xscript')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200327 var didCatch = false
Bram Moolenaarb185a402020-09-18 22:42:00 +0200328 try
329 source Xscript
330 catch
331 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception)
332 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
333 didCatch = true
334 endtry
335 assert_true(didCatch)
336
337 lines =<< trim END
338 vim9script
339 def FuncOne(nr: number)
340 echo nr
341 enddef
342 def FuncTwo()
343 FuncOne(1, 2)
344 enddef
345 defcompile
346 END
347 writefile(lines, 'Xscript')
348 didCatch = false
349 try
350 source Xscript
351 catch
352 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception)
353 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint)
354 didCatch = true
355 endtry
356 assert_true(didCatch)
357
358 delete('Xscript')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200359enddef
360
361" Default arg and varargs
362def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200363 var res = one .. ',' .. two
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200364 for s in rest
365 res ..= ',' .. s
366 endfor
367 return res
368enddef
369
370def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200371 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200372 MyDefVarargs('one')->assert_equal('one,foo')
373 MyDefVarargs('one', 'two')->assert_equal('one,two')
374 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200375 CheckDefFailure(['MyDefVarargs("one", 22)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200376 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200377 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
Bram Moolenaar77072282020-09-16 17:55:40 +0200378 'E1013: Argument 3: type mismatch, expected string but got number')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200379
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200380 var lines =<< trim END
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200381 vim9script
382 def Func(...l: list<string>)
383 echo l
384 enddef
385 Func('a', 'b', 'c')
386 END
387 CheckScriptSuccess(lines)
388
389 lines =<< trim END
390 vim9script
391 def Func(...l: list<string>)
392 echo l
393 enddef
394 Func()
395 END
396 CheckScriptSuccess(lines)
397
398 lines =<< trim END
399 vim9script
Bram Moolenaar2f8cbc42020-09-16 17:22:59 +0200400 def Func(...l: any)
401 echo l
402 enddef
403 Func(0)
404 END
405 CheckScriptSuccess(lines)
406
407 lines =<< trim END
408 vim9script
Bram Moolenaar28022722020-09-21 22:02:49 +0200409 def Func(..._l: list<string>)
410 echo _l
411 enddef
412 Func('a', 'b', 'c')
413 END
414 CheckScriptSuccess(lines)
415
416 lines =<< trim END
417 vim9script
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200418 def Func(...l: list<string>)
419 echo l
420 enddef
421 Func(1, 2, 3)
422 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200423 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200424
425 lines =<< trim END
426 vim9script
427 def Func(...l: list<string>)
428 echo l
429 enddef
430 Func('a', 9)
431 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200432 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200433
434 lines =<< trim END
435 vim9script
436 def Func(...l: list<string>)
437 echo l
438 enddef
439 Func(1, 'a')
440 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200441 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200442enddef
443
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200444def Test_call_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200445 var l = [3, 2, 1]
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200446 call('reverse', [l])
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200447 l->assert_equal([1, 2, 3])
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200448enddef
449
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200450let s:value = ''
451
452def FuncOneDefArg(opt = 'text')
453 s:value = opt
454enddef
455
456def FuncTwoDefArg(nr = 123, opt = 'text'): string
457 return nr .. opt
458enddef
459
460def FuncVarargs(...arg: list<string>): string
461 return join(arg, ',')
462enddef
463
464def Test_func_type_varargs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200465 var RefDefArg: func(?string)
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200466 RefDefArg = FuncOneDefArg
467 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200468 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200469 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200470 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200471
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200472 var RefDef2Arg: func(?number, ?string): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200473 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200474 RefDef2Arg()->assert_equal('123text')
475 RefDef2Arg(99)->assert_equal('99text')
476 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200477
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200478 CheckDefFailure(['var RefWrong: func(string?)'], 'E1010:')
479 CheckDefFailure(['var RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200480
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200481 var RefVarargs: func(...list<string>): string
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200482 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200483 RefVarargs()->assert_equal('')
484 RefVarargs('one')->assert_equal('one')
485 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200486
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200487 CheckDefFailure(['var RefWrong: func(...list<string>, string)'], 'E110:')
488 CheckDefFailure(['var RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200489enddef
490
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200491" Only varargs
492def MyVarargsOnly(...args: list<string>): string
493 return join(args, ',')
494enddef
495
496def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200497 MyVarargsOnly()->assert_equal('')
498 MyVarargsOnly('one')->assert_equal('one')
499 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaar77072282020-09-16 17:55:40 +0200500 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number')
501 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200502enddef
503
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200504def Test_using_var_as_arg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200505 writefile(['def Func(x: number)', 'var x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200506 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200507 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200508enddef
509
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200510def DictArg(arg: dict<string>)
511 arg['key'] = 'value'
512enddef
513
514def ListArg(arg: list<string>)
515 arg[0] = 'value'
516enddef
517
518def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200519 # works for dict and list
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200520 var d: dict<string> = {}
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200521 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200522 d['key']->assert_equal('value')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200523 var l: list<string> = []
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200524 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200525 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200526
Bram Moolenaard2c61702020-09-06 15:58:36 +0200527 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200528enddef
529
Bram Moolenaarb816dae2020-09-20 22:04:00 +0200530" These argument names are reserved in legacy functions.
531def WithReservedNames(firstline: string, lastline: string): string
532 return firstline .. lastline
533enddef
534
535def Test_argument_names()
536 assert_equal('OK', WithReservedNames('O', 'K'))
537enddef
538
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200539def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200540 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200541 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200542enddef
543
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200544func DefinedLater(arg)
545 return a:arg
546endfunc
547
548def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200549 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200550 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
551 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200552
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200553 var lines =<< trim END
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200554 vim9script
555 def RetNumber(): number
556 return 123
557 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200558 var Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200559 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200560 END
561 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200562
563 lines =<< trim END
564 vim9script
565 def RetNumber(): number
566 return 123
567 enddef
568 def Bar(F: func: number): number
569 return F()
570 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200571 var Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200572 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200573 END
574 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200575
576 lines =<< trim END
577 vim9script
578 def UseNumber(nr: number)
579 echo nr
580 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200581 var Funcref: func(number) = function('UseNumber')
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200582 Funcref(123)
583 END
584 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200585
586 lines =<< trim END
587 vim9script
588 def UseNumber(nr: number)
589 echo nr
590 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200591 var Funcref: func(string) = function('UseNumber')
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200592 END
Bram Moolenaar5e654232020-09-16 15:22:00 +0200593 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200594
595 lines =<< trim END
596 vim9script
597 def EchoNr(nr = 34)
598 g:echo = nr
599 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200600 var Funcref: func(?number) = function('EchoNr')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200601 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200602 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200603 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200604 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200605 END
606 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200607
608 lines =<< trim END
609 vim9script
610 def EchoList(...l: list<number>)
611 g:echo = l
612 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200613 var Funcref: func(...list<number>) = function('EchoList')
Bram Moolenaarace61322020-07-26 18:16:58 +0200614 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200615 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200616 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200617 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200618 END
619 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200620
621 lines =<< trim END
622 vim9script
623 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
624 g:optarg = opt
625 g:listarg = l
626 return nr
627 enddef
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200628 var Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200629 Funcref(10)->assert_equal(10)
630 g:optarg->assert_equal(12)
631 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200632
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200633 Funcref(11, 22)->assert_equal(11)
634 g:optarg->assert_equal(22)
635 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200636
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200637 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
638 g:optarg->assert_equal(18)
639 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200640 END
641 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200642enddef
643
644let SomeFunc = function('len')
645let NotAFunc = 'text'
646
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200647def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200648 # same arguments, different return type
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200649 var Ref1: func(bool): string
650 var Ref2: func(bool): number
651 var Ref3: func(bool): any
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200652 Ref3 = g:cond ? Ref1 : Ref2
653
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200654 # different number of arguments
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200655 var Refa1: func(bool): number
656 var Refa2: func(bool, number): number
657 var Refa3: func: number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200658 Refa3 = g:cond ? Refa1 : Refa2
659
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200660 # different argument types
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200661 var Refb1: func(bool, string): number
662 var Refb2: func(string, number): number
663 var Refb3: func(any, any): number
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200664 Refb3 = g:cond ? Refb1 : Refb2
665enddef
666
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200667def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200668 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200669enddef
670
671def DefinedEvenLater(arg: string): string
672 return arg
673enddef
674
675def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200676 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200677 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200678enddef
679
680def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200681 CheckScriptFailure([
682 'def Func(): number',
683 'return "a"',
684 'enddef',
685 'defcompile'], 'expected number but got string')
686 CheckScriptFailure([
687 'def Func(): string',
688 'return 1',
689 'enddef',
690 'defcompile'], 'expected string but got number')
691 CheckScriptFailure([
692 'def Func(): void',
693 'return "a"',
694 'enddef',
695 'defcompile'],
696 'E1096: Returning a value in a function without a return type')
697 CheckScriptFailure([
698 'def Func()',
699 'return "a"',
700 'enddef',
701 'defcompile'],
702 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200703
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200704 CheckScriptFailure([
705 'def Func(): number',
706 'return',
707 'enddef',
708 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200709
710 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
711 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200712 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200713
714 CheckScriptFailure([
715 'vim9script',
716 'def FuncB()',
717 ' return 123',
718 'enddef',
719 'def FuncA()',
720 ' FuncB()',
721 'enddef',
722 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200723enddef
724
725def Test_arg_type_wrong()
726 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200727 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200728 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200729 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200730enddef
731
732def Test_vim9script_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200733 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200734 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200735 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200736 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200737 name = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200738 enddef
739 MyFunc('foobar')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200740 name->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200741
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200742 var str = 'barfoo'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200743 str->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200744 name->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200745
Bram Moolenaar67979662020-06-20 22:50:47 +0200746 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200747 g:value->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200748 name->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200749
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200750 var listvar = []
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200751 def ListFunc(arg: list<number>)
752 listvar = arg
753 enddef
754 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200755 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200756
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200757 var dictvar = {}
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200758 def DictFunc(arg: dict<number>)
759 dictvar = arg
760 enddef
761 {'a': 1, 'b': 2}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200762 dictvar->assert_equal(#{a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200763 def CompiledDict()
764 {'a': 3, 'b': 4}->DictFunc()
765 enddef
766 CompiledDict()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200767 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200768
769 #{a: 3, b: 4}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200770 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200771
772 ('text')->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200773 name->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200774 ("some")->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200775 name->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200776
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200777 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200778 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200779 'asdfasdf'->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200780 name->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200781 "xyz"->MyFunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200782 name->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200783
784 def UseString()
785 'xyork'->MyFunc()
786 enddef
787 UseString()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200788 name->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200789
Bram Moolenaar10409562020-07-29 20:00:38 +0200790 def UseString2()
791 "knife"->MyFunc()
792 enddef
793 UseString2()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200794 name->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200795
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200796 # prepending a colon makes it a mark
797 new
798 setline(1, ['aaa', 'bbb', 'ccc'])
799 normal! 3Gmt1G
800 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200801 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200802 bwipe!
803
Bram Moolenaare6b53242020-07-01 17:28:33 +0200804 MyFunc(
805 'continued'
806 )
807 assert_equal('continued',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200808 name
Bram Moolenaare6b53242020-07-01 17:28:33 +0200809 )
810
811 call MyFunc(
812 'more'
813 ..
814 'lines'
815 )
816 assert_equal(
817 'morelines',
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200818 name)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200819 END
820 writefile(lines, 'Xcall.vim')
821 source Xcall.vim
822 delete('Xcall.vim')
823enddef
824
825def Test_vim9script_call_fail_decl()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200826 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200827 vim9script
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200828 var name = ''
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200829 def MyFunc(arg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200830 var name = 123
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200831 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200832 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200833 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200834 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200835enddef
836
Bram Moolenaar65b95452020-07-19 14:03:09 +0200837def Test_vim9script_call_fail_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200838 var lines =<< trim END
Bram Moolenaar65b95452020-07-19 14:03:09 +0200839 vim9script
840 def MyFunc(arg: string)
841 echo arg
842 enddef
843 MyFunc(1234)
844 END
Bram Moolenaar77072282020-09-16 17:55:40 +0200845 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200846enddef
847
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200848def Test_vim9script_call_fail_const()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200849 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200850 vim9script
851 const var = ''
852 def MyFunc(arg: string)
853 var = 'asdf'
854 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200855 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200856 END
857 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200858 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200859 delete('Xcall_const.vim')
860enddef
861
862" Test that inside :function a Python function can be defined, :def is not
863" recognized.
864func Test_function_python()
865 CheckFeature python3
Bram Moolenaar727345e2020-09-27 23:33:59 +0200866 let py = 'python3'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200867 execute py "<< EOF"
868def do_something():
869 return 1
870EOF
871endfunc
872
873def Test_delfunc()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200874 var lines =<< trim END
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200875 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200876 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200877 echo 'hello'
878 enddef
879
880 def CallGoneSoon()
881 GoneSoon()
882 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200883 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200884
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200885 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200886 CallGoneSoon()
887 END
888 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200889 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
890 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200891
892 delete('XToDelFunc')
893enddef
894
895def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200896 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200897 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200898 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200899 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200900 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200901 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200902 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200903 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200904 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200905
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200906 g:Func0()->assert_equal(0)
907 g:Func1()->assert_equal('Func1')
908 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200909
910 delfunc! Func0
911 delfunc! Func1
912 delfunc! Func2
913enddef
914
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200915def Test_vim9script_func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +0200916 var lines =<< trim END
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200917 vim9script
918 func Func(arg)
919 echo a:arg
920 endfunc
921 Func('text')
922 END
923 writefile(lines, 'XVim9Func')
924 so XVim9Func
925
926 delete('XVim9Func')
927enddef
928
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200929" Test for internal functions returning different types
930func Test_InternalFuncRetType()
931 let lines =<< trim END
932 def RetFloat(): float
933 return ceil(1.456)
934 enddef
935
936 def RetListAny(): list<any>
Bram Moolenaar17a836c2020-08-12 17:35:58 +0200937 return items({'k': 'v'})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200938 enddef
939
940 def RetListString(): list<string>
941 return split('a:b:c', ':')
942 enddef
943
944 def RetListDictAny(): list<dict<any>>
945 return getbufinfo()
946 enddef
947
948 def RetDictNumber(): dict<number>
949 return wordcount()
950 enddef
951
952 def RetDictString(): dict<string>
953 return environ()
954 enddef
955 END
956 call writefile(lines, 'Xscript')
957 source Xscript
958
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200959 call RetFloat()->assert_equal(2.0)
960 call RetListAny()->assert_equal([['k', 'v']])
961 call RetListString()->assert_equal(['a', 'b', 'c'])
962 call RetListDictAny()->assert_notequal([])
963 call RetDictNumber()->assert_notequal({})
964 call RetDictString()->assert_notequal({})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200965 call delete('Xscript')
966endfunc
967
968" Test for passing too many or too few arguments to internal functions
969func Test_internalfunc_arg_error()
970 let l =<< trim END
971 def! FArgErr(): float
972 return ceil(1.1, 2)
973 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200974 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200975 END
976 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200977 call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200978 let l =<< trim END
979 def! FArgErr(): float
980 return ceil()
981 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200982 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200983 END
984 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200985 call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200986 call delete('Xinvalidarg')
987endfunc
988
989let s:funcResult = 0
990
991def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200992 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200993enddef
994
995def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200996 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200997 return 1234
998enddef
999
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001000def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +02001001 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001002 return 'text'
1003enddef
1004
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001005def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001006 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001007enddef
1008
1009def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +02001010 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001011 return arg
1012enddef
1013
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001014def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +02001015 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +02001016enddef
1017
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001018def FuncOneArgRetString(arg: string): string
1019 return arg
1020enddef
1021
Bram Moolenaar89228602020-04-05 22:14:54 +02001022def FuncOneArgRetAny(arg: any): any
1023 return arg
1024enddef
1025
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001026def Test_func_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001027 var Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +02001028 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001029 Ref1 = FuncNoArgNoRet
1030 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001031 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001032
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001033 var Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +02001034 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001035 Ref2 = FuncNoArgNoRet
1036 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001037 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001038
Bram Moolenaar53900992020-08-22 19:02:02 +02001039 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001040 Ref2 = FuncOneArgNoRet
1041 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001042 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001043
Bram Moolenaar53900992020-08-22 19:02:02 +02001044 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001045 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001046 Ref2()->assert_equal(1234)
1047 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +02001048
Bram Moolenaar53900992020-08-22 19:02:02 +02001049 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +02001050 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001051 Ref2(13)->assert_equal(13)
1052 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001053enddef
1054
Bram Moolenaar9978d472020-07-05 16:01:56 +02001055def Test_repeat_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001056 var res = 0
Bram Moolenaar9978d472020-07-05 16:01:56 +02001057 for n in repeat([1], 3)
1058 res += n
1059 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001060 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +02001061
1062 res = 0
1063 for n in add([1, 2], 3)
1064 res += n
1065 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001066 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +02001067enddef
1068
Bram Moolenaar846178a2020-07-05 17:04:13 +02001069def Test_argv_return_type()
1070 next fileone filetwo
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001071 var res = ''
Bram Moolenaar846178a2020-07-05 17:04:13 +02001072 for name in argv()
1073 res ..= name
1074 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001075 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +02001076enddef
1077
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001078def Test_func_type_part()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001079 var RefVoid: func: void
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001080 RefVoid = FuncNoArgNoRet
1081 RefVoid = FuncOneArgNoRet
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001082 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number')
1083 CheckDefFailure(['var RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001084
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001085 var RefAny: func(): any
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001086 RefAny = FuncNoArgRetNumber
1087 RefAny = FuncNoArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001088 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()')
1089 CheckDefFailure(['var RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001090
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001091 var RefAnyNoArgs: func: any = RefAny
1092
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001093 var RefNr: func: number
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001094 RefNr = FuncNoArgRetNumber
1095 RefNr = FuncOneArgRetNumber
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001096 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()')
1097 CheckDefFailure(['var RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001098
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001099 var RefStr: func: string
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001100 RefStr = FuncNoArgRetString
1101 RefStr = FuncOneArgRetString
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001102 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()')
1103 CheckDefFailure(['var RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +02001104enddef
1105
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001106def Test_func_type_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001107 CheckDefFailure(['var ref1: func()'], 'E704:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001108
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001109 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number')
1110 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)')
1111 CheckDefFailure(['var Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number')
1112 CheckDefFailure(['var Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)')
1113 CheckDefFailure(['var Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)')
1114 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 +02001115
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001116 CheckDefFailure(['var RefWrong: func(string ,number)'], 'E1068:')
1117 CheckDefFailure(['var RefWrong: func(string,number)'], 'E1069:')
1118 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:')
1119 CheckDefFailure(['var RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001120enddef
1121
Bram Moolenaar89228602020-04-05 22:14:54 +02001122def Test_func_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001123 var nr: number
Bram Moolenaar89228602020-04-05 22:14:54 +02001124 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001125 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001126
1127 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001128 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001129
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001130 var str: string
Bram Moolenaar89228602020-04-05 22:14:54 +02001131 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001132 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001133
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001134 CheckDefFailure(['var str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001135enddef
1136
Bram Moolenaar6abd3dc2020-10-04 14:17:32 +02001137def Test_func_common_type()
1138 def FuncOne(n: number): number
1139 return n
1140 enddef
1141 def FuncTwo(s: string): number
1142 return len(s)
1143 enddef
1144 def FuncThree(n: number, s: string): number
1145 return n + len(s)
1146 enddef
1147 var list = [FuncOne, FuncTwo, FuncThree]
1148 assert_equal(8, list[0](8))
1149 assert_equal(4, list[1]('word'))
1150 assert_equal(7, list[2](3, 'word'))
1151enddef
1152
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001153def MultiLine(
1154 arg1: string,
1155 arg2 = 1234,
1156 ...rest: list<string>
1157 ): string
1158 return arg1 .. arg2 .. join(rest, '-')
1159enddef
1160
Bram Moolenaar2c330432020-04-13 14:41:35 +02001161def MultiLineComment(
1162 arg1: string, # comment
1163 arg2 = 1234, # comment
1164 ...rest: list<string> # comment
1165 ): string # comment
1166 return arg1 .. arg2 .. join(rest, '-')
1167enddef
1168
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001169def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001170 MultiLine('text')->assert_equal('text1234')
1171 MultiLine('text', 777)->assert_equal('text777')
1172 MultiLine('text', 777, 'one')->assert_equal('text777one')
1173 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001174enddef
1175
Bram Moolenaar23e03252020-04-12 22:22:31 +02001176func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001177 call MultiLine('text')->assert_equal('text1234')
1178 call MultiLine('text', 777)->assert_equal('text777')
1179 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1180 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001181endfunc
1182
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001183
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001184" When using CheckScriptFailure() for the below test, E1010 is generated instead
1185" of E1056.
1186func Test_E1056_1059()
1187 let caught_1056 = 0
1188 try
1189 def F():
1190 return 1
1191 enddef
1192 catch /E1056:/
1193 let caught_1056 = 1
1194 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001195 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001196
1197 let caught_1059 = 0
1198 try
1199 def F5(items : list)
1200 echo 'a'
1201 enddef
1202 catch /E1059:/
1203 let caught_1059 = 1
1204 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001205 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001206endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001207
Bram Moolenaar015f4262020-05-05 21:25:22 +02001208func DelMe()
1209 echo 'DelMe'
1210endfunc
1211
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001212def Test_error_reporting()
1213 # comment lines at the start of the function
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001214 var lines =<< trim END
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001215 " comment
1216 def Func()
1217 # comment
1218 # comment
1219 invalid
1220 enddef
1221 defcompile
1222 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001223 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001224 try
1225 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001226 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001227 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001228 v:exception->assert_match('Invalid command: invalid')
1229 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001230 endtry
1231
1232 # comment lines after the start of the function
1233 lines =<< trim END
1234 " comment
1235 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001236 var x = 1234
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001237 # comment
1238 # comment
1239 invalid
1240 enddef
1241 defcompile
1242 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001243 writefile(lines, 'Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001244 try
1245 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001246 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001247 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001248 v:exception->assert_match('Invalid command: invalid')
1249 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001250 endtry
1251
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001252 lines =<< trim END
1253 vim9script
1254 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001255 var db = #{foo: 1, bar: 2}
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001256 # comment
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001257 var x = db.asdf
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001258 enddef
1259 defcompile
1260 Func()
1261 END
Bram Moolenaar08052222020-09-14 17:04:31 +02001262 writefile(lines, 'Xdef')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001263 try
1264 source Xdef
1265 assert_report('should have failed')
1266 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001267 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001268 endtry
1269
Bram Moolenaar08052222020-09-14 17:04:31 +02001270 delete('Xdef')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001271enddef
1272
Bram Moolenaar015f4262020-05-05 21:25:22 +02001273def Test_deleted_function()
1274 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001275 'var RefMe: func = function("g:DelMe")',
Bram Moolenaar015f4262020-05-05 21:25:22 +02001276 'delfunc g:DelMe',
1277 'echo RefMe()'], 'E117:')
1278enddef
1279
1280def Test_unknown_function()
1281 CheckDefExecFailure([
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001282 'var Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001283 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001284enddef
1285
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001286def RefFunc(Ref: func(string): string): string
1287 return Ref('more')
1288enddef
1289
1290def Test_closure_simple()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001291 var local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001292 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001293enddef
1294
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001295def MakeRef()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001296 var local = 'some '
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001297 g:Ref = {s -> local .. s}
1298enddef
1299
1300def Test_closure_ref_after_return()
1301 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001302 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001303 unlet g:Ref
1304enddef
1305
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001306def MakeTwoRefs()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001307 var local = ['some']
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001308 g:Extend = {s -> local->add(s)}
1309 g:Read = {-> local}
1310enddef
1311
1312def Test_closure_two_refs()
1313 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001314 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001315 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001316 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001317 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001318 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001319
1320 unlet g:Extend
1321 unlet g:Read
1322enddef
1323
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001324def ReadRef(Ref: func(): list<string>): string
1325 return join(Ref(), ' ')
1326enddef
1327
Bram Moolenaar5e654232020-09-16 15:22:00 +02001328def ExtendRef(Ref: func(string): list<string>, add: string)
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001329 Ref(add)
1330enddef
1331
1332def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001333 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001334 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001335 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001336 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001337 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001338 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001339
1340 unlet g:Extend
1341 unlet g:Read
1342enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001343
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001344def MakeArgRefs(theArg: string)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001345 var local = 'loc_val'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001346 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1347enddef
1348
1349def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001350 var local = 'the_loc'
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001351 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1352enddef
1353
1354def Test_closure_using_argument()
1355 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001356 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001357
1358 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001359 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001360
1361 unlet g:UseArg
1362 unlet g:UseVararg
1363enddef
1364
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001365def MakeGetAndAppendRefs()
1366 var local = 'a'
1367
1368 def Append(arg: string)
1369 local ..= arg
1370 enddef
1371 g:Append = Append
1372
1373 def Get(): string
1374 return local
1375 enddef
1376 g:Get = Get
1377enddef
1378
1379def Test_closure_append_get()
1380 MakeGetAndAppendRefs()
1381 g:Get()->assert_equal('a')
1382 g:Append('-b')
1383 g:Get()->assert_equal('a-b')
1384 g:Append('-c')
1385 g:Get()->assert_equal('a-b-c')
1386
1387 unlet g:Append
1388 unlet g:Get
1389enddef
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001390
Bram Moolenaar04b12692020-05-04 23:24:44 +02001391def Test_nested_closure()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001392 var local = 'text'
Bram Moolenaar04b12692020-05-04 23:24:44 +02001393 def Closure(arg: string): string
1394 return local .. arg
1395 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001396 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001397enddef
1398
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001399func GetResult(Ref)
1400 return a:Ref('some')
1401endfunc
1402
1403def Test_call_closure_not_compiled()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001404 var text = 'text'
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001405 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001406 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001407enddef
1408
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001409def Test_double_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001410 var lines =<< trim END
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001411 vim9script
1412 def Func()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001413 var name = 0
1414 for i in range(2)
1415 timer_start(0, {-> name})
1416 endfor
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001417 enddef
1418 Func()
1419 END
Bram Moolenaar148ce7a2020-09-23 21:57:23 +02001420 CheckScriptSuccess(lines)
Bram Moolenaar7cbfaa52020-09-18 21:25:32 +02001421enddef
1422
Bram Moolenaar85d5e2b2020-10-10 14:13:01 +02001423def Test_nested_closure_used()
1424 var lines =<< trim END
1425 vim9script
1426 def Func()
1427 var x = 'hello'
1428 var Closure = {-> x}
1429 g:Myclosure = {-> Closure()}
1430 enddef
1431 Func()
1432 assert_equal('hello', g:Myclosure())
1433 END
1434 CheckScriptSuccess(lines)
1435enddef
Bram Moolenaar0876c782020-10-07 19:08:04 +02001436
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001437def Test_nested_closure_fails()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001438 var lines =<< trim END
Bram Moolenaarc70bdab2020-09-26 19:59:38 +02001439 vim9script
1440 def FuncA()
1441 FuncB(0)
1442 enddef
1443 def FuncB(n: number): list<string>
1444 return map([0], {_, v -> n})
1445 enddef
1446 FuncA()
1447 END
1448 CheckScriptFailure(lines, 'E1012:')
1449enddef
1450
Bram Moolenaar5366e1a2020-10-01 13:01:34 +02001451def Test_nested_lambda()
1452 var lines =<< trim END
1453 vim9script
1454 def Func()
1455 var x = 4
1456 var Lambda1 = {-> 7}
1457 var Lambda2 = {-> [Lambda1(), x]}
1458 var res = Lambda2()
1459 assert_equal([7, 4], res)
1460 enddef
1461 Func()
1462 END
1463 CheckScriptSuccess(lines)
1464enddef
1465
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001466def Test_sort_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001467 var res: list<number>
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001468 res = [1, 2, 3]->sort()
1469enddef
1470
Bram Moolenaar08e51f42020-09-16 23:23:36 +02001471def Test_sort_argument()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001472 var res = ['b', 'a', 'c']->sort('i')
Bram Moolenaar08e51f42020-09-16 23:23:36 +02001473 res->assert_equal(['a', 'b', 'c'])
1474enddef
1475
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001476def Test_getqflist_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001477 var l = getqflist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001478 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001479
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001480 var d = getqflist(#{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001481 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001482enddef
1483
1484def Test_getloclist_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001485 var l = getloclist(1)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001486 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001487
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001488 var d = getloclist(1, #{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001489 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001490enddef
1491
Bram Moolenaara66ba012020-07-05 18:41:08 +02001492def Test_copy_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001493 var l = copy([1, 2, 3])
1494 var res = 0
Bram Moolenaara66ba012020-07-05 18:41:08 +02001495 for n in l
1496 res += n
1497 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001498 res->assert_equal(6)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001499
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001500 var dl = deepcopy([1, 2, 3])
Bram Moolenaara66ba012020-07-05 18:41:08 +02001501 res = 0
1502 for n in dl
1503 res += n
1504 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001505 res->assert_equal(6)
Bram Moolenaar44b4a242020-09-05 17:18:28 +02001506
1507 dl = deepcopy([1, 2, 3], true)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001508enddef
1509
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001510def Test_extend_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001511 var l = extend([1, 2], [3])
1512 var res = 0
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001513 for n in l
1514 res += n
1515 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001516 res->assert_equal(6)
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001517enddef
1518
Bram Moolenaar2df47312020-09-05 17:30:44 +02001519def Test_garbagecollect()
1520 garbagecollect(true)
1521enddef
1522
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001523def Test_insert_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001524 var l = insert([2, 1], 3)
1525 var res = 0
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001526 for n in l
1527 res += n
1528 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001529 res->assert_equal(6)
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001530enddef
1531
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001532def Test_keys_return_type()
1533 const var: list<string> = #{a: 1, b: 2}->keys()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001534 var->assert_equal(['a', 'b'])
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001535enddef
1536
Bram Moolenaar67627352020-07-05 21:10:24 +02001537def Test_reverse_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001538 var l = reverse([1, 2, 3])
1539 var res = 0
Bram Moolenaar67627352020-07-05 21:10:24 +02001540 for n in l
1541 res += n
1542 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001543 res->assert_equal(6)
Bram Moolenaar67627352020-07-05 21:10:24 +02001544enddef
1545
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001546def Test_remove_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001547 var l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
1548 var res = 0
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001549 for n in l
1550 res += n
1551 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001552 res->assert_equal(3)
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001553enddef
1554
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001555def Test_filter_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001556 var l = filter([1, 2, 3], {-> 1})
1557 var res = 0
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001558 for n in l
1559 res += n
1560 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001561 res->assert_equal(6)
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001562enddef
1563
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001564def Test_bufnr()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001565 var buf = bufnr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001566 bufnr('%')->assert_equal(buf)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001567
1568 buf = bufnr('Xdummy', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001569 buf->assert_notequal(-1)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001570 exe 'bwipe! ' .. buf
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001571enddef
1572
Bram Moolenaarec65d772020-08-20 22:29:12 +02001573def Test_col()
1574 new
1575 setline(1, 'asdf')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001576 col([1, '$'])->assert_equal(5)
Bram Moolenaarec65d772020-08-20 22:29:12 +02001577enddef
1578
Bram Moolenaar24f77502020-09-04 19:50:57 +02001579def Test_char2nr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001580 char2nr('あ', true)->assert_equal(12354)
Bram Moolenaar24f77502020-09-04 19:50:57 +02001581enddef
1582
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001583def Test_getreg_return_type()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001584 var s1: string = getreg('"')
1585 var s2: string = getreg('"', 1)
1586 var s3: list<string> = getreg('"', 1, 1)
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001587enddef
1588
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001589def Wrong_dict_key_type(items: list<number>): list<number>
1590 return filter(items, {_, val -> get({val: 1}, 'x')})
1591enddef
1592
1593def Test_wrong_dict_key_type()
Bram Moolenaar5e654232020-09-16 15:22:00 +02001594 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:')
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001595enddef
1596
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001597def Line_continuation_in_def(dir: string = ''): string
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001598 var path: string = empty(dir)
1599 \ ? 'empty'
1600 \ : 'full'
1601 return path
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001602enddef
1603
1604def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001605 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001606enddef
1607
Bram Moolenaar5e654232020-09-16 15:22:00 +02001608def Line_continuation_in_lambda(): list<string>
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001609 var x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001610 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001611 ->toupper()})
1612 ->reverse()
1613 return x
1614enddef
1615
1616def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001617 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001618enddef
1619
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001620func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001621 CheckScreendump
1622
1623 let lines =<< trim END
1624 vim9script
1625 def EchoNothing()
1626 silent echo ''
1627 enddef
1628 defcompile
1629 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001630 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001631
1632 " Check that the balloon shows up after a mouse move
1633 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001634 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001635 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1636
1637 " clean up
1638 call StopVimInTerminal(buf)
1639 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001640endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001641
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001642""""""" builtin functions that behave differently in Vim9
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001643
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001644def Test_bufname()
1645 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001646 bufname('%')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001647 edit OtherFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001648 bufname('#')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001649 close
Bram Moolenaar191929b2020-08-19 21:20:49 +02001650enddef
1651
Bram Moolenaara5d38412020-09-02 21:02:35 +02001652def Test_bufwinid()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001653 var origwin = win_getid()
Bram Moolenaara5d38412020-09-02 21:02:35 +02001654 below split SomeFile
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001655 var SomeFileID = win_getid()
Bram Moolenaara5d38412020-09-02 21:02:35 +02001656 below split OtherFile
1657 below split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001658 bufwinid('SomeFile')->assert_equal(SomeFileID)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001659
1660 win_gotoid(origwin)
1661 only
1662 bwipe SomeFile
1663 bwipe OtherFile
1664enddef
1665
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001666def Test_count()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001667 count('ABC ABC ABC', 'b', true)->assert_equal(3)
1668 count('ABC ABC ABC', 'b', false)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001669enddef
1670
1671def Test_expand()
1672 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001673 expand('%', true, true)->assert_equal(['SomeFile'])
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001674 close
1675enddef
1676
1677def Test_getbufinfo()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001678 var bufinfo = getbufinfo(bufnr())
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001679 getbufinfo('%')->assert_equal(bufinfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001680
1681 edit Xtestfile1
1682 hide edit Xtestfile2
1683 hide enew
1684 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false})
1685 ->len()->assert_equal(3)
1686 bwipe Xtestfile1 Xtestfile2
1687enddef
1688
Bram Moolenaara5d38412020-09-02 21:02:35 +02001689def Test_getbufline()
1690 e SomeFile
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001691 var buf = bufnr()
Bram Moolenaara5d38412020-09-02 21:02:35 +02001692 e #
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001693 var lines = ['aaa', 'bbb', 'ccc']
Bram Moolenaara5d38412020-09-02 21:02:35 +02001694 setbufline(buf, 1, lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001695 getbufline('#', 1, '$')->assert_equal(lines)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001696
1697 bwipe!
1698enddef
1699
1700def Test_getchangelist()
1701 new
1702 setline(1, 'some text')
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001703 var changelist = bufnr()->getchangelist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001704 getchangelist('%')->assert_equal(changelist)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001705 bwipe!
1706enddef
1707
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001708def Test_getchar()
Bram Moolenaar636c5d52020-09-05 18:48:57 +02001709 while getchar(0)
1710 endwhile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001711 getchar(true)->assert_equal(0)
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001712enddef
1713
Bram Moolenaard217a872020-09-05 18:31:33 +02001714def Test_getcompletion()
1715 set wildignore=*.vim,*~
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001716 var l = getcompletion('run', 'file', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001717 l->assert_equal([])
Bram Moolenaard217a872020-09-05 18:31:33 +02001718 set wildignore&
1719enddef
1720
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001721def Test_getreg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001722 var lines = ['aaa', 'bbb', 'ccc']
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001723 setreg('a', lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001724 getreg('a', true, true)->assert_equal(lines)
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001725enddef
1726
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001727def Test_glob()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001728 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001729enddef
1730
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001731def Test_globpath()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001732 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001733enddef
1734
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001735def Test_has()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001736 has('eval', true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001737enddef
1738
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001739def Test_hasmapto()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001740 hasmapto('foobar', 'i', true)->assert_equal(0)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001741 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001742 hasmapto('foobar', 'i', true)->assert_equal(1)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001743 iunabbrev foo
1744enddef
1745
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001746def Test_index()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001747 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001748enddef
1749
1750def Test_list2str_str2list_utf8()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001751 var s = "\u3042\u3044"
1752 var l = [0x3042, 0x3044]
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001753 str2list(s, true)->assert_equal(l)
1754 list2str(l, true)->assert_equal(s)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001755enddef
1756
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001757def SID(): number
1758 return expand('<SID>')
1759 ->matchstr('<SNR>\zs\d\+\ze_$')
1760 ->str2nr()
1761enddef
1762
1763def Test_maparg()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001764 var lnum = str2nr(expand('<sflnum>'))
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001765 map foo bar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001766 maparg('foo', '', false, true)->assert_equal(#{
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001767 lnum: lnum + 1,
1768 script: 0,
1769 mode: ' ',
1770 silent: 0,
1771 noremap: 0,
1772 lhs: 'foo',
1773 lhsraw: 'foo',
1774 nowait: 0,
1775 expr: 0,
1776 sid: SID(),
1777 rhs: 'bar',
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001778 buffer: 0})
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001779 unmap foo
1780enddef
1781
1782def Test_mapcheck()
1783 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001784 mapcheck('foo', 'i', true)->assert_equal('foobar')
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001785 iunabbrev foo
1786enddef
1787
Bram Moolenaar74273e62020-10-01 21:37:21 +02001788def Test_maparg_mapset()
1789 nnoremap <F3> :echo "hit F3"<CR>
1790 var mapsave = maparg('<F3>', 'n', false, true)
1791 mapset('n', false, mapsave)
1792
1793 nunmap <F3>
1794enddef
1795
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001796def Test_nr2char()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001797 nr2char(97, true)->assert_equal('a')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001798enddef
1799
1800def Test_readdir()
1801 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1802 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
1803enddef
1804
1805def Test_search()
1806 new
1807 setline(1, ['foo', 'bar'])
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001808 var val = 0
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001809 # skip expr returns boolean
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001810 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001811 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001812 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001813 # skip expr returns number, only 0 and 1 are accepted
1814 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001815 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001816 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001817 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001818 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1819 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1820enddef
1821
1822def Test_searchcount()
1823 new
1824 setline(1, "foo bar")
1825 :/foo
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001826 searchcount(#{recompute: true})
1827 ->assert_equal(#{
1828 exact_match: 1,
1829 current: 1,
1830 total: 1,
1831 maxcount: 99,
1832 incomplete: 0})
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001833 bwipe!
1834enddef
1835
1836def Test_searchdecl()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001837 searchdecl('blah', true, true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001838enddef
1839
1840def Test_setbufvar()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001841 setbufvar(bufnr('%'), '&syntax', 'vim')
1842 &syntax->assert_equal('vim')
1843 setbufvar(bufnr('%'), '&ts', 16)
1844 &ts->assert_equal(16)
1845 settabwinvar(1, 1, '&syntax', 'vam')
1846 &syntax->assert_equal('vam')
1847 settabwinvar(1, 1, '&ts', 15)
1848 &ts->assert_equal(15)
1849 setlocal ts=8
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001850
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001851 setbufvar('%', 'myvar', 123)
1852 getbufvar('%', 'myvar')->assert_equal(123)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001853enddef
1854
Bram Moolenaar401f0c02020-09-05 22:37:39 +02001855def Test_setloclist()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001856 var items = [#{filename: '/tmp/file', lnum: 1, valid: true}]
1857 var what = #{items: items}
Bram Moolenaar401f0c02020-09-05 22:37:39 +02001858 setqflist([], ' ', what)
1859 setloclist(0, [], ' ', what)
1860enddef
1861
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001862def Test_setreg()
1863 setreg('a', ['aaa', 'bbb', 'ccc'])
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001864 var reginfo = getreginfo('a')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001865 setreg('a', reginfo)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001866 getreginfo('a')->assert_equal(reginfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001867enddef
1868
Bram Moolenaar7c27f332020-09-05 22:45:55 +02001869def Test_spellsuggest()
1870 if !has('spell')
1871 MissingFeature 'spell'
1872 else
1873 spellsuggest('marrch', 1, true)->assert_equal(['March'])
1874 endif
1875enddef
1876
Bram Moolenaar3986b942020-09-06 16:09:04 +02001877def Test_split()
1878 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
1879enddef
1880
1881def Test_str2nr()
1882 str2nr("1'000'000", 10, true)->assert_equal(1000000)
1883enddef
1884
1885def Test_strchars()
1886 strchars("A\u20dd", true)->assert_equal(1)
1887enddef
1888
Bram Moolenaarad304702020-09-06 18:22:53 +02001889def Test_submatch()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001890 var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
1891 var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()}
1892 var actual = substitute('A123456789', pat, Rep, '')
1893 var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001894 actual->assert_equal(expected)
Bram Moolenaarad304702020-09-06 18:22:53 +02001895enddef
1896
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001897def Test_synID()
1898 new
1899 setline(1, "text")
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001900 synID(1, 1, true)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001901 bwipe!
1902enddef
1903
Bram Moolenaarad304702020-09-06 18:22:53 +02001904def Test_term_gettty()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001905 if !has('terminal')
1906 MissingFeature 'terminal'
1907 else
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001908 var buf = Run_shell_in_terminal({})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001909 term_gettty(buf, true)->assert_notequal('')
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001910 StopShellInTerminal(buf)
1911 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001912enddef
1913
1914def Test_term_start()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001915 if !has('terminal')
1916 MissingFeature 'terminal'
1917 else
1918 botright new
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001919 var winnr = winnr()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001920 term_start(&shell, #{curwin: true})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001921 winnr()->assert_equal(winnr)
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001922 bwipe!
1923 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001924enddef
1925
Bram Moolenaar418155d2020-09-06 18:39:38 +02001926def Test_timer_paused()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001927 var id = timer_start(50, {-> 0})
Bram Moolenaar418155d2020-09-06 18:39:38 +02001928 timer_pause(id, true)
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02001929 var info = timer_info(id)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001930 info[0]['paused']->assert_equal(1)
Bram Moolenaar418155d2020-09-06 18:39:38 +02001931 timer_stop(id)
1932enddef
1933
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001934def Test_win_splitmove()
1935 split
1936 win_splitmove(1, 2, #{vertical: true, rightbelow: true})
1937 close
1938enddef
1939
1940""""""" end of builtin functions
1941
1942def Fibonacci(n: number): number
1943 if n < 2
1944 return n
1945 else
1946 return Fibonacci(n - 1) + Fibonacci(n - 2)
1947 endif
1948enddef
1949
Bram Moolenaar985116a2020-07-12 17:31:09 +02001950def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001951 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001952enddef
1953
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001954def TreeWalk(dir: string): list<any>
1955 return readdir(dir)->map({_, val ->
1956 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001957 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001958 : val
1959 })
1960enddef
1961
1962def Test_closure_in_map()
1963 mkdir('XclosureDir/tdir', 'p')
1964 writefile(['111'], 'XclosureDir/file1')
1965 writefile(['222'], 'XclosureDir/file2')
1966 writefile(['333'], 'XclosureDir/tdir/file3')
1967
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001968 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001969
1970 delete('XclosureDir', 'rf')
1971enddef
1972
Bram Moolenaar7b5d5442020-10-04 13:42:34 +02001973def Test_invalid_function_name()
1974 var lines =<< trim END
1975 vim9script
1976 def s: list<string>
1977 END
1978 CheckScriptFailure(lines, 'E129:')
1979
1980 lines =<< trim END
1981 vim9script
1982 def g: list<string>
1983 END
1984 CheckScriptFailure(lines, 'E129:')
1985
1986 lines =<< trim END
1987 vim9script
1988 def <SID>: list<string>
1989 END
1990 CheckScriptFailure(lines, 'E884:')
1991
1992 lines =<< trim END
1993 vim9script
1994 def F list<string>
1995 END
1996 CheckScriptFailure(lines, 'E488:')
1997enddef
1998
Bram Moolenaara90afb92020-07-15 22:38:56 +02001999def Test_partial_call()
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002000 var Xsetlist = function('setloclist', [0])
Bram Moolenaara90afb92020-07-15 22:38:56 +02002001 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002002 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02002003
2004 Xsetlist = function('setloclist', [0, [], ' '])
2005 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('setqflist')
2009 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002010 getqflist({'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 Moolenaar6abd3dc2020-10-04 14:17:32 +02002015
2016 var Len: func: number = function('len', ['word'])
2017 assert_equal(4, Len())
Bram Moolenaara90afb92020-07-15 22:38:56 +02002018enddef
2019
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002020def Test_cmd_modifier()
2021 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02002022 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002023enddef
2024
2025def Test_restore_modifiers()
2026 # check that when compiling a :def function command modifiers are not messed
2027 # up.
Bram Moolenaar7a9cbca2020-09-27 22:47:05 +02002028 var lines =<< trim END
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002029 vim9script
2030 set eventignore=
2031 autocmd QuickFixCmdPost * copen
2032 def AutocmdsDisabled()
2033 eval 0
2034 enddef
2035 func Func()
2036 noautocmd call s:AutocmdsDisabled()
2037 let g:ei_after = &eventignore
2038 endfunc
2039 Func()
2040 END
2041 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002042 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02002043enddef
2044
Bram Moolenaardfa3d552020-09-10 22:05:08 +02002045def StackTop()
2046 eval 1
2047 eval 2
2048 # call not on fourth line
2049 StackBot()
2050enddef
2051
2052def StackBot()
2053 # throw an error
2054 eval [][0]
2055enddef
2056
2057def Test_callstack_def()
2058 try
2059 StackTop()
2060 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02002061 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02002062 endtry
2063enddef
2064
Bram Moolenaare8211a32020-10-09 22:04:29 +02002065" Re-using spot for variable used in block
2066def Test_block_scoped_var()
2067 var lines =<< trim END
2068 vim9script
2069 def Func()
2070 var x = ['a', 'b', 'c']
2071 if 1
2072 var y = 'x'
2073 map(x, {-> y})
2074 endif
2075 var z = x
2076 assert_equal(['x', 'x', 'x'], z)
2077 enddef
2078 Func()
2079 END
2080 CheckScriptSuccess(lines)
2081enddef
2082
Bram Moolenaarf7779c62020-05-03 15:38:16 +02002083
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02002084" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker