blob: ac721a80c6211835a3a791e2513d9a29078e4207 [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
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010032let g:existing = 'yes'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010033
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010034def Test_assignment()
35 let bool1: bool = true
36 assert_equal(v:true, bool1)
37 let bool2: bool = false
38 assert_equal(v:false, bool2)
39
40 let list1: list<string> = ['sdf', 'asdf']
41 let list2: list<number> = [1, 2, 3]
42
43 " TODO: does not work yet
44 " let listS: list<string> = []
45 " let listN: list<number> = []
46
47 let dict1: dict<string> = #{key: 'value'}
48 let dict2: dict<number> = #{one: 1, two: 2}
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010049
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010050 g:newvar = 'new'
51 assert_equal('new', g:newvar)
52
53 assert_equal('yes', g:existing)
54 g:existing = 'no'
55 assert_equal('no', g:existing)
56
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010057 v:char = 'abc'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010058 assert_equal('abc', v:char)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010059
60 $ENVVAR = 'foobar'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010061 assert_equal('foobar', $ENVVAR)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010062 $ENVVAR = ''
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010063
Bram Moolenaarfd1823e2020-02-19 20:23:11 +010064 s:appendToMe ..= 'yyy'
65 assert_equal('xxxyyy', s:appendToMe)
66 s:addToMe += 222
67 assert_equal(333, s:addToMe)
Bram Moolenaar0bbf7222020-02-19 22:31:48 +010068 s:newVar = 'new'
69 assert_equal('new', s:newVar)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010070enddef
71
72func Test_assignment_failure()
73 call CheckDefFailure(['let var=234'], 'E1004:')
74 call CheckDefFailure(['let var =234'], 'E1004:')
75 call CheckDefFailure(['let var= 234'], 'E1004:')
76
77 call CheckDefFailure(['let true = 1'], 'E1034:')
78 call CheckDefFailure(['let false = 1'], 'E1034:')
79
80 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
81 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
82
83 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
84 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
85
86 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
87 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
88endfunc
89
90func Test_const()
91 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
92 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
93 call CheckDefFailure(['const two'], 'E1021:')
94endfunc
95
96def Test_block()
97 let outer = 1
98 {
99 let inner = 2
100 assert_equal(1, outer)
101 assert_equal(2, inner)
102 }
103 assert_equal(1, outer)
104enddef
105
106func Test_block_failure()
107 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
108endfunc
109
110def ReturnString(): string
111 return 'string'
112enddef
113
114def ReturnNumber(): number
115 return 123
116enddef
117
118def Test_return_string()
119 assert_equal('string', ReturnString())
120 assert_equal(123, ReturnNumber())
121enddef
122
123func Increment()
124 let g:counter += 1
125endfunc
126
127def Test_call_ufunc_count()
128 g:counter = 1
129 Increment()
130 Increment()
131 Increment()
132 " works with and without :call
133 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100134 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100135 unlet g:counter
136enddef
137
138def MyVarargs(arg: string, ...rest: list<string>): string
139 let res = arg
140 for s in rest
141 res ..= ',' .. s
142 endfor
143 return res
144enddef
145
146def Test_call_varargs()
147 assert_equal('one', MyVarargs('one'))
148 assert_equal('one,two', MyVarargs('one', 'two'))
149 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
150enddef
151
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100152def MyDefaultArgs(name = 'string'): string
153 return name
154enddef
155
156def Test_call_default_args()
157 assert_equal('string', MyDefaultArgs())
158 assert_equal('one', MyDefaultArgs('one'))
159 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
160enddef
161
162func Test_call_default_args_from_func()
163 call assert_equal('string', MyDefaultArgs())
164 call assert_equal('one', MyDefaultArgs('one'))
165 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
166endfunc
167
168" Default arg and varargs
169def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
170 let res = one .. ',' .. two
171 for s in rest
172 res ..= ',' .. s
173 endfor
174 return res
175enddef
176
177def Test_call_def_varargs()
178 call assert_fails('call MyDefVarargs()', 'E119:')
179 assert_equal('one,foo', MyDefVarargs('one'))
180 assert_equal('one,two', MyDefVarargs('one', 'two'))
181 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
182enddef
183
184
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100185"def Test_call_func_defined_later()
186" call assert_equal('one', DefineLater('one'))
187" call assert_fails('call NotDefined("one")', 'E99:')
188"enddef
189
190func DefineLater(arg)
191 return a:arg
192endfunc
193
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100194def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100195 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
196 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
197 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
198 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100199enddef
200
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100201def Test_arg_type_wrong()
202 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
203enddef
204
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100205def Test_try_catch()
206 let l = []
207 try
208 add(l, '1')
209 throw 'wrong'
210 add(l, '2')
211 catch
212 add(l, v:exception)
213 finally
214 add(l, '3')
215 endtry
216 assert_equal(['1', 'wrong', '3'], l)
217enddef
218
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100219def ThrowFromDef()
220 throw 'getout'
221enddef
222
223func CatchInFunc()
224 try
225 call ThrowFromDef()
226 catch
227 let g:thrown_func = v:exception
228 endtry
229endfunc
230
231def CatchInDef()
232 try
233 ThrowFromDef()
234 catch
235 g:thrown_def = v:exception
236 endtry
237enddef
238
239def Test_try_catch_nested()
240 CatchInFunc()
241 assert_equal('getout', g:thrown_func)
242
243 CatchInDef()
244 assert_equal('getout', g:thrown_def)
245enddef
246
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100247let s:export_script_lines =<< trim END
248 vim9script
249 let name: string = 'bob'
250 def Concat(arg: string): string
251 return name .. arg
252 enddef
253 let g:result = Concat('bie')
254 let g:localname = name
255
256 export const CONST = 1234
257 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100258 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100259 export def Exported(): string
260 return 'Exported'
261 enddef
262END
263
264def Test_vim9script()
265 let import_script_lines =<< trim END
266 vim9script
267 import {exported, Exported} from './Xexport.vim'
268 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100269 exported += 3
270 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100271 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100272
273 import {exp_name} from './Xexport.vim'
274 g:imported_name = exp_name
275 exp_name ..= ' Doe'
276 g:imported_name_appended = exp_name
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100277 END
278
279 writefile(import_script_lines, 'Ximport.vim')
280 writefile(s:export_script_lines, 'Xexport.vim')
281
282 source Ximport.vim
283
284 assert_equal('bobbie', g:result)
285 assert_equal('bob', g:localname)
286 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100287 assert_equal(9879, g:imported_added)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100288 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100289 assert_equal('John', g:imported_name)
290 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100291 assert_false(exists('g:name'))
292
293 unlet g:result
294 unlet g:localname
295 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100296 unlet g:imported_added
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100297 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100298 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100299 delete('Ximport.vim')
300 delete('Xexport.vim')
301
302 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
303 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
304enddef
305
306def Test_vim9script_call()
307 let lines =<< trim END
308 vim9script
309 let var = ''
310 def MyFunc(arg: string)
311 var = arg
312 enddef
313 MyFunc('foobar')
314 assert_equal('foobar', var)
315
316 let str = 'barfoo'
317 str->MyFunc()
318 assert_equal('barfoo', var)
319
320 let g:value = 'value'
321 g:value->MyFunc()
322 assert_equal('value', var)
323
324 let listvar = []
325 def ListFunc(arg: list<number>)
326 listvar = arg
327 enddef
328 [1, 2, 3]->ListFunc()
329 assert_equal([1, 2, 3], listvar)
330
331 let dictvar = {}
332 def DictFunc(arg: dict<number>)
333 dictvar = arg
334 enddef
335 {'a': 1, 'b': 2}->DictFunc()
336 assert_equal(#{a: 1, b: 2}, dictvar)
337 #{a: 3, b: 4}->DictFunc()
338 assert_equal(#{a: 3, b: 4}, dictvar)
339 END
340 writefile(lines, 'Xcall.vim')
341 source Xcall.vim
342 delete('Xcall.vim')
343enddef
344
345def Test_vim9script_call_fail_decl()
346 let lines =<< trim END
347 vim9script
348 let var = ''
349 def MyFunc(arg: string)
350 let var = 123
351 enddef
352 END
353 writefile(lines, 'Xcall_decl.vim')
354 assert_fails('source Xcall_decl.vim', 'E1054:')
355 delete('Xcall_decl.vim')
356enddef
357
358def Test_vim9script_call_fail_const()
359 let lines =<< trim END
360 vim9script
361 const var = ''
362 def MyFunc(arg: string)
363 var = 'asdf'
364 enddef
365 END
366 writefile(lines, 'Xcall_const.vim')
367 assert_fails('source Xcall_const.vim', 'E46:')
368 delete('Xcall_const.vim')
369enddef
370
371def Test_vim9script_reload()
372 let lines =<< trim END
373 vim9script
374 const var = ''
375 let valone = 1234
376 def MyFunc(arg: string)
377 valone = 5678
378 enddef
379 END
380 let morelines =<< trim END
381 let valtwo = 222
382 export def GetValtwo(): number
383 return valtwo
384 enddef
385 END
386 writefile(lines + morelines, 'Xreload.vim')
387 source Xreload.vim
388 source Xreload.vim
389 source Xreload.vim
390
391 let testlines =<< trim END
392 vim9script
393 def TheFunc()
394 import GetValtwo from './Xreload.vim'
395 assert_equal(222, GetValtwo())
396 enddef
397 TheFunc()
398 END
399 writefile(testlines, 'Ximport.vim')
400 source Ximport.vim
401
402 " test that when not using "morelines" valtwo is still defined
403 " need to source Xreload.vim again, import doesn't reload a script
404 writefile(lines, 'Xreload.vim')
405 source Xreload.vim
406 source Ximport.vim
407
408 " cannot declare a var twice
409 lines =<< trim END
410 vim9script
411 let valone = 1234
412 let valone = 5678
413 END
414 writefile(lines, 'Xreload.vim')
415 assert_fails('source Xreload.vim', 'E1041:')
416
417 delete('Xreload.vim')
418 delete('Ximport.vim')
419enddef
420
421def Test_import_absolute()
422 let import_lines = [
423 \ 'vim9script',
424 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100425 \ 'def UseExported()',
426 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100427 \ ' exported = 8888',
428 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100429 \ 'enddef',
430 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100431 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100432 \ ]
433 writefile(import_lines, 'Ximport_abs.vim')
434 writefile(s:export_script_lines, 'Xexport_abs.vim')
435
436 source Ximport_abs.vim
437
438 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100439 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100440 assert_match('<SNR>\d\+_UseExported.*'
441 \ .. 'g:imported_abs = exported.*'
442 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100443 \ .. '1 STOREG g:imported_abs.*'
444 \ .. 'exported = 8888.*'
445 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
446 \ .. 'g:imported_after = exported.*'
447 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
448 \ .. '5 STOREG g:imported_after.*'
449 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100450 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100451 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100452
453 delete('Ximport_abs.vim')
454 delete('Xexport_abs.vim')
455enddef
456
457def Test_import_rtp()
458 let import_lines = [
459 \ 'vim9script',
460 \ 'import exported from "Xexport_rtp.vim"',
461 \ 'g:imported_rtp = exported',
462 \ ]
463 writefile(import_lines, 'Ximport_rtp.vim')
464 mkdir('import')
465 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
466
467 let save_rtp = &rtp
468 &rtp = getcwd()
469 source Ximport_rtp.vim
470 &rtp = save_rtp
471
472 assert_equal(9876, g:imported_rtp)
473 unlet g:imported_rtp
474
475 delete('Ximport_rtp.vim')
476 delete('import/Xexport_rtp.vim')
477 delete('import', 'd')
478enddef
479
480def Test_fixed_size_list()
481 " will be allocated as one piece of memory, check that changes work
482 let l = [1, 2, 3, 4]
483 l->remove(0)
484 l->add(5)
485 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100486 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100487enddef
488
Bram Moolenaar673660a2020-01-26 16:50:05 +0100489" Test that inside :function a Python function can be defined, :def is not
490" recognized.
491func Test_function_python()
492 CheckFeature python3
493 let py = 'python3'
494 execute py "<< EOF"
495def do_something():
496 return 1
497EOF
498endfunc
499
Bram Moolenaar158906c2020-02-06 20:39:45 +0100500def IfElse(what: number): string
501 let res = ''
502 if what == 1
503 res = "one"
504 elseif what == 2
505 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100506 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100507 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100508 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100509 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100510enddef
511
Bram Moolenaar158906c2020-02-06 20:39:45 +0100512def Test_if_elseif_else()
513 assert_equal('one', IfElse(1))
514 assert_equal('two', IfElse(2))
515 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100516enddef
517
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100518def Test_delfunc()
519 let lines =<< trim END
520 vim9script
521 def GoneSoon()
522 echo 'hello'
523 enddef
524
525 def CallGoneSoon()
526 GoneSoon()
527 enddef
528
529 delfunc GoneSoon
530 CallGoneSoon()
531 END
532 writefile(lines, 'XToDelFunc')
533 assert_fails('so XToDelFunc', 'E933')
534 assert_fails('so XToDelFunc', 'E933')
535
536 delete('XToDelFunc')
537enddef
538
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100539
540" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker