blob: 04f8d7aa7e1fc535ca5fbecdccb4f28eee003d44 [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 Moolenaar05a55512020-07-05 15:52:19 +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')
738 assert_fails('so XToDelFunc', 'E933')
739 assert_fails('so XToDelFunc', 'E933')
740
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)
1275enddef
1276
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001277def Test_extend_return_type()
1278 let l = extend([1, 2], [3])
1279 let res = 0
1280 for n in l
1281 res += n
1282 endfor
1283 assert_equal(6, res)
1284enddef
1285
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001286def Test_insert_return_type()
1287 let l = insert([2, 1], 3)
1288 let res = 0
1289 for n in l
1290 res += n
1291 endfor
1292 assert_equal(6, res)
1293enddef
1294
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001295def Test_keys_return_type()
1296 const var: list<string> = #{a: 1, b: 2}->keys()
1297 assert_equal(['a', 'b'], var)
1298enddef
1299
Bram Moolenaar67627352020-07-05 21:10:24 +02001300def Test_reverse_return_type()
1301 let l = reverse([1, 2, 3])
1302 let res = 0
1303 for n in l
1304 res += n
1305 endfor
1306 assert_equal(6, res)
1307enddef
1308
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001309def Test_remove_return_type()
1310 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
1311 let res = 0
1312 for n in l
1313 res += n
1314 endfor
1315 assert_equal(3, res)
1316enddef
1317
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001318def Test_filter_return_type()
1319 let l = filter([1, 2, 3], {-> 1})
1320 let res = 0
1321 for n in l
1322 res += n
1323 endfor
1324 assert_equal(6, res)
1325enddef
1326
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001327def Test_bufnr()
1328 let buf = bufnr()
1329 assert_equal(buf, bufnr('%'))
1330enddef
1331
Bram Moolenaarec65d772020-08-20 22:29:12 +02001332def Test_col()
1333 new
1334 setline(1, 'asdf')
1335 assert_equal(5, col([1, '$']))
1336enddef
1337
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001338def Test_getreg_return_type()
1339 let s1: string = getreg('"')
1340 let s2: string = getreg('"', 1)
1341 let s3: list<string> = getreg('"', 1, 1)
1342enddef
1343
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001344def Wrong_dict_key_type(items: list<number>): list<number>
1345 return filter(items, {_, val -> get({val: 1}, 'x')})
1346enddef
1347
1348def Test_wrong_dict_key_type()
1349 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:')
1350enddef
1351
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001352def Line_continuation_in_def(dir: string = ''): string
1353 let path: string = empty(dir)
1354 \ ? 'empty'
1355 \ : 'full'
1356 return path
1357enddef
1358
1359def Test_line_continuation_in_def()
1360 assert_equal('full', Line_continuation_in_def('.'))
1361enddef
1362
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001363def Line_continuation_in_lambda(): list<number>
1364 let x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001365 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001366 ->toupper()})
1367 ->reverse()
1368 return x
1369enddef
1370
1371def Test_line_continuation_in_lambda()
1372 assert_equal(['D', 'C', 'B', 'A'], Line_continuation_in_lambda())
1373enddef
1374
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001375func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001376 CheckScreendump
1377
1378 let lines =<< trim END
1379 vim9script
1380 def EchoNothing()
1381 silent echo ''
1382 enddef
1383 defcompile
1384 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001385 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001386
1387 " Check that the balloon shows up after a mouse move
1388 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001389 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001390 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1391
1392 " clean up
1393 call StopVimInTerminal(buf)
1394 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001395endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001396
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001397def Test_search()
1398 new
1399 setline(1, ['foo', 'bar'])
1400 let val = 0
Bram Moolenaard70840e2020-08-22 15:06:35 +02001401 # skip expr returns boolean
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001402 assert_equal(2, search('bar', 'W', 0, 0, {-> val == 1}))
Bram Moolenaard70840e2020-08-22 15:06:35 +02001403 :1
1404 assert_equal(0, search('bar', 'W', 0, 0, {-> val == 0}))
1405 # skip expr returns number, only 0 and 1 are accepted
1406 :1
1407 assert_equal(2, search('bar', 'W', 0, 0, {-> 0}))
1408 :1
1409 assert_equal(0, search('bar', 'W', 0, 0, {-> 1}))
1410 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1411 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001412enddef
1413
Bram Moolenaarf8abbf32020-08-19 16:00:06 +02001414def Test_readdir()
Bram Moolenaard70840e2020-08-22 15:06:35 +02001415 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1416 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
Bram Moolenaaraf8822c2020-08-19 13:55:01 +02001417enddef
1418
Bram Moolenaar191929b2020-08-19 21:20:49 +02001419def Test_setbufvar()
1420 setbufvar(bufnr('%'), '&syntax', 'vim')
1421 assert_equal('vim', &syntax)
1422 setbufvar(bufnr('%'), '&ts', 16)
1423 assert_equal(16, &ts)
1424 settabwinvar(1, 1, '&syntax', 'vam')
1425 assert_equal('vam', &syntax)
1426 settabwinvar(1, 1, '&ts', 15)
1427 assert_equal(15, &ts)
1428 setlocal ts=8
Bram Moolenaar6f84b6d2020-09-01 23:16:32 +02001429
1430 setbufvar('%', 'myvar', 123)
1431 assert_equal(123, getbufvar('%', 'myvar'))
Bram Moolenaar191929b2020-08-19 21:20:49 +02001432enddef
1433
Bram Moolenaara5d38412020-09-02 21:02:35 +02001434def Test_bufwinid()
1435 let origwin = win_getid()
1436 below split SomeFile
1437 let SomeFileID = win_getid()
1438 below split OtherFile
1439 below split SomeFile
1440 assert_equal(SomeFileID, bufwinid('SomeFile'))
1441
1442 win_gotoid(origwin)
1443 only
1444 bwipe SomeFile
1445 bwipe OtherFile
1446enddef
1447
1448def Test_getbufline()
1449 e SomeFile
1450 let buf = bufnr()
1451 e #
1452 let lines = ['aaa', 'bbb', 'ccc']
1453 setbufline(buf, 1, lines)
1454 assert_equal(lines, getbufline('#', 1, '$'))
1455
1456 bwipe!
1457enddef
1458
1459def Test_getchangelist()
1460 new
1461 setline(1, 'some text')
1462 let changelist = bufnr()->getchangelist()
1463 assert_equal(changelist, getchangelist('%'))
1464 bwipe!
1465enddef
1466
Bram Moolenaar6a950582020-08-28 16:39:33 +02001467def Test_setreg()
1468 setreg('a', ['aaa', 'bbb', 'ccc'])
1469 let reginfo = getreginfo('a')
1470 setreg('a', reginfo)
1471 assert_equal(reginfo, getreginfo('a'))
1472enddef
1473
Bram Moolenaar02aaad92020-08-30 21:26:57 +02001474def Test_bufname()
1475 split SomeFile
1476 assert_equal('SomeFile', bufname('%'))
1477 edit OtherFile
1478 assert_equal('SomeFile', bufname('#'))
1479 close
1480enddef
1481
Bram Moolenaar3767e3a2020-09-01 23:06:01 +02001482def Test_gebufinfo()
1483 let bufinfo = getbufinfo(bufnr())
1484 assert_equal(bufinfo, getbufinfo('%'))
1485enddef
1486
Bram Moolenaar985116a2020-07-12 17:31:09 +02001487def Fibonacci(n: number): number
1488 if n < 2
1489 return n
1490 else
1491 return Fibonacci(n - 1) + Fibonacci(n - 2)
1492 endif
1493enddef
1494
Bram Moolenaar119f5572020-09-02 21:31:22 +02001495def Test_count()
1496 assert_equal(3, count('ABC ABC ABC', 'b', true))
1497 assert_equal(0, count('ABC ABC ABC', 'b', false))
1498enddef
1499
Bram Moolenaar6c553f92020-09-02 22:10:34 +02001500def Test_index()
1501 assert_equal(3, index(['a', 'b', 'a', 'B'], 'b', 2, true))
1502enddef
1503
Bram Moolenaar551d25e2020-09-02 21:37:56 +02001504def Test_expand()
1505 split SomeFile
1506 assert_equal(['SomeFile'], expand('%', true, true))
1507 close
1508enddef
1509
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001510def Test_getreg()
1511 let lines = ['aaa', 'bbb', 'ccc']
1512 setreg('a', lines)
1513 assert_equal(lines, getreg('a', true, true))
1514enddef
1515
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001516def Test_glob()
1517 assert_equal(['runtest.vim'], glob('runtest.vim', true, true, true))
1518enddef
1519
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001520def Test_globpath()
1521 assert_equal(['./runtest.vim'], globpath('.', 'runtest.vim', true, true, true))
1522enddef
1523
Bram Moolenaar985116a2020-07-12 17:31:09 +02001524def Test_recursive_call()
1525 assert_equal(6765, Fibonacci(20))
1526enddef
1527
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001528def TreeWalk(dir: string): list<any>
1529 return readdir(dir)->map({_, val ->
1530 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001531 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001532 : val
1533 })
1534enddef
1535
1536def Test_closure_in_map()
1537 mkdir('XclosureDir/tdir', 'p')
1538 writefile(['111'], 'XclosureDir/file1')
1539 writefile(['222'], 'XclosureDir/file2')
1540 writefile(['333'], 'XclosureDir/tdir/file3')
1541
1542 assert_equal(['file1', 'file2', {'tdir': ['file3']}], TreeWalk('XclosureDir'))
1543
1544 delete('XclosureDir', 'rf')
1545enddef
1546
Bram Moolenaara90afb92020-07-15 22:38:56 +02001547def Test_partial_call()
1548 let Xsetlist = function('setloclist', [0])
1549 Xsetlist([], ' ', {'title': 'test'})
1550 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1551
1552 Xsetlist = function('setloclist', [0, [], ' '])
1553 Xsetlist({'title': 'test'})
1554 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1555
1556 Xsetlist = function('setqflist')
1557 Xsetlist([], ' ', {'title': 'test'})
1558 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1559
1560 Xsetlist = function('setqflist', [[], ' '])
1561 Xsetlist({'title': 'test'})
1562 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1563enddef
1564
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001565def Test_cmd_modifier()
1566 tab echo '0'
1567 call CheckDefFailure(['5tab echo 3'], 'E16:')
1568enddef
1569
1570def Test_restore_modifiers()
1571 # check that when compiling a :def function command modifiers are not messed
1572 # up.
1573 let lines =<< trim END
1574 vim9script
1575 set eventignore=
1576 autocmd QuickFixCmdPost * copen
1577 def AutocmdsDisabled()
1578 eval 0
1579 enddef
1580 func Func()
1581 noautocmd call s:AutocmdsDisabled()
1582 let g:ei_after = &eventignore
1583 endfunc
1584 Func()
1585 END
1586 CheckScriptSuccess(lines)
1587 assert_equal('', g:ei_after)
1588enddef
1589
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001590
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001591" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker