blob: c80271626162d0a4b0e3628873543004e3944946 [file] [log] [blame]
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001" Test various aspects of the Vim9 script language.
2
3source check.vim
Bram Moolenaarad304702020-09-06 18:22:53 +02004source term_util.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02005source view_util.vim
Bram Moolenaar04b12692020-05-04 23:24:44 +02006source vim9.vim
Bram Moolenaar47e7d702020-07-05 18:18:42 +02007source screendump.vim
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02008
9func Test_def_basic()
10 def SomeFunc(): string
11 return 'yes'
12 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020013 call SomeFunc()->assert_equal('yes')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020014endfunc
15
16def ReturnString(): string
17 return 'string'
18enddef
19
20def ReturnNumber(): number
21 return 123
22enddef
23
24let g:notNumber = 'string'
25
26def ReturnGlobal(): number
27 return g:notNumber
28enddef
29
30def Test_return_something()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020031 ReturnString()->assert_equal('string')
32 ReturnNumber()->assert_equal(123)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +020033 assert_fails('ReturnGlobal()', 'E1029: Expected number but got string', '', 1, 'ReturnGlobal')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020034enddef
35
Bram Moolenaarefd88552020-06-18 20:50:10 +020036def Test_missing_return()
37 CheckDefFailure(['def Missing(): number',
38 ' if g:cond',
39 ' echo "no return"',
40 ' else',
41 ' return 0',
42 ' endif'
43 'enddef'], 'E1027:')
44 CheckDefFailure(['def Missing(): number',
45 ' if g:cond',
46 ' return 1',
47 ' else',
48 ' echo "no return"',
49 ' endif'
50 'enddef'], 'E1027:')
51 CheckDefFailure(['def Missing(): number',
52 ' if g:cond',
53 ' return 1',
54 ' else',
55 ' return 2',
56 ' endif'
57 ' return 3'
58 'enddef'], 'E1095:')
59enddef
60
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020061let s:nothing = 0
62def ReturnNothing()
63 s:nothing = 1
64 if true
65 return
66 endif
67 s:nothing = 2
68enddef
69
70def Test_return_nothing()
71 ReturnNothing()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020072 s:nothing->assert_equal(1)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020073enddef
74
75func Increment()
76 let g:counter += 1
77endfunc
78
79def Test_call_ufunc_count()
80 g:counter = 1
81 Increment()
82 Increment()
83 Increment()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +020084 # works with and without :call
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020085 g:counter->assert_equal(4)
86 eval g:counter->assert_equal(4)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +020087 unlet g:counter
88enddef
89
90def MyVarargs(arg: string, ...rest: list<string>): string
91 let res = arg
92 for s in rest
93 res ..= ',' .. s
94 endfor
95 return res
96enddef
97
98def Test_call_varargs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +020099 MyVarargs('one')->assert_equal('one')
100 MyVarargs('one', 'two')->assert_equal('one,two')
101 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200102enddef
103
104def MyDefaultArgs(name = 'string'): string
105 return name
106enddef
107
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200108def MyDefaultSecond(name: string, second: bool = true): string
109 return second ? name : 'none'
110enddef
111
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200112def Test_call_default_args()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200113 MyDefaultArgs()->assert_equal('string')
114 MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200115 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200116
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200117 MyDefaultSecond('test')->assert_equal('test')
118 MyDefaultSecond('test', true)->assert_equal('test')
119 MyDefaultSecond('test', false)->assert_equal('none')
Bram Moolenaare30f64b2020-07-15 19:48:20 +0200120
Bram Moolenaar822ba242020-05-24 23:00:18 +0200121 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:')
122 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 +0200123enddef
124
125def Test_nested_function()
126 def Nested(arg: string): string
127 return 'nested ' .. arg
128 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200129 Nested('function')->assert_equal('nested function')
Bram Moolenaar04b12692020-05-04 23:24:44 +0200130
Bram Moolenaar0e65d3d2020-05-05 17:53:16 +0200131 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:')
132 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:')
133
Bram Moolenaar04b12692020-05-04 23:24:44 +0200134 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:')
Bram Moolenaarbcbf4132020-08-01 22:35:13 +0200135 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:')
136 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:')
Bram Moolenaar8b848ca2020-09-10 22:28:01 +0200137
138 CheckDefFailure([
139 'def Outer()',
140 ' def Inner()',
141 ' # comment',
142 ' enddef',
143 ' def Inner()',
144 ' enddef',
145 'enddef'], 'E1073:')
146 CheckDefFailure([
147 'def Outer()',
148 ' def Inner()',
149 ' # comment',
150 ' enddef',
151 ' def! Inner()',
152 ' enddef',
153 'enddef'], 'E1117:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200154enddef
155
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200156func Test_call_default_args_from_func()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200157 call MyDefaultArgs()->assert_equal('string')
158 call MyDefaultArgs('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200159 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200160endfunc
161
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200162def Test_nested_global_function()
163 let lines =<< trim END
164 vim9script
165 def Outer()
166 def g:Inner(): string
167 return 'inner'
168 enddef
169 enddef
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200170 defcompile
171 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200172 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200173 delfunc g:Inner
174 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200175 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200176 delfunc g:Inner
177 Outer()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200178 g:Inner()->assert_equal('inner')
Bram Moolenaaraf8edbb2020-08-01 00:03:09 +0200179 delfunc g:Inner
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200180 END
181 CheckScriptSuccess(lines)
Bram Moolenaar2c79e9d2020-08-01 18:57:52 +0200182
183 lines =<< trim END
184 vim9script
185 def Outer()
186 def g:Inner(): string
187 return 'inner'
188 enddef
189 enddef
190 defcompile
191 Outer()
192 Outer()
193 END
194 CheckScriptFailure(lines, "E122:")
Bram Moolenaarad486a02020-08-01 23:22:18 +0200195
196 lines =<< trim END
197 vim9script
198 def Func()
199 echo 'script'
200 enddef
201 def Outer()
202 def Func()
203 echo 'inner'
204 enddef
205 enddef
206 defcompile
207 END
208 CheckScriptFailure(lines, "E1073:")
Bram Moolenaar38ddf332020-07-31 22:05:04 +0200209enddef
210
Bram Moolenaar333894b2020-08-01 18:53:07 +0200211def Test_global_local_function()
212 let lines =<< trim END
213 vim9script
214 def g:Func(): string
215 return 'global'
216 enddef
217 def Func(): string
218 return 'local'
219 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200220 g:Func()->assert_equal('global')
221 Func()->assert_equal('local')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200222 END
223 CheckScriptSuccess(lines)
Bram Moolenaar035d6e92020-08-11 22:30:42 +0200224
225 lines =<< trim END
226 vim9script
227 def g:Funcy()
228 echo 'funcy'
229 enddef
230 s:Funcy()
231 END
232 CheckScriptFailure(lines, 'E117:')
Bram Moolenaar333894b2020-08-01 18:53:07 +0200233enddef
234
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200235func TakesOneArg(arg)
236 echo a:arg
237endfunc
238
239def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200240 CheckDefFailure(['TakesOneArg()'], 'E119:')
241 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
242 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
243 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200244
245 let lines =<< trim END
246 vim9script
247 def Func(s: string)
248 echo s
249 enddef
250 Func([])
251 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200252 call CheckScriptFailure(lines, 'E1013: argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200253enddef
254
255" Default arg and varargs
256def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
257 let res = one .. ',' .. two
258 for s in rest
259 res ..= ',' .. s
260 endfor
261 return res
262enddef
263
264def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200265 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200266 MyDefVarargs('one')->assert_equal('one,foo')
267 MyDefVarargs('one', 'two')->assert_equal('one,two')
268 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200269 CheckDefFailure(['MyDefVarargs("one", 22)'],
270 'E1013: argument 2: type mismatch, expected string but got number')
271 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
272 'E1013: argument 3: type mismatch, expected string but got number')
273
274 let lines =<< trim END
275 vim9script
276 def Func(...l: list<string>)
277 echo l
278 enddef
279 Func('a', 'b', 'c')
280 END
281 CheckScriptSuccess(lines)
282
283 lines =<< trim END
284 vim9script
285 def Func(...l: list<string>)
286 echo l
287 enddef
288 Func()
289 END
290 CheckScriptSuccess(lines)
291
292 lines =<< trim END
293 vim9script
294 def Func(...l: list<string>)
295 echo l
296 enddef
297 Func(1, 2, 3)
298 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200299 CheckScriptFailure(lines, 'E1013: argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200300
301 lines =<< trim END
302 vim9script
303 def Func(...l: list<string>)
304 echo l
305 enddef
306 Func('a', 9)
307 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200308 CheckScriptFailure(lines, 'E1013: argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200309
310 lines =<< trim END
311 vim9script
312 def Func(...l: list<string>)
313 echo l
314 enddef
315 Func(1, 'a')
316 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200317 CheckScriptFailure(lines, 'E1013: argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200318enddef
319
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200320def Test_call_call()
321 let l = [3, 2, 1]
322 call('reverse', [l])
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200323 l->assert_equal([1, 2, 3])
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200324enddef
325
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200326let s:value = ''
327
328def FuncOneDefArg(opt = 'text')
329 s:value = opt
330enddef
331
332def FuncTwoDefArg(nr = 123, opt = 'text'): string
333 return nr .. opt
334enddef
335
336def FuncVarargs(...arg: list<string>): string
337 return join(arg, ',')
338enddef
339
340def Test_func_type_varargs()
341 let RefDefArg: func(?string)
342 RefDefArg = FuncOneDefArg
343 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200344 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200345 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200346 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200347
348 let RefDef2Arg: func(?number, ?string): string
349 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200350 RefDef2Arg()->assert_equal('123text')
351 RefDef2Arg(99)->assert_equal('99text')
352 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200353
Bram Moolenaard2c61702020-09-06 15:58:36 +0200354 CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:')
355 CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200356
357 let RefVarargs: func(...list<string>): string
358 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200359 RefVarargs()->assert_equal('')
360 RefVarargs('one')->assert_equal('one')
361 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200362
Bram Moolenaard2c61702020-09-06 15:58:36 +0200363 CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:')
364 CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200365enddef
366
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200367" Only varargs
368def MyVarargsOnly(...args: list<string>): string
369 return join(args, ',')
370enddef
371
372def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200373 MyVarargsOnly()->assert_equal('')
374 MyVarargsOnly('one')->assert_equal('one')
375 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200376 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number')
377 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200378enddef
379
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200380def Test_using_var_as_arg()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200381 writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200382 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200383 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200384enddef
385
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200386def DictArg(arg: dict<string>)
387 arg['key'] = 'value'
388enddef
389
390def ListArg(arg: list<string>)
391 arg[0] = 'value'
392enddef
393
394def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200395 # works for dict and list
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200396 let d: dict<string> = {}
397 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200398 d['key']->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200399 let l: list<string> = []
400 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200401 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200402
Bram Moolenaard2c61702020-09-06 15:58:36 +0200403 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200404enddef
405
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200406def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200407 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200408 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200409enddef
410
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200411func DefinedLater(arg)
412 return a:arg
413endfunc
414
415def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200416 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200417 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
418 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200419
420 let lines =<< trim END
421 vim9script
422 def RetNumber(): number
423 return 123
424 enddef
425 let Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200426 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200427 END
428 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200429
430 lines =<< trim END
431 vim9script
432 def RetNumber(): number
433 return 123
434 enddef
435 def Bar(F: func: number): number
436 return F()
437 enddef
438 let Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200439 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200440 END
441 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200442
443 lines =<< trim END
444 vim9script
445 def UseNumber(nr: number)
446 echo nr
447 enddef
448 let Funcref: func(number) = function('UseNumber')
449 Funcref(123)
450 END
451 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200452
453 lines =<< trim END
454 vim9script
455 def UseNumber(nr: number)
456 echo nr
457 enddef
458 let Funcref: func(string) = function('UseNumber')
459 END
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200460 CheckScriptFailure(lines, 'E1012: type mismatch, expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200461
462 lines =<< trim END
463 vim9script
464 def EchoNr(nr = 34)
465 g:echo = nr
466 enddef
467 let Funcref: func(?number) = function('EchoNr')
468 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200469 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200470 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200471 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200472 END
473 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200474
475 lines =<< trim END
476 vim9script
477 def EchoList(...l: list<number>)
478 g:echo = l
479 enddef
480 let Funcref: func(...list<number>) = function('EchoList')
481 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200482 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200483 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200484 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200485 END
486 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200487
488 lines =<< trim END
489 vim9script
490 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
491 g:optarg = opt
492 g:listarg = l
493 return nr
494 enddef
495 let Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200496 Funcref(10)->assert_equal(10)
497 g:optarg->assert_equal(12)
498 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200499
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200500 Funcref(11, 22)->assert_equal(11)
501 g:optarg->assert_equal(22)
502 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200503
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200504 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
505 g:optarg->assert_equal(18)
506 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200507 END
508 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200509enddef
510
511let SomeFunc = function('len')
512let NotAFunc = 'text'
513
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200514def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200515 # same arguments, different return type
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200516 let Ref1: func(bool): string
517 let Ref2: func(bool): number
518 let Ref3: func(bool): any
519 Ref3 = g:cond ? Ref1 : Ref2
520
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200521 # different number of arguments
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200522 let Refa1: func(bool): number
523 let Refa2: func(bool, number): number
524 let Refa3: func: number
525 Refa3 = g:cond ? Refa1 : Refa2
526
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200527 # different argument types
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200528 let Refb1: func(bool, string): number
529 let Refb2: func(string, number): number
530 let Refb3: func(any, any): number
531 Refb3 = g:cond ? Refb1 : Refb2
532enddef
533
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200534def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200535 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200536enddef
537
538def DefinedEvenLater(arg: string): string
539 return arg
540enddef
541
542def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200543 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200544 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200545enddef
546
547def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200548 CheckScriptFailure([
549 'def Func(): number',
550 'return "a"',
551 'enddef',
552 'defcompile'], 'expected number but got string')
553 CheckScriptFailure([
554 'def Func(): string',
555 'return 1',
556 'enddef',
557 'defcompile'], 'expected string but got number')
558 CheckScriptFailure([
559 'def Func(): void',
560 'return "a"',
561 'enddef',
562 'defcompile'],
563 'E1096: Returning a value in a function without a return type')
564 CheckScriptFailure([
565 'def Func()',
566 'return "a"',
567 'enddef',
568 'defcompile'],
569 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200570
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200571 CheckScriptFailure([
572 'def Func(): number',
573 'return',
574 'enddef',
575 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200576
577 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
578 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200579 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200580
581 CheckScriptFailure([
582 'vim9script',
583 'def FuncB()',
584 ' return 123',
585 'enddef',
586 'def FuncA()',
587 ' FuncB()',
588 'enddef',
589 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200590enddef
591
592def Test_arg_type_wrong()
593 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200594 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200595 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200596 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200597enddef
598
599def Test_vim9script_call()
600 let lines =<< trim END
601 vim9script
602 let var = ''
603 def MyFunc(arg: string)
604 var = arg
605 enddef
606 MyFunc('foobar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200607 var->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200608
609 let str = 'barfoo'
610 str->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200611 var->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200612
Bram Moolenaar67979662020-06-20 22:50:47 +0200613 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200614 g:value->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200615 var->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200616
617 let listvar = []
618 def ListFunc(arg: list<number>)
619 listvar = arg
620 enddef
621 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200622 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200623
624 let dictvar = {}
625 def DictFunc(arg: dict<number>)
626 dictvar = arg
627 enddef
628 {'a': 1, 'b': 2}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200629 dictvar->assert_equal(#{a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200630 def CompiledDict()
631 {'a': 3, 'b': 4}->DictFunc()
632 enddef
633 CompiledDict()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200634 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200635
636 #{a: 3, b: 4}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200637 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200638
639 ('text')->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200640 var->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200641 ("some")->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200642 var->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200643
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200644 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200645 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200646 'asdfasdf'->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200647 var->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200648 "xyz"->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200649 var->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200650
651 def UseString()
652 'xyork'->MyFunc()
653 enddef
654 UseString()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200655 var->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200656
Bram Moolenaar10409562020-07-29 20:00:38 +0200657 def UseString2()
658 "knife"->MyFunc()
659 enddef
660 UseString2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200661 var->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200662
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200663 # prepending a colon makes it a mark
664 new
665 setline(1, ['aaa', 'bbb', 'ccc'])
666 normal! 3Gmt1G
667 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200668 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200669 bwipe!
670
Bram Moolenaare6b53242020-07-01 17:28:33 +0200671 MyFunc(
672 'continued'
673 )
674 assert_equal('continued',
675 var
676 )
677
678 call MyFunc(
679 'more'
680 ..
681 'lines'
682 )
683 assert_equal(
684 'morelines',
685 var)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200686 END
687 writefile(lines, 'Xcall.vim')
688 source Xcall.vim
689 delete('Xcall.vim')
690enddef
691
692def Test_vim9script_call_fail_decl()
693 let lines =<< trim END
694 vim9script
695 let var = ''
696 def MyFunc(arg: string)
697 let var = 123
698 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200699 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200700 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200701 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200702enddef
703
Bram Moolenaar65b95452020-07-19 14:03:09 +0200704def Test_vim9script_call_fail_type()
705 let lines =<< trim END
706 vim9script
707 def MyFunc(arg: string)
708 echo arg
709 enddef
710 MyFunc(1234)
711 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200712 CheckScriptFailure(lines, 'E1013: argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200713enddef
714
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200715def Test_vim9script_call_fail_const()
716 let lines =<< trim END
717 vim9script
718 const var = ''
719 def MyFunc(arg: string)
720 var = 'asdf'
721 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200722 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200723 END
724 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200725 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200726 delete('Xcall_const.vim')
727enddef
728
729" Test that inside :function a Python function can be defined, :def is not
730" recognized.
731func Test_function_python()
732 CheckFeature python3
733 let py = 'python3'
734 execute py "<< EOF"
735def do_something():
736 return 1
737EOF
738endfunc
739
740def Test_delfunc()
741 let lines =<< trim END
742 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200743 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200744 echo 'hello'
745 enddef
746
747 def CallGoneSoon()
748 GoneSoon()
749 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200750 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200751
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200752 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200753 CallGoneSoon()
754 END
755 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200756 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
757 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200758
759 delete('XToDelFunc')
760enddef
761
762def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200763 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200764 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200765 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200766 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200767 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200768 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200769 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200770 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200771 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200772
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200773 g:Func0()->assert_equal(0)
774 g:Func1()->assert_equal('Func1')
775 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200776
777 delfunc! Func0
778 delfunc! Func1
779 delfunc! Func2
780enddef
781
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200782def Test_vim9script_func()
783 let lines =<< trim END
784 vim9script
785 func Func(arg)
786 echo a:arg
787 endfunc
788 Func('text')
789 END
790 writefile(lines, 'XVim9Func')
791 so XVim9Func
792
793 delete('XVim9Func')
794enddef
795
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200796" Test for internal functions returning different types
797func Test_InternalFuncRetType()
798 let lines =<< trim END
799 def RetFloat(): float
800 return ceil(1.456)
801 enddef
802
803 def RetListAny(): list<any>
Bram Moolenaar17a836c2020-08-12 17:35:58 +0200804 return items({'k': 'v'})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200805 enddef
806
807 def RetListString(): list<string>
808 return split('a:b:c', ':')
809 enddef
810
811 def RetListDictAny(): list<dict<any>>
812 return getbufinfo()
813 enddef
814
815 def RetDictNumber(): dict<number>
816 return wordcount()
817 enddef
818
819 def RetDictString(): dict<string>
820 return environ()
821 enddef
822 END
823 call writefile(lines, 'Xscript')
824 source Xscript
825
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200826 call RetFloat()->assert_equal(2.0)
827 call RetListAny()->assert_equal([['k', 'v']])
828 call RetListString()->assert_equal(['a', 'b', 'c'])
829 call RetListDictAny()->assert_notequal([])
830 call RetDictNumber()->assert_notequal({})
831 call RetDictString()->assert_notequal({})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200832 call delete('Xscript')
833endfunc
834
835" Test for passing too many or too few arguments to internal functions
836func Test_internalfunc_arg_error()
837 let l =<< trim END
838 def! FArgErr(): float
839 return ceil(1.1, 2)
840 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200841 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200842 END
843 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200844 call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200845 let l =<< trim END
846 def! FArgErr(): float
847 return ceil()
848 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200849 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200850 END
851 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200852 call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200853 call delete('Xinvalidarg')
854endfunc
855
856let s:funcResult = 0
857
858def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200859 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200860enddef
861
862def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200863 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200864 return 1234
865enddef
866
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200867def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +0200868 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200869 return 'text'
870enddef
871
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200872def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200873 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200874enddef
875
876def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200877 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200878 return arg
879enddef
880
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200881def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200882 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200883enddef
884
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200885def FuncOneArgRetString(arg: string): string
886 return arg
887enddef
888
Bram Moolenaar89228602020-04-05 22:14:54 +0200889def FuncOneArgRetAny(arg: any): any
890 return arg
891enddef
892
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200893def Test_func_type()
894 let Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +0200895 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200896 Ref1 = FuncNoArgNoRet
897 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200898 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200899
900 let Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +0200901 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200902 Ref2 = FuncNoArgNoRet
903 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200904 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200905
Bram Moolenaar53900992020-08-22 19:02:02 +0200906 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200907 Ref2 = FuncOneArgNoRet
908 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200909 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200910
Bram Moolenaar53900992020-08-22 19:02:02 +0200911 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200912 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200913 Ref2()->assert_equal(1234)
914 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200915
Bram Moolenaar53900992020-08-22 19:02:02 +0200916 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200917 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200918 Ref2(13)->assert_equal(13)
919 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200920enddef
921
Bram Moolenaar9978d472020-07-05 16:01:56 +0200922def Test_repeat_return_type()
923 let res = 0
924 for n in repeat([1], 3)
925 res += n
926 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200927 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +0200928
929 res = 0
930 for n in add([1, 2], 3)
931 res += n
932 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200933 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +0200934enddef
935
Bram Moolenaar846178a2020-07-05 17:04:13 +0200936def Test_argv_return_type()
937 next fileone filetwo
938 let res = ''
939 for name in argv()
940 res ..= name
941 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200942 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +0200943enddef
944
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200945def Test_func_type_part()
946 let RefVoid: func: void
947 RefVoid = FuncNoArgNoRet
948 RefVoid = FuncOneArgNoRet
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200949 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func() but got func(): number')
950 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: type mismatch, expected func() but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200951
952 let RefAny: func(): any
953 RefAny = FuncNoArgRetNumber
954 RefAny = FuncNoArgRetString
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200955 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): any but got func()')
956 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: type mismatch, expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200957
958 let RefNr: func: number
959 RefNr = FuncNoArgRetNumber
960 RefNr = FuncOneArgRetNumber
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200961 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): number but got func()')
962 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: type mismatch, expected func(): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200963
964 let RefStr: func: string
965 RefStr = FuncNoArgRetString
966 RefStr = FuncOneArgRetString
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200967 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): string but got func()')
968 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func(): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200969enddef
970
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200971def Test_func_type_fails()
972 CheckDefFailure(['let ref1: func()'], 'E704:')
973
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200974 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func() but got func(): number')
975 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: type mismatch, expected func() but got func(number)')
976 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: type mismatch, expected func() but got func(number): number')
977 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: type mismatch, expected func(bool) but got func(bool, number)')
978 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: type mismatch, expected func(?bool) but got func(bool, number)')
979 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 +0200980
Bram Moolenaard2c61702020-09-06 15:58:36 +0200981 CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:')
982 CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:')
983 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:')
984 CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200985enddef
986
Bram Moolenaar89228602020-04-05 22:14:54 +0200987def Test_func_return_type()
988 let nr: number
989 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200990 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +0200991
992 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200993 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +0200994
995 let str: string
996 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200997 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +0200998
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200999 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1012: type mismatch, expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001000enddef
1001
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001002def MultiLine(
1003 arg1: string,
1004 arg2 = 1234,
1005 ...rest: list<string>
1006 ): string
1007 return arg1 .. arg2 .. join(rest, '-')
1008enddef
1009
Bram Moolenaar2c330432020-04-13 14:41:35 +02001010def MultiLineComment(
1011 arg1: string, # comment
1012 arg2 = 1234, # comment
1013 ...rest: list<string> # comment
1014 ): string # comment
1015 return arg1 .. arg2 .. join(rest, '-')
1016enddef
1017
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001018def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001019 MultiLine('text')->assert_equal('text1234')
1020 MultiLine('text', 777)->assert_equal('text777')
1021 MultiLine('text', 777, 'one')->assert_equal('text777one')
1022 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001023enddef
1024
Bram Moolenaar23e03252020-04-12 22:22:31 +02001025func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001026 call MultiLine('text')->assert_equal('text1234')
1027 call MultiLine('text', 777)->assert_equal('text777')
1028 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1029 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001030endfunc
1031
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001032
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001033" When using CheckScriptFailure() for the below test, E1010 is generated instead
1034" of E1056.
1035func Test_E1056_1059()
1036 let caught_1056 = 0
1037 try
1038 def F():
1039 return 1
1040 enddef
1041 catch /E1056:/
1042 let caught_1056 = 1
1043 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001044 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001045
1046 let caught_1059 = 0
1047 try
1048 def F5(items : list)
1049 echo 'a'
1050 enddef
1051 catch /E1059:/
1052 let caught_1059 = 1
1053 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001054 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001055endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001056
Bram Moolenaar015f4262020-05-05 21:25:22 +02001057func DelMe()
1058 echo 'DelMe'
1059endfunc
1060
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001061def Test_error_reporting()
1062 # comment lines at the start of the function
1063 let lines =<< trim END
1064 " comment
1065 def Func()
1066 # comment
1067 # comment
1068 invalid
1069 enddef
1070 defcompile
1071 END
1072 call writefile(lines, 'Xdef')
1073 try
1074 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001075 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001076 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001077 v:exception->assert_match('Invalid command: invalid')
1078 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001079 endtry
1080
1081 # comment lines after the start of the function
1082 lines =<< trim END
1083 " comment
1084 def Func()
1085 let x = 1234
1086 # comment
1087 # comment
1088 invalid
1089 enddef
1090 defcompile
1091 END
1092 call writefile(lines, 'Xdef')
1093 try
1094 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001095 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001096 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001097 v:exception->assert_match('Invalid command: invalid')
1098 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001099 endtry
1100
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001101 lines =<< trim END
1102 vim9script
1103 def Func()
1104 let db = #{foo: 1, bar: 2}
1105 # comment
1106 let x = db.asdf
1107 enddef
1108 defcompile
1109 Func()
1110 END
1111 call writefile(lines, 'Xdef')
1112 try
1113 source Xdef
1114 assert_report('should have failed')
1115 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001116 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001117 endtry
1118
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001119 call delete('Xdef')
1120enddef
1121
Bram Moolenaar015f4262020-05-05 21:25:22 +02001122def Test_deleted_function()
1123 CheckDefExecFailure([
1124 'let RefMe: func = function("g:DelMe")',
1125 'delfunc g:DelMe',
1126 'echo RefMe()'], 'E117:')
1127enddef
1128
1129def Test_unknown_function()
1130 CheckDefExecFailure([
1131 'let Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001132 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001133enddef
1134
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001135def RefFunc(Ref: func(string): string): string
1136 return Ref('more')
1137enddef
1138
1139def Test_closure_simple()
1140 let local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001141 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001142enddef
1143
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001144def MakeRef()
1145 let local = 'some '
1146 g:Ref = {s -> local .. s}
1147enddef
1148
1149def Test_closure_ref_after_return()
1150 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001151 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001152 unlet g:Ref
1153enddef
1154
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001155def MakeTwoRefs()
1156 let local = ['some']
1157 g:Extend = {s -> local->add(s)}
1158 g:Read = {-> local}
1159enddef
1160
1161def Test_closure_two_refs()
1162 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001163 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001164 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001165 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001166 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001167 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001168
1169 unlet g:Extend
1170 unlet g:Read
1171enddef
1172
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001173def ReadRef(Ref: func(): list<string>): string
1174 return join(Ref(), ' ')
1175enddef
1176
1177def ExtendRef(Ref: func(string), add: string)
1178 Ref(add)
1179enddef
1180
1181def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001182 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001183 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001184 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001185 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001186 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001187 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001188
1189 unlet g:Extend
1190 unlet g:Read
1191enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001192
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001193def MakeArgRefs(theArg: string)
1194 let local = 'loc_val'
1195 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1196enddef
1197
1198def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
1199 let local = 'the_loc'
1200 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1201enddef
1202
1203def Test_closure_using_argument()
1204 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001205 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001206
1207 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001208 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001209
1210 unlet g:UseArg
1211 unlet g:UseVararg
1212enddef
1213
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001214def MakeGetAndAppendRefs()
1215 let local = 'a'
1216
1217 def Append(arg: string)
1218 local ..= arg
1219 enddef
1220 g:Append = Append
1221
1222 def Get(): string
1223 return local
1224 enddef
1225 g:Get = Get
1226enddef
1227
1228def Test_closure_append_get()
1229 MakeGetAndAppendRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001230 g:Get()->assert_equal('a')
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001231 g:Append('-b')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001232 g:Get()->assert_equal('a-b')
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001233 g:Append('-c')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001234 g:Get()->assert_equal('a-b-c')
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001235
1236 unlet g:Append
1237 unlet g:Get
1238enddef
1239
Bram Moolenaar04b12692020-05-04 23:24:44 +02001240def Test_nested_closure()
1241 let local = 'text'
1242 def Closure(arg: string): string
1243 return local .. arg
1244 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001245 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001246enddef
1247
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001248func GetResult(Ref)
1249 return a:Ref('some')
1250endfunc
1251
1252def Test_call_closure_not_compiled()
1253 let text = 'text'
1254 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001255 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001256enddef
1257
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001258def Test_sort_return_type()
1259 let res: list<number>
1260 res = [1, 2, 3]->sort()
1261enddef
1262
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001263def Test_getqflist_return_type()
1264 let l = getqflist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001265 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001266
1267 let d = getqflist(#{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001268 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001269enddef
1270
1271def Test_getloclist_return_type()
1272 let l = getloclist(1)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001273 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001274
1275 let d = getloclist(1, #{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001276 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001277enddef
1278
Bram Moolenaara66ba012020-07-05 18:41:08 +02001279def Test_copy_return_type()
1280 let l = copy([1, 2, 3])
1281 let res = 0
1282 for n in l
1283 res += n
1284 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001285 res->assert_equal(6)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001286
1287 let dl = deepcopy([1, 2, 3])
1288 res = 0
1289 for n in dl
1290 res += n
1291 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001292 res->assert_equal(6)
Bram Moolenaar44b4a242020-09-05 17:18:28 +02001293
1294 dl = deepcopy([1, 2, 3], true)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001295enddef
1296
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001297def Test_extend_return_type()
1298 let l = extend([1, 2], [3])
1299 let res = 0
1300 for n in l
1301 res += n
1302 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001303 res->assert_equal(6)
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001304enddef
1305
Bram Moolenaar2df47312020-09-05 17:30:44 +02001306def Test_garbagecollect()
1307 garbagecollect(true)
1308enddef
1309
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001310def Test_insert_return_type()
1311 let l = insert([2, 1], 3)
1312 let res = 0
1313 for n in l
1314 res += n
1315 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001316 res->assert_equal(6)
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001317enddef
1318
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001319def Test_keys_return_type()
1320 const var: list<string> = #{a: 1, b: 2}->keys()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001321 var->assert_equal(['a', 'b'])
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001322enddef
1323
Bram Moolenaar67627352020-07-05 21:10:24 +02001324def Test_reverse_return_type()
1325 let l = reverse([1, 2, 3])
1326 let res = 0
1327 for n in l
1328 res += n
1329 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001330 res->assert_equal(6)
Bram Moolenaar67627352020-07-05 21:10:24 +02001331enddef
1332
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001333def Test_remove_return_type()
1334 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
1335 let res = 0
1336 for n in l
1337 res += n
1338 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001339 res->assert_equal(3)
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001340enddef
1341
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001342def Test_filter_return_type()
1343 let l = filter([1, 2, 3], {-> 1})
1344 let res = 0
1345 for n in l
1346 res += n
1347 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001348 res->assert_equal(6)
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001349enddef
1350
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001351def Test_bufnr()
1352 let buf = bufnr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001353 bufnr('%')->assert_equal(buf)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001354
1355 buf = bufnr('Xdummy', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001356 buf->assert_notequal(-1)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001357 exe 'bwipe! ' .. buf
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001358enddef
1359
Bram Moolenaarec65d772020-08-20 22:29:12 +02001360def Test_col()
1361 new
1362 setline(1, 'asdf')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001363 col([1, '$'])->assert_equal(5)
Bram Moolenaarec65d772020-08-20 22:29:12 +02001364enddef
1365
Bram Moolenaar24f77502020-09-04 19:50:57 +02001366def Test_char2nr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001367 char2nr('あ', true)->assert_equal(12354)
Bram Moolenaar24f77502020-09-04 19:50:57 +02001368enddef
1369
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001370def Test_getreg_return_type()
1371 let s1: string = getreg('"')
1372 let s2: string = getreg('"', 1)
1373 let s3: list<string> = getreg('"', 1, 1)
1374enddef
1375
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001376def Wrong_dict_key_type(items: list<number>): list<number>
1377 return filter(items, {_, val -> get({val: 1}, 'x')})
1378enddef
1379
1380def Test_wrong_dict_key_type()
1381 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:')
1382enddef
1383
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001384def Line_continuation_in_def(dir: string = ''): string
1385 let path: string = empty(dir)
1386 \ ? 'empty'
1387 \ : 'full'
1388 return path
1389enddef
1390
1391def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001392 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001393enddef
1394
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001395def Line_continuation_in_lambda(): list<number>
1396 let x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001397 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001398 ->toupper()})
1399 ->reverse()
1400 return x
1401enddef
1402
1403def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001404 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001405enddef
1406
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001407func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001408 CheckScreendump
1409
1410 let lines =<< trim END
1411 vim9script
1412 def EchoNothing()
1413 silent echo ''
1414 enddef
1415 defcompile
1416 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001417 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001418
1419 " Check that the balloon shows up after a mouse move
1420 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001421 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001422 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1423
1424 " clean up
1425 call StopVimInTerminal(buf)
1426 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001427endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001428
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001429""""""" builtin functions that behave differently in Vim9
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001430
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001431def Test_bufname()
1432 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001433 bufname('%')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001434 edit OtherFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001435 bufname('#')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001436 close
Bram Moolenaar191929b2020-08-19 21:20:49 +02001437enddef
1438
Bram Moolenaara5d38412020-09-02 21:02:35 +02001439def Test_bufwinid()
1440 let origwin = win_getid()
1441 below split SomeFile
1442 let SomeFileID = win_getid()
1443 below split OtherFile
1444 below split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001445 bufwinid('SomeFile')->assert_equal(SomeFileID)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001446
1447 win_gotoid(origwin)
1448 only
1449 bwipe SomeFile
1450 bwipe OtherFile
1451enddef
1452
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001453def Test_count()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001454 count('ABC ABC ABC', 'b', true)->assert_equal(3)
1455 count('ABC ABC ABC', 'b', false)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001456enddef
1457
1458def Test_expand()
1459 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001460 expand('%', true, true)->assert_equal(['SomeFile'])
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001461 close
1462enddef
1463
1464def Test_getbufinfo()
1465 let bufinfo = getbufinfo(bufnr())
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001466 getbufinfo('%')->assert_equal(bufinfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001467
1468 edit Xtestfile1
1469 hide edit Xtestfile2
1470 hide enew
1471 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false})
1472 ->len()->assert_equal(3)
1473 bwipe Xtestfile1 Xtestfile2
1474enddef
1475
Bram Moolenaara5d38412020-09-02 21:02:35 +02001476def Test_getbufline()
1477 e SomeFile
1478 let buf = bufnr()
1479 e #
1480 let lines = ['aaa', 'bbb', 'ccc']
1481 setbufline(buf, 1, lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001482 getbufline('#', 1, '$')->assert_equal(lines)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001483
1484 bwipe!
1485enddef
1486
1487def Test_getchangelist()
1488 new
1489 setline(1, 'some text')
1490 let changelist = bufnr()->getchangelist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001491 getchangelist('%')->assert_equal(changelist)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001492 bwipe!
1493enddef
1494
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001495def Test_getchar()
Bram Moolenaar636c5d52020-09-05 18:48:57 +02001496 while getchar(0)
1497 endwhile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001498 getchar(true)->assert_equal(0)
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001499enddef
1500
Bram Moolenaard217a872020-09-05 18:31:33 +02001501def Test_getcompletion()
1502 set wildignore=*.vim,*~
1503 let l = getcompletion('run', 'file', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001504 l->assert_equal([])
Bram Moolenaard217a872020-09-05 18:31:33 +02001505 set wildignore&
1506enddef
1507
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001508def Test_getreg()
1509 let lines = ['aaa', 'bbb', 'ccc']
1510 setreg('a', lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001511 getreg('a', true, true)->assert_equal(lines)
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001512enddef
1513
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001514def Test_glob()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001515 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001516enddef
1517
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001518def Test_globpath()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001519 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001520enddef
1521
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001522def Test_has()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001523 has('eval', true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001524enddef
1525
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001526def Test_hasmapto()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001527 hasmapto('foobar', 'i', true)->assert_equal(0)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001528 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001529 hasmapto('foobar', 'i', true)->assert_equal(1)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001530 iunabbrev foo
1531enddef
1532
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001533def Test_index()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001534 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001535enddef
1536
1537def Test_list2str_str2list_utf8()
1538 let s = "\u3042\u3044"
1539 let l = [0x3042, 0x3044]
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001540 str2list(s, true)->assert_equal(l)
1541 list2str(l, true)->assert_equal(s)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001542enddef
1543
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001544def SID(): number
1545 return expand('<SID>')
1546 ->matchstr('<SNR>\zs\d\+\ze_$')
1547 ->str2nr()
1548enddef
1549
1550def Test_maparg()
1551 let lnum = str2nr(expand('<sflnum>'))
1552 map foo bar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001553 maparg('foo', '', false, true)->assert_equal(#{
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001554 lnum: lnum + 1,
1555 script: 0,
1556 mode: ' ',
1557 silent: 0,
1558 noremap: 0,
1559 lhs: 'foo',
1560 lhsraw: 'foo',
1561 nowait: 0,
1562 expr: 0,
1563 sid: SID(),
1564 rhs: 'bar',
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001565 buffer: 0})
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001566 unmap foo
1567enddef
1568
1569def Test_mapcheck()
1570 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001571 mapcheck('foo', 'i', true)->assert_equal('foobar')
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001572 iunabbrev foo
1573enddef
1574
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001575def Test_nr2char()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001576 nr2char(97, true)->assert_equal('a')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001577enddef
1578
1579def Test_readdir()
1580 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1581 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
1582enddef
1583
1584def Test_search()
1585 new
1586 setline(1, ['foo', 'bar'])
1587 let val = 0
1588 # skip expr returns boolean
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001589 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001590 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001591 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001592 # skip expr returns number, only 0 and 1 are accepted
1593 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001594 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001595 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001596 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001597 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1598 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1599enddef
1600
1601def Test_searchcount()
1602 new
1603 setline(1, "foo bar")
1604 :/foo
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001605 searchcount(#{recompute: true})
1606 ->assert_equal(#{
1607 exact_match: 1,
1608 current: 1,
1609 total: 1,
1610 maxcount: 99,
1611 incomplete: 0})
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001612 bwipe!
1613enddef
1614
1615def Test_searchdecl()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001616 searchdecl('blah', true, true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001617enddef
1618
1619def Test_setbufvar()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001620 setbufvar(bufnr('%'), '&syntax', 'vim')
1621 &syntax->assert_equal('vim')
1622 setbufvar(bufnr('%'), '&ts', 16)
1623 &ts->assert_equal(16)
1624 settabwinvar(1, 1, '&syntax', 'vam')
1625 &syntax->assert_equal('vam')
1626 settabwinvar(1, 1, '&ts', 15)
1627 &ts->assert_equal(15)
1628 setlocal ts=8
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001629
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001630 setbufvar('%', 'myvar', 123)
1631 getbufvar('%', 'myvar')->assert_equal(123)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001632enddef
1633
Bram Moolenaar401f0c02020-09-05 22:37:39 +02001634def Test_setloclist()
1635 let items = [#{filename: '/tmp/file', lnum: 1, valid: true}]
1636 let what = #{items: items}
1637 setqflist([], ' ', what)
1638 setloclist(0, [], ' ', what)
1639enddef
1640
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001641def Test_setreg()
1642 setreg('a', ['aaa', 'bbb', 'ccc'])
1643 let reginfo = getreginfo('a')
1644 setreg('a', reginfo)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001645 getreginfo('a')->assert_equal(reginfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001646enddef
1647
Bram Moolenaar7c27f332020-09-05 22:45:55 +02001648def Test_spellsuggest()
1649 if !has('spell')
1650 MissingFeature 'spell'
1651 else
1652 spellsuggest('marrch', 1, true)->assert_equal(['March'])
1653 endif
1654enddef
1655
Bram Moolenaar3986b942020-09-06 16:09:04 +02001656def Test_split()
1657 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
1658enddef
1659
1660def Test_str2nr()
1661 str2nr("1'000'000", 10, true)->assert_equal(1000000)
1662enddef
1663
1664def Test_strchars()
1665 strchars("A\u20dd", true)->assert_equal(1)
1666enddef
1667
Bram Moolenaarad304702020-09-06 18:22:53 +02001668def Test_submatch()
1669 let pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
1670 let Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()}
1671 let actual = substitute('A123456789', pat, Rep, '')
1672 let expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001673 actual->assert_equal(expected)
Bram Moolenaarad304702020-09-06 18:22:53 +02001674enddef
1675
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001676def Test_synID()
1677 new
1678 setline(1, "text")
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001679 synID(1, 1, true)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001680 bwipe!
1681enddef
1682
Bram Moolenaarad304702020-09-06 18:22:53 +02001683def Test_term_gettty()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001684 if !has('terminal')
1685 MissingFeature 'terminal'
1686 else
1687 let buf = Run_shell_in_terminal({})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001688 term_gettty(buf, true)->assert_notequal('')
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001689 StopShellInTerminal(buf)
1690 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001691enddef
1692
1693def Test_term_start()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001694 if !has('terminal')
1695 MissingFeature 'terminal'
1696 else
1697 botright new
1698 let winnr = winnr()
1699 term_start(&shell, #{curwin: true})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001700 winnr()->assert_equal(winnr)
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001701 bwipe!
1702 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001703enddef
1704
Bram Moolenaar418155d2020-09-06 18:39:38 +02001705def Test_timer_paused()
1706 let id = timer_start(50, {-> 0})
1707 timer_pause(id, true)
1708 let info = timer_info(id)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001709 info[0]['paused']->assert_equal(1)
Bram Moolenaar418155d2020-09-06 18:39:38 +02001710 timer_stop(id)
1711enddef
1712
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001713def Test_win_splitmove()
1714 split
1715 win_splitmove(1, 2, #{vertical: true, rightbelow: true})
1716 close
1717enddef
1718
1719""""""" end of builtin functions
1720
1721def Fibonacci(n: number): number
1722 if n < 2
1723 return n
1724 else
1725 return Fibonacci(n - 1) + Fibonacci(n - 2)
1726 endif
1727enddef
1728
Bram Moolenaar985116a2020-07-12 17:31:09 +02001729def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001730 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001731enddef
1732
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001733def TreeWalk(dir: string): list<any>
1734 return readdir(dir)->map({_, val ->
1735 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001736 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001737 : val
1738 })
1739enddef
1740
1741def Test_closure_in_map()
1742 mkdir('XclosureDir/tdir', 'p')
1743 writefile(['111'], 'XclosureDir/file1')
1744 writefile(['222'], 'XclosureDir/file2')
1745 writefile(['333'], 'XclosureDir/tdir/file3')
1746
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001747 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001748
1749 delete('XclosureDir', 'rf')
1750enddef
1751
Bram Moolenaara90afb92020-07-15 22:38:56 +02001752def Test_partial_call()
1753 let Xsetlist = function('setloclist', [0])
1754 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001755 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001756
1757 Xsetlist = function('setloclist', [0, [], ' '])
1758 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001759 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001760
1761 Xsetlist = function('setqflist')
1762 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001763 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001764
1765 Xsetlist = function('setqflist', [[], ' '])
1766 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001767 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001768enddef
1769
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001770def Test_cmd_modifier()
1771 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001772 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001773enddef
1774
1775def Test_restore_modifiers()
1776 # check that when compiling a :def function command modifiers are not messed
1777 # up.
1778 let lines =<< trim END
1779 vim9script
1780 set eventignore=
1781 autocmd QuickFixCmdPost * copen
1782 def AutocmdsDisabled()
1783 eval 0
1784 enddef
1785 func Func()
1786 noautocmd call s:AutocmdsDisabled()
1787 let g:ei_after = &eventignore
1788 endfunc
1789 Func()
1790 END
1791 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001792 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001793enddef
1794
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001795def StackTop()
1796 eval 1
1797 eval 2
1798 # call not on fourth line
1799 StackBot()
1800enddef
1801
1802def StackBot()
1803 # throw an error
1804 eval [][0]
1805enddef
1806
1807def Test_callstack_def()
1808 try
1809 StackTop()
1810 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001811 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001812 endtry
1813enddef
1814
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001815
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001816" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker