blob: 8651ef8ebdc4f1fa586ada97f432b7507486b1c4 [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 Moolenaar252e88a2020-07-05 20:47:18 +02001288def Test_insert_return_type()
1289 let l = insert([2, 1], 3)
1290 let res = 0
1291 for n in l
1292 res += n
1293 endfor
1294 assert_equal(6, res)
1295enddef
1296
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001297def Test_keys_return_type()
1298 const var: list<string> = #{a: 1, b: 2}->keys()
1299 assert_equal(['a', 'b'], var)
1300enddef
1301
Bram Moolenaar67627352020-07-05 21:10:24 +02001302def Test_reverse_return_type()
1303 let l = reverse([1, 2, 3])
1304 let res = 0
1305 for n in l
1306 res += n
1307 endfor
1308 assert_equal(6, res)
1309enddef
1310
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001311def Test_remove_return_type()
1312 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
1313 let res = 0
1314 for n in l
1315 res += n
1316 endfor
1317 assert_equal(3, res)
1318enddef
1319
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001320def Test_filter_return_type()
1321 let l = filter([1, 2, 3], {-> 1})
1322 let res = 0
1323 for n in l
1324 res += n
1325 endfor
1326 assert_equal(6, res)
1327enddef
1328
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001329def Test_bufnr()
1330 let buf = bufnr()
1331 assert_equal(buf, bufnr('%'))
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001332
1333 buf = bufnr('Xdummy', true)
1334 assert_notequal(-1, buf)
1335 exe 'bwipe! ' .. buf
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001336enddef
1337
Bram Moolenaarec65d772020-08-20 22:29:12 +02001338def Test_col()
1339 new
1340 setline(1, 'asdf')
1341 assert_equal(5, col([1, '$']))
1342enddef
1343
Bram Moolenaar24f77502020-09-04 19:50:57 +02001344def Test_char2nr()
1345 assert_equal(12354, char2nr('あ', true))
1346enddef
1347
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001348def Test_getreg_return_type()
1349 let s1: string = getreg('"')
1350 let s2: string = getreg('"', 1)
1351 let s3: list<string> = getreg('"', 1, 1)
1352enddef
1353
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001354def Wrong_dict_key_type(items: list<number>): list<number>
1355 return filter(items, {_, val -> get({val: 1}, 'x')})
1356enddef
1357
1358def Test_wrong_dict_key_type()
1359 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:')
1360enddef
1361
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001362def Line_continuation_in_def(dir: string = ''): string
1363 let path: string = empty(dir)
1364 \ ? 'empty'
1365 \ : 'full'
1366 return path
1367enddef
1368
1369def Test_line_continuation_in_def()
1370 assert_equal('full', Line_continuation_in_def('.'))
1371enddef
1372
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001373def Line_continuation_in_lambda(): list<number>
1374 let x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001375 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001376 ->toupper()})
1377 ->reverse()
1378 return x
1379enddef
1380
1381def Test_line_continuation_in_lambda()
1382 assert_equal(['D', 'C', 'B', 'A'], Line_continuation_in_lambda())
1383enddef
1384
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001385func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001386 CheckScreendump
1387
1388 let lines =<< trim END
1389 vim9script
1390 def EchoNothing()
1391 silent echo ''
1392 enddef
1393 defcompile
1394 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001395 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001396
1397 " Check that the balloon shows up after a mouse move
1398 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001399 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001400 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1401
1402 " clean up
1403 call StopVimInTerminal(buf)
1404 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001405endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001406
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001407def Test_search()
1408 new
1409 setline(1, ['foo', 'bar'])
1410 let val = 0
Bram Moolenaard70840e2020-08-22 15:06:35 +02001411 # skip expr returns boolean
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001412 assert_equal(2, search('bar', 'W', 0, 0, {-> val == 1}))
Bram Moolenaard70840e2020-08-22 15:06:35 +02001413 :1
1414 assert_equal(0, search('bar', 'W', 0, 0, {-> val == 0}))
1415 # skip expr returns number, only 0 and 1 are accepted
1416 :1
1417 assert_equal(2, search('bar', 'W', 0, 0, {-> 0}))
1418 :1
1419 assert_equal(0, search('bar', 'W', 0, 0, {-> 1}))
1420 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1421 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001422enddef
1423
Bram Moolenaarf8abbf32020-08-19 16:00:06 +02001424def Test_readdir()
Bram Moolenaard70840e2020-08-22 15:06:35 +02001425 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1426 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
Bram Moolenaaraf8822c2020-08-19 13:55:01 +02001427enddef
1428
Bram Moolenaar191929b2020-08-19 21:20:49 +02001429def Test_setbufvar()
1430 setbufvar(bufnr('%'), '&syntax', 'vim')
1431 assert_equal('vim', &syntax)
1432 setbufvar(bufnr('%'), '&ts', 16)
1433 assert_equal(16, &ts)
1434 settabwinvar(1, 1, '&syntax', 'vam')
1435 assert_equal('vam', &syntax)
1436 settabwinvar(1, 1, '&ts', 15)
1437 assert_equal(15, &ts)
1438 setlocal ts=8
Bram Moolenaar6f84b6d2020-09-01 23:16:32 +02001439
1440 setbufvar('%', 'myvar', 123)
1441 assert_equal(123, getbufvar('%', 'myvar'))
Bram Moolenaar191929b2020-08-19 21:20:49 +02001442enddef
1443
Bram Moolenaara5d38412020-09-02 21:02:35 +02001444def Test_bufwinid()
1445 let origwin = win_getid()
1446 below split SomeFile
1447 let SomeFileID = win_getid()
1448 below split OtherFile
1449 below split SomeFile
1450 assert_equal(SomeFileID, bufwinid('SomeFile'))
1451
1452 win_gotoid(origwin)
1453 only
1454 bwipe SomeFile
1455 bwipe OtherFile
1456enddef
1457
1458def 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 Moolenaar6a950582020-08-28 16:39:33 +02001477def Test_setreg()
1478 setreg('a', ['aaa', 'bbb', 'ccc'])
1479 let reginfo = getreginfo('a')
1480 setreg('a', reginfo)
1481 assert_equal(reginfo, getreginfo('a'))
1482enddef
1483
Bram Moolenaar02aaad92020-08-30 21:26:57 +02001484def Test_bufname()
1485 split SomeFile
1486 assert_equal('SomeFile', bufname('%'))
1487 edit OtherFile
1488 assert_equal('SomeFile', bufname('#'))
1489 close
1490enddef
1491
Bram Moolenaar3767e3a2020-09-01 23:06:01 +02001492def Test_gebufinfo()
1493 let bufinfo = getbufinfo(bufnr())
1494 assert_equal(bufinfo, getbufinfo('%'))
1495enddef
1496
Bram Moolenaar985116a2020-07-12 17:31:09 +02001497def Fibonacci(n: number): number
1498 if n < 2
1499 return n
1500 else
1501 return Fibonacci(n - 1) + Fibonacci(n - 2)
1502 endif
1503enddef
1504
Bram Moolenaar119f5572020-09-02 21:31:22 +02001505def Test_count()
1506 assert_equal(3, count('ABC ABC ABC', 'b', true))
1507 assert_equal(0, count('ABC ABC ABC', 'b', false))
1508enddef
1509
Bram Moolenaar6c553f92020-09-02 22:10:34 +02001510def Test_index()
1511 assert_equal(3, index(['a', 'b', 'a', 'B'], 'b', 2, true))
1512enddef
1513
Bram Moolenaar551d25e2020-09-02 21:37:56 +02001514def Test_expand()
1515 split SomeFile
1516 assert_equal(['SomeFile'], expand('%', true, true))
1517 close
1518enddef
1519
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001520def Test_getreg()
1521 let lines = ['aaa', 'bbb', 'ccc']
1522 setreg('a', lines)
1523 assert_equal(lines, getreg('a', true, true))
1524enddef
1525
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001526def Test_glob()
1527 assert_equal(['runtest.vim'], glob('runtest.vim', true, true, true))
1528enddef
1529
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001530def Test_globpath()
1531 assert_equal(['./runtest.vim'], globpath('.', 'runtest.vim', true, true, true))
1532enddef
1533
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001534def Test_hasmapto()
1535 assert_equal(0, hasmapto('foobar', 'i', true))
1536 iabbrev foo foobar
1537 assert_equal(1, hasmapto('foobar', 'i', true))
1538 iunabbrev foo
1539enddef
1540
1541def SID(): number
1542 return expand('<SID>')
1543 ->matchstr('<SNR>\zs\d\+\ze_$')
1544 ->str2nr()
1545enddef
1546
1547def Test_maparg()
1548 let lnum = str2nr(expand('<sflnum>'))
1549 map foo bar
1550 assert_equal(#{
1551 lnum: lnum + 1,
1552 script: 0,
1553 mode: ' ',
1554 silent: 0,
1555 noremap: 0,
1556 lhs: 'foo',
1557 lhsraw: 'foo',
1558 nowait: 0,
1559 expr: 0,
1560 sid: SID(),
1561 rhs: 'bar',
1562 buffer: 0},
1563 maparg('foo', '', false, true))
1564 unmap foo
1565enddef
1566
1567def Test_mapcheck()
1568 iabbrev foo foobar
1569 assert_equal('foobar', mapcheck('foo', 'i', true))
1570 iunabbrev foo
1571enddef
1572
Bram Moolenaar985116a2020-07-12 17:31:09 +02001573def Test_recursive_call()
1574 assert_equal(6765, Fibonacci(20))
1575enddef
1576
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001577def TreeWalk(dir: string): list<any>
1578 return readdir(dir)->map({_, val ->
1579 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001580 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001581 : val
1582 })
1583enddef
1584
1585def Test_closure_in_map()
1586 mkdir('XclosureDir/tdir', 'p')
1587 writefile(['111'], 'XclosureDir/file1')
1588 writefile(['222'], 'XclosureDir/file2')
1589 writefile(['333'], 'XclosureDir/tdir/file3')
1590
1591 assert_equal(['file1', 'file2', {'tdir': ['file3']}], TreeWalk('XclosureDir'))
1592
1593 delete('XclosureDir', 'rf')
1594enddef
1595
Bram Moolenaara90afb92020-07-15 22:38:56 +02001596def Test_partial_call()
1597 let Xsetlist = function('setloclist', [0])
1598 Xsetlist([], ' ', {'title': 'test'})
1599 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1600
1601 Xsetlist = function('setloclist', [0, [], ' '])
1602 Xsetlist({'title': 'test'})
1603 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1604
1605 Xsetlist = function('setqflist')
1606 Xsetlist([], ' ', {'title': 'test'})
1607 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1608
1609 Xsetlist = function('setqflist', [[], ' '])
1610 Xsetlist({'title': 'test'})
1611 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1612enddef
1613
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001614def Test_cmd_modifier()
1615 tab echo '0'
1616 call CheckDefFailure(['5tab echo 3'], 'E16:')
1617enddef
1618
1619def Test_restore_modifiers()
1620 # check that when compiling a :def function command modifiers are not messed
1621 # up.
1622 let lines =<< trim END
1623 vim9script
1624 set eventignore=
1625 autocmd QuickFixCmdPost * copen
1626 def AutocmdsDisabled()
1627 eval 0
1628 enddef
1629 func Func()
1630 noautocmd call s:AutocmdsDisabled()
1631 let g:ei_after = &eventignore
1632 endfunc
1633 Func()
1634 END
1635 CheckScriptSuccess(lines)
1636 assert_equal('', g:ei_after)
1637enddef
1638
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001639
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001640" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker