comparison src/testdir/test_vim9_func.vim @ 19912:d4fa9db88d16 v8.2.0512

patch 8.2.0512: Vim9: no optional arguments in func type Commit: https://github.com/vim/vim/commit/5deeb3f1f9db4eabd36e99cbf857fe376eb37e10 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Apr 5 17:08:17 2020 +0200 patch 8.2.0512: Vim9: no optional arguments in func type Problem: Vim9: no optional arguments in func type. Solution: Check for question mark after type. Find function reference without function().
author Bram Moolenaar <Bram@vim.org>
date Sun, 05 Apr 2020 17:15:25 +0200
parents
children 1f42c49c3d29
comparison
equal deleted inserted replaced
19911:70edfdef3b83 19912:d4fa9db88d16
1 " Test various aspects of the Vim9 script language.
2
3 source check.vim
4 source view_util.vim
5
6 " Check that "lines" inside ":def" results in an "error" message.
7 func CheckDefFailure(lines, error)
8 call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef')
9 call assert_fails('so Xdef', a:error, a:lines)
10 call delete('Xdef')
11 endfunc
12
13 func CheckScriptFailure(lines, error)
14 call writefile(a:lines, 'Xdef')
15 call assert_fails('so Xdef', a:error, a:lines)
16 call delete('Xdef')
17 endfunc
18
19 func Test_def_basic()
20 def SomeFunc(): string
21 return 'yes'
22 enddef
23 call assert_equal('yes', SomeFunc())
24 endfunc
25
26 def ReturnString(): string
27 return 'string'
28 enddef
29
30 def ReturnNumber(): number
31 return 123
32 enddef
33
34 let g:notNumber = 'string'
35
36 def ReturnGlobal(): number
37 return g:notNumber
38 enddef
39
40 def Test_return_something()
41 assert_equal('string', ReturnString())
42 assert_equal(123, ReturnNumber())
43 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
44 enddef
45
46 let s:nothing = 0
47 def ReturnNothing()
48 s:nothing = 1
49 if true
50 return
51 endif
52 s:nothing = 2
53 enddef
54
55 def Test_return_nothing()
56 ReturnNothing()
57 assert_equal(1, s:nothing)
58 enddef
59
60 func Increment()
61 let g:counter += 1
62 endfunc
63
64 def Test_call_ufunc_count()
65 g:counter = 1
66 Increment()
67 Increment()
68 Increment()
69 " works with and without :call
70 assert_equal(4, g:counter)
71 call assert_equal(4, g:counter)
72 unlet g:counter
73 enddef
74
75 def MyVarargs(arg: string, ...rest: list<string>): string
76 let res = arg
77 for s in rest
78 res ..= ',' .. s
79 endfor
80 return res
81 enddef
82
83 def Test_call_varargs()
84 assert_equal('one', MyVarargs('one'))
85 assert_equal('one,two', MyVarargs('one', 'two'))
86 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
87 enddef
88
89 def MyDefaultArgs(name = 'string'): string
90 return name
91 enddef
92
93 def Test_call_default_args()
94 assert_equal('string', MyDefaultArgs())
95 assert_equal('one', MyDefaultArgs('one'))
96 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
97
98 call CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef'], 'E1001:')
99 enddef
100
101 func Test_call_default_args_from_func()
102 call assert_equal('string', MyDefaultArgs())
103 call assert_equal('one', MyDefaultArgs('one'))
104 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
105 endfunc
106
107 func TakesOneArg(arg)
108 echo a:arg
109 endfunc
110
111 def Test_call_wrong_args()
112 call CheckDefFailure(['TakesOneArg()'], 'E119:')
113 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
114 call CheckDefFailure(['bufnr(xxx)'], 'E1001:')
115 enddef
116
117 " Default arg and varargs
118 def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
119 let res = one .. ',' .. two
120 for s in rest
121 res ..= ',' .. s
122 endfor
123 return res
124 enddef
125
126 def Test_call_def_varargs()
127 call assert_fails('call MyDefVarargs()', 'E119:')
128 assert_equal('one,foo', MyDefVarargs('one'))
129 assert_equal('one,two', MyDefVarargs('one', 'two'))
130 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
131 enddef
132
133 def Test_using_var_as_arg()
134 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
135 call assert_fails('so Xdef', 'E1006:')
136 call delete('Xdef')
137 enddef
138
139 def Test_call_func_defined_later()
140 call assert_equal('one', DefinedLater('one'))
141 call assert_fails('call NotDefined("one")', 'E117:')
142 enddef
143
144 func DefinedLater(arg)
145 return a:arg
146 endfunc
147
148 def FuncWithForwardCall()
149 return DefinedEvenLater("yes")
150 enddef
151
152 def DefinedEvenLater(arg: string): string
153 return arg
154 enddef
155
156 def Test_error_in_nested_function()
157 " Error in called function requires unwinding the call stack.
158 assert_fails('call FuncWithForwardCall()', 'E1029')
159 enddef
160
161 def Test_return_type_wrong()
162 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
163 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
164 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
165 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
166
167 CheckScriptFailure(['def Func(): number', 'return', 'enddef'], 'E1003:')
168
169 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
170 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
171 enddef
172
173 def Test_arg_type_wrong()
174 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
175 enddef
176
177 def Test_vim9script_call()
178 let lines =<< trim END
179 vim9script
180 let var = ''
181 def MyFunc(arg: string)
182 var = arg
183 enddef
184 MyFunc('foobar')
185 assert_equal('foobar', var)
186
187 let str = 'barfoo'
188 str->MyFunc()
189 assert_equal('barfoo', var)
190
191 let g:value = 'value'
192 g:value->MyFunc()
193 assert_equal('value', var)
194
195 let listvar = []
196 def ListFunc(arg: list<number>)
197 listvar = arg
198 enddef
199 [1, 2, 3]->ListFunc()
200 assert_equal([1, 2, 3], listvar)
201
202 let dictvar = {}
203 def DictFunc(arg: dict<number>)
204 dictvar = arg
205 enddef
206 {'a': 1, 'b': 2}->DictFunc()
207 assert_equal(#{a: 1, b: 2}, dictvar)
208 def CompiledDict()
209 {'a': 3, 'b': 4}->DictFunc()
210 enddef
211 CompiledDict()
212 assert_equal(#{a: 3, b: 4}, dictvar)
213
214 #{a: 3, b: 4}->DictFunc()
215 assert_equal(#{a: 3, b: 4}, dictvar)
216
217 ('text')->MyFunc()
218 assert_equal('text', var)
219 ("some")->MyFunc()
220 assert_equal('some', var)
221 END
222 writefile(lines, 'Xcall.vim')
223 source Xcall.vim
224 delete('Xcall.vim')
225 enddef
226
227 def Test_vim9script_call_fail_decl()
228 let lines =<< trim END
229 vim9script
230 let var = ''
231 def MyFunc(arg: string)
232 let var = 123
233 enddef
234 END
235 writefile(lines, 'Xcall_decl.vim')
236 assert_fails('source Xcall_decl.vim', 'E1054:')
237 delete('Xcall_decl.vim')
238 enddef
239
240 def Test_vim9script_call_fail_const()
241 let lines =<< trim END
242 vim9script
243 const var = ''
244 def MyFunc(arg: string)
245 var = 'asdf'
246 enddef
247 END
248 writefile(lines, 'Xcall_const.vim')
249 assert_fails('source Xcall_const.vim', 'E46:')
250 delete('Xcall_const.vim')
251 enddef
252
253 " Test that inside :function a Python function can be defined, :def is not
254 " recognized.
255 func Test_function_python()
256 CheckFeature python3
257 let py = 'python3'
258 execute py "<< EOF"
259 def do_something():
260 return 1
261 EOF
262 endfunc
263
264 def Test_delfunc()
265 let lines =<< trim END
266 vim9script
267 def GoneSoon()
268 echo 'hello'
269 enddef
270
271 def CallGoneSoon()
272 GoneSoon()
273 enddef
274
275 delfunc GoneSoon
276 CallGoneSoon()
277 END
278 writefile(lines, 'XToDelFunc')
279 assert_fails('so XToDelFunc', 'E933')
280 assert_fails('so XToDelFunc', 'E933')
281
282 delete('XToDelFunc')
283 enddef
284
285 def Test_redef_failure()
286 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
287 so Xdef
288 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
289 so Xdef
290 call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
291 call assert_fails('so Xdef', 'E1027:')
292 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
293 so Xdef
294 call delete('Xdef')
295
296 call assert_equal(0, Func0())
297 call assert_equal('Func1', Func1())
298 call assert_equal('Func2', Func2())
299
300 delfunc! Func0
301 delfunc! Func1
302 delfunc! Func2
303 enddef
304
305 " Test for internal functions returning different types
306 func Test_InternalFuncRetType()
307 let lines =<< trim END
308 def RetFloat(): float
309 return ceil(1.456)
310 enddef
311
312 def RetListAny(): list<any>
313 return items({'k' : 'v'})
314 enddef
315
316 def RetListString(): list<string>
317 return split('a:b:c', ':')
318 enddef
319
320 def RetListDictAny(): list<dict<any>>
321 return getbufinfo()
322 enddef
323
324 def RetDictNumber(): dict<number>
325 return wordcount()
326 enddef
327
328 def RetDictString(): dict<string>
329 return environ()
330 enddef
331 END
332 call writefile(lines, 'Xscript')
333 source Xscript
334
335 call assert_equal(2.0, RetFloat())
336 call assert_equal([['k', 'v']], RetListAny())
337 call assert_equal(['a', 'b', 'c'], RetListString())
338 call assert_notequal([], RetListDictAny())
339 call assert_notequal({}, RetDictNumber())
340 call assert_notequal({}, RetDictString())
341 call delete('Xscript')
342 endfunc
343
344 " Test for passing too many or too few arguments to internal functions
345 func Test_internalfunc_arg_error()
346 let l =<< trim END
347 def! FArgErr(): float
348 return ceil(1.1, 2)
349 enddef
350 END
351 call writefile(l, 'Xinvalidarg')
352 call assert_fails('so Xinvalidarg', 'E118:')
353 let l =<< trim END
354 def! FArgErr(): float
355 return ceil()
356 enddef
357 END
358 call writefile(l, 'Xinvalidarg')
359 call assert_fails('so Xinvalidarg', 'E119:')
360 call delete('Xinvalidarg')
361 endfunc
362
363 let s:funcResult = 0
364
365 def FuncNoArgNoRet()
366 funcResult = 11
367 enddef
368
369 def FuncNoArgRetNumber(): number
370 funcResult = 22
371 return 1234
372 enddef
373
374 def FuncOneArgNoRet(arg: number)
375 funcResult = arg
376 enddef
377
378 def FuncOneArgRetNumber(arg: number): number
379 funcResult = arg
380 return arg
381 enddef
382
383 def Test_func_type()
384 let Ref1: func()
385 funcResult = 0
386 Ref1 = FuncNoArgNoRet
387 Ref1()
388 assert_equal(11, funcResult)
389 enddef
390
391 def Test_func_type_fails()
392 CheckDefFailure(['let ref1: func()'], 'E704:')
393
394 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
395 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)')
396 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number')
397 enddef
398
399
400 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker