blob: 7a1385c74ec771f3a524d1c4d459cbeaa8852dee [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 Moolenaar0f769812020-09-12 18:32:34 +0200235def Test_local_function_shadows_global()
236 let lines =<< trim END
237 vim9script
238 def g:Gfunc(): string
239 return 'global'
240 enddef
241 def AnotherFunc(): number
242 let Gfunc = function('len')
243 return Gfunc('testing')
244 enddef
245 g:Gfunc()->assert_equal('global')
246 AnotherFunc()->assert_equal(7)
247 delfunc g:Gfunc
248 END
249 CheckScriptSuccess(lines)
250
251 lines =<< trim END
252 vim9script
253 def g:Func(): string
254 return 'global'
255 enddef
256 def AnotherFunc()
257 g:Func = function('len')
258 enddef
259 AnotherFunc()
260 END
261 CheckScriptFailure(lines, 'E705:')
262 delfunc g:Func
263enddef
264
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200265func TakesOneArg(arg)
266 echo a:arg
267endfunc
268
269def Test_call_wrong_args()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200270 CheckDefFailure(['TakesOneArg()'], 'E119:')
271 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
272 CheckDefFailure(['bufnr(xxx)'], 'E1001:')
273 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:')
Bram Moolenaaree8580e2020-08-28 17:19:07 +0200274
275 let lines =<< trim END
276 vim9script
277 def Func(s: string)
278 echo s
279 enddef
280 Func([])
281 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200282 call CheckScriptFailure(lines, 'E1013: argument 1: type mismatch, expected string but got list<unknown>', 5)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200283enddef
284
285" Default arg and varargs
286def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
287 let res = one .. ',' .. two
288 for s in rest
289 res ..= ',' .. s
290 endfor
291 return res
292enddef
293
294def Test_call_def_varargs()
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200295 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200296 MyDefVarargs('one')->assert_equal('one,foo')
297 MyDefVarargs('one', 'two')->assert_equal('one,two')
298 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200299 CheckDefFailure(['MyDefVarargs("one", 22)'],
300 'E1013: argument 2: type mismatch, expected string but got number')
301 CheckDefFailure(['MyDefVarargs("one", "two", 123)'],
302 'E1013: argument 3: type mismatch, expected string but got number')
303
304 let lines =<< trim END
305 vim9script
306 def Func(...l: list<string>)
307 echo l
308 enddef
309 Func('a', 'b', 'c')
310 END
311 CheckScriptSuccess(lines)
312
313 lines =<< trim END
314 vim9script
315 def Func(...l: list<string>)
316 echo l
317 enddef
318 Func()
319 END
320 CheckScriptSuccess(lines)
321
322 lines =<< trim END
323 vim9script
324 def Func(...l: list<string>)
325 echo l
326 enddef
327 Func(1, 2, 3)
328 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200329 CheckScriptFailure(lines, 'E1013: argument 1: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200330
331 lines =<< trim END
332 vim9script
333 def Func(...l: list<string>)
334 echo l
335 enddef
336 Func('a', 9)
337 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200338 CheckScriptFailure(lines, 'E1013: argument 2: type mismatch')
Bram Moolenaar24aa48b2020-07-25 16:33:02 +0200339
340 lines =<< trim END
341 vim9script
342 def Func(...l: list<string>)
343 echo l
344 enddef
345 Func(1, 'a')
346 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200347 CheckScriptFailure(lines, 'E1013: argument 1: type mismatch')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200348enddef
349
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200350def Test_call_call()
351 let l = [3, 2, 1]
352 call('reverse', [l])
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200353 l->assert_equal([1, 2, 3])
Bram Moolenaar575f24b2020-08-12 14:21:11 +0200354enddef
355
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200356let s:value = ''
357
358def FuncOneDefArg(opt = 'text')
359 s:value = opt
360enddef
361
362def FuncTwoDefArg(nr = 123, opt = 'text'): string
363 return nr .. opt
364enddef
365
366def FuncVarargs(...arg: list<string>): string
367 return join(arg, ',')
368enddef
369
370def Test_func_type_varargs()
371 let RefDefArg: func(?string)
372 RefDefArg = FuncOneDefArg
373 RefDefArg()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200374 s:value->assert_equal('text')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200375 RefDefArg('some')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200376 s:value->assert_equal('some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200377
378 let RefDef2Arg: func(?number, ?string): string
379 RefDef2Arg = FuncTwoDefArg
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200380 RefDef2Arg()->assert_equal('123text')
381 RefDef2Arg(99)->assert_equal('99text')
382 RefDef2Arg(77, 'some')->assert_equal('77some')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200383
Bram Moolenaard2c61702020-09-06 15:58:36 +0200384 CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:')
385 CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200386
387 let RefVarargs: func(...list<string>): string
388 RefVarargs = FuncVarargs
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200389 RefVarargs()->assert_equal('')
390 RefVarargs('one')->assert_equal('one')
391 RefVarargs('one', 'two')->assert_equal('one,two')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200392
Bram Moolenaard2c61702020-09-06 15:58:36 +0200393 CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:')
394 CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:')
Bram Moolenaar1378fbc2020-04-11 20:50:33 +0200395enddef
396
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200397" Only varargs
398def MyVarargsOnly(...args: list<string>): string
399 return join(args, ',')
400enddef
401
402def Test_call_varargs_only()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200403 MyVarargsOnly()->assert_equal('')
404 MyVarargsOnly('one')->assert_equal('one')
405 MyVarargsOnly('one', 'two')->assert_equal('one,two')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200406 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number')
407 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number')
Bram Moolenaar0b76b422020-04-07 22:05:08 +0200408enddef
409
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200410def Test_using_var_as_arg()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200411 writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200412 assert_fails('so Xdef', 'E1006:', '', 1, 'Func')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200413 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200414enddef
415
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200416def DictArg(arg: dict<string>)
417 arg['key'] = 'value'
418enddef
419
420def ListArg(arg: list<string>)
421 arg[0] = 'value'
422enddef
423
424def Test_assign_to_argument()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200425 # works for dict and list
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200426 let d: dict<string> = {}
427 DictArg(d)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200428 d['key']->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200429 let l: list<string> = []
430 ListArg(l)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200431 l[0]->assert_equal('value')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200432
Bram Moolenaard2c61702020-09-06 15:58:36 +0200433 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:')
Bram Moolenaarcb2bdb12020-05-10 22:53:56 +0200434enddef
435
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200436def Test_call_func_defined_later()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200437 g:DefinedLater('one')->assert_equal('one')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200438 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200439enddef
440
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200441func DefinedLater(arg)
442 return a:arg
443endfunc
444
445def Test_call_funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200446 g:SomeFunc('abc')->assert_equal(3)
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200447 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call
448 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref')
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200449
450 let lines =<< trim END
451 vim9script
452 def RetNumber(): number
453 return 123
454 enddef
455 let Funcref: func: number = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200456 Funcref()->assert_equal(123)
Bram Moolenaar2f1980f2020-07-22 19:30:06 +0200457 END
458 CheckScriptSuccess(lines)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200459
460 lines =<< trim END
461 vim9script
462 def RetNumber(): number
463 return 123
464 enddef
465 def Bar(F: func: number): number
466 return F()
467 enddef
468 let Funcref = function('RetNumber')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200469 Bar(Funcref)->assert_equal(123)
Bram Moolenaar0f60e802020-07-22 20:16:11 +0200470 END
471 CheckScriptSuccess(lines)
Bram Moolenaarbfba8652020-07-23 20:09:10 +0200472
473 lines =<< trim END
474 vim9script
475 def UseNumber(nr: number)
476 echo nr
477 enddef
478 let Funcref: func(number) = function('UseNumber')
479 Funcref(123)
480 END
481 CheckScriptSuccess(lines)
Bram Moolenaarb8070e32020-07-23 20:56:04 +0200482
483 lines =<< trim END
484 vim9script
485 def UseNumber(nr: number)
486 echo nr
487 enddef
488 let Funcref: func(string) = function('UseNumber')
489 END
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200490 CheckScriptFailure(lines, 'E1012: type mismatch, expected func(string) but got func(number)')
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200491
492 lines =<< trim END
493 vim9script
494 def EchoNr(nr = 34)
495 g:echo = nr
496 enddef
497 let Funcref: func(?number) = function('EchoNr')
498 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200499 g:echo->assert_equal(34)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200500 Funcref(123)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200501 g:echo->assert_equal(123)
Bram Moolenaar4fc224c2020-07-26 17:56:25 +0200502 END
503 CheckScriptSuccess(lines)
Bram Moolenaarace61322020-07-26 18:16:58 +0200504
505 lines =<< trim END
506 vim9script
507 def EchoList(...l: list<number>)
508 g:echo = l
509 enddef
510 let Funcref: func(...list<number>) = function('EchoList')
511 Funcref()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200512 g:echo->assert_equal([])
Bram Moolenaarace61322020-07-26 18:16:58 +0200513 Funcref(1, 2, 3)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200514 g:echo->assert_equal([1, 2, 3])
Bram Moolenaarace61322020-07-26 18:16:58 +0200515 END
516 CheckScriptSuccess(lines)
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200517
518 lines =<< trim END
519 vim9script
520 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number
521 g:optarg = opt
522 g:listarg = l
523 return nr
524 enddef
525 let Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200526 Funcref(10)->assert_equal(10)
527 g:optarg->assert_equal(12)
528 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200529
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200530 Funcref(11, 22)->assert_equal(11)
531 g:optarg->assert_equal(22)
532 g:listarg->assert_equal([])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200533
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200534 Funcref(17, 18, 1, 2, 3)->assert_equal(17)
535 g:optarg->assert_equal(18)
536 g:listarg->assert_equal([1, 2, 3])
Bram Moolenaar01865ad2020-07-26 18:33:09 +0200537 END
538 CheckScriptSuccess(lines)
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200539enddef
540
541let SomeFunc = function('len')
542let NotAFunc = 'text'
543
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200544def CombineFuncrefTypes()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200545 # same arguments, different return type
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200546 let Ref1: func(bool): string
547 let Ref2: func(bool): number
548 let Ref3: func(bool): any
549 Ref3 = g:cond ? Ref1 : Ref2
550
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200551 # different number of arguments
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200552 let Refa1: func(bool): number
553 let Refa2: func(bool, number): number
554 let Refa3: func: number
555 Refa3 = g:cond ? Refa1 : Refa2
556
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200557 # different argument types
Bram Moolenaar99aaf0c2020-04-12 14:39:53 +0200558 let Refb1: func(bool, string): number
559 let Refb2: func(string, number): number
560 let Refb3: func(any, any): number
561 Refb3 = g:cond ? Refb1 : Refb2
562enddef
563
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200564def FuncWithForwardCall()
Bram Moolenaar1df8b3f2020-04-23 18:13:23 +0200565 return g:DefinedEvenLater("yes")
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200566enddef
567
568def DefinedEvenLater(arg: string): string
569 return arg
570enddef
571
572def Test_error_in_nested_function()
Bram Moolenaarf5be8cd2020-07-17 20:36:00 +0200573 # Error in called function requires unwinding the call stack.
Bram Moolenaar44d66522020-09-06 22:26:57 +0200574 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200575enddef
576
577def Test_return_type_wrong()
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200578 CheckScriptFailure([
579 'def Func(): number',
580 'return "a"',
581 'enddef',
582 'defcompile'], 'expected number but got string')
583 CheckScriptFailure([
584 'def Func(): string',
585 'return 1',
586 'enddef',
587 'defcompile'], 'expected string but got number')
588 CheckScriptFailure([
589 'def Func(): void',
590 'return "a"',
591 'enddef',
592 'defcompile'],
593 'E1096: Returning a value in a function without a return type')
594 CheckScriptFailure([
595 'def Func()',
596 'return "a"',
597 'enddef',
598 'defcompile'],
599 'E1096: Returning a value in a function without a return type')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200600
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200601 CheckScriptFailure([
602 'def Func(): number',
603 'return',
604 'enddef',
605 'defcompile'], 'E1003:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200606
607 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
608 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200609 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:')
Bram Moolenaar5a849da2020-08-08 16:47:30 +0200610
611 CheckScriptFailure([
612 'vim9script',
613 'def FuncB()',
614 ' return 123',
615 'enddef',
616 'def FuncA()',
617 ' FuncB()',
618 'enddef',
619 'defcompile'], 'E1096:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200620enddef
621
622def Test_arg_type_wrong()
623 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
Bram Moolenaaree4e0c12020-04-06 21:35:05 +0200624 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...')
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200625 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:')
Bram Moolenaar6e949782020-04-13 17:21:00 +0200626 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200627enddef
628
629def Test_vim9script_call()
630 let lines =<< trim END
631 vim9script
632 let var = ''
633 def MyFunc(arg: string)
634 var = arg
635 enddef
636 MyFunc('foobar')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200637 var->assert_equal('foobar')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200638
639 let str = 'barfoo'
640 str->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200641 var->assert_equal('barfoo')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200642
Bram Moolenaar67979662020-06-20 22:50:47 +0200643 g:value = 'value'
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200644 g:value->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200645 var->assert_equal('value')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200646
647 let listvar = []
648 def ListFunc(arg: list<number>)
649 listvar = arg
650 enddef
651 [1, 2, 3]->ListFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200652 listvar->assert_equal([1, 2, 3])
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200653
654 let dictvar = {}
655 def DictFunc(arg: dict<number>)
656 dictvar = arg
657 enddef
658 {'a': 1, 'b': 2}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200659 dictvar->assert_equal(#{a: 1, b: 2})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200660 def CompiledDict()
661 {'a': 3, 'b': 4}->DictFunc()
662 enddef
663 CompiledDict()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200664 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200665
666 #{a: 3, b: 4}->DictFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200667 dictvar->assert_equal(#{a: 3, b: 4})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200668
669 ('text')->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200670 var->assert_equal('text')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200671 ("some")->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200672 var->assert_equal('some')
Bram Moolenaare6b53242020-07-01 17:28:33 +0200673
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200674 # line starting with single quote is not a mark
Bram Moolenaar10409562020-07-29 20:00:38 +0200675 # line starting with double quote can be a method call
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200676 'asdfasdf'->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200677 var->assert_equal('asdfasdf')
Bram Moolenaar10409562020-07-29 20:00:38 +0200678 "xyz"->MyFunc()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200679 var->assert_equal('xyz')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200680
681 def UseString()
682 'xyork'->MyFunc()
683 enddef
684 UseString()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200685 var->assert_equal('xyork')
Bram Moolenaar3d48e252020-07-15 14:15:52 +0200686
Bram Moolenaar10409562020-07-29 20:00:38 +0200687 def UseString2()
688 "knife"->MyFunc()
689 enddef
690 UseString2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200691 var->assert_equal('knife')
Bram Moolenaar10409562020-07-29 20:00:38 +0200692
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200693 # prepending a colon makes it a mark
694 new
695 setline(1, ['aaa', 'bbb', 'ccc'])
696 normal! 3Gmt1G
697 :'t
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200698 getcurpos()[1]->assert_equal(3)
Bram Moolenaar13e12b82020-07-24 18:47:22 +0200699 bwipe!
700
Bram Moolenaare6b53242020-07-01 17:28:33 +0200701 MyFunc(
702 'continued'
703 )
704 assert_equal('continued',
705 var
706 )
707
708 call MyFunc(
709 'more'
710 ..
711 'lines'
712 )
713 assert_equal(
714 'morelines',
715 var)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200716 END
717 writefile(lines, 'Xcall.vim')
718 source Xcall.vim
719 delete('Xcall.vim')
720enddef
721
722def Test_vim9script_call_fail_decl()
723 let lines =<< trim END
724 vim9script
725 let var = ''
726 def MyFunc(arg: string)
727 let var = 123
728 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200729 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200730 END
Bram Moolenaar6c4bfe42020-07-23 18:26:30 +0200731 CheckScriptFailure(lines, 'E1054:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200732enddef
733
Bram Moolenaar65b95452020-07-19 14:03:09 +0200734def Test_vim9script_call_fail_type()
735 let lines =<< trim END
736 vim9script
737 def MyFunc(arg: string)
738 echo arg
739 enddef
740 MyFunc(1234)
741 END
Bram Moolenaar8b565c22020-08-30 23:24:20 +0200742 CheckScriptFailure(lines, 'E1013: argument 1: type mismatch, expected string but got number')
Bram Moolenaar65b95452020-07-19 14:03:09 +0200743enddef
744
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200745def Test_vim9script_call_fail_const()
746 let lines =<< trim END
747 vim9script
748 const var = ''
749 def MyFunc(arg: string)
750 var = 'asdf'
751 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200752 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200753 END
754 writefile(lines, 'Xcall_const.vim')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200755 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200756 delete('Xcall_const.vim')
757enddef
758
759" Test that inside :function a Python function can be defined, :def is not
760" recognized.
761func Test_function_python()
762 CheckFeature python3
763 let py = 'python3'
764 execute py "<< EOF"
765def do_something():
766 return 1
767EOF
768endfunc
769
770def Test_delfunc()
771 let lines =<< trim END
772 vim9script
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200773 def g:GoneSoon()
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200774 echo 'hello'
775 enddef
776
777 def CallGoneSoon()
778 GoneSoon()
779 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200780 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200781
Bram Moolenaar4c17ad92020-04-27 22:47:51 +0200782 delfunc g:GoneSoon
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200783 CallGoneSoon()
784 END
785 writefile(lines, 'XToDelFunc')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200786 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
787 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200788
789 delete('XToDelFunc')
790enddef
791
792def Test_redef_failure()
Bram Moolenaard2c61702020-09-06 15:58:36 +0200793 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200794 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200795 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200796 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200797 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200798 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0')
Bram Moolenaard2c61702020-09-06 15:58:36 +0200799 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200800 so Xdef
Bram Moolenaard2c61702020-09-06 15:58:36 +0200801 delete('Xdef')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200802
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200803 g:Func0()->assert_equal(0)
804 g:Func1()->assert_equal('Func1')
805 g:Func2()->assert_equal('Func2')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200806
807 delfunc! Func0
808 delfunc! Func1
809 delfunc! Func2
810enddef
811
Bram Moolenaarf93c7fe2020-04-23 22:16:53 +0200812def Test_vim9script_func()
813 let lines =<< trim END
814 vim9script
815 func Func(arg)
816 echo a:arg
817 endfunc
818 Func('text')
819 END
820 writefile(lines, 'XVim9Func')
821 so XVim9Func
822
823 delete('XVim9Func')
824enddef
825
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200826" Test for internal functions returning different types
827func Test_InternalFuncRetType()
828 let lines =<< trim END
829 def RetFloat(): float
830 return ceil(1.456)
831 enddef
832
833 def RetListAny(): list<any>
Bram Moolenaar17a836c2020-08-12 17:35:58 +0200834 return items({'k': 'v'})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200835 enddef
836
837 def RetListString(): list<string>
838 return split('a:b:c', ':')
839 enddef
840
841 def RetListDictAny(): list<dict<any>>
842 return getbufinfo()
843 enddef
844
845 def RetDictNumber(): dict<number>
846 return wordcount()
847 enddef
848
849 def RetDictString(): dict<string>
850 return environ()
851 enddef
852 END
853 call writefile(lines, 'Xscript')
854 source Xscript
855
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200856 call RetFloat()->assert_equal(2.0)
857 call RetListAny()->assert_equal([['k', 'v']])
858 call RetListString()->assert_equal(['a', 'b', 'c'])
859 call RetListDictAny()->assert_notequal([])
860 call RetDictNumber()->assert_notequal({})
861 call RetDictString()->assert_notequal({})
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200862 call delete('Xscript')
863endfunc
864
865" Test for passing too many or too few arguments to internal functions
866func Test_internalfunc_arg_error()
867 let l =<< trim END
868 def! FArgErr(): float
869 return ceil(1.1, 2)
870 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200871 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200872 END
873 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200874 call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200875 let l =<< trim END
876 def! FArgErr(): float
877 return ceil()
878 enddef
Bram Moolenaar822ba242020-05-24 23:00:18 +0200879 defcompile
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200880 END
881 call writefile(l, 'Xinvalidarg')
Bram Moolenaar9bd5d872020-09-06 21:47:48 +0200882 call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200883 call delete('Xinvalidarg')
884endfunc
885
886let s:funcResult = 0
887
888def FuncNoArgNoRet()
Bram Moolenaar53900992020-08-22 19:02:02 +0200889 s:funcResult = 11
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200890enddef
891
892def FuncNoArgRetNumber(): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200893 s:funcResult = 22
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200894 return 1234
895enddef
896
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200897def FuncNoArgRetString(): string
Bram Moolenaar53900992020-08-22 19:02:02 +0200898 s:funcResult = 45
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200899 return 'text'
900enddef
901
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200902def FuncOneArgNoRet(arg: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200903 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200904enddef
905
906def FuncOneArgRetNumber(arg: number): number
Bram Moolenaar53900992020-08-22 19:02:02 +0200907 s:funcResult = arg
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200908 return arg
909enddef
910
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200911def FuncTwoArgNoRet(one: bool, two: number)
Bram Moolenaar53900992020-08-22 19:02:02 +0200912 s:funcResult = two
Bram Moolenaar08938ee2020-04-11 23:17:17 +0200913enddef
914
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200915def FuncOneArgRetString(arg: string): string
916 return arg
917enddef
918
Bram Moolenaar89228602020-04-05 22:14:54 +0200919def FuncOneArgRetAny(arg: any): any
920 return arg
921enddef
922
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200923def Test_func_type()
924 let Ref1: func()
Bram Moolenaar53900992020-08-22 19:02:02 +0200925 s:funcResult = 0
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200926 Ref1 = FuncNoArgNoRet
927 Ref1()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200928 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200929
930 let Ref2: func
Bram Moolenaar53900992020-08-22 19:02:02 +0200931 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200932 Ref2 = FuncNoArgNoRet
933 Ref2()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200934 s:funcResult->assert_equal(11)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200935
Bram Moolenaar53900992020-08-22 19:02:02 +0200936 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200937 Ref2 = FuncOneArgNoRet
938 Ref2(12)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200939 s:funcResult->assert_equal(12)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200940
Bram Moolenaar53900992020-08-22 19:02:02 +0200941 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200942 Ref2 = FuncNoArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200943 Ref2()->assert_equal(1234)
944 s:funcResult->assert_equal(22)
Bram Moolenaar4c683752020-04-05 21:38:23 +0200945
Bram Moolenaar53900992020-08-22 19:02:02 +0200946 s:funcResult = 0
Bram Moolenaar4c683752020-04-05 21:38:23 +0200947 Ref2 = FuncOneArgRetNumber
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200948 Ref2(13)->assert_equal(13)
949 s:funcResult->assert_equal(13)
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +0200950enddef
951
Bram Moolenaar9978d472020-07-05 16:01:56 +0200952def Test_repeat_return_type()
953 let res = 0
954 for n in repeat([1], 3)
955 res += n
956 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200957 res->assert_equal(3)
Bram Moolenaarfce82b32020-07-05 16:07:21 +0200958
959 res = 0
960 for n in add([1, 2], 3)
961 res += n
962 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200963 res->assert_equal(6)
Bram Moolenaar9978d472020-07-05 16:01:56 +0200964enddef
965
Bram Moolenaar846178a2020-07-05 17:04:13 +0200966def Test_argv_return_type()
967 next fileone filetwo
968 let res = ''
969 for name in argv()
970 res ..= name
971 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +0200972 res->assert_equal('fileonefiletwo')
Bram Moolenaar846178a2020-07-05 17:04:13 +0200973enddef
974
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200975def Test_func_type_part()
976 let RefVoid: func: void
977 RefVoid = FuncNoArgNoRet
978 RefVoid = FuncOneArgNoRet
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200979 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func() but got func(): number')
980 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: type mismatch, expected func() but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200981
982 let RefAny: func(): any
983 RefAny = FuncNoArgRetNumber
984 RefAny = FuncNoArgRetString
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200985 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): any but got func()')
986 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: type mismatch, expected func(): any but got func(number)')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200987
988 let RefNr: func: number
989 RefNr = FuncNoArgRetNumber
990 RefNr = FuncOneArgRetNumber
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200991 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): number but got func()')
992 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: type mismatch, expected func(): number but got func(): string')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200993
994 let RefStr: func: string
995 RefStr = FuncNoArgRetString
996 RefStr = FuncOneArgRetString
Bram Moolenaar451c2e32020-08-15 16:33:28 +0200997 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: type mismatch, expected func(): string but got func()')
998 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func(): string but got func(): number')
Bram Moolenaarec5929d2020-04-07 20:53:39 +0200999enddef
1000
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001001def Test_func_type_fails()
1002 CheckDefFailure(['let ref1: func()'], 'E704:')
1003
Bram Moolenaar451c2e32020-08-15 16:33:28 +02001004 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: type mismatch, expected func() but got func(): number')
1005 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: type mismatch, expected func() but got func(number)')
1006 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: type mismatch, expected func() but got func(number): number')
1007 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: type mismatch, expected func(bool) but got func(bool, number)')
1008 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: type mismatch, expected func(?bool) but got func(bool, number)')
1009 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 +02001010
Bram Moolenaard2c61702020-09-06 15:58:36 +02001011 CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:')
1012 CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:')
1013 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:')
1014 CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:')
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001015enddef
1016
Bram Moolenaar89228602020-04-05 22:14:54 +02001017def Test_func_return_type()
1018 let nr: number
1019 nr = FuncNoArgRetNumber()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001020 nr->assert_equal(1234)
Bram Moolenaar89228602020-04-05 22:14:54 +02001021
1022 nr = FuncOneArgRetAny(122)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001023 nr->assert_equal(122)
Bram Moolenaar89228602020-04-05 22:14:54 +02001024
1025 let str: string
1026 str = FuncOneArgRetAny('yes')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001027 str->assert_equal('yes')
Bram Moolenaar89228602020-04-05 22:14:54 +02001028
Bram Moolenaar451c2e32020-08-15 16:33:28 +02001029 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1012: type mismatch, expected string but got number')
Bram Moolenaar89228602020-04-05 22:14:54 +02001030enddef
1031
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001032def MultiLine(
1033 arg1: string,
1034 arg2 = 1234,
1035 ...rest: list<string>
1036 ): string
1037 return arg1 .. arg2 .. join(rest, '-')
1038enddef
1039
Bram Moolenaar2c330432020-04-13 14:41:35 +02001040def MultiLineComment(
1041 arg1: string, # comment
1042 arg2 = 1234, # comment
1043 ...rest: list<string> # comment
1044 ): string # comment
1045 return arg1 .. arg2 .. join(rest, '-')
1046enddef
1047
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001048def Test_multiline()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001049 MultiLine('text')->assert_equal('text1234')
1050 MultiLine('text', 777)->assert_equal('text777')
1051 MultiLine('text', 777, 'one')->assert_equal('text777one')
1052 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001053enddef
1054
Bram Moolenaar23e03252020-04-12 22:22:31 +02001055func Test_multiline_not_vim9()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001056 call MultiLine('text')->assert_equal('text1234')
1057 call MultiLine('text', 777)->assert_equal('text777')
1058 call MultiLine('text', 777, 'one')->assert_equal('text777one')
1059 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two')
Bram Moolenaar23e03252020-04-12 22:22:31 +02001060endfunc
1061
Bram Moolenaar5e774c72020-04-12 21:53:00 +02001062
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001063" When using CheckScriptFailure() for the below test, E1010 is generated instead
1064" of E1056.
1065func Test_E1056_1059()
1066 let caught_1056 = 0
1067 try
1068 def F():
1069 return 1
1070 enddef
1071 catch /E1056:/
1072 let caught_1056 = 1
1073 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001074 eval caught_1056->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001075
1076 let caught_1059 = 0
1077 try
1078 def F5(items : list)
1079 echo 'a'
1080 enddef
1081 catch /E1059:/
1082 let caught_1059 = 1
1083 endtry
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001084 eval caught_1059->assert_equal(1)
Bram Moolenaaree4e0c12020-04-06 21:35:05 +02001085endfunc
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001086
Bram Moolenaar015f4262020-05-05 21:25:22 +02001087func DelMe()
1088 echo 'DelMe'
1089endfunc
1090
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001091def Test_error_reporting()
1092 # comment lines at the start of the function
1093 let lines =<< trim END
1094 " comment
1095 def Func()
1096 # comment
1097 # comment
1098 invalid
1099 enddef
1100 defcompile
1101 END
1102 call writefile(lines, 'Xdef')
1103 try
1104 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001105 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001106 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001107 v:exception->assert_match('Invalid command: invalid')
1108 v:throwpoint->assert_match(', line 3$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001109 endtry
1110
1111 # comment lines after the start of the function
1112 lines =<< trim END
1113 " comment
1114 def Func()
1115 let x = 1234
1116 # comment
1117 # comment
1118 invalid
1119 enddef
1120 defcompile
1121 END
1122 call writefile(lines, 'Xdef')
1123 try
1124 source Xdef
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001125 assert_report('should have failed')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001126 catch /E476:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001127 v:exception->assert_match('Invalid command: invalid')
1128 v:throwpoint->assert_match(', line 4$')
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001129 endtry
1130
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001131 lines =<< trim END
1132 vim9script
1133 def Func()
1134 let db = #{foo: 1, bar: 2}
1135 # comment
1136 let x = db.asdf
1137 enddef
1138 defcompile
1139 Func()
1140 END
1141 call writefile(lines, 'Xdef')
1142 try
1143 source Xdef
1144 assert_report('should have failed')
1145 catch /E716:/
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001146 v:throwpoint->assert_match('_Func, line 3$')
Bram Moolenaar7517ffd2020-08-14 18:35:07 +02001147 endtry
1148
Bram Moolenaarbf8feb52020-08-08 14:26:31 +02001149 call delete('Xdef')
1150enddef
1151
Bram Moolenaar015f4262020-05-05 21:25:22 +02001152def Test_deleted_function()
1153 CheckDefExecFailure([
1154 'let RefMe: func = function("g:DelMe")',
1155 'delfunc g:DelMe',
1156 'echo RefMe()'], 'E117:')
1157enddef
1158
1159def Test_unknown_function()
1160 CheckDefExecFailure([
1161 'let Ref: func = function("NotExist")',
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02001162 'delfunc g:NotExist'], 'E700:')
Bram Moolenaar015f4262020-05-05 21:25:22 +02001163enddef
1164
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001165def RefFunc(Ref: func(string): string): string
1166 return Ref('more')
1167enddef
1168
1169def Test_closure_simple()
1170 let local = 'some '
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001171 RefFunc({s -> local .. s})->assert_equal('some more')
Bram Moolenaarc8cd2b32020-05-01 19:29:08 +02001172enddef
1173
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001174def MakeRef()
1175 let local = 'some '
1176 g:Ref = {s -> local .. s}
1177enddef
1178
1179def Test_closure_ref_after_return()
1180 MakeRef()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001181 g:Ref('thing')->assert_equal('some thing')
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001182 unlet g:Ref
1183enddef
1184
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001185def MakeTwoRefs()
1186 let local = ['some']
1187 g:Extend = {s -> local->add(s)}
1188 g:Read = {-> local}
1189enddef
1190
1191def Test_closure_two_refs()
1192 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001193 join(g:Read(), ' ')->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001194 g:Extend('more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001195 join(g:Read(), ' ')->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001196 g:Extend('even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001197 join(g:Read(), ' ')->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001198
1199 unlet g:Extend
1200 unlet g:Read
1201enddef
1202
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001203def ReadRef(Ref: func(): list<string>): string
1204 return join(Ref(), ' ')
1205enddef
1206
1207def ExtendRef(Ref: func(string), add: string)
1208 Ref(add)
1209enddef
1210
1211def Test_closure_two_indirect_refs()
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001212 MakeTwoRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001213 ReadRef(g:Read)->assert_equal('some')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001214 ExtendRef(g:Extend, 'more')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001215 ReadRef(g:Read)->assert_equal('some more')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001216 ExtendRef(g:Extend, 'even')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001217 ReadRef(g:Read)->assert_equal('some more even')
Bram Moolenaar5adc55c2020-05-02 23:12:58 +02001218
1219 unlet g:Extend
1220 unlet g:Read
1221enddef
Bram Moolenaarbf67ea12020-05-02 17:52:42 +02001222
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001223def MakeArgRefs(theArg: string)
1224 let local = 'loc_val'
1225 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s}
1226enddef
1227
1228def MakeArgRefsVarargs(theArg: string, ...rest: list<string>)
1229 let local = 'the_loc'
1230 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)}
1231enddef
1232
1233def Test_closure_using_argument()
1234 MakeArgRefs('arg_val')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001235 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001236
1237 MakeArgRefsVarargs('arg_val', 'one', 'two')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001238 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two')
Bram Moolenaar2fd4cd72020-05-03 22:30:49 +02001239
1240 unlet g:UseArg
1241 unlet g:UseVararg
1242enddef
1243
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001244def MakeGetAndAppendRefs()
1245 let local = 'a'
1246
1247 def Append(arg: string)
1248 local ..= arg
1249 enddef
1250 g:Append = Append
1251
1252 def Get(): string
1253 return local
1254 enddef
1255 g:Get = Get
1256enddef
1257
1258def Test_closure_append_get()
1259 MakeGetAndAppendRefs()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001260 g:Get()->assert_equal('a')
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001261 g:Append('-b')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001262 g:Get()->assert_equal('a-b')
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001263 g:Append('-c')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001264 g:Get()->assert_equal('a-b-c')
Bram Moolenaarb68b3462020-05-06 21:06:30 +02001265
1266 unlet g:Append
1267 unlet g:Get
1268enddef
1269
Bram Moolenaar04b12692020-05-04 23:24:44 +02001270def Test_nested_closure()
1271 let local = 'text'
1272 def Closure(arg: string): string
1273 return local .. arg
1274 enddef
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001275 Closure('!!!')->assert_equal('text!!!')
Bram Moolenaar04b12692020-05-04 23:24:44 +02001276enddef
1277
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001278func GetResult(Ref)
1279 return a:Ref('some')
1280endfunc
1281
1282def Test_call_closure_not_compiled()
1283 let text = 'text'
1284 g:Ref = {s -> s .. text}
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001285 GetResult(g:Ref)->assert_equal('sometext')
Bram Moolenaar6f5b6df2020-05-16 21:20:12 +02001286enddef
1287
Bram Moolenaar865af6b2020-06-18 18:45:49 +02001288def Test_sort_return_type()
1289 let res: list<number>
1290 res = [1, 2, 3]->sort()
1291enddef
1292
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001293def Test_getqflist_return_type()
1294 let l = getqflist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001295 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001296
1297 let d = getqflist(#{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001298 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001299enddef
1300
1301def Test_getloclist_return_type()
1302 let l = getloclist(1)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001303 l->assert_equal([])
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001304
1305 let d = getloclist(1, #{items: 0})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001306 d->assert_equal(#{items: []})
Bram Moolenaarf151ad12020-06-30 13:38:01 +02001307enddef
1308
Bram Moolenaara66ba012020-07-05 18:41:08 +02001309def Test_copy_return_type()
1310 let l = copy([1, 2, 3])
1311 let res = 0
1312 for n in l
1313 res += n
1314 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001315 res->assert_equal(6)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001316
1317 let dl = deepcopy([1, 2, 3])
1318 res = 0
1319 for n in dl
1320 res += n
1321 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001322 res->assert_equal(6)
Bram Moolenaar44b4a242020-09-05 17:18:28 +02001323
1324 dl = deepcopy([1, 2, 3], true)
Bram Moolenaara66ba012020-07-05 18:41:08 +02001325enddef
1326
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001327def Test_extend_return_type()
1328 let l = extend([1, 2], [3])
1329 let res = 0
1330 for n in l
1331 res += n
1332 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001333 res->assert_equal(6)
Bram Moolenaarb3c019c2020-07-05 20:08:39 +02001334enddef
1335
Bram Moolenaar2df47312020-09-05 17:30:44 +02001336def Test_garbagecollect()
1337 garbagecollect(true)
1338enddef
1339
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001340def Test_insert_return_type()
1341 let l = insert([2, 1], 3)
1342 let res = 0
1343 for n in l
1344 res += n
1345 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001346 res->assert_equal(6)
Bram Moolenaar252e88a2020-07-05 20:47:18 +02001347enddef
1348
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001349def Test_keys_return_type()
1350 const var: list<string> = #{a: 1, b: 2}->keys()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001351 var->assert_equal(['a', 'b'])
Bram Moolenaar32f335f2020-08-14 18:56:45 +02001352enddef
1353
Bram Moolenaar67627352020-07-05 21:10:24 +02001354def Test_reverse_return_type()
1355 let l = reverse([1, 2, 3])
1356 let res = 0
1357 for n in l
1358 res += n
1359 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001360 res->assert_equal(6)
Bram Moolenaar67627352020-07-05 21:10:24 +02001361enddef
1362
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001363def Test_remove_return_type()
1364 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one')
1365 let res = 0
1366 for n in l
1367 res += n
1368 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001369 res->assert_equal(3)
Bram Moolenaarad7c2492020-07-05 20:55:29 +02001370enddef
1371
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001372def Test_filter_return_type()
1373 let l = filter([1, 2, 3], {-> 1})
1374 let res = 0
1375 for n in l
1376 res += n
1377 endfor
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001378 res->assert_equal(6)
Bram Moolenaar0d94ad62020-07-05 20:16:41 +02001379enddef
1380
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001381def Test_bufnr()
1382 let buf = bufnr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001383 bufnr('%')->assert_equal(buf)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001384
1385 buf = bufnr('Xdummy', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001386 buf->assert_notequal(-1)
Bram Moolenaarfe136c92020-09-04 18:35:26 +02001387 exe 'bwipe! ' .. buf
Bram Moolenaarf39397e2020-08-17 22:21:36 +02001388enddef
1389
Bram Moolenaarec65d772020-08-20 22:29:12 +02001390def Test_col()
1391 new
1392 setline(1, 'asdf')
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001393 col([1, '$'])->assert_equal(5)
Bram Moolenaarec65d772020-08-20 22:29:12 +02001394enddef
1395
Bram Moolenaar24f77502020-09-04 19:50:57 +02001396def Test_char2nr()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001397 char2nr('あ', true)->assert_equal(12354)
Bram Moolenaar24f77502020-09-04 19:50:57 +02001398enddef
1399
Bram Moolenaar3d945cc2020-08-06 21:26:59 +02001400def Test_getreg_return_type()
1401 let s1: string = getreg('"')
1402 let s2: string = getreg('"', 1)
1403 let s3: list<string> = getreg('"', 1, 1)
1404enddef
1405
Bram Moolenaarf1a23682020-07-13 18:55:48 +02001406def Wrong_dict_key_type(items: list<number>): list<number>
1407 return filter(items, {_, val -> get({val: 1}, 'x')})
1408enddef
1409
1410def Test_wrong_dict_key_type()
1411 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:')
1412enddef
1413
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001414def Line_continuation_in_def(dir: string = ''): string
1415 let path: string = empty(dir)
1416 \ ? 'empty'
1417 \ : 'full'
1418 return path
1419enddef
1420
1421def Test_line_continuation_in_def()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001422 Line_continuation_in_def('.')->assert_equal('full')
Bram Moolenaaracd4c5e2020-06-22 19:39:03 +02001423enddef
1424
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001425def Line_continuation_in_lambda(): list<number>
1426 let x = range(97, 100)
Bram Moolenaar914e7ea2020-07-11 15:20:48 +02001427 ->map({_, v -> nr2char(v)
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001428 ->toupper()})
1429 ->reverse()
1430 return x
1431enddef
1432
1433def Test_line_continuation_in_lambda()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001434 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A'])
Bram Moolenaar7a4b8982020-07-08 17:36:21 +02001435enddef
1436
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001437func Test_silent_echo()
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001438 CheckScreendump
1439
1440 let lines =<< trim END
1441 vim9script
1442 def EchoNothing()
1443 silent echo ''
1444 enddef
1445 defcompile
1446 END
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001447 call writefile(lines, 'XTest_silent_echo')
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001448
1449 " Check that the balloon shows up after a mouse move
1450 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001451 call term_sendkeys(buf, ":abc")
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001452 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
1453
1454 " clean up
1455 call StopVimInTerminal(buf)
1456 call delete('XTest_silent_echo')
Bram Moolenaar8f510af2020-07-05 18:48:23 +02001457endfunc
Bram Moolenaar47e7d702020-07-05 18:18:42 +02001458
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001459""""""" builtin functions that behave differently in Vim9
Bram Moolenaare15eebd2020-08-18 19:11:38 +02001460
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001461def Test_bufname()
1462 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001463 bufname('%')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001464 edit OtherFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001465 bufname('#')->assert_equal('SomeFile')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001466 close
Bram Moolenaar191929b2020-08-19 21:20:49 +02001467enddef
1468
Bram Moolenaara5d38412020-09-02 21:02:35 +02001469def Test_bufwinid()
1470 let origwin = win_getid()
1471 below split SomeFile
1472 let SomeFileID = win_getid()
1473 below split OtherFile
1474 below split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001475 bufwinid('SomeFile')->assert_equal(SomeFileID)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001476
1477 win_gotoid(origwin)
1478 only
1479 bwipe SomeFile
1480 bwipe OtherFile
1481enddef
1482
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001483def Test_count()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001484 count('ABC ABC ABC', 'b', true)->assert_equal(3)
1485 count('ABC ABC ABC', 'b', false)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001486enddef
1487
1488def Test_expand()
1489 split SomeFile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001490 expand('%', true, true)->assert_equal(['SomeFile'])
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001491 close
1492enddef
1493
1494def Test_getbufinfo()
1495 let bufinfo = getbufinfo(bufnr())
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001496 getbufinfo('%')->assert_equal(bufinfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001497
1498 edit Xtestfile1
1499 hide edit Xtestfile2
1500 hide enew
1501 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false})
1502 ->len()->assert_equal(3)
1503 bwipe Xtestfile1 Xtestfile2
1504enddef
1505
Bram Moolenaara5d38412020-09-02 21:02:35 +02001506def Test_getbufline()
1507 e SomeFile
1508 let buf = bufnr()
1509 e #
1510 let lines = ['aaa', 'bbb', 'ccc']
1511 setbufline(buf, 1, lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001512 getbufline('#', 1, '$')->assert_equal(lines)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001513
1514 bwipe!
1515enddef
1516
1517def Test_getchangelist()
1518 new
1519 setline(1, 'some text')
1520 let changelist = bufnr()->getchangelist()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001521 getchangelist('%')->assert_equal(changelist)
Bram Moolenaara5d38412020-09-02 21:02:35 +02001522 bwipe!
1523enddef
1524
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001525def Test_getchar()
Bram Moolenaar636c5d52020-09-05 18:48:57 +02001526 while getchar(0)
1527 endwhile
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001528 getchar(true)->assert_equal(0)
Bram Moolenaarc08cc722020-09-05 17:51:23 +02001529enddef
1530
Bram Moolenaard217a872020-09-05 18:31:33 +02001531def Test_getcompletion()
1532 set wildignore=*.vim,*~
1533 let l = getcompletion('run', 'file', true)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001534 l->assert_equal([])
Bram Moolenaard217a872020-09-05 18:31:33 +02001535 set wildignore&
1536enddef
1537
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001538def Test_getreg()
1539 let lines = ['aaa', 'bbb', 'ccc']
1540 setreg('a', lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001541 getreg('a', true, true)->assert_equal(lines)
Bram Moolenaar67ff97d2020-09-02 21:45:54 +02001542enddef
1543
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001544def Test_glob()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001545 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
Bram Moolenaar5892ea12020-09-02 21:53:11 +02001546enddef
1547
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001548def Test_globpath()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001549 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
Bram Moolenaarf966ce52020-09-02 21:57:07 +02001550enddef
1551
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001552def Test_has()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001553 has('eval', true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001554enddef
1555
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001556def Test_hasmapto()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001557 hasmapto('foobar', 'i', true)->assert_equal(0)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001558 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001559 hasmapto('foobar', 'i', true)->assert_equal(1)
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001560 iunabbrev foo
1561enddef
1562
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001563def Test_index()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001564 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001565enddef
1566
1567def Test_list2str_str2list_utf8()
1568 let s = "\u3042\u3044"
1569 let l = [0x3042, 0x3044]
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001570 str2list(s, true)->assert_equal(l)
1571 list2str(l, true)->assert_equal(s)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001572enddef
1573
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001574def SID(): number
1575 return expand('<SID>')
1576 ->matchstr('<SNR>\zs\d\+\ze_$')
1577 ->str2nr()
1578enddef
1579
1580def Test_maparg()
1581 let lnum = str2nr(expand('<sflnum>'))
1582 map foo bar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001583 maparg('foo', '', false, true)->assert_equal(#{
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001584 lnum: lnum + 1,
1585 script: 0,
1586 mode: ' ',
1587 silent: 0,
1588 noremap: 0,
1589 lhs: 'foo',
1590 lhsraw: 'foo',
1591 nowait: 0,
1592 expr: 0,
1593 sid: SID(),
1594 rhs: 'bar',
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001595 buffer: 0})
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001596 unmap foo
1597enddef
1598
1599def Test_mapcheck()
1600 iabbrev foo foobar
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001601 mapcheck('foo', 'i', true)->assert_equal('foobar')
Bram Moolenaar04d594b2020-09-02 22:25:35 +02001602 iunabbrev foo
1603enddef
1604
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001605def Test_nr2char()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001606 nr2char(97, true)->assert_equal('a')
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001607enddef
1608
1609def Test_readdir()
1610 eval expand('sautest')->readdir({e -> e[0] !=# '.'})
1611 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'})
1612enddef
1613
1614def Test_search()
1615 new
1616 setline(1, ['foo', 'bar'])
1617 let val = 0
1618 # skip expr returns boolean
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001619 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001620 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001621 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001622 # skip expr returns number, only 0 and 1 are accepted
1623 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001624 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001625 :1
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001626 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001627 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1628 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:')
1629enddef
1630
1631def Test_searchcount()
1632 new
1633 setline(1, "foo bar")
1634 :/foo
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001635 searchcount(#{recompute: true})
1636 ->assert_equal(#{
1637 exact_match: 1,
1638 current: 1,
1639 total: 1,
1640 maxcount: 99,
1641 incomplete: 0})
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001642 bwipe!
1643enddef
1644
1645def Test_searchdecl()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001646 searchdecl('blah', true, true)->assert_equal(1)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001647enddef
1648
1649def Test_setbufvar()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001650 setbufvar(bufnr('%'), '&syntax', 'vim')
1651 &syntax->assert_equal('vim')
1652 setbufvar(bufnr('%'), '&ts', 16)
1653 &ts->assert_equal(16)
1654 settabwinvar(1, 1, '&syntax', 'vam')
1655 &syntax->assert_equal('vam')
1656 settabwinvar(1, 1, '&ts', 15)
1657 &ts->assert_equal(15)
1658 setlocal ts=8
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001659
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001660 setbufvar('%', 'myvar', 123)
1661 getbufvar('%', 'myvar')->assert_equal(123)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001662enddef
1663
Bram Moolenaar401f0c02020-09-05 22:37:39 +02001664def Test_setloclist()
1665 let items = [#{filename: '/tmp/file', lnum: 1, valid: true}]
1666 let what = #{items: items}
1667 setqflist([], ' ', what)
1668 setloclist(0, [], ' ', what)
1669enddef
1670
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001671def Test_setreg()
1672 setreg('a', ['aaa', 'bbb', 'ccc'])
1673 let reginfo = getreginfo('a')
1674 setreg('a', reginfo)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001675 getreginfo('a')->assert_equal(reginfo)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001676enddef
1677
Bram Moolenaar7c27f332020-09-05 22:45:55 +02001678def Test_spellsuggest()
1679 if !has('spell')
1680 MissingFeature 'spell'
1681 else
1682 spellsuggest('marrch', 1, true)->assert_equal(['March'])
1683 endif
1684enddef
1685
Bram Moolenaar3986b942020-09-06 16:09:04 +02001686def Test_split()
1687 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
1688enddef
1689
1690def Test_str2nr()
1691 str2nr("1'000'000", 10, true)->assert_equal(1000000)
1692enddef
1693
1694def Test_strchars()
1695 strchars("A\u20dd", true)->assert_equal(1)
1696enddef
1697
Bram Moolenaarad304702020-09-06 18:22:53 +02001698def Test_submatch()
1699 let pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)'
1700 let Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()}
1701 let actual = substitute('A123456789', pat, Rep, '')
1702 let expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001703 actual->assert_equal(expected)
Bram Moolenaarad304702020-09-06 18:22:53 +02001704enddef
1705
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001706def Test_synID()
1707 new
1708 setline(1, "text")
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001709 synID(1, 1, true)->assert_equal(0)
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001710 bwipe!
1711enddef
1712
Bram Moolenaarad304702020-09-06 18:22:53 +02001713def Test_term_gettty()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001714 if !has('terminal')
1715 MissingFeature 'terminal'
1716 else
1717 let buf = Run_shell_in_terminal({})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001718 term_gettty(buf, true)->assert_notequal('')
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001719 StopShellInTerminal(buf)
1720 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001721enddef
1722
1723def Test_term_start()
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001724 if !has('terminal')
1725 MissingFeature 'terminal'
1726 else
1727 botright new
1728 let winnr = winnr()
1729 term_start(&shell, #{curwin: true})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001730 winnr()->assert_equal(winnr)
Bram Moolenaar63969ef2020-09-06 20:06:59 +02001731 bwipe!
1732 endif
Bram Moolenaarad304702020-09-06 18:22:53 +02001733enddef
1734
Bram Moolenaar418155d2020-09-06 18:39:38 +02001735def Test_timer_paused()
1736 let id = timer_start(50, {-> 0})
1737 timer_pause(id, true)
1738 let info = timer_info(id)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001739 info[0]['paused']->assert_equal(1)
Bram Moolenaar418155d2020-09-06 18:39:38 +02001740 timer_stop(id)
1741enddef
1742
Bram Moolenaar4b9bd692020-09-05 21:57:53 +02001743def Test_win_splitmove()
1744 split
1745 win_splitmove(1, 2, #{vertical: true, rightbelow: true})
1746 close
1747enddef
1748
1749""""""" end of builtin functions
1750
1751def Fibonacci(n: number): number
1752 if n < 2
1753 return n
1754 else
1755 return Fibonacci(n - 1) + Fibonacci(n - 2)
1756 endif
1757enddef
1758
Bram Moolenaar985116a2020-07-12 17:31:09 +02001759def Test_recursive_call()
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001760 Fibonacci(20)->assert_equal(6765)
Bram Moolenaar985116a2020-07-12 17:31:09 +02001761enddef
1762
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001763def TreeWalk(dir: string): list<any>
1764 return readdir(dir)->map({_, val ->
1765 fnamemodify(dir .. '/' .. val, ':p')->isdirectory()
Bram Moolenaarbb1b5e22020-08-05 10:53:21 +02001766 ? {val: TreeWalk(dir .. '/' .. val)}
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001767 : val
1768 })
1769enddef
1770
1771def Test_closure_in_map()
1772 mkdir('XclosureDir/tdir', 'p')
1773 writefile(['111'], 'XclosureDir/file1')
1774 writefile(['222'], 'XclosureDir/file2')
1775 writefile(['333'], 'XclosureDir/tdir/file3')
1776
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001777 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}])
Bram Moolenaar08f7a412020-07-13 20:41:08 +02001778
1779 delete('XclosureDir', 'rf')
1780enddef
1781
Bram Moolenaara90afb92020-07-15 22:38:56 +02001782def Test_partial_call()
1783 let Xsetlist = function('setloclist', [0])
1784 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001785 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001786
1787 Xsetlist = function('setloclist', [0, [], ' '])
1788 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001789 getloclist(0, {'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001790
1791 Xsetlist = function('setqflist')
1792 Xsetlist([], ' ', {'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001793 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001794
1795 Xsetlist = function('setqflist', [[], ' '])
1796 Xsetlist({'title': 'test'})
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001797 getqflist({'title': 1})->assert_equal({'title': 'test'})
Bram Moolenaara90afb92020-07-15 22:38:56 +02001798enddef
1799
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001800def Test_cmd_modifier()
1801 tab echo '0'
Bram Moolenaard2c61702020-09-06 15:58:36 +02001802 CheckDefFailure(['5tab echo 3'], 'E16:')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001803enddef
1804
1805def Test_restore_modifiers()
1806 # check that when compiling a :def function command modifiers are not messed
1807 # up.
1808 let lines =<< trim END
1809 vim9script
1810 set eventignore=
1811 autocmd QuickFixCmdPost * copen
1812 def AutocmdsDisabled()
1813 eval 0
1814 enddef
1815 func Func()
1816 noautocmd call s:AutocmdsDisabled()
1817 let g:ei_after = &eventignore
1818 endfunc
1819 Func()
1820 END
1821 CheckScriptSuccess(lines)
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001822 g:ei_after->assert_equal('')
Bram Moolenaar2dd0a2c2020-08-08 15:10:27 +02001823enddef
1824
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001825def StackTop()
1826 eval 1
1827 eval 2
1828 # call not on fourth line
1829 StackBot()
1830enddef
1831
1832def StackBot()
1833 # throw an error
1834 eval [][0]
1835enddef
1836
1837def Test_callstack_def()
1838 try
1839 StackTop()
1840 catch
Bram Moolenaarc0c71e92020-09-11 19:09:48 +02001841 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2')
Bram Moolenaardfa3d552020-09-10 22:05:08 +02001842 endtry
1843enddef
1844
Bram Moolenaarf7779c62020-05-03 15:38:16 +02001845
Bram Moolenaar5deeb3f2020-04-05 17:08:17 +02001846" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker