blob: a02855d1e9398a9749ecc9c78821e30170a35dda [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
Bram Moolenaarad39c092020-02-26 18:23:43 +01004source view_util.vim
Bram Moolenaar673660a2020-01-26 16:50:05 +01005
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01006" Check that "lines" inside ":def" results in an "error" message.
7func CheckDefFailure(lines, error)
Bram Moolenaar978d1702020-01-26 17:38:12 +01008 call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01009 call assert_fails('so Xdef', a:error, a:lines)
10 call delete('Xdef')
11endfunc
12
13func CheckScriptFailure(lines, error)
14 call writefile(a:lines, 'Xdef')
15 call assert_fails('so Xdef', a:error, a:lines)
16 call delete('Xdef')
17endfunc
18
19def Test_syntax()
20 let var = 234
21 let other: list<string> = ['asdf']
22enddef
23
24func Test_def_basic()
25 def SomeFunc(): string
26 return 'yes'
27 enddef
28 call assert_equal('yes', SomeFunc())
29endfunc
30
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010031let s:appendToMe = 'xxx'
32let s:addToMe = 111
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010033let g:existing = 'yes'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010034
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010035def Test_assignment()
36 let bool1: bool = true
37 assert_equal(v:true, bool1)
38 let bool2: bool = false
39 assert_equal(v:false, bool2)
40
Bram Moolenaar0c2ca582020-02-25 22:58:29 +010041 let list1: list<bool> = [false, true, false]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010042 let list2: list<number> = [1, 2, 3]
Bram Moolenaar0c2ca582020-02-25 22:58:29 +010043 let list3: list<string> = ['sdf', 'asdf']
44 let list4: list<any> = ['yes', true, 1234]
45 let list5: list<blob> = [0z01, 0z02]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010046
Bram Moolenaar436472f2020-02-20 22:54:43 +010047 let listS: list<string> = []
48 let listN: list<number> = []
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010049
Bram Moolenaar0c2ca582020-02-25 22:58:29 +010050 let dict1: dict<bool> = #{one: false, two: true}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010051 let dict2: dict<number> = #{one: 1, two: 2}
Bram Moolenaar0c2ca582020-02-25 22:58:29 +010052 let dict3: dict<string> = #{key: 'value'}
53 let dict4: dict<any> = #{one: 1, two: '2'}
54 let dict5: dict<blob> = #{one: 0z01, tw: 0z02}
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010055
Bram Moolenaar42a480b2020-02-29 23:23:47 +010056 if has('channel')
57 let chan1: channel
Bram Moolenaarfbdd08e2020-03-01 14:04:46 +010058 let job1: job
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +010059 let job2: job = job_start('willfail')
Bram Moolenaar42a480b2020-02-29 23:23:47 +010060 endif
Bram Moolenaarfbdd08e2020-03-01 14:04:46 +010061 if has('float')
62 let float1: float = 3.4
63 endif
Bram Moolenaar087d2e12020-03-01 15:36:42 +010064 let funky1: func
65 let funky2: func = function('len')
66 let party1: partial
67 let party2: partial = funcref('Test_syntax')
Bram Moolenaar42a480b2020-02-29 23:23:47 +010068
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +010069 " type becomes list<any>
70 let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
Bram Moolenaar5381c7a2020-03-02 22:53:32 +010071 " type becomes dict<any>
72 let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +010073
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010074 g:newvar = 'new'
75 assert_equal('new', g:newvar)
76
77 assert_equal('yes', g:existing)
78 g:existing = 'no'
79 assert_equal('no', g:existing)
80
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010081 v:char = 'abc'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010082 assert_equal('abc', v:char)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010083
84 $ENVVAR = 'foobar'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010085 assert_equal('foobar', $ENVVAR)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010086 $ENVVAR = ''
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010087
Bram Moolenaarfd1823e2020-02-19 20:23:11 +010088 s:appendToMe ..= 'yyy'
89 assert_equal('xxxyyy', s:appendToMe)
90 s:addToMe += 222
91 assert_equal(333, s:addToMe)
Bram Moolenaar0bbf7222020-02-19 22:31:48 +010092 s:newVar = 'new'
93 assert_equal('new', s:newVar)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010094enddef
95
96func Test_assignment_failure()
97 call CheckDefFailure(['let var=234'], 'E1004:')
98 call CheckDefFailure(['let var =234'], 'E1004:')
99 call CheckDefFailure(['let var= 234'], 'E1004:')
100
101 call CheckDefFailure(['let true = 1'], 'E1034:')
102 call CheckDefFailure(['let false = 1'], 'E1034:')
103
104 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
105 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
106
107 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
108 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
109
110 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
111 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100112
113 call CheckDefFailure(['let var: dict <number>'], 'E1007:')
114 call CheckDefFailure(['let var: dict<number'], 'E1009:')
115
116 call CheckDefFailure(['let var: ally'], 'E1010:')
117 call CheckDefFailure(['let var: bram'], 'E1010:')
118 call CheckDefFailure(['let var: cathy'], 'E1010:')
119 call CheckDefFailure(['let var: dom'], 'E1010:')
120 call CheckDefFailure(['let var: freddy'], 'E1010:')
121 call CheckDefFailure(['let var: john'], 'E1010:')
122 call CheckDefFailure(['let var: larry'], 'E1010:')
123 call CheckDefFailure(['let var: ned'], 'E1010:')
124 call CheckDefFailure(['let var: pam'], 'E1010:')
125 call CheckDefFailure(['let var: sam'], 'E1010:')
126 call CheckDefFailure(['let var: vim'], 'E1010:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100127endfunc
128
129func Test_const()
130 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
131 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
132 call CheckDefFailure(['const two'], 'E1021:')
133endfunc
134
135def Test_block()
136 let outer = 1
137 {
138 let inner = 2
139 assert_equal(1, outer)
140 assert_equal(2, inner)
141 }
142 assert_equal(1, outer)
143enddef
144
145func Test_block_failure()
146 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
147endfunc
148
149def ReturnString(): string
150 return 'string'
151enddef
152
153def ReturnNumber(): number
154 return 123
155enddef
156
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100157let g:notNumber = 'string'
158
159def ReturnGlobal(): number
160 return g:notNumber
161enddef
162
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100163def Test_return_string()
164 assert_equal('string', ReturnString())
165 assert_equal(123, ReturnNumber())
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100166 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100167enddef
168
169func Increment()
170 let g:counter += 1
171endfunc
172
173def Test_call_ufunc_count()
174 g:counter = 1
175 Increment()
176 Increment()
177 Increment()
178 " works with and without :call
179 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100180 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100181 unlet g:counter
182enddef
183
184def MyVarargs(arg: string, ...rest: list<string>): string
185 let res = arg
186 for s in rest
187 res ..= ',' .. s
188 endfor
189 return res
190enddef
191
192def Test_call_varargs()
193 assert_equal('one', MyVarargs('one'))
194 assert_equal('one,two', MyVarargs('one', 'two'))
195 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
196enddef
197
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100198def MyDefaultArgs(name = 'string'): string
199 return name
200enddef
201
202def Test_call_default_args()
203 assert_equal('string', MyDefaultArgs())
204 assert_equal('one', MyDefaultArgs('one'))
205 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
206enddef
207
208func Test_call_default_args_from_func()
209 call assert_equal('string', MyDefaultArgs())
210 call assert_equal('one', MyDefaultArgs('one'))
211 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
212endfunc
213
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100214func TakesOneArg(arg)
215 echo a:arg
216endfunc
217
218def Test_call_wrong_arg_count()
219 call CheckDefFailure(['TakesOneArg()'], 'E119:')
220 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
221enddef
222
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100223" Default arg and varargs
224def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
225 let res = one .. ',' .. two
226 for s in rest
227 res ..= ',' .. s
228 endfor
229 return res
230enddef
231
232def Test_call_def_varargs()
233 call assert_fails('call MyDefVarargs()', 'E119:')
234 assert_equal('one,foo', MyDefVarargs('one'))
235 assert_equal('one,two', MyDefVarargs('one', 'two'))
236 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
237enddef
238
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100239def Test_using_var_as_arg()
240 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
241 call assert_fails('so Xdef', 'E1006:')
242 call delete('Xdef')
243enddef
244
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100245def Test_call_func_defined_later()
246 call assert_equal('one', DefinedLater('one'))
247 call assert_fails('call NotDefined("one")', 'E117:')
248enddef
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100249
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100250func DefinedLater(arg)
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100251 return a:arg
252endfunc
253
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100254def FuncWithForwardCall()
255 return DefinedEvenLater("yes")
256enddef
257
258def DefinedEvenLater(arg: string): string
259 return arg
260enddef
261
262def Test_error_in_nested_function()
263 " Error in called function requires unwinding the call stack.
264 assert_fails('call FuncWithForwardCall()', 'E1029')
265enddef
266
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100267def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100268 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
269 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
270 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
271 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100272enddef
273
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100274def Test_arg_type_wrong()
275 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
276enddef
277
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100278def Test_try_catch()
279 let l = []
280 try
281 add(l, '1')
282 throw 'wrong'
283 add(l, '2')
284 catch
285 add(l, v:exception)
286 finally
287 add(l, '3')
288 endtry
289 assert_equal(['1', 'wrong', '3'], l)
290enddef
291
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100292def ThrowFromDef()
293 throw 'getout'
294enddef
295
296func CatchInFunc()
297 try
298 call ThrowFromDef()
299 catch
300 let g:thrown_func = v:exception
301 endtry
302endfunc
303
304def CatchInDef()
305 try
306 ThrowFromDef()
307 catch
308 g:thrown_def = v:exception
309 endtry
310enddef
311
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100312def ReturnFinally(): string
313 try
314 return 'intry'
315 finally
316 g:in_finally = 'finally'
317 endtry
318 return 'end'
319enddef
320
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100321def Test_try_catch_nested()
322 CatchInFunc()
323 assert_equal('getout', g:thrown_func)
324
325 CatchInDef()
326 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100327
328 assert_equal('intry', ReturnFinally())
329 assert_equal('finally', g:in_finally)
330enddef
331
332def Test_try_catch_match()
333 let seq = 'a'
334 try
335 throw 'something'
336 catch /nothing/
337 seq ..= 'x'
338 catch /some/
339 seq ..= 'b'
340 catch /asdf/
341 seq ..= 'x'
342 finally
343 seq ..= 'c'
344 endtry
345 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100346enddef
347
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100348let s:export_script_lines =<< trim END
349 vim9script
350 let name: string = 'bob'
351 def Concat(arg: string): string
352 return name .. arg
353 enddef
354 let g:result = Concat('bie')
355 let g:localname = name
356
357 export const CONST = 1234
358 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100359 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100360 export def Exported(): string
361 return 'Exported'
362 enddef
363END
364
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100365def Test_vim9_import_export()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100366 let import_script_lines =<< trim END
367 vim9script
368 import {exported, Exported} from './Xexport.vim'
369 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100370 exported += 3
371 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100372 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100373
374 import {exp_name} from './Xexport.vim'
375 g:imported_name = exp_name
376 exp_name ..= ' Doe'
377 g:imported_name_appended = exp_name
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100378 g:imported_later = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100379 END
380
381 writefile(import_script_lines, 'Ximport.vim')
382 writefile(s:export_script_lines, 'Xexport.vim')
383
384 source Ximport.vim
385
386 assert_equal('bobbie', g:result)
387 assert_equal('bob', g:localname)
388 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100389 assert_equal(9879, g:imported_added)
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100390 assert_equal(9879, g:imported_later)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100391 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100392 assert_equal('John', g:imported_name)
393 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100394 assert_false(exists('g:name'))
395
396 unlet g:result
397 unlet g:localname
398 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100399 unlet g:imported_added
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100400 unlet g:imported_later
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100401 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100402 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100403 delete('Ximport.vim')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100404
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100405 let import_in_def_lines =<< trim END
406 vim9script
407 def ImportInDef()
408 import exported from './Xexport.vim'
409 g:imported = exported
410 exported += 7
411 g:imported_added = exported
412 enddef
413 ImportInDef()
414 END
415 writefile(import_in_def_lines, 'Ximport2.vim')
416 source Ximport2.vim
417 " TODO: this should be 9879
418 assert_equal(9876, g:imported)
419 assert_equal(9883, g:imported_added)
420 unlet g:imported
421 unlet g:imported_added
422 delete('Ximport2.vim')
423
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100424 let import_star_as_lines =<< trim END
425 vim9script
426 import * as Export from './Xexport.vim'
427 def UseExport()
428 g:imported = Export.exported
429 enddef
430 UseExport()
431 END
432 writefile(import_star_as_lines, 'Ximport.vim')
433 source Ximport.vim
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100434 assert_equal(9883, g:imported)
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100435
436 let import_star_lines =<< trim END
437 vim9script
438 import * from './Xexport.vim'
439 g:imported = exported
440 END
441 writefile(import_star_lines, 'Ximport.vim')
442 assert_fails('source Ximport.vim', 'E1045:')
443
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100444 " try to import something that exists but is not exported
445 let import_not_exported_lines =<< trim END
446 vim9script
447 import name from './Xexport.vim'
448 END
449 writefile(import_not_exported_lines, 'Ximport.vim')
450 assert_fails('source Ximport.vim', 'E1049:')
451
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100452 " try to import something that is already defined
453 let import_already_defined =<< trim END
454 vim9script
455 let exported = 'something'
456 import exported from './Xexport.vim'
457 END
458 writefile(import_already_defined, 'Ximport.vim')
459 assert_fails('source Ximport.vim', 'E1073:')
460
461 " try to import something that is already defined
462 import_already_defined =<< trim END
463 vim9script
464 let exported = 'something'
465 import * as exported from './Xexport.vim'
466 END
467 writefile(import_already_defined, 'Ximport.vim')
468 assert_fails('source Ximport.vim', 'E1073:')
469
470 " try to import something that is already defined
471 import_already_defined =<< trim END
472 vim9script
473 let exported = 'something'
474 import {exported} from './Xexport.vim'
475 END
476 writefile(import_already_defined, 'Ximport.vim')
477 assert_fails('source Ximport.vim', 'E1073:')
478
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100479 " import a very long name, requires making a copy
480 let import_long_name_lines =<< trim END
481 vim9script
482 import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
483 END
484 writefile(import_long_name_lines, 'Ximport.vim')
485 assert_fails('source Ximport.vim', 'E1048:')
486
487 let import_no_from_lines =<< trim END
488 vim9script
489 import name './Xexport.vim'
490 END
491 writefile(import_no_from_lines, 'Ximport.vim')
492 assert_fails('source Ximport.vim', 'E1070:')
493
494 let import_invalid_string_lines =<< trim END
495 vim9script
496 import name from Xexport.vim
497 END
498 writefile(import_invalid_string_lines, 'Ximport.vim')
499 assert_fails('source Ximport.vim', 'E1071:')
500
501 let import_wrong_name_lines =<< trim END
502 vim9script
503 import name from './XnoExport.vim'
504 END
505 writefile(import_wrong_name_lines, 'Ximport.vim')
506 assert_fails('source Ximport.vim', 'E1053:')
507
508 let import_missing_comma_lines =<< trim END
509 vim9script
510 import {exported name} from './Xexport.vim'
511 END
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100512 writefile(import_missing_comma_lines, 'Ximport3.vim')
513 assert_fails('source Ximport3.vim', 'E1046:')
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100514
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100515 delete('Ximport.vim')
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100516 delete('Ximport3.vim')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100517 delete('Xexport.vim')
518
Bram Moolenaar750802b2020-02-23 18:08:33 +0100519 " Check that in a Vim9 script 'cpo' is set to the Vim default.
520 set cpo&vi
521 let cpo_before = &cpo
522 let lines =<< trim END
523 vim9script
524 g:cpo_in_vim9script = &cpo
525 END
526 writefile(lines, 'Xvim9_script')
527 source Xvim9_script
528 assert_equal(cpo_before, &cpo)
529 set cpo&vim
530 assert_equal(&cpo, g:cpo_in_vim9script)
531 delete('Xvim9_script')
532enddef
533
534def Test_vim9script_fails()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100535 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
536 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100537 CheckScriptFailure(['export let some = 123'], 'E1042:')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100538 CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100539 CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
540 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
541
542 assert_fails('vim9script', 'E1038')
543 assert_fails('export something', 'E1042')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100544enddef
545
546def Test_vim9script_call()
547 let lines =<< trim END
548 vim9script
549 let var = ''
550 def MyFunc(arg: string)
551 var = arg
552 enddef
553 MyFunc('foobar')
554 assert_equal('foobar', var)
555
556 let str = 'barfoo'
557 str->MyFunc()
558 assert_equal('barfoo', var)
559
560 let g:value = 'value'
561 g:value->MyFunc()
562 assert_equal('value', var)
563
564 let listvar = []
565 def ListFunc(arg: list<number>)
566 listvar = arg
567 enddef
568 [1, 2, 3]->ListFunc()
569 assert_equal([1, 2, 3], listvar)
570
571 let dictvar = {}
572 def DictFunc(arg: dict<number>)
573 dictvar = arg
574 enddef
575 {'a': 1, 'b': 2}->DictFunc()
576 assert_equal(#{a: 1, b: 2}, dictvar)
577 #{a: 3, b: 4}->DictFunc()
578 assert_equal(#{a: 3, b: 4}, dictvar)
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100579
580 ('text')->MyFunc()
581 assert_equal('text', var)
582 ("some")->MyFunc()
583 assert_equal('some', var)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100584 END
585 writefile(lines, 'Xcall.vim')
586 source Xcall.vim
587 delete('Xcall.vim')
588enddef
589
590def Test_vim9script_call_fail_decl()
591 let lines =<< trim END
592 vim9script
593 let var = ''
594 def MyFunc(arg: string)
595 let var = 123
596 enddef
597 END
598 writefile(lines, 'Xcall_decl.vim')
599 assert_fails('source Xcall_decl.vim', 'E1054:')
600 delete('Xcall_decl.vim')
601enddef
602
603def Test_vim9script_call_fail_const()
604 let lines =<< trim END
605 vim9script
606 const var = ''
607 def MyFunc(arg: string)
608 var = 'asdf'
609 enddef
610 END
611 writefile(lines, 'Xcall_const.vim')
612 assert_fails('source Xcall_const.vim', 'E46:')
613 delete('Xcall_const.vim')
614enddef
615
616def Test_vim9script_reload()
617 let lines =<< trim END
618 vim9script
619 const var = ''
620 let valone = 1234
621 def MyFunc(arg: string)
622 valone = 5678
623 enddef
624 END
625 let morelines =<< trim END
626 let valtwo = 222
627 export def GetValtwo(): number
628 return valtwo
629 enddef
630 END
631 writefile(lines + morelines, 'Xreload.vim')
632 source Xreload.vim
633 source Xreload.vim
634 source Xreload.vim
635
636 let testlines =<< trim END
637 vim9script
638 def TheFunc()
639 import GetValtwo from './Xreload.vim'
640 assert_equal(222, GetValtwo())
641 enddef
642 TheFunc()
643 END
644 writefile(testlines, 'Ximport.vim')
645 source Ximport.vim
646
647 " test that when not using "morelines" valtwo is still defined
648 " need to source Xreload.vim again, import doesn't reload a script
649 writefile(lines, 'Xreload.vim')
650 source Xreload.vim
651 source Ximport.vim
652
653 " cannot declare a var twice
654 lines =<< trim END
655 vim9script
656 let valone = 1234
657 let valone = 5678
658 END
659 writefile(lines, 'Xreload.vim')
660 assert_fails('source Xreload.vim', 'E1041:')
661
662 delete('Xreload.vim')
663 delete('Ximport.vim')
664enddef
665
666def Test_import_absolute()
667 let import_lines = [
668 \ 'vim9script',
669 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100670 \ 'def UseExported()',
671 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100672 \ ' exported = 8888',
673 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100674 \ 'enddef',
675 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100676 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100677 \ ]
678 writefile(import_lines, 'Ximport_abs.vim')
679 writefile(s:export_script_lines, 'Xexport_abs.vim')
680
681 source Ximport_abs.vim
682
683 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100684 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100685 assert_match('<SNR>\d\+_UseExported.*'
686 \ .. 'g:imported_abs = exported.*'
687 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100688 \ .. '1 STOREG g:imported_abs.*'
689 \ .. 'exported = 8888.*'
690 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
691 \ .. 'g:imported_after = exported.*'
692 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
693 \ .. '5 STOREG g:imported_after.*'
694 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100695 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100696 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100697
698 delete('Ximport_abs.vim')
699 delete('Xexport_abs.vim')
700enddef
701
702def Test_import_rtp()
703 let import_lines = [
704 \ 'vim9script',
705 \ 'import exported from "Xexport_rtp.vim"',
706 \ 'g:imported_rtp = exported',
707 \ ]
708 writefile(import_lines, 'Ximport_rtp.vim')
709 mkdir('import')
710 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
711
712 let save_rtp = &rtp
713 &rtp = getcwd()
714 source Ximport_rtp.vim
715 &rtp = save_rtp
716
717 assert_equal(9876, g:imported_rtp)
718 unlet g:imported_rtp
719
720 delete('Ximport_rtp.vim')
721 delete('import/Xexport_rtp.vim')
722 delete('import', 'd')
723enddef
724
725def Test_fixed_size_list()
726 " will be allocated as one piece of memory, check that changes work
727 let l = [1, 2, 3, 4]
728 l->remove(0)
729 l->add(5)
730 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100731 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100732enddef
733
Bram Moolenaar673660a2020-01-26 16:50:05 +0100734" Test that inside :function a Python function can be defined, :def is not
735" recognized.
736func Test_function_python()
737 CheckFeature python3
738 let py = 'python3'
739 execute py "<< EOF"
740def do_something():
741 return 1
742EOF
743endfunc
744
Bram Moolenaar158906c2020-02-06 20:39:45 +0100745def IfElse(what: number): string
746 let res = ''
747 if what == 1
748 res = "one"
749 elseif what == 2
750 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100751 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100752 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100753 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100754 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100755enddef
756
Bram Moolenaar158906c2020-02-06 20:39:45 +0100757def Test_if_elseif_else()
758 assert_equal('one', IfElse(1))
759 assert_equal('two', IfElse(2))
760 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100761enddef
762
Bram Moolenaar6d69bf62020-03-03 19:02:12 +0100763let g:bool_true = v:true
764let g:bool_false = v:false
765
766def Test_if_const_expr()
767 let res = false
768 if true ? true : false
769 res = true
770 endif
771 assert_equal(true, res)
772
773 res = false
774 if g:bool_true ? true : false
775 res = true
776 endif
777 assert_equal(true, res)
778
779 res = false
780 if true ? g:bool_true : false
781 res = true
782 endif
783 assert_equal(true, res)
784
785 res = false
786 if true ? true : g:bool_false
787 res = true
788 endif
789 assert_equal(true, res)
790
791 res = false
792 if true ? false : true
793 res = true
794 endif
795 assert_equal(false, res)
796
797 res = false
798 if false ? false : true
799 res = true
800 endif
801 assert_equal(true, res)
802
803 res = false
804 if false ? true : false
805 res = true
806 endif
807 assert_equal(false, res)
808
809 res = false
810 if true && true
811 res = true
812 endif
813 assert_equal(true, res)
814
815 res = false
816 if true && false
817 res = true
818 endif
819 assert_equal(false, res)
820
821 res = false
822 if g:bool_true && false
823 res = true
824 endif
825 assert_equal(false, res)
826
827 res = false
828 if true && g:bool_false
829 res = true
830 endif
831 assert_equal(false, res)
832
833 res = false
834 if false && false
835 res = true
836 endif
837 assert_equal(false, res)
838
839 res = false
840 if true || false
841 res = true
842 endif
843 assert_equal(true, res)
844
845 res = false
846 if g:bool_true || false
847 res = true
848 endif
849 assert_equal(true, res)
850
851 res = false
852 if true || g:bool_false
853 res = true
854 endif
855 assert_equal(true, res)
856
857 res = false
858 if false || false
859 res = true
860 endif
861 assert_equal(false, res)
862
863enddef
864
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100865def Test_delfunc()
866 let lines =<< trim END
867 vim9script
868 def GoneSoon()
869 echo 'hello'
870 enddef
871
872 def CallGoneSoon()
873 GoneSoon()
874 enddef
875
876 delfunc GoneSoon
877 CallGoneSoon()
878 END
879 writefile(lines, 'XToDelFunc')
880 assert_fails('so XToDelFunc', 'E933')
881 assert_fails('so XToDelFunc', 'E933')
882
883 delete('XToDelFunc')
884enddef
885
Bram Moolenaarad39c092020-02-26 18:23:43 +0100886def Test_execute_cmd()
887 new
888 setline(1, 'default')
889 execute 'call setline(1, "execute-string")'
890 assert_equal('execute-string', getline(1))
891 let cmd1 = 'call setline(1,'
892 let cmd2 = '"execute-var")'
893 execute cmd1 cmd2
894 assert_equal('execute-var', getline(1))
895 execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
896 assert_equal('execute-var-string', getline(1))
897 let cmd_first = 'call '
898 let cmd_last = 'setline(1, "execute-var-var")'
899 execute cmd_first .. cmd_last
900 assert_equal('execute-var-var', getline(1))
901 bwipe!
902enddef
903
904def Test_echo_cmd()
905 echo 'something'
906 assert_match('^something$', Screenline(&lines))
907
908 let str1 = 'some'
909 let str2 = 'more'
910 echo str1 str2
911 assert_match('^some more$', Screenline(&lines))
912enddef
913
Bram Moolenaar41fe0612020-03-01 16:22:40 +0100914def Test_for_outside_of_function()
915 let lines =<< trim END
916 vim9script
917 new
918 for var in range(0, 3)
919 append(line('$'), var)
920 endfor
921 assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
922 bwipe!
923 END
924 writefile(lines, 'Xvim9for.vim')
925 source Xvim9for.vim
926 delete('Xvim9for.vim')
927enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100928
Bram Moolenaard0df1aa2020-03-04 21:50:46 +0100929def Test_while_loop()
930 let result = ''
931 let cnt = 0
932 while cnt < 555
933 if cnt == 3
934 break
935 endif
936 cnt += 1
937 if cnt == 2
938 continue
939 endif
940 result ..= cnt .. '_'
941 endwhile
942 assert_equal('1_3_', result)
943enddef
944
Bram Moolenaar20431c92020-03-20 18:39:46 +0100945def Test_interrupt_loop()
946 let x = 0
947 while 1
948 x += 1
949 if x == 100
950 feedkeys("\<C-C>", 'L')
951 endif
952 endwhile
953enddef
954
Bram Moolenaard0df1aa2020-03-04 21:50:46 +0100955def Test_substitute_cmd()
956 new
957 setline(1, 'something')
958 :substitute(some(other(
959 assert_equal('otherthing', getline(1))
960 bwipe!
961
962 " also when the context is Vim9 script
963 let lines =<< trim END
964 vim9script
965 new
966 setline(1, 'something')
967 :substitute(some(other(
968 assert_equal('otherthing', getline(1))
969 bwipe!
970 END
971 writefile(lines, 'Xvim9lines')
972 source Xvim9lines
973
974 delete('Xvim9lines')
975enddef
976
Bram Moolenaar20431c92020-03-20 18:39:46 +0100977def Test_redef_failure()
978 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
979 so Xdef
980 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
981 so Xdef
982 call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
983 call assert_fails('so Xdef', 'E1027:')
984 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
985 so Xdef
986 call delete('Xdef')
987
988 call assert_equal(0, Func0())
989 call assert_equal('Func1', Func1())
990 call assert_equal('Func2', Func2())
991
992 delfunc! Func0
993 delfunc! Func1
994 delfunc! Func2
995enddef
996
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100997" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker