blob: 47c37f0bd19d0983dc30c1dfa4afd9937cec3dbd [file] [log] [blame]
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001" Test various aspects of the Vim9 script language.
2
3source check.vim
4source view_util.vim
Bram Moolenaar04b12692020-05-04 23:24:44 +02005source vim9.vim
Bram Moolenaar47e7d702020-07-05 18:18:42 +02006source screendump.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02007
8func Test_def_basic()
9 def SomeFunc(): string
10 return 'yes'
11 enddef
12 call assert_equal('yes', SomeFunc())
13endfunc
14
15def ReturnString(): string
16 return 'string'
17enddef
18
19def ReturnNumber(): number
20 return 123
21enddef
22
23let g:notNumber = 'string'
24
25def ReturnGlobal(): number
26 return g:notNumber
27enddef
28
29def Test_return_something()
30 assert_equal('string', ReturnString())
31 assert_equal(123, ReturnNumber())
32 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
33enddef
34
Bram Moolenaarefd88552020-06-18 20:50:10 +020035def Test_missing_return()
36 CheckDefFailure(['def Missing(): number',
37 ' if g:cond',
38 ' echo "no return"',
39 ' else',
40 ' return 0',
41 ' endif'
42 'enddef'], 'E1027:')
43 CheckDefFailure(['def Missing(): number',
44 ' if g:cond',
45 ' return 1',
46 ' else',
47 ' echo "no return"',
48 ' endif'
49 'enddef'], 'E1027:')
50 CheckDefFailure(['def Missing(): number',
51 ' if g:cond',
52 ' return 1',
53 ' else',
54 ' return 2',
55 ' endif'
56 ' return 3'
57 'enddef'], 'E1095:')
58enddef
59
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020060let s:nothing = 0
61def ReturnNothing()
62 s:nothing = 1
63 if true
64 return
65 endif
66 s:nothing = 2
67enddef
68
69def Test_return_nothing()
70 ReturnNothing()
71 assert_equal(1, s:nothing)
72enddef
73
74func Increment()
75 let g:counter += 1
76endfunc
77
78def Test_call_ufunc_count()
79 g:counter = 1
80 Increment()
81 Increment()
82 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +020083 # works with and without :call
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020084 assert_equal(4, g:counter)
85 call assert_equal(4, g:counter)
86 unlet g:counter
87enddef
88
89def MyVarargs(arg: string, ...rest: list<string>): string
90 let res = arg
91 for s in rest
92 res ..= ',' .. s
93 endfor
94 return res
95enddef
96
97def Test_call_varargs()
98 assert_equal('one', MyVarargs('one'))
99 assert_equal('one,two', MyVarargs('one', 'two'))
100 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
101enddef
102
103def MyDefaultArgs(name = 'string'): string
104 return name
105enddef
106
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200107def MyDefaultSecond(name: string, second: bool = true): string
108 return second ? name : 'none'
109enddef
110
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200111def Test_call_default_args()
112 assert_equal('string', MyDefaultArgs())
113 assert_equal('one', MyDefaultArgs('one'))
114 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
115
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200116 assert_equal('test', MyDefaultSecond('test'))
117 assert_equal('test', MyDefaultSecond('test', true))
118 assert_equal('none', MyDefaultSecond('test', false))
119
Bram Moolenaar822ba242020-05-24 23:00:18 +0200120 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
121 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 +0200122enddef
123
124def Test_nested_function()
125 def Nested(arg: string): string
126 return 'nested ' .. arg
127 enddef
128 assert_equal('nested function', Nested('function'))
129
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200130 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
131 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
132
Bram Moolenaar04b12692020-05-04 23:24:44 +0200133 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200134 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
135 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200136enddef
137
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200138func Test_call_default_args_from_func()
139 call assert_equal('string', MyDefaultArgs())
140 call assert_equal('one', MyDefaultArgs('one'))
141 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
142endfunc
143
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200144def Test_nested_global_function()
145 let lines =<< trim END
146 vim9script
147 def Outer()
148 def g:Inner(): string
149 return 'inner'
150 enddef
151 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200152 defcompile
153 Outer()
154 assert_equal('inner', g:Inner())
155 delfunc g:Inner
156 Outer()
157 assert_equal('inner', g:Inner())
158 delfunc g:Inner
159 Outer()
160 assert_equal('inner', g:Inner())
161 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200162 END
163 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200164
165 lines =<< trim END
166 vim9script
167 def Outer()
168 def g:Inner(): string
169 return 'inner'
170 enddef
171 enddef
172 defcompile
173 Outer()
174 Outer()
175 END
176 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200177
178 lines =<< trim END
179 vim9script
180 def Func()
181 echo 'script'
182 enddef
183 def Outer()
184 def Func()
185 echo 'inner'
186 enddef
187 enddef
188 defcompile
189 END
190 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200191enddef
192
Bram Moolenaar333894b2020-08-01 18:53:07 +0200193def Test_global_local_function()
194 let lines =<< trim END
195 vim9script
196 def g:Func(): string
197 return 'global'
198 enddef
199 def Func(): string
200 return 'local'
201 enddef
202 assert_equal('global', g:Func())
203 assert_equal('local', Func())
204 END
205 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200206
207 lines =<< trim END
208 vim9script
209 def g:Funcy()
210 echo 'funcy'
211 enddef
212 s:Funcy()
213 END
214 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200215enddef
216
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200217func TakesOneArg(arg)
218 echo a:arg
219endfunc
220
221def Test_call_wrong_args()
222 call CheckDefFailure(['TakesOneArg()'], 'E119:')
223 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
224 call CheckDefFailure(['bufnr(xxx)'], 'E1001:')
Bram Moolenaar1c0d44f2020-05-02 19:04:58 +0200225 call CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200226
227 let lines =<< trim END
228 vim9script
229 def Func(s: string)
230 echo s
231 enddef
232 Func([])
233 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200234 call CheckScriptFailure(lines, 'E1013: argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200235enddef
236
237" Default arg and varargs
238def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
239 let res = one .. ',' .. two
240 for s in rest
241 res ..= ',' .. s
242 endfor
243 return res
244enddef
245
246def Test_call_def_varargs()
247 call assert_fails('call MyDefVarargs()', 'E119:')
248 assert_equal('one,foo', MyDefVarargs('one'))
249 assert_equal('one,two', MyDefVarargs('one', 'two'))
250 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200251 CheckDefFailure(['MyDefVarargs("one", 22)'],
252 'E1013: argument 2: type mismatch, expected string but got number')
253 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
254 'E1013: argument 3: type mismatch, expected string but got number')
255
256 let lines =<< trim END
257 vim9script
258 def Func(...l: list<string>)
259 echo l
260 enddef
261 Func('a', 'b', 'c')
262 END
263 CheckScriptSuccess(lines)
264
265 lines =<< trim END
266 vim9script
267 def Func(...l: list<string>)
268 echo l
269 enddef
270 Func()
271 END
272 CheckScriptSuccess(lines)
273
274 lines =<< trim END
275 vim9script
276 def Func(...l: list<string>)
277 echo l
278 enddef
279 Func(1, 2, 3)
280 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200281 CheckScriptFailure(lines, 'E1013: argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200282
283 lines =<< trim END
284 vim9script
285 def Func(...l: list<string>)
286 echo l
287 enddef
288 Func('a', 9)
289 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200290 CheckScriptFailure(lines, 'E1013: argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200291
292 lines =<< trim END
293 vim9script
294 def Func(...l: list<string>)
295 echo l
296 enddef
297 Func(1, 'a')
298 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200299 CheckScriptFailure(lines, 'E1013: argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200300enddef
301
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200302def Test_call_call()
303 let l = [3, 2, 1]
304 call('reverse', [l])
305 assert_equal([1, 2, 3], l)
306enddef
307
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200308let s:value = ''
309
310def FuncOneDefArg(opt = 'text')
311 s:value = opt
312enddef
313
314def FuncTwoDefArg(nr = 123, opt = 'text'): string
315 return nr .. opt
316enddef
317
318def FuncVarargs(...arg: list<string>): string
319 return join(arg, ',')
320enddef
321
322def Test_func_type_varargs()
323 let RefDefArg: func(?string)
324 RefDefArg = FuncOneDefArg
325 RefDefArg()
326 assert_equal('text', s:value)
327 RefDefArg('some')
328 assert_equal('some', s:value)
329
330 let RefDef2Arg: func(?number, ?string): string
331 RefDef2Arg = FuncTwoDefArg
332 assert_equal('123text', RefDef2Arg())
333 assert_equal('99text', RefDef2Arg(99))
334 assert_equal('77some', RefDef2Arg(77, 'some'))
335
336 call CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:')
337 call CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:')
338
339 let RefVarargs: func(...list<string>): string
340 RefVarargs = FuncVarargs
341 assert_equal('', RefVarargs())
342 assert_equal('one', RefVarargs('one'))
343 assert_equal('one,two', RefVarargs('one', 'two'))
344
345 call CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:')
346 call CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:')
347enddef
348
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200349" Only varargs
350def MyVarargsOnly(...args: list<string>): string
351 return join(args, ',')
352enddef
353
354def Test_call_varargs_only()
355 assert_equal('', MyVarargsOnly())
356 assert_equal('one', MyVarargsOnly('one'))
357 assert_equal('one,two', MyVarargsOnly('one', 'two'))
358 call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number')
359 call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number')
360enddef
361
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200362def Test_using_var_as_arg()
Bram Moolenaar822ba242020-05-24 23:00:18 +0200363 call writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200364 call assert_fails('so Xdef', 'E1006:')
365 call delete('Xdef')
366enddef
367
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200368def DictArg(arg: dict<string>)
369 arg['key'] = 'value'
370enddef
371
372def ListArg(arg: list<string>)
373 arg[0] = 'value'
374enddef
375
376def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200377 # works for dict and list
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200378 let d: dict<string> = {}
379 DictArg(d)
380 assert_equal('value', d['key'])
381 let l: list<string> = []
382 ListArg(l)
383 assert_equal('value', l[0])
384
Bram Moolenaar822ba242020-05-24 23:00:18 +0200385 call CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200386enddef
387
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200388def Test_call_func_defined_later()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200389 call assert_equal('one', g:DefinedLater('one'))
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200390 call assert_fails('call NotDefined("one")', 'E117:')
391enddef
392
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200393func DefinedLater(arg)
394 return a:arg
395endfunc
396
397def Test_call_funcref()
398 assert_equal(3, g:SomeFunc('abc'))
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200399 assert_fails('NotAFunc()', 'E117:') # comment after call
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200400 assert_fails('g:NotAFunc()', 'E117:')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200401
402 let lines =<< trim END
403 vim9script
404 def RetNumber(): number
405 return 123
406 enddef
407 let Funcref: func: number = function('RetNumber')
408 assert_equal(123, Funcref())
409 END
410 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200411
412 lines =<< trim END
413 vim9script
414 def RetNumber(): number
415 return 123
416 enddef
417 def Bar(F: func: number): number
418 return F()
419 enddef
420 let Funcref = function('RetNumber')
421 assert_equal(123, Bar(Funcref))
422 END
423 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200424
425 lines =<< trim END
426 vim9script
427 def UseNumber(nr: number)
428 echo nr
429 enddef
430 let Funcref: func(number) = function('UseNumber')
431 Funcref(123)
432 END
433 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200434
435 lines =<< trim END
436 vim9script
437 def UseNumber(nr: number)
438 echo nr
439 enddef
440 let Funcref: func(string) = function('UseNumber')
441 END
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200442 CheckScriptFailure(lines, 'E1012: type mismatch, expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200443
444 lines =<< trim END
445 vim9script
446 def EchoNr(nr = 34)
447 g:echo = nr
448 enddef
449 let Funcref: func(?number) = function('EchoNr')
450 Funcref()
451 assert_equal(34, g:echo)
452 Funcref(123)
453 assert_equal(123, g:echo)
454 END
455 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200456
457 lines =<< trim END
458 vim9script
459 def EchoList(...l: list<number>)
460 g:echo = l
461 enddef
462 let Funcref: func(...list<number>) = function('EchoList')
463 Funcref()
464 assert_equal([], g:echo)
465 Funcref(1, 2, 3)
466 assert_equal([1, 2, 3], g:echo)
467 END
468 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200469
470 lines =<< trim END
471 vim9script
472 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
473 g:optarg = opt
474 g:listarg = l
475 return nr
476 enddef
477 let Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
478 assert_equal(10, Funcref(10))
479 assert_equal(12, g:optarg)
480 assert_equal([], g:listarg)
481
482 assert_equal(11, Funcref(11, 22))
483 assert_equal(22, g:optarg)
484 assert_equal([], g:listarg)
485
486 assert_equal(17, Funcref(17, 18, 1, 2, 3))
487 assert_equal(18, g:optarg)
488 assert_equal([1, 2, 3], g:listarg)
489 END
490 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200491enddef
492
493let SomeFunc = function('len')
494let NotAFunc = 'text'
495
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200496def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200497 # same arguments, different return type
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200498 let Ref1: func(bool): string
499 let Ref2: func(bool): number
500 let Ref3: func(bool): any
501 Ref3 = g:cond ? Ref1 : Ref2
502
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200503 # different number of arguments
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200504 let Refa1: func(bool): number
505 let Refa2: func(bool, number): number
506 let Refa3: func: number
507 Refa3 = g:cond ? Refa1 : Refa2
508
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200509 # different argument types
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200510 let Refb1: func(bool, string): number
511 let Refb2: func(string, number): number
512 let Refb3: func(any, any): number
513 Refb3 = g:cond ? Refb1 : Refb2
514enddef
515
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200516def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200517 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200518enddef
519
520def DefinedEvenLater(arg: string): string
521 return arg
522enddef
523
524def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200525 # Error in called function requires unwinding the call stack.
Bram Moolenaare2e40752020-09-04 21:18:46 +0200526 assert_fails('call FuncWithForwardCall()', 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200527enddef
528
529def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200530 CheckScriptFailure([
531 'def Func(): number',
532 'return "a"',
533 'enddef',
534 'defcompile'], 'expected number but got string')
535 CheckScriptFailure([
536 'def Func(): string',
537 'return 1',
538 'enddef',
539 'defcompile'], 'expected string but got number')
540 CheckScriptFailure([
541 'def Func(): void',
542 'return "a"',
543 'enddef',
544 'defcompile'],
545 'E1096: Returning a value in a function without a return type')
546 CheckScriptFailure([
547 'def Func()',
548 'return "a"',
549 'enddef',
550 'defcompile'],
551 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200552
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200553 CheckScriptFailure([
554 'def Func(): number',
555 'return',
556 'enddef',
557 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200558
559 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
560 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200561 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200562
563 CheckScriptFailure([
564 'vim9script',
565 'def FuncB()',
566 ' return 123',
567 'enddef',
568 'def FuncA()',
569 ' FuncB()',
570 'enddef',
571 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200572enddef
573
574def Test_arg_type_wrong()
575 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200576 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200577 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200578 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200579enddef
580
581def Test_vim9script_call()
582 let lines =<< trim END
583 vim9script
584 let var = ''
585 def MyFunc(arg: string)
586 var = arg
587 enddef
588 MyFunc('foobar')
589 assert_equal('foobar', var)
590
591 let str = 'barfoo'
592 str->MyFunc()
593 assert_equal('barfoo', var)
594
Bram Moolenaar67979662020-06-20 22:50:47 +0200595 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200596 g:value->MyFunc()
597 assert_equal('value', var)
598
599 let listvar = []
600 def ListFunc(arg: list<number>)
601 listvar = arg
602 enddef
603 [1, 2, 3]->ListFunc()
604 assert_equal([1, 2, 3], listvar)
605
606 let dictvar = {}
607 def DictFunc(arg: dict<number>)
608 dictvar = arg
609 enddef
610 {'a': 1, 'b': 2}->DictFunc()
611 assert_equal(#{a: 1, b: 2}, dictvar)
612 def CompiledDict()
613 {'a': 3, 'b': 4}->DictFunc()
614 enddef
615 CompiledDict()
616 assert_equal(#{a: 3, b: 4}, dictvar)
617
618 #{a: 3, b: 4}->DictFunc()
619 assert_equal(#{a: 3, b: 4}, dictvar)
620
621 ('text')->MyFunc()
622 assert_equal('text', var)
623 ("some")->MyFunc()
624 assert_equal('some', var)
Bram Moolenaare6b53242020-07-01 17:28:33 +0200625
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200626 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200627 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200628 'asdfasdf'->MyFunc()
629 assert_equal('asdfasdf', var)
Bram Moolenaar10409562020-07-29 20:00:38 +0200630 "xyz"->MyFunc()
631 assert_equal('xyz', var)
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200632
633 def UseString()
634 'xyork'->MyFunc()
635 enddef
636 UseString()
637 assert_equal('xyork', var)
638
Bram Moolenaar10409562020-07-29 20:00:38 +0200639 def UseString2()
640 "knife"->MyFunc()
641 enddef
642 UseString2()
643 assert_equal('knife', var)
644
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200645 # prepending a colon makes it a mark
646 new
647 setline(1, ['aaa', 'bbb', 'ccc'])
648 normal! 3Gmt1G
649 :'t
650 assert_equal(3, getcurpos()[1])
651 bwipe!
652
Bram Moolenaare6b53242020-07-01 17:28:33 +0200653 MyFunc(
654 'continued'
655 )
656 assert_equal('continued',
657 var
658 )
659
660 call MyFunc(
661 'more'
662 ..
663 'lines'
664 )
665 assert_equal(
666 'morelines',
667 var)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200668 END
669 writefile(lines, 'Xcall.vim')
670 source Xcall.vim
671 delete('Xcall.vim')
672enddef
673
674def Test_vim9script_call_fail_decl()
675 let lines =<< trim END
676 vim9script
677 let var = ''
678 def MyFunc(arg: string)
679 let var = 123
680 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200681 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200682 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200683 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200684enddef
685
Bram Moolenaar65b95452020-07-19 14:03:09 +0200686def Test_vim9script_call_fail_type()
687 let lines =<< trim END
688 vim9script
689 def MyFunc(arg: string)
690 echo arg
691 enddef
692 MyFunc(1234)
693 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200694 CheckScriptFailure(lines, 'E1013: argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200695enddef
696
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200697def Test_vim9script_call_fail_const()
698 let lines =<< trim END
699 vim9script
700 const var = ''
701 def MyFunc(arg: string)
702 var = 'asdf'
703 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200704 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200705 END
706 writefile(lines, 'Xcall_const.vim')
707 assert_fails('source Xcall_const.vim', 'E46:')
708 delete('Xcall_const.vim')
709enddef
710
711" Test that inside :function a Python function can be defined, :def is not
712" recognized.
713func Test_function_python()
714 CheckFeature python3
715 let py = 'python3'
716 execute py "<< EOF"
717def do_something():
718 return 1
719EOF
720endfunc
721
722def Test_delfunc()
723 let lines =<< trim END
724 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200725 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200726 echo 'hello'
727 enddef
728
729 def CallGoneSoon()
730 GoneSoon()
731 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200732 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200733
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200734 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200735 CallGoneSoon()
736 END
737 writefile(lines, 'XToDelFunc')
Bram Moolenaare2e40752020-09-04 21:18:46 +0200738 assert_fails('so XToDelFunc', 'E933:')
739 assert_fails('so XToDelFunc', 'E933:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200740
741 delete('XToDelFunc')
742enddef
743
744def Test_redef_failure()
745 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
746 so Xdef
747 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
748 so Xdef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200749 call writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200750 call assert_fails('so Xdef', 'E1027:')
751 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
752 so Xdef
753 call delete('Xdef')
754
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200755 call assert_equal(0, g:Func0())
756 call assert_equal('Func1', g:Func1())
757 call assert_equal('Func2', g:Func2())
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200758
759 delfunc! Func0
760 delfunc! Func1
761 delfunc! Func2
762enddef
763
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200764def Test_vim9script_func()
765 let lines =<< trim END
766 vim9script
767 func Func(arg)
768 echo a:arg
769 endfunc
770 Func('text')
771 END
772 writefile(lines, 'XVim9Func')
773 so XVim9Func
774
775 delete('XVim9Func')
776enddef
777
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200778" Test for internal functions returning different types
779func Test_InternalFuncRetType()
780 let lines =<< trim END
781 def RetFloat(): float
782 return ceil(1.456)
783 enddef
784
785 def RetListAny(): list<any>
Bram Moolenaar17a836c2020-08-12 17:35:58 +0200786 return items({'k': 'v'})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200787 enddef
788
789 def RetListString(): list<string>
790 return split('a:b:c', ':')
791 enddef
792
793 def RetListDictAny(): list<dict<any>>
794 return getbufinfo()
795 enddef
796
797 def RetDictNumber(): dict<number>
798 return wordcount()
799 enddef
800
801 def RetDictString(): dict<string>
802 return environ()
803 enddef
804 END
805 call writefile(lines, 'Xscript')
806 source Xscript
807
808 call assert_equal(2.0, RetFloat())
809 call assert_equal([['k', 'v']], RetListAny())
810 call assert_equal(['a', 'b', 'c'], RetListString())
811 call assert_notequal([], RetListDictAny())
812 call assert_notequal({}, RetDictNumber())
813 call assert_notequal({}, RetDictString())
814 call delete('Xscript')
815endfunc
816
817" Test for passing too many or too few arguments to internal functions
818func Test_internalfunc_arg_error()
819 let l =<< trim END
820 def! FArgErr(): float
821 return ceil(1.1, 2)
822 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200823 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200824 END
825 call writefile(l, 'Xinvalidarg')
826 call assert_fails('so Xinvalidarg', 'E118:')
827 let l =<< trim END
828 def! FArgErr(): float
829 return ceil()
830 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200831 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200832 END
833 call writefile(l, 'Xinvalidarg')
834 call assert_fails('so Xinvalidarg', 'E119:')
835 call delete('Xinvalidarg')
836endfunc
837
838let s:funcResult = 0
839
840def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200841 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200842enddef
843
844def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200845 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200846 return 1234
847enddef
848
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200849def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +0200850 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200851 return 'text'
852enddef
853
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200854def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200855 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200856enddef
857
858def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200859 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200860 return arg
861enddef
862
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200863def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200864 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200865enddef
866
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200867def FuncOneArgRetString(arg: string): string
868 return arg
869enddef
870
Bram Moolenaar89228602020-04-05 22:14:54 +0200871def FuncOneArgRetAny(arg: any): any
872 return arg
873enddef
874
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200875def Test_func_type()
876 let Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +0200877 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200878 Ref1 = FuncNoArgNoRet
879 Ref1()
Bram Moolenaar53900992020-08-22 19:02:02 +0200880 assert_equal(11, s:funcResult)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200881
882 let Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +0200883 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200884 Ref2 = FuncNoArgNoRet
885 Ref2()
Bram Moolenaar53900992020-08-22 19:02:02 +0200886 assert_equal(11, s:funcResult)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200887
Bram Moolenaar53900992020-08-22 19:02:02 +0200888 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200889 Ref2 = FuncOneArgNoRet
890 Ref2(12)
Bram Moolenaar53900992020-08-22 19:02:02 +0200891 assert_equal(12, s:funcResult)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200892
Bram Moolenaar53900992020-08-22 19:02:02 +0200893 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200894 Ref2 = FuncNoArgRetNumber
895 assert_equal(1234, Ref2())
Bram Moolenaar53900992020-08-22 19:02:02 +0200896 assert_equal(22, s:funcResult)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200897
Bram Moolenaar53900992020-08-22 19:02:02 +0200898 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200899 Ref2 = FuncOneArgRetNumber
900 assert_equal(13, Ref2(13))
Bram Moolenaar53900992020-08-22 19:02:02 +0200901 assert_equal(13, s:funcResult)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200902enddef
903
Bram Moolenaar9978d472020-07-05 16:01:56 +0200904def Test_repeat_return_type()
905 let res = 0
906 for n in repeat([1], 3)
907 res += n
908 endfor
909 assert_equal(3, res)
Bram Moolenaarfce82b32020-07-05 16:07:21 +0200910
911 res = 0
912 for n in add([1, 2], 3)
913 res += n
914 endfor
915 assert_equal(6, res)
Bram Moolenaar9978d472020-07-05 16:01:56 +0200916enddef
917
Bram Moolenaar846178a2020-07-05 17:04:13 +0200918def Test_argv_return_type()
919 next fileone filetwo
920 let res = ''
921 for name in argv()
922 res ..= name
923 endfor
924 assert_equal('fileonefiletwo', res)
925enddef
926
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200927def Test_func_type_part()
928 let RefVoid: func: void
929 RefVoid = FuncNoArgNoRet
930 RefVoid = FuncOneArgNoRet
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200931 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func() but got func(): number')
932 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: type mismatch, expected func() but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200933
934 let RefAny: func(): any
935 RefAny = FuncNoArgRetNumber
936 RefAny = FuncNoArgRetString
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200937 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): any but got func()')
938 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: type mismatch, expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200939
940 let RefNr: func: number
941 RefNr = FuncNoArgRetNumber
942 RefNr = FuncOneArgRetNumber
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200943 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): number but got func()')
944 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: type mismatch, expected func(): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200945
946 let RefStr: func: string
947 RefStr = FuncNoArgRetString
948 RefStr = FuncOneArgRetString
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200949 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): string but got func()')
950 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func(): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200951enddef
952
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200953def Test_func_type_fails()
954 CheckDefFailure(['let ref1: func()'], 'E704:')
955
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200956 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func() but got func(): number')
957 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: type mismatch, expected func() but got func(number)')
958 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: type mismatch, expected func() but got func(number): number')
959 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: type mismatch, expected func(bool) but got func(bool, number)')
960 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: type mismatch, expected func(?bool) but got func(bool, number)')
961 CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: type mismatch, expected func(...bool) but got func(bool, number)')
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200962
963 call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:')
964 call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:')
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200965 call CheckDefFailure(['let RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E1005:')
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200966 call CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200967enddef
968
Bram Moolenaar89228602020-04-05 22:14:54 +0200969def Test_func_return_type()
970 let nr: number
971 nr = FuncNoArgRetNumber()
972 assert_equal(1234, nr)
973
974 nr = FuncOneArgRetAny(122)
975 assert_equal(122, nr)
976
977 let str: string
978 str = FuncOneArgRetAny('yes')
979 assert_equal('yes', str)
980
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200981 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1012: type mismatch, expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +0200982enddef
983
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200984def MultiLine(
985 arg1: string,
986 arg2 = 1234,
987 ...rest: list<string>
988 ): string
989 return arg1 .. arg2 .. join(rest, '-')
990enddef
991
Bram Moolenaar2c330432020-04-13 14:41:35 +0200992def MultiLineComment(
993 arg1: string, # comment
994 arg2 = 1234, # comment
995 ...rest: list<string> # comment
996 ): string # comment
997 return arg1 .. arg2 .. join(rest, '-')
998enddef
999
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001000def Test_multiline()
1001 assert_equal('text1234', MultiLine('text'))
1002 assert_equal('text777', MultiLine('text', 777))
1003 assert_equal('text777one', MultiLine('text', 777, 'one'))
1004 assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two'))
1005enddef
1006
Bram Moolenaar23e03252020-04-12 22:22:31 +02001007func Test_multiline_not_vim9()
1008 call assert_equal('text1234', MultiLine('text'))
1009 call assert_equal('text777', MultiLine('text', 777))
1010 call assert_equal('text777one', MultiLine('text', 777, 'one'))
1011 call assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two'))
1012endfunc
1013
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001014
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001015" When using CheckScriptFailure() for the below test, E1010 is generated instead
1016" of E1056.
1017func Test_E1056_1059()
1018 let caught_1056 = 0
1019 try
1020 def F():
1021 return 1
1022 enddef
1023 catch /E1056:/
1024 let caught_1056 = 1
1025 endtry
1026 call assert_equal(1, caught_1056)
1027
1028 let caught_1059 = 0
1029 try
1030 def F5(items : list)
1031 echo 'a'
1032 enddef
1033 catch /E1059:/
1034 let caught_1059 = 1
1035 endtry
1036 call assert_equal(1, caught_1059)
1037endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001038
Bram Moolenaar015f4262020-05-05 21:25:22 +02001039func DelMe()
1040 echo 'DelMe'
1041endfunc
1042
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001043def Test_error_reporting()
1044 # comment lines at the start of the function
1045 let lines =<< trim END
1046 " comment
1047 def Func()
1048 # comment
1049 # comment
1050 invalid
1051 enddef
1052 defcompile
1053 END
1054 call writefile(lines, 'Xdef')
1055 try
1056 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001057 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001058 catch /E476:/
1059 assert_match('Invalid command: invalid', v:exception)
1060 assert_match(', line 3$', v:throwpoint)
1061 endtry
1062
1063 # comment lines after the start of the function
1064 lines =<< trim END
1065 " comment
1066 def Func()
1067 let x = 1234
1068 # comment
1069 # comment
1070 invalid
1071 enddef
1072 defcompile
1073 END
1074 call writefile(lines, 'Xdef')
1075 try
1076 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001077 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001078 catch /E476:/
1079 assert_match('Invalid command: invalid', v:exception)
1080 assert_match(', line 4$', v:throwpoint)
1081 endtry
1082
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001083 lines =<< trim END
1084 vim9script
1085 def Func()
1086 let db = #{foo: 1, bar: 2}
1087 # comment
1088 let x = db.asdf
1089 enddef
1090 defcompile
1091 Func()
1092 END
1093 call writefile(lines, 'Xdef')
1094 try
1095 source Xdef
1096 assert_report('should have failed')
1097 catch /E716:/
1098 assert_match('_Func, line 3$', v:throwpoint)
1099 endtry
1100
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001101 call delete('Xdef')
1102enddef
1103
Bram Moolenaar015f4262020-05-05 21:25:22 +02001104def Test_deleted_function()
1105 CheckDefExecFailure([
1106 'let RefMe: func = function("g:DelMe")',
1107 'delfunc g:DelMe',
1108 'echo RefMe()'], 'E117:')
1109enddef
1110
1111def Test_unknown_function()
1112 CheckDefExecFailure([
1113 'let Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001114 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001115enddef
1116
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001117def RefFunc(Ref: func(string): string): string
1118 return Ref('more')
1119enddef
1120
1121def Test_closure_simple()
1122 let local = 'some '
1123 assert_equal('some more', RefFunc({s -> local .. s}))
1124enddef
1125
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001126def MakeRef()
1127 let local = 'some '
1128 g:Ref = {s -> local .. s}
1129enddef
1130
1131def Test_closure_ref_after_return()
1132 MakeRef()
1133 assert_equal('some thing', g:Ref('thing'))
1134 unlet g:Ref
1135enddef
1136
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001137def MakeTwoRefs()
1138 let local = ['some']
1139 g:Extend = {s -> local->add(s)}
1140 g:Read = {-> local}
1141enddef
1142
1143def Test_closure_two_refs()
1144 MakeTwoRefs()
1145 assert_equal('some', join(g:Read(), ' '))
1146 g:Extend('more')
1147 assert_equal('some more', join(g:Read(), ' '))
1148 g:Extend('even')
1149 assert_equal('some more even', join(g:Read(), ' '))
1150
1151 unlet g:Extend
1152 unlet g:Read
1153enddef
1154
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001155def ReadRef(Ref: func(): list<string>): string
1156 return join(Ref(), ' ')
1157enddef
1158
1159def ExtendRef(Ref: func(string), add: string)
1160 Ref(add)
1161enddef
1162
1163def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001164 MakeTwoRefs()
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001165 assert_equal('some', ReadRef(g:Read))
1166 ExtendRef(g:Extend, 'more')
1167 assert_equal('some more', ReadRef(g:Read))
1168 ExtendRef(g:Extend, 'even')
1169 assert_equal('some more even', ReadRef(g:Read))
1170
1171 unlet g:Extend
1172 unlet g:Read
1173enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001174
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001175def MakeArgRefs(theArg: string)
1176 let local = 'loc_val'
1177 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1178enddef
1179
1180def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
1181 let local = 'the_loc'
1182 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1183enddef
1184
1185def Test_closure_using_argument()
1186 MakeArgRefs('arg_val')
1187 assert_equal('arg_val/loc_val/call_val', g:UseArg('call_val'))
1188
1189 MakeArgRefsVarargs('arg_val', 'one', 'two')
1190 assert_equal('arg_val/the_loc/call_val/one two', g:UseVararg('call_val'))
1191
1192 unlet g:UseArg
1193 unlet g:UseVararg
1194enddef
1195
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001196def MakeGetAndAppendRefs()
1197 let local = 'a'
1198
1199 def Append(arg: string)
1200 local ..= arg
1201 enddef
1202 g:Append = Append
1203
1204 def Get(): string
1205 return local
1206 enddef
1207 g:Get = Get
1208enddef
1209
1210def Test_closure_append_get()
1211 MakeGetAndAppendRefs()
1212 assert_equal('a', g:Get())
1213 g:Append('-b')
1214 assert_equal('a-b', g:Get())
1215 g:Append('-c')
1216 assert_equal('a-b-c', g:Get())
1217
1218 unlet g:Append
1219 unlet g:Get
1220enddef
1221
Bram Moolenaar04b12692020-05-04 23:24:44 +02001222def Test_nested_closure()
1223 let local = 'text'
1224 def Closure(arg: string): string
1225 return local .. arg
1226 enddef
1227 assert_equal('text!!!', Closure('!!!'))
1228enddef
1229
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001230func GetResult(Ref)
1231 return a:Ref('some')
1232endfunc
1233
1234def Test_call_closure_not_compiled()
1235 let text = 'text'
1236 g:Ref = {s -> s .. text}
1237 assert_equal('sometext', GetResult(g:Ref))
1238enddef
1239
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001240def Test_sort_return_type()
1241 let res: list<number>
1242 res = [1, 2, 3]->sort()
1243enddef
1244
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001245def Test_getqflist_return_type()
1246 let l = getqflist()
1247 assert_equal([], l)
1248
1249 let d = getqflist(#{items: 0})
1250 assert_equal(#{items: []}, d)
1251enddef
1252
1253def Test_getloclist_return_type()
1254 let l = getloclist(1)
1255 assert_equal([], l)
1256
1257 let d = getloclist(1, #{items: 0})
1258 assert_equal(#{items: []}, d)
1259enddef
1260
Bram Moolenaara66ba012020-07-05 18:41:08 +02001261def Test_copy_return_type()
1262 let l = copy([1, 2, 3])
1263 let res = 0
1264 for n in l
1265 res += n
1266 endfor
1267 assert_equal(6, res)
1268
1269 let dl = deepcopy([1, 2, 3])
1270 res = 0
1271 for n in dl
1272 res += n
1273 endfor
1274 assert_equal(6, res)
Bram Moolenaar44b4a242020-09-05 17:18:28 +02001275
1276 dl = deepcopy([1, 2, 3], true)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001277enddef
1278
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001279def Test_extend_return_type()
1280 let l = extend([1, 2], [3])
1281 let res = 0
1282 for n in l
1283 res += n
1284 endfor
1285 assert_equal(6, res)
1286enddef
1287
Bram Moolenaar2df47312020-09-05 17:30:44 +02001288def Test_garbagecollect()
1289 garbagecollect(true)
1290enddef
1291
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001292def Test_insert_return_type()
1293 let l = insert([2, 1], 3)
1294 let res = 0
1295 for n in l
1296 res += n
1297 endfor
1298 assert_equal(6, res)
1299enddef
1300
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001301def Test_keys_return_type()
1302 const var: list<string> = #{a: 1, b: 2}->keys()
1303 assert_equal(['a', 'b'], var)
1304enddef
1305
Bram Moolenaar67627352020-07-05 21:10:24 +02001306def Test_reverse_return_type()
1307 let l = reverse([1, 2, 3])
1308 let res = 0
1309 for n in l
1310 res += n
1311 endfor
1312 assert_equal(6, res)
1313enddef
1314
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001315def Test_remove_return_type()
1316 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
1317 let res = 0
1318 for n in l
1319 res += n
1320 endfor
1321 assert_equal(3, res)
1322enddef
1323
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001324def Test_filter_return_type()
1325 let l = filter([1, 2, 3], {-> 1})
1326 let res = 0
1327 for n in l
1328 res += n
1329 endfor
1330 assert_equal(6, res)
1331enddef
1332
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001333def Test_bufnr()
1334 let buf = bufnr()
1335 assert_equal(buf, bufnr('%'))
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001336
1337 buf = bufnr('Xdummy', true)
1338 assert_notequal(-1, buf)
1339 exe 'bwipe! ' .. buf
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001340enddef
1341
Bram Moolenaarec65d772020-08-20 22:29:12 +02001342def Test_col()
1343 new
1344 setline(1, 'asdf')
1345 assert_equal(5, col([1, '$']))
1346enddef
1347
Bram Moolenaar24f77502020-09-04 19:50:57 +02001348def Test_char2nr()
1349 assert_equal(12354, char2nr('あ', true))
1350enddef
1351
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001352def Test_getreg_return_type()
1353 let s1: string = getreg('"')
1354 let s2: string = getreg('"', 1)
1355 let s3: list<string> = getreg('"', 1, 1)
1356enddef
1357
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001358def Wrong_dict_key_type(items: list<number>): list<number>
1359 return filter(items, {_, val -> get({val: 1}, 'x')})
1360enddef
1361
1362def Test_wrong_dict_key_type()
1363 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:')
1364enddef
1365
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001366def Line_continuation_in_def(dir: string = ''): string
1367 let path: string = empty(dir)
1368 \ ? 'empty'
1369 \ : 'full'
1370 return path
1371enddef
1372
1373def Test_line_continuation_in_def()
1374 assert_equal('full', Line_continuation_in_def('.'))
1375enddef
1376
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001377def Line_continuation_in_lambda(): list<number>
1378 let x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001379 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001380 ->toupper()})
1381 ->reverse()
1382 return x
1383enddef
1384
1385def Test_line_continuation_in_lambda()
1386 assert_equal(['D', 'C', 'B', 'A'], Line_continuation_in_lambda())
1387enddef
1388
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001389func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001390 CheckScreendump
1391
1392 let lines =<< trim END
1393 vim9script
1394 def EchoNothing()
1395 silent echo ''
1396 enddef
1397 defcompile
1398 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001399 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001400
1401 " Check that the balloon shows up after a mouse move
1402 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001403 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001404 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1405
1406 " clean up
1407 call StopVimInTerminal(buf)
1408 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001409endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001410
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001411""""""" builtin functions that behave differently in Vim9
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001412
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001413def Test_bufname()
1414 split SomeFile
1415 assert_equal('SomeFile', bufname('%'))
1416 edit OtherFile
1417 assert_equal('SomeFile', bufname('#'))
1418 close
Bram Moolenaar191929b2020-08-19 21:20:49 +02001419enddef
1420
Bram Moolenaara5d38412020-09-02 21:02:35 +02001421def Test_bufwinid()
1422 let origwin = win_getid()
1423 below split SomeFile
1424 let SomeFileID = win_getid()
1425 below split OtherFile
1426 below split SomeFile
1427 assert_equal(SomeFileID, bufwinid('SomeFile'))
1428
1429 win_gotoid(origwin)
1430 only
1431 bwipe SomeFile
1432 bwipe OtherFile
1433enddef
1434
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001435def Test_count()
1436 assert_equal(3, count('ABC ABC ABC', 'b', true))
1437 assert_equal(0, count('ABC ABC ABC', 'b', false))
1438enddef
1439
1440def Test_expand()
1441 split SomeFile
1442 assert_equal(['SomeFile'], expand('%', true, true))
1443 close
1444enddef
1445
1446def Test_getbufinfo()
1447 let bufinfo = getbufinfo(bufnr())
1448 assert_equal(bufinfo, getbufinfo('%'))
1449
1450 edit Xtestfile1
1451 hide edit Xtestfile2
1452 hide enew
1453 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false})
1454 ->len()->assert_equal(3)
1455 bwipe Xtestfile1 Xtestfile2
1456enddef
1457
Bram Moolenaara5d38412020-09-02 21:02:35 +02001458def Test_getbufline()
1459 e SomeFile
1460 let buf = bufnr()
1461 e #
1462 let lines = ['aaa', 'bbb', 'ccc']
1463 setbufline(buf, 1, lines)
1464 assert_equal(lines, getbufline('#', 1, '$'))
1465
1466 bwipe!
1467enddef
1468
1469def Test_getchangelist()
1470 new
1471 setline(1, 'some text')
1472 let changelist = bufnr()->getchangelist()
1473 assert_equal(changelist, getchangelist('%'))
1474 bwipe!
1475enddef
1476
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001477def Test_getchar()
Bram Moolenaar636c5d52020-09-05 18:48:57 +02001478 while getchar(0)
1479 endwhile
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001480 assert_equal(0, getchar(true))
1481enddef
1482
Bram Moolenaard217a872020-09-05 18:31:33 +02001483def Test_getcompletion()
1484 set wildignore=*.vim,*~
1485 let l = getcompletion('run', 'file', true)
1486 assert_equal([], l)
1487 set wildignore&
1488enddef
1489
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001490def Test_getreg()
1491 let lines = ['aaa', 'bbb', 'ccc']
1492 setreg('a', lines)
1493 assert_equal(lines, getreg('a', true, true))
1494enddef
1495
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001496def Test_glob()
1497 assert_equal(['runtest.vim'], glob('runtest.vim', true, true, true))
1498enddef
1499
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001500def Test_globpath()
1501 assert_equal(['./runtest.vim'], globpath('.', 'runtest.vim', true, true, true))
1502enddef
1503
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001504def Test_has()
1505 assert_equal(1, has('eval', true))
1506enddef
1507
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001508def Test_hasmapto()
1509 assert_equal(0, hasmapto('foobar', 'i', true))
1510 iabbrev foo foobar
1511 assert_equal(1, hasmapto('foobar', 'i', true))
1512 iunabbrev foo
1513enddef
1514
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001515def Test_index()
1516 assert_equal(3, index(['a', 'b', 'a', 'B'], 'b', 2, true))
1517enddef
1518
1519def Test_list2str_str2list_utf8()
1520 let s = "\u3042\u3044"
1521 let l = [0x3042, 0x3044]
1522 assert_equal(l, str2list(s, true))
1523 assert_equal(s, list2str(l, true))
1524enddef
1525
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001526def SID(): number
1527 return expand('<SID>')
1528 ->matchstr('<SNR>\zs\d\+\ze_$')
1529 ->str2nr()
1530enddef
1531
1532def Test_maparg()
1533 let lnum = str2nr(expand('<sflnum>'))
1534 map foo bar
1535 assert_equal(#{
1536 lnum: lnum + 1,
1537 script: 0,
1538 mode: ' ',
1539 silent: 0,
1540 noremap: 0,
1541 lhs: 'foo',
1542 lhsraw: 'foo',
1543 nowait: 0,
1544 expr: 0,
1545 sid: SID(),
1546 rhs: 'bar',
1547 buffer: 0},
1548 maparg('foo', '', false, true))
1549 unmap foo
1550enddef
1551
1552def Test_mapcheck()
1553 iabbrev foo foobar
1554 assert_equal('foobar', mapcheck('foo', 'i', true))
1555 iunabbrev foo
1556enddef
1557
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001558def Test_nr2char()
1559 assert_equal('a', nr2char(97, true))
1560enddef
1561
1562def Test_readdir()
1563 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1564 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
1565enddef
1566
1567def Test_search()
1568 new
1569 setline(1, ['foo', 'bar'])
1570 let val = 0
1571 # skip expr returns boolean
1572 assert_equal(2, search('bar', 'W', 0, 0, {-> val == 1}))
1573 :1
1574 assert_equal(0, search('bar', 'W', 0, 0, {-> val == 0}))
1575 # skip expr returns number, only 0 and 1 are accepted
1576 :1
1577 assert_equal(2, search('bar', 'W', 0, 0, {-> 0}))
1578 :1
1579 assert_equal(0, search('bar', 'W', 0, 0, {-> 1}))
1580 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1581 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1582enddef
1583
1584def Test_searchcount()
1585 new
1586 setline(1, "foo bar")
1587 :/foo
1588 assert_equal(#{
1589 exact_match: 1,
1590 current: 1,
1591 total: 1,
1592 maxcount: 99,
1593 incomplete: 0,
1594 }, searchcount(#{recompute: true}))
1595 bwipe!
1596enddef
1597
1598def Test_searchdecl()
1599 assert_equal(1, searchdecl('blah', true, true))
1600enddef
1601
1602def Test_setbufvar()
1603 setbufvar(bufnr('%'), '&syntax', 'vim')
1604 assert_equal('vim', &syntax)
1605 setbufvar(bufnr('%'), '&ts', 16)
1606 assert_equal(16, &ts)
1607 settabwinvar(1, 1, '&syntax', 'vam')
1608 assert_equal('vam', &syntax)
1609 settabwinvar(1, 1, '&ts', 15)
1610 assert_equal(15, &ts)
1611 setlocal ts=8
1612
1613 setbufvar('%', 'myvar', 123)
1614 assert_equal(123, getbufvar('%', 'myvar'))
1615enddef
1616
Bram Moolenaar401f0c02020-09-05 22:37:39 +02001617def Test_setloclist()
1618 let items = [#{filename: '/tmp/file', lnum: 1, valid: true}]
1619 let what = #{items: items}
1620 setqflist([], ' ', what)
1621 setloclist(0, [], ' ', what)
1622enddef
1623
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001624def Test_setreg()
1625 setreg('a', ['aaa', 'bbb', 'ccc'])
1626 let reginfo = getreginfo('a')
1627 setreg('a', reginfo)
1628 assert_equal(reginfo, getreginfo('a'))
1629enddef
1630
1631def Test_synID()
1632 new
1633 setline(1, "text")
1634 assert_equal(0, synID(1, 1, true))
1635 bwipe!
1636enddef
1637
1638def Test_win_splitmove()
1639 split
1640 win_splitmove(1, 2, #{vertical: true, rightbelow: true})
1641 close
1642enddef
1643
1644""""""" end of builtin functions
1645
1646def Fibonacci(n: number): number
1647 if n < 2
1648 return n
1649 else
1650 return Fibonacci(n - 1) + Fibonacci(n - 2)
1651 endif
1652enddef
1653
Bram Moolenaar985116a2020-07-12 17:31:09 +02001654def Test_recursive_call()
1655 assert_equal(6765, Fibonacci(20))
1656enddef
1657
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001658def TreeWalk(dir: string): list<any>
1659 return readdir(dir)->map({_, val ->
1660 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001661 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001662 : val
1663 })
1664enddef
1665
1666def Test_closure_in_map()
1667 mkdir('XclosureDir/tdir', 'p')
1668 writefile(['111'], 'XclosureDir/file1')
1669 writefile(['222'], 'XclosureDir/file2')
1670 writefile(['333'], 'XclosureDir/tdir/file3')
1671
1672 assert_equal(['file1', 'file2', {'tdir': ['file3']}], TreeWalk('XclosureDir'))
1673
1674 delete('XclosureDir', 'rf')
1675enddef
1676
Bram Moolenaara90afb92020-07-15 22:38:56 +02001677def Test_partial_call()
1678 let Xsetlist = function('setloclist', [0])
1679 Xsetlist([], ' ', {'title': 'test'})
1680 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1681
1682 Xsetlist = function('setloclist', [0, [], ' '])
1683 Xsetlist({'title': 'test'})
1684 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1685
1686 Xsetlist = function('setqflist')
1687 Xsetlist([], ' ', {'title': 'test'})
1688 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1689
1690 Xsetlist = function('setqflist', [[], ' '])
1691 Xsetlist({'title': 'test'})
1692 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1693enddef
1694
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001695def Test_cmd_modifier()
1696 tab echo '0'
1697 call CheckDefFailure(['5tab echo 3'], 'E16:')
1698enddef
1699
1700def Test_restore_modifiers()
1701 # check that when compiling a :def function command modifiers are not messed
1702 # up.
1703 let lines =<< trim END
1704 vim9script
1705 set eventignore=
1706 autocmd QuickFixCmdPost * copen
1707 def AutocmdsDisabled()
1708 eval 0
1709 enddef
1710 func Func()
1711 noautocmd call s:AutocmdsDisabled()
1712 let g:ei_after = &eventignore
1713 endfunc
1714 Func()
1715 END
1716 CheckScriptSuccess(lines)
1717 assert_equal('', g:ei_after)
1718enddef
1719
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001720
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001721" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker