blob: 107ee02450637116204d289e09b92e0a85af4910 [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
Bram Moolenaar436472f2020-02-20 22:54:43 +010043 let listS: list<string> = []
44 let listN: list<number> = []
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010045
46 let dict1: dict<string> = #{key: 'value'}
47 let dict2: dict<number> = #{one: 1, two: 2}
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010048
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010049 g:newvar = 'new'
50 assert_equal('new', g:newvar)
51
52 assert_equal('yes', g:existing)
53 g:existing = 'no'
54 assert_equal('no', g:existing)
55
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010056 v:char = 'abc'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010057 assert_equal('abc', v:char)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010058
59 $ENVVAR = 'foobar'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010060 assert_equal('foobar', $ENVVAR)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010061 $ENVVAR = ''
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010062
Bram Moolenaarfd1823e2020-02-19 20:23:11 +010063 s:appendToMe ..= 'yyy'
64 assert_equal('xxxyyy', s:appendToMe)
65 s:addToMe += 222
66 assert_equal(333, s:addToMe)
Bram Moolenaar0bbf7222020-02-19 22:31:48 +010067 s:newVar = 'new'
68 assert_equal('new', s:newVar)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010069enddef
70
71func Test_assignment_failure()
72 call CheckDefFailure(['let var=234'], 'E1004:')
73 call CheckDefFailure(['let var =234'], 'E1004:')
74 call CheckDefFailure(['let var= 234'], 'E1004:')
75
76 call CheckDefFailure(['let true = 1'], 'E1034:')
77 call CheckDefFailure(['let false = 1'], 'E1034:')
78
79 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
80 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
81
82 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
83 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
84
85 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
86 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
87endfunc
88
89func Test_const()
90 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
91 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
92 call CheckDefFailure(['const two'], 'E1021:')
93endfunc
94
95def Test_block()
96 let outer = 1
97 {
98 let inner = 2
99 assert_equal(1, outer)
100 assert_equal(2, inner)
101 }
102 assert_equal(1, outer)
103enddef
104
105func Test_block_failure()
106 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
107endfunc
108
109def ReturnString(): string
110 return 'string'
111enddef
112
113def ReturnNumber(): number
114 return 123
115enddef
116
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100117let g:notNumber = 'string'
118
119def ReturnGlobal(): number
120 return g:notNumber
121enddef
122
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100123def Test_return_string()
124 assert_equal('string', ReturnString())
125 assert_equal(123, ReturnNumber())
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100126 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100127enddef
128
129func Increment()
130 let g:counter += 1
131endfunc
132
133def Test_call_ufunc_count()
134 g:counter = 1
135 Increment()
136 Increment()
137 Increment()
138 " works with and without :call
139 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100140 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100141 unlet g:counter
142enddef
143
144def MyVarargs(arg: string, ...rest: list<string>): string
145 let res = arg
146 for s in rest
147 res ..= ',' .. s
148 endfor
149 return res
150enddef
151
152def Test_call_varargs()
153 assert_equal('one', MyVarargs('one'))
154 assert_equal('one,two', MyVarargs('one', 'two'))
155 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
156enddef
157
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100158def MyDefaultArgs(name = 'string'): string
159 return name
160enddef
161
162def Test_call_default_args()
163 assert_equal('string', MyDefaultArgs())
164 assert_equal('one', MyDefaultArgs('one'))
165 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
166enddef
167
168func Test_call_default_args_from_func()
169 call assert_equal('string', MyDefaultArgs())
170 call assert_equal('one', MyDefaultArgs('one'))
171 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
172endfunc
173
174" Default arg and varargs
175def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
176 let res = one .. ',' .. two
177 for s in rest
178 res ..= ',' .. s
179 endfor
180 return res
181enddef
182
183def Test_call_def_varargs()
184 call assert_fails('call MyDefVarargs()', 'E119:')
185 assert_equal('one,foo', MyDefVarargs('one'))
186 assert_equal('one,two', MyDefVarargs('one', 'two'))
187 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
188enddef
189
190
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100191"def Test_call_func_defined_later()
192" call assert_equal('one', DefineLater('one'))
193" call assert_fails('call NotDefined("one")', 'E99:')
194"enddef
195
196func DefineLater(arg)
197 return a:arg
198endfunc
199
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100200def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100201 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
202 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
203 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
204 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100205enddef
206
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100207def Test_arg_type_wrong()
208 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
209enddef
210
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100211def Test_try_catch()
212 let l = []
213 try
214 add(l, '1')
215 throw 'wrong'
216 add(l, '2')
217 catch
218 add(l, v:exception)
219 finally
220 add(l, '3')
221 endtry
222 assert_equal(['1', 'wrong', '3'], l)
223enddef
224
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100225def ThrowFromDef()
226 throw 'getout'
227enddef
228
229func CatchInFunc()
230 try
231 call ThrowFromDef()
232 catch
233 let g:thrown_func = v:exception
234 endtry
235endfunc
236
237def CatchInDef()
238 try
239 ThrowFromDef()
240 catch
241 g:thrown_def = v:exception
242 endtry
243enddef
244
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100245def ReturnFinally(): string
246 try
247 return 'intry'
248 finally
249 g:in_finally = 'finally'
250 endtry
251 return 'end'
252enddef
253
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100254def Test_try_catch_nested()
255 CatchInFunc()
256 assert_equal('getout', g:thrown_func)
257
258 CatchInDef()
259 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100260
261 assert_equal('intry', ReturnFinally())
262 assert_equal('finally', g:in_finally)
263enddef
264
265def Test_try_catch_match()
266 let seq = 'a'
267 try
268 throw 'something'
269 catch /nothing/
270 seq ..= 'x'
271 catch /some/
272 seq ..= 'b'
273 catch /asdf/
274 seq ..= 'x'
275 finally
276 seq ..= 'c'
277 endtry
278 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100279enddef
280
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100281let s:export_script_lines =<< trim END
282 vim9script
283 let name: string = 'bob'
284 def Concat(arg: string): string
285 return name .. arg
286 enddef
287 let g:result = Concat('bie')
288 let g:localname = name
289
290 export const CONST = 1234
291 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100292 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100293 export def Exported(): string
294 return 'Exported'
295 enddef
296END
297
298def Test_vim9script()
299 let import_script_lines =<< trim END
300 vim9script
301 import {exported, Exported} from './Xexport.vim'
302 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100303 exported += 3
304 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100305 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100306
307 import {exp_name} from './Xexport.vim'
308 g:imported_name = exp_name
309 exp_name ..= ' Doe'
310 g:imported_name_appended = exp_name
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100311 END
312
313 writefile(import_script_lines, 'Ximport.vim')
314 writefile(s:export_script_lines, 'Xexport.vim')
315
316 source Ximport.vim
317
318 assert_equal('bobbie', g:result)
319 assert_equal('bob', g:localname)
320 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100321 assert_equal(9879, g:imported_added)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100322 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100323 assert_equal('John', g:imported_name)
324 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100325 assert_false(exists('g:name'))
326
327 unlet g:result
328 unlet g:localname
329 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100330 unlet g:imported_added
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100331 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100332 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100333 delete('Ximport.vim')
334 delete('Xexport.vim')
335
336 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
337 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
338enddef
339
340def Test_vim9script_call()
341 let lines =<< trim END
342 vim9script
343 let var = ''
344 def MyFunc(arg: string)
345 var = arg
346 enddef
347 MyFunc('foobar')
348 assert_equal('foobar', var)
349
350 let str = 'barfoo'
351 str->MyFunc()
352 assert_equal('barfoo', var)
353
354 let g:value = 'value'
355 g:value->MyFunc()
356 assert_equal('value', var)
357
358 let listvar = []
359 def ListFunc(arg: list<number>)
360 listvar = arg
361 enddef
362 [1, 2, 3]->ListFunc()
363 assert_equal([1, 2, 3], listvar)
364
365 let dictvar = {}
366 def DictFunc(arg: dict<number>)
367 dictvar = arg
368 enddef
369 {'a': 1, 'b': 2}->DictFunc()
370 assert_equal(#{a: 1, b: 2}, dictvar)
371 #{a: 3, b: 4}->DictFunc()
372 assert_equal(#{a: 3, b: 4}, dictvar)
373 END
374 writefile(lines, 'Xcall.vim')
375 source Xcall.vim
376 delete('Xcall.vim')
377enddef
378
379def Test_vim9script_call_fail_decl()
380 let lines =<< trim END
381 vim9script
382 let var = ''
383 def MyFunc(arg: string)
384 let var = 123
385 enddef
386 END
387 writefile(lines, 'Xcall_decl.vim')
388 assert_fails('source Xcall_decl.vim', 'E1054:')
389 delete('Xcall_decl.vim')
390enddef
391
392def Test_vim9script_call_fail_const()
393 let lines =<< trim END
394 vim9script
395 const var = ''
396 def MyFunc(arg: string)
397 var = 'asdf'
398 enddef
399 END
400 writefile(lines, 'Xcall_const.vim')
401 assert_fails('source Xcall_const.vim', 'E46:')
402 delete('Xcall_const.vim')
403enddef
404
405def Test_vim9script_reload()
406 let lines =<< trim END
407 vim9script
408 const var = ''
409 let valone = 1234
410 def MyFunc(arg: string)
411 valone = 5678
412 enddef
413 END
414 let morelines =<< trim END
415 let valtwo = 222
416 export def GetValtwo(): number
417 return valtwo
418 enddef
419 END
420 writefile(lines + morelines, 'Xreload.vim')
421 source Xreload.vim
422 source Xreload.vim
423 source Xreload.vim
424
425 let testlines =<< trim END
426 vim9script
427 def TheFunc()
428 import GetValtwo from './Xreload.vim'
429 assert_equal(222, GetValtwo())
430 enddef
431 TheFunc()
432 END
433 writefile(testlines, 'Ximport.vim')
434 source Ximport.vim
435
436 " test that when not using "morelines" valtwo is still defined
437 " need to source Xreload.vim again, import doesn't reload a script
438 writefile(lines, 'Xreload.vim')
439 source Xreload.vim
440 source Ximport.vim
441
442 " cannot declare a var twice
443 lines =<< trim END
444 vim9script
445 let valone = 1234
446 let valone = 5678
447 END
448 writefile(lines, 'Xreload.vim')
449 assert_fails('source Xreload.vim', 'E1041:')
450
451 delete('Xreload.vim')
452 delete('Ximport.vim')
453enddef
454
455def Test_import_absolute()
456 let import_lines = [
457 \ 'vim9script',
458 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100459 \ 'def UseExported()',
460 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100461 \ ' exported = 8888',
462 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100463 \ 'enddef',
464 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100465 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100466 \ ]
467 writefile(import_lines, 'Ximport_abs.vim')
468 writefile(s:export_script_lines, 'Xexport_abs.vim')
469
470 source Ximport_abs.vim
471
472 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100473 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100474 assert_match('<SNR>\d\+_UseExported.*'
475 \ .. 'g:imported_abs = exported.*'
476 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100477 \ .. '1 STOREG g:imported_abs.*'
478 \ .. 'exported = 8888.*'
479 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
480 \ .. 'g:imported_after = exported.*'
481 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
482 \ .. '5 STOREG g:imported_after.*'
483 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100484 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100485 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100486
487 delete('Ximport_abs.vim')
488 delete('Xexport_abs.vim')
489enddef
490
491def Test_import_rtp()
492 let import_lines = [
493 \ 'vim9script',
494 \ 'import exported from "Xexport_rtp.vim"',
495 \ 'g:imported_rtp = exported',
496 \ ]
497 writefile(import_lines, 'Ximport_rtp.vim')
498 mkdir('import')
499 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
500
501 let save_rtp = &rtp
502 &rtp = getcwd()
503 source Ximport_rtp.vim
504 &rtp = save_rtp
505
506 assert_equal(9876, g:imported_rtp)
507 unlet g:imported_rtp
508
509 delete('Ximport_rtp.vim')
510 delete('import/Xexport_rtp.vim')
511 delete('import', 'd')
512enddef
513
514def Test_fixed_size_list()
515 " will be allocated as one piece of memory, check that changes work
516 let l = [1, 2, 3, 4]
517 l->remove(0)
518 l->add(5)
519 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100520 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100521enddef
522
Bram Moolenaar673660a2020-01-26 16:50:05 +0100523" Test that inside :function a Python function can be defined, :def is not
524" recognized.
525func Test_function_python()
526 CheckFeature python3
527 let py = 'python3'
528 execute py "<< EOF"
529def do_something():
530 return 1
531EOF
532endfunc
533
Bram Moolenaar158906c2020-02-06 20:39:45 +0100534def IfElse(what: number): string
535 let res = ''
536 if what == 1
537 res = "one"
538 elseif what == 2
539 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100540 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100541 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100542 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100543 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100544enddef
545
Bram Moolenaar158906c2020-02-06 20:39:45 +0100546def Test_if_elseif_else()
547 assert_equal('one', IfElse(1))
548 assert_equal('two', IfElse(2))
549 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100550enddef
551
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100552def Test_delfunc()
553 let lines =<< trim END
554 vim9script
555 def GoneSoon()
556 echo 'hello'
557 enddef
558
559 def CallGoneSoon()
560 GoneSoon()
561 enddef
562
563 delfunc GoneSoon
564 CallGoneSoon()
565 END
566 writefile(lines, 'XToDelFunc')
567 assert_fails('so XToDelFunc', 'E933')
568 assert_fails('so XToDelFunc', 'E933')
569
570 delete('XToDelFunc')
571enddef
572
Bram Moolenaar5b1c8fe2020-02-21 18:42:43 +0100573def Test_substitute_cmd()
574 new
575 setline(1, 'something')
576 :substitute(some(other(
577 assert_equal('otherthing', getline(1))
578enddef
579
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100580
581" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker