Mercurial > vim
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 |