blob: 2c23a0e16e4c8d967c471f9e84be82addeedf46e [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 Moolenaar5deeb3f2020-04-05 17:08:17 +0200226enddef
227
228" Default arg and varargs
229def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
230 let res = one .. ',' .. two
231 for s in rest
232 res ..= ',' .. s
233 endfor
234 return res
235enddef
236
237def Test_call_def_varargs()
238 call assert_fails('call MyDefVarargs()', 'E119:')
239 assert_equal('one,foo', MyDefVarargs('one'))
240 assert_equal('one,two', MyDefVarargs('one', 'two'))
241 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200242 CheckDefFailure(['MyDefVarargs("one", 22)'],
243 'E1013: argument 2: type mismatch, expected string but got number')
244 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
245 'E1013: argument 3: type mismatch, expected string but got number')
246
247 let lines =<< trim END
248 vim9script
249 def Func(...l: list<string>)
250 echo l
251 enddef
252 Func('a', 'b', 'c')
253 END
254 CheckScriptSuccess(lines)
255
256 lines =<< trim END
257 vim9script
258 def Func(...l: list<string>)
259 echo l
260 enddef
261 Func()
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(1, 2, 3)
271 END
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200272 CheckScriptFailure(lines, 'E1012:')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200273
274 lines =<< trim END
275 vim9script
276 def Func(...l: list<string>)
277 echo l
278 enddef
279 Func('a', 9)
280 END
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200281 CheckScriptFailure(lines, 'E1012:')
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(1, 'a')
289 END
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200290 CheckScriptFailure(lines, 'E1012:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200291enddef
292
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200293def Test_call_call()
294 let l = [3, 2, 1]
295 call('reverse', [l])
296 assert_equal([1, 2, 3], l)
297enddef
298
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200299let s:value = ''
300
301def FuncOneDefArg(opt = 'text')
302 s:value = opt
303enddef
304
305def FuncTwoDefArg(nr = 123, opt = 'text'): string
306 return nr .. opt
307enddef
308
309def FuncVarargs(...arg: list<string>): string
310 return join(arg, ',')
311enddef
312
313def Test_func_type_varargs()
314 let RefDefArg: func(?string)
315 RefDefArg = FuncOneDefArg
316 RefDefArg()
317 assert_equal('text', s:value)
318 RefDefArg('some')
319 assert_equal('some', s:value)
320
321 let RefDef2Arg: func(?number, ?string): string
322 RefDef2Arg = FuncTwoDefArg
323 assert_equal('123text', RefDef2Arg())
324 assert_equal('99text', RefDef2Arg(99))
325 assert_equal('77some', RefDef2Arg(77, 'some'))
326
327 call CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:')
328 call CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:')
329
330 let RefVarargs: func(...list<string>): string
331 RefVarargs = FuncVarargs
332 assert_equal('', RefVarargs())
333 assert_equal('one', RefVarargs('one'))
334 assert_equal('one,two', RefVarargs('one', 'two'))
335
336 call CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:')
337 call CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:')
338enddef
339
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200340" Only varargs
341def MyVarargsOnly(...args: list<string>): string
342 return join(args, ',')
343enddef
344
345def Test_call_varargs_only()
346 assert_equal('', MyVarargsOnly())
347 assert_equal('one', MyVarargsOnly('one'))
348 assert_equal('one,two', MyVarargsOnly('one', 'two'))
349 call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number')
350 call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number')
351enddef
352
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200353def Test_using_var_as_arg()
Bram Moolenaar822ba242020-05-24 23:00:18 +0200354 call writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200355 call assert_fails('so Xdef', 'E1006:')
356 call delete('Xdef')
357enddef
358
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200359def DictArg(arg: dict<string>)
360 arg['key'] = 'value'
361enddef
362
363def ListArg(arg: list<string>)
364 arg[0] = 'value'
365enddef
366
367def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200368 # works for dict and list
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200369 let d: dict<string> = {}
370 DictArg(d)
371 assert_equal('value', d['key'])
372 let l: list<string> = []
373 ListArg(l)
374 assert_equal('value', l[0])
375
Bram Moolenaar822ba242020-05-24 23:00:18 +0200376 call CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200377enddef
378
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200379def Test_call_func_defined_later()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200380 call assert_equal('one', g:DefinedLater('one'))
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200381 call assert_fails('call NotDefined("one")', 'E117:')
382enddef
383
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200384func DefinedLater(arg)
385 return a:arg
386endfunc
387
388def Test_call_funcref()
389 assert_equal(3, g:SomeFunc('abc'))
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200390 assert_fails('NotAFunc()', 'E117:') # comment after call
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200391 assert_fails('g:NotAFunc()', 'E117:')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200392
393 let lines =<< trim END
394 vim9script
395 def RetNumber(): number
396 return 123
397 enddef
398 let Funcref: func: number = function('RetNumber')
399 assert_equal(123, Funcref())
400 END
401 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200402
403 lines =<< trim END
404 vim9script
405 def RetNumber(): number
406 return 123
407 enddef
408 def Bar(F: func: number): number
409 return F()
410 enddef
411 let Funcref = function('RetNumber')
412 assert_equal(123, Bar(Funcref))
413 END
414 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200415
416 lines =<< trim END
417 vim9script
418 def UseNumber(nr: number)
419 echo nr
420 enddef
421 let Funcref: func(number) = function('UseNumber')
422 Funcref(123)
423 END
424 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200425
426 lines =<< trim END
427 vim9script
428 def UseNumber(nr: number)
429 echo nr
430 enddef
431 let Funcref: func(string) = function('UseNumber')
432 END
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200433 CheckScriptFailure(lines, 'E1012: type mismatch, expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200434
435 lines =<< trim END
436 vim9script
437 def EchoNr(nr = 34)
438 g:echo = nr
439 enddef
440 let Funcref: func(?number) = function('EchoNr')
441 Funcref()
442 assert_equal(34, g:echo)
443 Funcref(123)
444 assert_equal(123, g:echo)
445 END
446 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200447
448 lines =<< trim END
449 vim9script
450 def EchoList(...l: list<number>)
451 g:echo = l
452 enddef
453 let Funcref: func(...list<number>) = function('EchoList')
454 Funcref()
455 assert_equal([], g:echo)
456 Funcref(1, 2, 3)
457 assert_equal([1, 2, 3], g:echo)
458 END
459 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200460
461 lines =<< trim END
462 vim9script
463 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
464 g:optarg = opt
465 g:listarg = l
466 return nr
467 enddef
468 let Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
469 assert_equal(10, Funcref(10))
470 assert_equal(12, g:optarg)
471 assert_equal([], g:listarg)
472
473 assert_equal(11, Funcref(11, 22))
474 assert_equal(22, g:optarg)
475 assert_equal([], g:listarg)
476
477 assert_equal(17, Funcref(17, 18, 1, 2, 3))
478 assert_equal(18, g:optarg)
479 assert_equal([1, 2, 3], g:listarg)
480 END
481 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200482enddef
483
484let SomeFunc = function('len')
485let NotAFunc = 'text'
486
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200487def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200488 # same arguments, different return type
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200489 let Ref1: func(bool): string
490 let Ref2: func(bool): number
491 let Ref3: func(bool): any
492 Ref3 = g:cond ? Ref1 : Ref2
493
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200494 # different number of arguments
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200495 let Refa1: func(bool): number
496 let Refa2: func(bool, number): number
497 let Refa3: func: number
498 Refa3 = g:cond ? Refa1 : Refa2
499
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200500 # different argument types
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200501 let Refb1: func(bool, string): number
502 let Refb2: func(string, number): number
503 let Refb3: func(any, any): number
504 Refb3 = g:cond ? Refb1 : Refb2
505enddef
506
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200507def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200508 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200509enddef
510
511def DefinedEvenLater(arg: string): string
512 return arg
513enddef
514
515def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200516 # Error in called function requires unwinding the call stack.
Bram Moolenaar05a55512020-07-05 15:52:19 +0200517 assert_fails('call FuncWithForwardCall()', 'E1096')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200518enddef
519
520def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200521 CheckScriptFailure([
522 'def Func(): number',
523 'return "a"',
524 'enddef',
525 'defcompile'], 'expected number but got string')
526 CheckScriptFailure([
527 'def Func(): string',
528 'return 1',
529 'enddef',
530 'defcompile'], 'expected string but got number')
531 CheckScriptFailure([
532 'def Func(): void',
533 'return "a"',
534 'enddef',
535 'defcompile'],
536 'E1096: Returning a value in a function without a return type')
537 CheckScriptFailure([
538 'def Func()',
539 'return "a"',
540 'enddef',
541 'defcompile'],
542 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200543
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200544 CheckScriptFailure([
545 'def Func(): number',
546 'return',
547 'enddef',
548 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200549
550 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
551 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200552 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200553
554 CheckScriptFailure([
555 'vim9script',
556 'def FuncB()',
557 ' return 123',
558 'enddef',
559 'def FuncA()',
560 ' FuncB()',
561 'enddef',
562 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200563enddef
564
565def Test_arg_type_wrong()
566 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200567 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200568 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200569 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200570enddef
571
572def Test_vim9script_call()
573 let lines =<< trim END
574 vim9script
575 let var = ''
576 def MyFunc(arg: string)
577 var = arg
578 enddef
579 MyFunc('foobar')
580 assert_equal('foobar', var)
581
582 let str = 'barfoo'
583 str->MyFunc()
584 assert_equal('barfoo', var)
585
Bram Moolenaar67979662020-06-20 22:50:47 +0200586 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200587 g:value->MyFunc()
588 assert_equal('value', var)
589
590 let listvar = []
591 def ListFunc(arg: list<number>)
592 listvar = arg
593 enddef
594 [1, 2, 3]->ListFunc()
595 assert_equal([1, 2, 3], listvar)
596
597 let dictvar = {}
598 def DictFunc(arg: dict<number>)
599 dictvar = arg
600 enddef
601 {'a': 1, 'b': 2}->DictFunc()
602 assert_equal(#{a: 1, b: 2}, dictvar)
603 def CompiledDict()
604 {'a': 3, 'b': 4}->DictFunc()
605 enddef
606 CompiledDict()
607 assert_equal(#{a: 3, b: 4}, dictvar)
608
609 #{a: 3, b: 4}->DictFunc()
610 assert_equal(#{a: 3, b: 4}, dictvar)
611
612 ('text')->MyFunc()
613 assert_equal('text', var)
614 ("some")->MyFunc()
615 assert_equal('some', var)
Bram Moolenaare6b53242020-07-01 17:28:33 +0200616
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200617 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200618 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200619 'asdfasdf'->MyFunc()
620 assert_equal('asdfasdf', var)
Bram Moolenaar10409562020-07-29 20:00:38 +0200621 "xyz"->MyFunc()
622 assert_equal('xyz', var)
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200623
624 def UseString()
625 'xyork'->MyFunc()
626 enddef
627 UseString()
628 assert_equal('xyork', var)
629
Bram Moolenaar10409562020-07-29 20:00:38 +0200630 def UseString2()
631 "knife"->MyFunc()
632 enddef
633 UseString2()
634 assert_equal('knife', var)
635
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200636 # prepending a colon makes it a mark
637 new
638 setline(1, ['aaa', 'bbb', 'ccc'])
639 normal! 3Gmt1G
640 :'t
641 assert_equal(3, getcurpos()[1])
642 bwipe!
643
Bram Moolenaare6b53242020-07-01 17:28:33 +0200644 MyFunc(
645 'continued'
646 )
647 assert_equal('continued',
648 var
649 )
650
651 call MyFunc(
652 'more'
653 ..
654 'lines'
655 )
656 assert_equal(
657 'morelines',
658 var)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200659 END
660 writefile(lines, 'Xcall.vim')
661 source Xcall.vim
662 delete('Xcall.vim')
663enddef
664
665def Test_vim9script_call_fail_decl()
666 let lines =<< trim END
667 vim9script
668 let var = ''
669 def MyFunc(arg: string)
670 let var = 123
671 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200672 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200673 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200674 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200675enddef
676
Bram Moolenaar65b95452020-07-19 14:03:09 +0200677def Test_vim9script_call_fail_type()
678 let lines =<< trim END
679 vim9script
680 def MyFunc(arg: string)
681 echo arg
682 enddef
683 MyFunc(1234)
684 END
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200685 CheckScriptFailure(lines, 'E1012: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200686enddef
687
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200688def Test_vim9script_call_fail_const()
689 let lines =<< trim END
690 vim9script
691 const var = ''
692 def MyFunc(arg: string)
693 var = 'asdf'
694 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200695 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200696 END
697 writefile(lines, 'Xcall_const.vim')
698 assert_fails('source Xcall_const.vim', 'E46:')
699 delete('Xcall_const.vim')
700enddef
701
702" Test that inside :function a Python function can be defined, :def is not
703" recognized.
704func Test_function_python()
705 CheckFeature python3
706 let py = 'python3'
707 execute py "<< EOF"
708def do_something():
709 return 1
710EOF
711endfunc
712
713def Test_delfunc()
714 let lines =<< trim END
715 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200716 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200717 echo 'hello'
718 enddef
719
720 def CallGoneSoon()
721 GoneSoon()
722 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200723 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200724
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200725 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200726 CallGoneSoon()
727 END
728 writefile(lines, 'XToDelFunc')
729 assert_fails('so XToDelFunc', 'E933')
730 assert_fails('so XToDelFunc', 'E933')
731
732 delete('XToDelFunc')
733enddef
734
735def Test_redef_failure()
736 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
737 so Xdef
738 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
739 so Xdef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200740 call writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200741 call assert_fails('so Xdef', 'E1027:')
742 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
743 so Xdef
744 call delete('Xdef')
745
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200746 call assert_equal(0, g:Func0())
747 call assert_equal('Func1', g:Func1())
748 call assert_equal('Func2', g:Func2())
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200749
750 delfunc! Func0
751 delfunc! Func1
752 delfunc! Func2
753enddef
754
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200755def Test_vim9script_func()
756 let lines =<< trim END
757 vim9script
758 func Func(arg)
759 echo a:arg
760 endfunc
761 Func('text')
762 END
763 writefile(lines, 'XVim9Func')
764 so XVim9Func
765
766 delete('XVim9Func')
767enddef
768
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200769" Test for internal functions returning different types
770func Test_InternalFuncRetType()
771 let lines =<< trim END
772 def RetFloat(): float
773 return ceil(1.456)
774 enddef
775
776 def RetListAny(): list<any>
Bram Moolenaar17a836c2020-08-12 17:35:58 +0200777 return items({'k': 'v'})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200778 enddef
779
780 def RetListString(): list<string>
781 return split('a:b:c', ':')
782 enddef
783
784 def RetListDictAny(): list<dict<any>>
785 return getbufinfo()
786 enddef
787
788 def RetDictNumber(): dict<number>
789 return wordcount()
790 enddef
791
792 def RetDictString(): dict<string>
793 return environ()
794 enddef
795 END
796 call writefile(lines, 'Xscript')
797 source Xscript
798
799 call assert_equal(2.0, RetFloat())
800 call assert_equal([['k', 'v']], RetListAny())
801 call assert_equal(['a', 'b', 'c'], RetListString())
802 call assert_notequal([], RetListDictAny())
803 call assert_notequal({}, RetDictNumber())
804 call assert_notequal({}, RetDictString())
805 call delete('Xscript')
806endfunc
807
808" Test for passing too many or too few arguments to internal functions
809func Test_internalfunc_arg_error()
810 let l =<< trim END
811 def! FArgErr(): float
812 return ceil(1.1, 2)
813 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200814 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200815 END
816 call writefile(l, 'Xinvalidarg')
817 call assert_fails('so Xinvalidarg', 'E118:')
818 let l =<< trim END
819 def! FArgErr(): float
820 return ceil()
821 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200822 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200823 END
824 call writefile(l, 'Xinvalidarg')
825 call assert_fails('so Xinvalidarg', 'E119:')
826 call delete('Xinvalidarg')
827endfunc
828
829let s:funcResult = 0
830
831def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200832 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200833enddef
834
835def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200836 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200837 return 1234
838enddef
839
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200840def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +0200841 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200842 return 'text'
843enddef
844
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200845def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200846 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200847enddef
848
849def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200850 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200851 return arg
852enddef
853
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200854def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200855 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200856enddef
857
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200858def FuncOneArgRetString(arg: string): string
859 return arg
860enddef
861
Bram Moolenaar89228602020-04-05 22:14:54 +0200862def FuncOneArgRetAny(arg: any): any
863 return arg
864enddef
865
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200866def Test_func_type()
867 let Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +0200868 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200869 Ref1 = FuncNoArgNoRet
870 Ref1()
Bram Moolenaar53900992020-08-22 19:02:02 +0200871 assert_equal(11, s:funcResult)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200872
873 let Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +0200874 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200875 Ref2 = FuncNoArgNoRet
876 Ref2()
Bram Moolenaar53900992020-08-22 19:02:02 +0200877 assert_equal(11, s:funcResult)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200878
Bram Moolenaar53900992020-08-22 19:02:02 +0200879 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200880 Ref2 = FuncOneArgNoRet
881 Ref2(12)
Bram Moolenaar53900992020-08-22 19:02:02 +0200882 assert_equal(12, s:funcResult)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200883
Bram Moolenaar53900992020-08-22 19:02:02 +0200884 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200885 Ref2 = FuncNoArgRetNumber
886 assert_equal(1234, Ref2())
Bram Moolenaar53900992020-08-22 19:02:02 +0200887 assert_equal(22, s:funcResult)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200888
Bram Moolenaar53900992020-08-22 19:02:02 +0200889 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200890 Ref2 = FuncOneArgRetNumber
891 assert_equal(13, Ref2(13))
Bram Moolenaar53900992020-08-22 19:02:02 +0200892 assert_equal(13, s:funcResult)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200893enddef
894
Bram Moolenaar9978d472020-07-05 16:01:56 +0200895def Test_repeat_return_type()
896 let res = 0
897 for n in repeat([1], 3)
898 res += n
899 endfor
900 assert_equal(3, res)
Bram Moolenaarfce82b32020-07-05 16:07:21 +0200901
902 res = 0
903 for n in add([1, 2], 3)
904 res += n
905 endfor
906 assert_equal(6, res)
Bram Moolenaar9978d472020-07-05 16:01:56 +0200907enddef
908
Bram Moolenaar846178a2020-07-05 17:04:13 +0200909def Test_argv_return_type()
910 next fileone filetwo
911 let res = ''
912 for name in argv()
913 res ..= name
914 endfor
915 assert_equal('fileonefiletwo', res)
916enddef
917
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200918def Test_func_type_part()
919 let RefVoid: func: void
920 RefVoid = FuncNoArgNoRet
921 RefVoid = FuncOneArgNoRet
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200922 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func() but got func(): number')
923 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: type mismatch, expected func() but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200924
925 let RefAny: func(): any
926 RefAny = FuncNoArgRetNumber
927 RefAny = FuncNoArgRetString
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200928 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): any but got func()')
929 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: type mismatch, expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200930
931 let RefNr: func: number
932 RefNr = FuncNoArgRetNumber
933 RefNr = FuncOneArgRetNumber
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200934 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): number but got func()')
935 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: type mismatch, expected func(): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200936
937 let RefStr: func: string
938 RefStr = FuncNoArgRetString
939 RefStr = FuncOneArgRetString
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200940 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): string but got func()')
941 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func(): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200942enddef
943
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200944def Test_func_type_fails()
945 CheckDefFailure(['let ref1: func()'], 'E704:')
946
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200947 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func() but got func(): number')
948 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: type mismatch, expected func() but got func(number)')
949 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: type mismatch, expected func() but got func(number): number')
950 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: type mismatch, expected func(bool) but got func(bool, number)')
951 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: type mismatch, expected func(?bool) but got func(bool, number)')
952 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 +0200953
954 call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:')
955 call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:')
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200956 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 +0200957 call CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200958enddef
959
Bram Moolenaar89228602020-04-05 22:14:54 +0200960def Test_func_return_type()
961 let nr: number
962 nr = FuncNoArgRetNumber()
963 assert_equal(1234, nr)
964
965 nr = FuncOneArgRetAny(122)
966 assert_equal(122, nr)
967
968 let str: string
969 str = FuncOneArgRetAny('yes')
970 assert_equal('yes', str)
971
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200972 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1012: type mismatch, expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +0200973enddef
974
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200975def MultiLine(
976 arg1: string,
977 arg2 = 1234,
978 ...rest: list<string>
979 ): string
980 return arg1 .. arg2 .. join(rest, '-')
981enddef
982
Bram Moolenaar2c330432020-04-13 14:41:35 +0200983def MultiLineComment(
984 arg1: string, # comment
985 arg2 = 1234, # comment
986 ...rest: list<string> # comment
987 ): string # comment
988 return arg1 .. arg2 .. join(rest, '-')
989enddef
990
Bram Moolenaar5e774c72020-04-12 21:53:00 +0200991def Test_multiline()
992 assert_equal('text1234', MultiLine('text'))
993 assert_equal('text777', MultiLine('text', 777))
994 assert_equal('text777one', MultiLine('text', 777, 'one'))
995 assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two'))
996enddef
997
Bram Moolenaar23e03252020-04-12 22:22:31 +0200998func Test_multiline_not_vim9()
999 call assert_equal('text1234', MultiLine('text'))
1000 call assert_equal('text777', MultiLine('text', 777))
1001 call assert_equal('text777one', MultiLine('text', 777, 'one'))
1002 call assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two'))
1003endfunc
1004
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001005
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001006" When using CheckScriptFailure() for the below test, E1010 is generated instead
1007" of E1056.
1008func Test_E1056_1059()
1009 let caught_1056 = 0
1010 try
1011 def F():
1012 return 1
1013 enddef
1014 catch /E1056:/
1015 let caught_1056 = 1
1016 endtry
1017 call assert_equal(1, caught_1056)
1018
1019 let caught_1059 = 0
1020 try
1021 def F5(items : list)
1022 echo 'a'
1023 enddef
1024 catch /E1059:/
1025 let caught_1059 = 1
1026 endtry
1027 call assert_equal(1, caught_1059)
1028endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001029
Bram Moolenaar015f4262020-05-05 21:25:22 +02001030func DelMe()
1031 echo 'DelMe'
1032endfunc
1033
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001034def Test_error_reporting()
1035 # comment lines at the start of the function
1036 let lines =<< trim END
1037 " comment
1038 def Func()
1039 # comment
1040 # comment
1041 invalid
1042 enddef
1043 defcompile
1044 END
1045 call writefile(lines, 'Xdef')
1046 try
1047 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001048 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001049 catch /E476:/
1050 assert_match('Invalid command: invalid', v:exception)
1051 assert_match(', line 3$', v:throwpoint)
1052 endtry
1053
1054 # comment lines after the start of the function
1055 lines =<< trim END
1056 " comment
1057 def Func()
1058 let x = 1234
1059 # comment
1060 # comment
1061 invalid
1062 enddef
1063 defcompile
1064 END
1065 call writefile(lines, 'Xdef')
1066 try
1067 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001068 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001069 catch /E476:/
1070 assert_match('Invalid command: invalid', v:exception)
1071 assert_match(', line 4$', v:throwpoint)
1072 endtry
1073
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001074 lines =<< trim END
1075 vim9script
1076 def Func()
1077 let db = #{foo: 1, bar: 2}
1078 # comment
1079 let x = db.asdf
1080 enddef
1081 defcompile
1082 Func()
1083 END
1084 call writefile(lines, 'Xdef')
1085 try
1086 source Xdef
1087 assert_report('should have failed')
1088 catch /E716:/
1089 assert_match('_Func, line 3$', v:throwpoint)
1090 endtry
1091
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001092 call delete('Xdef')
1093enddef
1094
Bram Moolenaar015f4262020-05-05 21:25:22 +02001095def Test_deleted_function()
1096 CheckDefExecFailure([
1097 'let RefMe: func = function("g:DelMe")',
1098 'delfunc g:DelMe',
1099 'echo RefMe()'], 'E117:')
1100enddef
1101
1102def Test_unknown_function()
1103 CheckDefExecFailure([
1104 'let Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001105 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001106enddef
1107
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001108def RefFunc(Ref: func(string): string): string
1109 return Ref('more')
1110enddef
1111
1112def Test_closure_simple()
1113 let local = 'some '
1114 assert_equal('some more', RefFunc({s -> local .. s}))
1115enddef
1116
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001117def MakeRef()
1118 let local = 'some '
1119 g:Ref = {s -> local .. s}
1120enddef
1121
1122def Test_closure_ref_after_return()
1123 MakeRef()
1124 assert_equal('some thing', g:Ref('thing'))
1125 unlet g:Ref
1126enddef
1127
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001128def MakeTwoRefs()
1129 let local = ['some']
1130 g:Extend = {s -> local->add(s)}
1131 g:Read = {-> local}
1132enddef
1133
1134def Test_closure_two_refs()
1135 MakeTwoRefs()
1136 assert_equal('some', join(g:Read(), ' '))
1137 g:Extend('more')
1138 assert_equal('some more', join(g:Read(), ' '))
1139 g:Extend('even')
1140 assert_equal('some more even', join(g:Read(), ' '))
1141
1142 unlet g:Extend
1143 unlet g:Read
1144enddef
1145
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001146def ReadRef(Ref: func(): list<string>): string
1147 return join(Ref(), ' ')
1148enddef
1149
1150def ExtendRef(Ref: func(string), add: string)
1151 Ref(add)
1152enddef
1153
1154def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001155 MakeTwoRefs()
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001156 assert_equal('some', ReadRef(g:Read))
1157 ExtendRef(g:Extend, 'more')
1158 assert_equal('some more', ReadRef(g:Read))
1159 ExtendRef(g:Extend, 'even')
1160 assert_equal('some more even', ReadRef(g:Read))
1161
1162 unlet g:Extend
1163 unlet g:Read
1164enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001165
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001166def MakeArgRefs(theArg: string)
1167 let local = 'loc_val'
1168 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1169enddef
1170
1171def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
1172 let local = 'the_loc'
1173 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1174enddef
1175
1176def Test_closure_using_argument()
1177 MakeArgRefs('arg_val')
1178 assert_equal('arg_val/loc_val/call_val', g:UseArg('call_val'))
1179
1180 MakeArgRefsVarargs('arg_val', 'one', 'two')
1181 assert_equal('arg_val/the_loc/call_val/one two', g:UseVararg('call_val'))
1182
1183 unlet g:UseArg
1184 unlet g:UseVararg
1185enddef
1186
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001187def MakeGetAndAppendRefs()
1188 let local = 'a'
1189
1190 def Append(arg: string)
1191 local ..= arg
1192 enddef
1193 g:Append = Append
1194
1195 def Get(): string
1196 return local
1197 enddef
1198 g:Get = Get
1199enddef
1200
1201def Test_closure_append_get()
1202 MakeGetAndAppendRefs()
1203 assert_equal('a', g:Get())
1204 g:Append('-b')
1205 assert_equal('a-b', g:Get())
1206 g:Append('-c')
1207 assert_equal('a-b-c', g:Get())
1208
1209 unlet g:Append
1210 unlet g:Get
1211enddef
1212
Bram Moolenaar04b12692020-05-04 23:24:44 +02001213def Test_nested_closure()
1214 let local = 'text'
1215 def Closure(arg: string): string
1216 return local .. arg
1217 enddef
1218 assert_equal('text!!!', Closure('!!!'))
1219enddef
1220
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001221func GetResult(Ref)
1222 return a:Ref('some')
1223endfunc
1224
1225def Test_call_closure_not_compiled()
1226 let text = 'text'
1227 g:Ref = {s -> s .. text}
1228 assert_equal('sometext', GetResult(g:Ref))
1229enddef
1230
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001231def Test_sort_return_type()
1232 let res: list<number>
1233 res = [1, 2, 3]->sort()
1234enddef
1235
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001236def Test_getqflist_return_type()
1237 let l = getqflist()
1238 assert_equal([], l)
1239
1240 let d = getqflist(#{items: 0})
1241 assert_equal(#{items: []}, d)
1242enddef
1243
1244def Test_getloclist_return_type()
1245 let l = getloclist(1)
1246 assert_equal([], l)
1247
1248 let d = getloclist(1, #{items: 0})
1249 assert_equal(#{items: []}, d)
1250enddef
1251
Bram Moolenaara66ba012020-07-05 18:41:08 +02001252def Test_copy_return_type()
1253 let l = copy([1, 2, 3])
1254 let res = 0
1255 for n in l
1256 res += n
1257 endfor
1258 assert_equal(6, res)
1259
1260 let dl = deepcopy([1, 2, 3])
1261 res = 0
1262 for n in dl
1263 res += n
1264 endfor
1265 assert_equal(6, res)
1266enddef
1267
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001268def Test_extend_return_type()
1269 let l = extend([1, 2], [3])
1270 let res = 0
1271 for n in l
1272 res += n
1273 endfor
1274 assert_equal(6, res)
1275enddef
1276
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001277def Test_insert_return_type()
1278 let l = insert([2, 1], 3)
1279 let res = 0
1280 for n in l
1281 res += n
1282 endfor
1283 assert_equal(6, res)
1284enddef
1285
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001286def Test_keys_return_type()
1287 const var: list<string> = #{a: 1, b: 2}->keys()
1288 assert_equal(['a', 'b'], var)
1289enddef
1290
Bram Moolenaar67627352020-07-05 21:10:24 +02001291def Test_reverse_return_type()
1292 let l = reverse([1, 2, 3])
1293 let res = 0
1294 for n in l
1295 res += n
1296 endfor
1297 assert_equal(6, res)
1298enddef
1299
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001300def Test_remove_return_type()
1301 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
1302 let res = 0
1303 for n in l
1304 res += n
1305 endfor
1306 assert_equal(3, res)
1307enddef
1308
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001309def Test_filter_return_type()
1310 let l = filter([1, 2, 3], {-> 1})
1311 let res = 0
1312 for n in l
1313 res += n
1314 endfor
1315 assert_equal(6, res)
1316enddef
1317
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001318def Test_bufnr()
1319 let buf = bufnr()
1320 assert_equal(buf, bufnr('%'))
1321enddef
1322
Bram Moolenaarec65d772020-08-20 22:29:12 +02001323def Test_col()
1324 new
1325 setline(1, 'asdf')
1326 assert_equal(5, col([1, '$']))
1327enddef
1328
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001329def Test_getreg_return_type()
1330 let s1: string = getreg('"')
1331 let s2: string = getreg('"', 1)
1332 let s3: list<string> = getreg('"', 1, 1)
1333enddef
1334
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001335def Wrong_dict_key_type(items: list<number>): list<number>
1336 return filter(items, {_, val -> get({val: 1}, 'x')})
1337enddef
1338
1339def Test_wrong_dict_key_type()
1340 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:')
1341enddef
1342
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001343def Line_continuation_in_def(dir: string = ''): string
1344 let path: string = empty(dir)
1345 \ ? 'empty'
1346 \ : 'full'
1347 return path
1348enddef
1349
1350def Test_line_continuation_in_def()
1351 assert_equal('full', Line_continuation_in_def('.'))
1352enddef
1353
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001354def Line_continuation_in_lambda(): list<number>
1355 let x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001356 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001357 ->toupper()})
1358 ->reverse()
1359 return x
1360enddef
1361
1362def Test_line_continuation_in_lambda()
1363 assert_equal(['D', 'C', 'B', 'A'], Line_continuation_in_lambda())
1364enddef
1365
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001366func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001367 CheckScreendump
1368
1369 let lines =<< trim END
1370 vim9script
1371 def EchoNothing()
1372 silent echo ''
1373 enddef
1374 defcompile
1375 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001376 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001377
1378 " Check that the balloon shows up after a mouse move
1379 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001380 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001381 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1382
1383 " clean up
1384 call StopVimInTerminal(buf)
1385 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001386endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001387
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001388def Test_search()
1389 new
1390 setline(1, ['foo', 'bar'])
1391 let val = 0
Bram Moolenaard70840e2020-08-22 15:06:35 +02001392 # skip expr returns boolean
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001393 assert_equal(2, search('bar', 'W', 0, 0, {-> val == 1}))
Bram Moolenaard70840e2020-08-22 15:06:35 +02001394 :1
1395 assert_equal(0, search('bar', 'W', 0, 0, {-> val == 0}))
1396 # skip expr returns number, only 0 and 1 are accepted
1397 :1
1398 assert_equal(2, search('bar', 'W', 0, 0, {-> 0}))
1399 :1
1400 assert_equal(0, search('bar', 'W', 0, 0, {-> 1}))
1401 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1402 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001403enddef
1404
Bram Moolenaarf8abbf32020-08-19 16:00:06 +02001405def Test_readdir()
Bram Moolenaard70840e2020-08-22 15:06:35 +02001406 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1407 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
Bram Moolenaaraf8822c2020-08-19 13:55:01 +02001408enddef
1409
Bram Moolenaar191929b2020-08-19 21:20:49 +02001410def Test_setbufvar()
1411 setbufvar(bufnr('%'), '&syntax', 'vim')
1412 assert_equal('vim', &syntax)
1413 setbufvar(bufnr('%'), '&ts', 16)
1414 assert_equal(16, &ts)
1415 settabwinvar(1, 1, '&syntax', 'vam')
1416 assert_equal('vam', &syntax)
1417 settabwinvar(1, 1, '&ts', 15)
1418 assert_equal(15, &ts)
1419 setlocal ts=8
1420enddef
1421
Bram Moolenaar6a950582020-08-28 16:39:33 +02001422def Test_setreg()
1423 setreg('a', ['aaa', 'bbb', 'ccc'])
1424 let reginfo = getreginfo('a')
1425 setreg('a', reginfo)
1426 assert_equal(reginfo, getreginfo('a'))
1427enddef
1428
Bram Moolenaar985116a2020-07-12 17:31:09 +02001429def Fibonacci(n: number): number
1430 if n < 2
1431 return n
1432 else
1433 return Fibonacci(n - 1) + Fibonacci(n - 2)
1434 endif
1435enddef
1436
1437def Test_recursive_call()
1438 assert_equal(6765, Fibonacci(20))
1439enddef
1440
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001441def TreeWalk(dir: string): list<any>
1442 return readdir(dir)->map({_, val ->
1443 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001444 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001445 : val
1446 })
1447enddef
1448
1449def Test_closure_in_map()
1450 mkdir('XclosureDir/tdir', 'p')
1451 writefile(['111'], 'XclosureDir/file1')
1452 writefile(['222'], 'XclosureDir/file2')
1453 writefile(['333'], 'XclosureDir/tdir/file3')
1454
1455 assert_equal(['file1', 'file2', {'tdir': ['file3']}], TreeWalk('XclosureDir'))
1456
1457 delete('XclosureDir', 'rf')
1458enddef
1459
Bram Moolenaara90afb92020-07-15 22:38:56 +02001460def Test_partial_call()
1461 let Xsetlist = function('setloclist', [0])
1462 Xsetlist([], ' ', {'title': 'test'})
1463 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1464
1465 Xsetlist = function('setloclist', [0, [], ' '])
1466 Xsetlist({'title': 'test'})
1467 assert_equal({'title': 'test'}, getloclist(0, {'title': 1}))
1468
1469 Xsetlist = function('setqflist')
1470 Xsetlist([], ' ', {'title': 'test'})
1471 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1472
1473 Xsetlist = function('setqflist', [[], ' '])
1474 Xsetlist({'title': 'test'})
1475 assert_equal({'title': 'test'}, getqflist({'title': 1}))
1476enddef
1477
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001478def Test_cmd_modifier()
1479 tab echo '0'
1480 call CheckDefFailure(['5tab echo 3'], 'E16:')
1481enddef
1482
1483def Test_restore_modifiers()
1484 # check that when compiling a :def function command modifiers are not messed
1485 # up.
1486 let lines =<< trim END
1487 vim9script
1488 set eventignore=
1489 autocmd QuickFixCmdPost * copen
1490 def AutocmdsDisabled()
1491 eval 0
1492 enddef
1493 func Func()
1494 noautocmd call s:AutocmdsDisabled()
1495 let g:ei_after = &eventignore
1496 endfunc
1497 Func()
1498 END
1499 CheckScriptSuccess(lines)
1500 assert_equal('', g:ei_after)
1501enddef
1502
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001503
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001504" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker