blob: 892806f39a622ef8b84ce27d39890f8e7238d7e3 [file] [log] [blame]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001" Test various aspects of the Vim9 script language.
2
Bram Moolenaar673660a2020-01-26 16:50:05 +01003source check.vim
4
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01005" Check that "lines" inside ":def" results in an "error" message.
6func CheckDefFailure(lines, error)
Bram Moolenaar978d1702020-01-26 17:38:12 +01007 call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01008 call assert_fails('so Xdef', a:error, a:lines)
9 call delete('Xdef')
10endfunc
11
12func CheckScriptFailure(lines, error)
13 call writefile(a:lines, 'Xdef')
14 call assert_fails('so Xdef', a:error, a:lines)
15 call delete('Xdef')
16endfunc
17
18def Test_syntax()
19 let var = 234
20 let other: list<string> = ['asdf']
21enddef
22
23func Test_def_basic()
24 def SomeFunc(): string
25 return 'yes'
26 enddef
27 call assert_equal('yes', SomeFunc())
28endfunc
29
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010030let s:appendToMe = 'xxx'
31let s:addToMe = 111
32
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010033def Test_assignment()
34 let bool1: bool = true
35 assert_equal(v:true, bool1)
36 let bool2: bool = false
37 assert_equal(v:false, bool2)
38
39 let list1: list<string> = ['sdf', 'asdf']
40 let list2: list<number> = [1, 2, 3]
41
42 " TODO: does not work yet
43 " let listS: list<string> = []
44 " let listN: list<number> = []
45
46 let dict1: dict<string> = #{key: 'value'}
47 let dict2: dict<number> = #{one: 1, two: 2}
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010048
49 v:char = 'abc'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010050 assert_equal('abc', v:char)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010051
52 $ENVVAR = 'foobar'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010053 assert_equal('foobar', $ENVVAR)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010054 $ENVVAR = ''
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010055
56 appendToMe ..= 'yyy'
57 assert_equal('xxxyyy', appendToMe)
58 addToMe += 222
59 assert_equal(333, addToMe)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010060enddef
61
62func Test_assignment_failure()
63 call CheckDefFailure(['let var=234'], 'E1004:')
64 call CheckDefFailure(['let var =234'], 'E1004:')
65 call CheckDefFailure(['let var= 234'], 'E1004:')
66
67 call CheckDefFailure(['let true = 1'], 'E1034:')
68 call CheckDefFailure(['let false = 1'], 'E1034:')
69
70 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
71 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
72
73 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
74 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
75
76 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
77 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
78endfunc
79
80func Test_const()
81 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
82 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
83 call CheckDefFailure(['const two'], 'E1021:')
84endfunc
85
86def Test_block()
87 let outer = 1
88 {
89 let inner = 2
90 assert_equal(1, outer)
91 assert_equal(2, inner)
92 }
93 assert_equal(1, outer)
94enddef
95
96func Test_block_failure()
97 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
98endfunc
99
100def ReturnString(): string
101 return 'string'
102enddef
103
104def ReturnNumber(): number
105 return 123
106enddef
107
108def Test_return_string()
109 assert_equal('string', ReturnString())
110 assert_equal(123, ReturnNumber())
111enddef
112
113func Increment()
114 let g:counter += 1
115endfunc
116
117def Test_call_ufunc_count()
118 g:counter = 1
119 Increment()
120 Increment()
121 Increment()
122 " works with and without :call
123 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100124 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100125 unlet g:counter
126enddef
127
128def MyVarargs(arg: string, ...rest: list<string>): string
129 let res = arg
130 for s in rest
131 res ..= ',' .. s
132 endfor
133 return res
134enddef
135
136def Test_call_varargs()
137 assert_equal('one', MyVarargs('one'))
138 assert_equal('one,two', MyVarargs('one', 'two'))
139 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
140enddef
141
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100142def MyDefaultArgs(name = 'string'): string
143 return name
144enddef
145
146def Test_call_default_args()
147 assert_equal('string', MyDefaultArgs())
148 assert_equal('one', MyDefaultArgs('one'))
149 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
150enddef
151
152func Test_call_default_args_from_func()
153 call assert_equal('string', MyDefaultArgs())
154 call assert_equal('one', MyDefaultArgs('one'))
155 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
156endfunc
157
158" Default arg and varargs
159def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
160 let res = one .. ',' .. two
161 for s in rest
162 res ..= ',' .. s
163 endfor
164 return res
165enddef
166
167def Test_call_def_varargs()
168 call assert_fails('call MyDefVarargs()', 'E119:')
169 assert_equal('one,foo', MyDefVarargs('one'))
170 assert_equal('one,two', MyDefVarargs('one', 'two'))
171 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
172enddef
173
174
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100175"def Test_call_func_defined_later()
176" call assert_equal('one', DefineLater('one'))
177" call assert_fails('call NotDefined("one")', 'E99:')
178"enddef
179
180func DefineLater(arg)
181 return a:arg
182endfunc
183
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100184def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100185 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
186 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
187 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
188 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100189enddef
190
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100191def Test_arg_type_wrong()
192 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
193enddef
194
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100195def Test_try_catch()
196 let l = []
197 try
198 add(l, '1')
199 throw 'wrong'
200 add(l, '2')
201 catch
202 add(l, v:exception)
203 finally
204 add(l, '3')
205 endtry
206 assert_equal(['1', 'wrong', '3'], l)
207enddef
208
209let s:export_script_lines =<< trim END
210 vim9script
211 let name: string = 'bob'
212 def Concat(arg: string): string
213 return name .. arg
214 enddef
215 let g:result = Concat('bie')
216 let g:localname = name
217
218 export const CONST = 1234
219 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100220 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100221 export def Exported(): string
222 return 'Exported'
223 enddef
224END
225
226def Test_vim9script()
227 let import_script_lines =<< trim END
228 vim9script
229 import {exported, Exported} from './Xexport.vim'
230 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100231 exported += 3
232 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100233 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100234
235 import {exp_name} from './Xexport.vim'
236 g:imported_name = exp_name
237 exp_name ..= ' Doe'
238 g:imported_name_appended = exp_name
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100239 END
240
241 writefile(import_script_lines, 'Ximport.vim')
242 writefile(s:export_script_lines, 'Xexport.vim')
243
244 source Ximport.vim
245
246 assert_equal('bobbie', g:result)
247 assert_equal('bob', g:localname)
248 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100249 assert_equal(9879, g:imported_added)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100250 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100251 assert_equal('John', g:imported_name)
252 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100253 assert_false(exists('g:name'))
254
255 unlet g:result
256 unlet g:localname
257 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100258 unlet g:imported_added
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100259 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100260 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100261 delete('Ximport.vim')
262 delete('Xexport.vim')
263
264 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
265 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
266enddef
267
268def Test_vim9script_call()
269 let lines =<< trim END
270 vim9script
271 let var = ''
272 def MyFunc(arg: string)
273 var = arg
274 enddef
275 MyFunc('foobar')
276 assert_equal('foobar', var)
277
278 let str = 'barfoo'
279 str->MyFunc()
280 assert_equal('barfoo', var)
281
282 let g:value = 'value'
283 g:value->MyFunc()
284 assert_equal('value', var)
285
286 let listvar = []
287 def ListFunc(arg: list<number>)
288 listvar = arg
289 enddef
290 [1, 2, 3]->ListFunc()
291 assert_equal([1, 2, 3], listvar)
292
293 let dictvar = {}
294 def DictFunc(arg: dict<number>)
295 dictvar = arg
296 enddef
297 {'a': 1, 'b': 2}->DictFunc()
298 assert_equal(#{a: 1, b: 2}, dictvar)
299 #{a: 3, b: 4}->DictFunc()
300 assert_equal(#{a: 3, b: 4}, dictvar)
301 END
302 writefile(lines, 'Xcall.vim')
303 source Xcall.vim
304 delete('Xcall.vim')
305enddef
306
307def Test_vim9script_call_fail_decl()
308 let lines =<< trim END
309 vim9script
310 let var = ''
311 def MyFunc(arg: string)
312 let var = 123
313 enddef
314 END
315 writefile(lines, 'Xcall_decl.vim')
316 assert_fails('source Xcall_decl.vim', 'E1054:')
317 delete('Xcall_decl.vim')
318enddef
319
320def Test_vim9script_call_fail_const()
321 let lines =<< trim END
322 vim9script
323 const var = ''
324 def MyFunc(arg: string)
325 var = 'asdf'
326 enddef
327 END
328 writefile(lines, 'Xcall_const.vim')
329 assert_fails('source Xcall_const.vim', 'E46:')
330 delete('Xcall_const.vim')
331enddef
332
333def Test_vim9script_reload()
334 let lines =<< trim END
335 vim9script
336 const var = ''
337 let valone = 1234
338 def MyFunc(arg: string)
339 valone = 5678
340 enddef
341 END
342 let morelines =<< trim END
343 let valtwo = 222
344 export def GetValtwo(): number
345 return valtwo
346 enddef
347 END
348 writefile(lines + morelines, 'Xreload.vim')
349 source Xreload.vim
350 source Xreload.vim
351 source Xreload.vim
352
353 let testlines =<< trim END
354 vim9script
355 def TheFunc()
356 import GetValtwo from './Xreload.vim'
357 assert_equal(222, GetValtwo())
358 enddef
359 TheFunc()
360 END
361 writefile(testlines, 'Ximport.vim')
362 source Ximport.vim
363
364 " test that when not using "morelines" valtwo is still defined
365 " need to source Xreload.vim again, import doesn't reload a script
366 writefile(lines, 'Xreload.vim')
367 source Xreload.vim
368 source Ximport.vim
369
370 " cannot declare a var twice
371 lines =<< trim END
372 vim9script
373 let valone = 1234
374 let valone = 5678
375 END
376 writefile(lines, 'Xreload.vim')
377 assert_fails('source Xreload.vim', 'E1041:')
378
379 delete('Xreload.vim')
380 delete('Ximport.vim')
381enddef
382
383def Test_import_absolute()
384 let import_lines = [
385 \ 'vim9script',
386 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100387 \ 'def UseExported()',
388 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100389 \ ' exported = 8888',
390 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100391 \ 'enddef',
392 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100393 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100394 \ ]
395 writefile(import_lines, 'Ximport_abs.vim')
396 writefile(s:export_script_lines, 'Xexport_abs.vim')
397
398 source Ximport_abs.vim
399
400 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100401 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100402 assert_match('<SNR>\d\+_UseExported.*'
403 \ .. 'g:imported_abs = exported.*'
404 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100405 \ .. '1 STOREG g:imported_abs.*'
406 \ .. 'exported = 8888.*'
407 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
408 \ .. 'g:imported_after = exported.*'
409 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
410 \ .. '5 STOREG g:imported_after.*'
411 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100412 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100413 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100414
415 delete('Ximport_abs.vim')
416 delete('Xexport_abs.vim')
417enddef
418
419def Test_import_rtp()
420 let import_lines = [
421 \ 'vim9script',
422 \ 'import exported from "Xexport_rtp.vim"',
423 \ 'g:imported_rtp = exported',
424 \ ]
425 writefile(import_lines, 'Ximport_rtp.vim')
426 mkdir('import')
427 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
428
429 let save_rtp = &rtp
430 &rtp = getcwd()
431 source Ximport_rtp.vim
432 &rtp = save_rtp
433
434 assert_equal(9876, g:imported_rtp)
435 unlet g:imported_rtp
436
437 delete('Ximport_rtp.vim')
438 delete('import/Xexport_rtp.vim')
439 delete('import', 'd')
440enddef
441
442def Test_fixed_size_list()
443 " will be allocated as one piece of memory, check that changes work
444 let l = [1, 2, 3, 4]
445 l->remove(0)
446 l->add(5)
447 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100448 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100449enddef
450
Bram Moolenaar673660a2020-01-26 16:50:05 +0100451" Test that inside :function a Python function can be defined, :def is not
452" recognized.
453func Test_function_python()
454 CheckFeature python3
455 let py = 'python3'
456 execute py "<< EOF"
457def do_something():
458 return 1
459EOF
460endfunc
461
Bram Moolenaar158906c2020-02-06 20:39:45 +0100462def IfElse(what: number): string
463 let res = ''
464 if what == 1
465 res = "one"
466 elseif what == 2
467 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100468 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100469 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100470 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100471 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100472enddef
473
Bram Moolenaar158906c2020-02-06 20:39:45 +0100474def Test_if_elseif_else()
475 assert_equal('one', IfElse(1))
476 assert_equal('two', IfElse(2))
477 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100478enddef
479
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100480
481" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker