blob: 3e217300fe4624ad54e50cb441c61852afbb94b2 [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('%'))
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001330
1331 buf = bufnr('Xdummy', true)
1332 assert_notequal(-1, buf)
1333 exe 'bwipe! ' .. buf
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001334enddef
1335
Bram Moolenaarec65d772020-08-20 22:29:12 +02001336def Test_col()
1337 new
1338 setline(1, 'asdf')
1339 assert_equal(5, col([1, '$']))
1340enddef
1341
Bram Moolenaar24f77502020-09-04 19:50:57 +02001342def Test_char2nr()
1343 assert_equal(12354, char2nr('あ', true))
1344enddef
1345
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001346def Test_getreg_return_type()
1347 let s1: string = getreg('"')
1348 let s2: string = getreg('"', 1)
1349 let s3: list<string> = getreg('"', 1, 1)
1350enddef
1351
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001352def Wrong_dict_key_type(items: list<number>): list<number>
1353 return filter(items, {_, val -> get({val: 1}, 'x')})
1354enddef
1355
1356def Test_wrong_dict_key_type()
1357 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:')
1358enddef
1359
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001360def Line_continuation_in_def(dir: string = ''): string
1361 let path: string = empty(dir)
1362 \ ? 'empty'
1363 \ : 'full'
1364 return path
1365enddef
1366
1367def Test_line_continuation_in_def()
1368 assert_equal('full', Line_continuation_in_def('.'))
1369enddef
1370
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001371def Line_continuation_in_lambda(): list<number>
1372 let x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001373 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001374 ->toupper()})
1375 ->reverse()
1376 return x
1377enddef
1378
1379def Test_line_continuation_in_lambda()
1380 assert_equal(['D', 'C', 'B', 'A'], Line_continuation_in_lambda())
1381enddef
1382
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001383func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001384 CheckScreendump
1385
1386 let lines =<< trim END
1387 vim9script
1388 def EchoNothing()
1389 silent echo ''
1390 enddef
1391 defcompile
1392 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001393 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001394
1395 " Check that the balloon shows up after a mouse move
1396 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001397 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001398 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1399
1400 " clean up
1401 call StopVimInTerminal(buf)
1402 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001403endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001404
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001405def Test_search()
1406 new
1407 setline(1, ['foo', 'bar'])
1408 let val = 0
Bram Moolenaard70840e2020-08-22 15:06:35 +02001409 # skip expr returns boolean
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001410 assert_equal(2, search('bar', 'W', 0, 0, {-> val == 1}))
Bram Moolenaard70840e2020-08-22 15:06:35 +02001411 :1
1412 assert_equal(0, search('bar', 'W', 0, 0, {-> val == 0}))
1413 # skip expr returns number, only 0 and 1 are accepted
1414 :1
1415 assert_equal(2, search('bar', 'W', 0, 0, {-> 0}))
1416 :1
1417 assert_equal(0, search('bar', 'W', 0, 0, {-> 1}))
1418 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1419 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001420enddef
1421
Bram Moolenaarf8abbf32020-08-19 16:00:06 +02001422def Test_readdir()
Bram Moolenaard70840e2020-08-22 15:06:35 +02001423 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1424 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
Bram Moolenaaraf8822c2020-08-19 13:55:01 +02001425enddef
1426
Bram Moolenaar191929b2020-08-19 21:20:49 +02001427def Test_setbufvar()
1428 setbufvar(bufnr('%'), '&syntax', 'vim')
1429 assert_equal('vim', &syntax)
1430 setbufvar(bufnr('%'), '&ts', 16)
1431 assert_equal(16, &ts)
1432 settabwinvar(1, 1, '&syntax', 'vam')
1433 assert_equal('vam', &syntax)
1434 settabwinvar(1, 1, '&ts', 15)
1435 assert_equal(15, &ts)
1436 setlocal ts=8
Bram Moolenaar6f84b6d2020-09-01 23:16:32 +02001437
1438 setbufvar('%', 'myvar', 123)
1439 assert_equal(123, getbufvar('%', 'myvar'))
Bram Moolenaar191929b2020-08-19 21:20:49 +02001440enddef
1441
Bram Moolenaara5d38412020-09-02 21:02:35 +02001442def Test_bufwinid()
1443 let origwin = win_getid()
1444 below split SomeFile
1445 let SomeFileID = win_getid()
1446 below split OtherFile
1447 below split SomeFile
1448 assert_equal(SomeFileID, bufwinid('SomeFile'))
1449
1450 win_gotoid(origwin)
1451 only
1452 bwipe SomeFile
1453 bwipe OtherFile
1454enddef
1455
1456def Test_getbufline()
1457 e SomeFile
1458 let buf = bufnr()
1459 e #
1460 let lines = ['aaa', 'bbb', 'ccc']
1461 setbufline(buf, 1, lines)
1462 assert_equal(lines, getbufline('#', 1, '$'))
1463
1464 bwipe!
1465enddef
1466
1467def Test_getchangelist()
1468 new
1469 setline(1, 'some text')
1470 let changelist = bufnr()->getchangelist()
1471 assert_equal(changelist, getchangelist('%'))
1472 bwipe!
1473enddef
1474
Bram Moolenaar6a950582020-08-28 16:39:33 +02001475def Test_setreg()
1476 setreg('a', ['aaa', 'bbb', 'ccc'])
1477 let reginfo = getreginfo('a')
1478 setreg('a', reginfo)
1479 assert_equal(reginfo, getreginfo('a'))
1480enddef
1481
Bram Moolenaar02aaad92020-08-30 21:26:57 +02001482def Test_bufname()
1483 split SomeFile
1484 assert_equal('SomeFile', bufname('%'))
1485 edit OtherFile
1486 assert_equal('SomeFile', bufname('#'))
1487 close
1488enddef
1489
Bram Moolenaar3767e3a2020-09-01 23:06:01 +02001490def Test_gebufinfo()
1491 let bufinfo = getbufinfo(bufnr())
1492 assert_equal(bufinfo, getbufinfo('%'))
1493enddef
1494
Bram Moolenaar985116a2020-07-12 17:31:09 +02001495def Fibonacci(n: number): number
1496 if n < 2
1497 return n
1498 else
1499 return Fibonacci(n - 1) + Fibonacci(n - 2)
1500 endif
1501enddef
1502
Bram Moolenaar119f5572020-09-02 21:31:22 +02001503def Test_count()
1504 assert_equal(3, count('ABC ABC ABC', 'b', true))
1505 assert_equal(0, count('ABC ABC ABC', 'b', false))
1506enddef
1507
Bram Moolenaar6c553f92020-09-02 22:10:34 +02001508def Test_index()
1509 assert_equal(3, index(['a', 'b', 'a', 'B'], 'b', 2, true))
1510enddef
1511
Bram Moolenaar551d25e2020-09-02 21:37:56 +02001512def Test_expand()
1513 split SomeFile
1514 assert_equal(['SomeFile'], expand('%', true, true))
1515 close
1516enddef
1517
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001518def Test_getreg()
1519 let lines = ['aaa', 'bbb', 'ccc']
1520 setreg('a', lines)
1521 assert_equal(lines, getreg('a', true, true))
1522enddef
1523
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001524def Test_glob()
1525 assert_equal(['runtest.vim'], glob('runtest.vim', true, true, true))
1526enddef
1527
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001528def Test_globpath()
1529 assert_equal(['./runtest.vim'], globpath('.', 'runtest.vim', true, true, true))
1530enddef
1531
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001532def Test_hasmapto()
1533 assert_equal(0, hasmapto('foobar', 'i', true))
1534 iabbrev foo foobar
1535 assert_equal(1, hasmapto('foobar', 'i', true))
1536 iunabbrev foo
1537enddef
1538
1539def SID(): number
1540 return expand('<SID>')
1541 ->matchstr('<SNR>\zs\d\+\ze_$')
1542 ->str2nr()
1543enddef
1544
1545def Test_maparg()
1546 let lnum = str2nr(expand('<sflnum>'))
1547 map foo bar
1548 assert_equal(#{
1549 lnum: lnum + 1,
1550 script: 0,
1551 mode: ' ',
1552 silent: 0,
1553 noremap: 0,
1554 lhs: 'foo',
1555 lhsraw: 'foo',
1556 nowait: 0,
1557 expr: 0,
1558 sid: SID(),
1559 rhs: 'bar',
1560 buffer: 0},
1561 maparg('foo', '', false, true))
1562 unmap foo
1563enddef
1564
1565def Test_mapcheck()
1566 iabbrev foo foobar
1567 assert_equal('foobar', mapcheck('foo', 'i', true))
1568 iunabbrev foo
1569enddef
1570
Bram Moolenaar985116a2020-07-12 17:31:09 +02001571def Test_recursive_call()
1572 assert_equal(6765, Fibonacci(20))
1573enddef
1574
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001575def TreeWalk(dir: string): list<any>
1576 return readdir(dir)->map({_, val ->
1577 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001578 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001579 : val
1580 })
1581enddef
1582
1583def Test_closure_in_map()
1584 mkdir('XclosureDir/tdir', 'p')
1585 writefile(['111'], 'XclosureDir/file1')
1586 writefile(['222'], 'XclosureDir/file2')
1587 writefile(['333'], 'XclosureDir/tdir/file3')
1588
1589 assert_equal(['file1', 'file2', {'tdir': ['file3']}], TreeWalk('XclosureDir'))
1590
1591 delete('XclosureDir', 'rf')
1592enddef
1593
Bram Moolenaara90afb92020-07-15 22:38:56 +02001594def Test_partial_call()
1595 let Xsetlist = function('setloclist', [0])
1596 Xsetlist([], ' ', {'title': 'test'})
1597 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1598
1599 Xsetlist = function('setloclist', [0, [], ' '])
1600 Xsetlist({'title': 'test'})
1601 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1602
1603 Xsetlist = function('setqflist')
1604 Xsetlist([], ' ', {'title': 'test'})
1605 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1606
1607 Xsetlist = function('setqflist', [[], ' '])
1608 Xsetlist({'title': 'test'})
1609 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1610enddef
1611
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001612def Test_cmd_modifier()
1613 tab echo '0'
1614 call CheckDefFailure(['5tab echo 3'], 'E16:')
1615enddef
1616
1617def Test_restore_modifiers()
1618 # check that when compiling a :def function command modifiers are not messed
1619 # up.
1620 let lines =<< trim END
1621 vim9script
1622 set eventignore=
1623 autocmd QuickFixCmdPost * copen
1624 def AutocmdsDisabled()
1625 eval 0
1626 enddef
1627 func Func()
1628 noautocmd call s:AutocmdsDisabled()
1629 let g:ei_after = &eventignore
1630 endfunc
1631 Func()
1632 END
1633 CheckScriptSuccess(lines)
1634 assert_equal('', g:ei_after)
1635enddef
1636
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001637
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001638" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker