blob: 9b49e7cbb16a96d1dc0dbdb248ae88a6cd345f4d [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 Moolenaarcf3f8bf2020-03-26 13:15:42 +0100272
273 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
274 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100275enddef
276
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100277def Test_arg_type_wrong()
278 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
279enddef
280
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100281def Test_try_catch()
282 let l = []
283 try
284 add(l, '1')
285 throw 'wrong'
286 add(l, '2')
287 catch
288 add(l, v:exception)
289 finally
290 add(l, '3')
291 endtry
292 assert_equal(['1', 'wrong', '3'], l)
293enddef
294
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100295def ThrowFromDef()
296 throw 'getout'
297enddef
298
299func CatchInFunc()
300 try
301 call ThrowFromDef()
302 catch
303 let g:thrown_func = v:exception
304 endtry
305endfunc
306
307def CatchInDef()
308 try
309 ThrowFromDef()
310 catch
311 g:thrown_def = v:exception
312 endtry
313enddef
314
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100315def ReturnFinally(): string
316 try
317 return 'intry'
318 finally
319 g:in_finally = 'finally'
320 endtry
321 return 'end'
322enddef
323
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100324def Test_try_catch_nested()
325 CatchInFunc()
326 assert_equal('getout', g:thrown_func)
327
328 CatchInDef()
329 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100330
331 assert_equal('intry', ReturnFinally())
332 assert_equal('finally', g:in_finally)
333enddef
334
335def Test_try_catch_match()
336 let seq = 'a'
337 try
338 throw 'something'
339 catch /nothing/
340 seq ..= 'x'
341 catch /some/
342 seq ..= 'b'
343 catch /asdf/
344 seq ..= 'x'
345 finally
346 seq ..= 'c'
347 endtry
348 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100349enddef
350
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100351let s:export_script_lines =<< trim END
352 vim9script
353 let name: string = 'bob'
354 def Concat(arg: string): string
355 return name .. arg
356 enddef
357 let g:result = Concat('bie')
358 let g:localname = name
359
360 export const CONST = 1234
361 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100362 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100363 export def Exported(): string
364 return 'Exported'
365 enddef
366END
367
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100368def Test_vim9_import_export()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100369 let import_script_lines =<< trim END
370 vim9script
371 import {exported, Exported} from './Xexport.vim'
372 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100373 exported += 3
374 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100375 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100376
377 import {exp_name} from './Xexport.vim'
378 g:imported_name = exp_name
379 exp_name ..= ' Doe'
380 g:imported_name_appended = exp_name
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100381 g:imported_later = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100382 END
383
384 writefile(import_script_lines, 'Ximport.vim')
385 writefile(s:export_script_lines, 'Xexport.vim')
386
387 source Ximport.vim
388
389 assert_equal('bobbie', g:result)
390 assert_equal('bob', g:localname)
391 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100392 assert_equal(9879, g:imported_added)
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100393 assert_equal(9879, g:imported_later)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100394 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100395 assert_equal('John', g:imported_name)
396 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100397 assert_false(exists('g:name'))
398
399 unlet g:result
400 unlet g:localname
401 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100402 unlet g:imported_added
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100403 unlet g:imported_later
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100404 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100405 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100406 delete('Ximport.vim')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100407
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100408 let import_in_def_lines =<< trim END
409 vim9script
410 def ImportInDef()
411 import exported from './Xexport.vim'
412 g:imported = exported
413 exported += 7
414 g:imported_added = exported
415 enddef
416 ImportInDef()
417 END
418 writefile(import_in_def_lines, 'Ximport2.vim')
419 source Ximport2.vim
420 " TODO: this should be 9879
421 assert_equal(9876, g:imported)
422 assert_equal(9883, g:imported_added)
423 unlet g:imported
424 unlet g:imported_added
425 delete('Ximport2.vim')
426
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100427 let import_star_as_lines =<< trim END
428 vim9script
429 import * as Export from './Xexport.vim'
430 def UseExport()
431 g:imported = Export.exported
432 enddef
433 UseExport()
434 END
435 writefile(import_star_as_lines, 'Ximport.vim')
436 source Ximport.vim
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100437 assert_equal(9883, g:imported)
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100438
439 let import_star_lines =<< trim END
440 vim9script
441 import * from './Xexport.vim'
442 g:imported = exported
443 END
444 writefile(import_star_lines, 'Ximport.vim')
445 assert_fails('source Ximport.vim', 'E1045:')
446
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100447 " try to import something that exists but is not exported
448 let import_not_exported_lines =<< trim END
449 vim9script
450 import name from './Xexport.vim'
451 END
452 writefile(import_not_exported_lines, 'Ximport.vim')
453 assert_fails('source Ximport.vim', 'E1049:')
454
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100455 " try to import something that is already defined
456 let import_already_defined =<< trim END
457 vim9script
458 let exported = 'something'
459 import exported from './Xexport.vim'
460 END
461 writefile(import_already_defined, 'Ximport.vim')
462 assert_fails('source Ximport.vim', 'E1073:')
463
464 " try to import something that is already defined
465 import_already_defined =<< trim END
466 vim9script
467 let exported = 'something'
468 import * as exported from './Xexport.vim'
469 END
470 writefile(import_already_defined, 'Ximport.vim')
471 assert_fails('source Ximport.vim', 'E1073:')
472
473 " try to import something that is already defined
474 import_already_defined =<< trim END
475 vim9script
476 let exported = 'something'
477 import {exported} from './Xexport.vim'
478 END
479 writefile(import_already_defined, 'Ximport.vim')
480 assert_fails('source Ximport.vim', 'E1073:')
481
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100482 " import a very long name, requires making a copy
483 let import_long_name_lines =<< trim END
484 vim9script
485 import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
486 END
487 writefile(import_long_name_lines, 'Ximport.vim')
488 assert_fails('source Ximport.vim', 'E1048:')
489
490 let import_no_from_lines =<< trim END
491 vim9script
492 import name './Xexport.vim'
493 END
494 writefile(import_no_from_lines, 'Ximport.vim')
495 assert_fails('source Ximport.vim', 'E1070:')
496
497 let import_invalid_string_lines =<< trim END
498 vim9script
499 import name from Xexport.vim
500 END
501 writefile(import_invalid_string_lines, 'Ximport.vim')
502 assert_fails('source Ximport.vim', 'E1071:')
503
504 let import_wrong_name_lines =<< trim END
505 vim9script
506 import name from './XnoExport.vim'
507 END
508 writefile(import_wrong_name_lines, 'Ximport.vim')
509 assert_fails('source Ximport.vim', 'E1053:')
510
511 let import_missing_comma_lines =<< trim END
512 vim9script
513 import {exported name} from './Xexport.vim'
514 END
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100515 writefile(import_missing_comma_lines, 'Ximport3.vim')
516 assert_fails('source Ximport3.vim', 'E1046:')
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100517
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100518 delete('Ximport.vim')
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100519 delete('Ximport3.vim')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100520 delete('Xexport.vim')
521
Bram Moolenaar750802b2020-02-23 18:08:33 +0100522 " Check that in a Vim9 script 'cpo' is set to the Vim default.
523 set cpo&vi
524 let cpo_before = &cpo
525 let lines =<< trim END
526 vim9script
527 g:cpo_in_vim9script = &cpo
528 END
529 writefile(lines, 'Xvim9_script')
530 source Xvim9_script
531 assert_equal(cpo_before, &cpo)
532 set cpo&vim
533 assert_equal(&cpo, g:cpo_in_vim9script)
534 delete('Xvim9_script')
535enddef
536
537def Test_vim9script_fails()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100538 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
539 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100540 CheckScriptFailure(['export let some = 123'], 'E1042:')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100541 CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100542 CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
543 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
544
545 assert_fails('vim9script', 'E1038')
546 assert_fails('export something', 'E1042')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100547enddef
548
549def Test_vim9script_call()
550 let lines =<< trim END
551 vim9script
552 let var = ''
553 def MyFunc(arg: string)
554 var = arg
555 enddef
556 MyFunc('foobar')
557 assert_equal('foobar', var)
558
559 let str = 'barfoo'
560 str->MyFunc()
561 assert_equal('barfoo', var)
562
563 let g:value = 'value'
564 g:value->MyFunc()
565 assert_equal('value', var)
566
567 let listvar = []
568 def ListFunc(arg: list<number>)
569 listvar = arg
570 enddef
571 [1, 2, 3]->ListFunc()
572 assert_equal([1, 2, 3], listvar)
573
574 let dictvar = {}
575 def DictFunc(arg: dict<number>)
576 dictvar = arg
577 enddef
578 {'a': 1, 'b': 2}->DictFunc()
579 assert_equal(#{a: 1, b: 2}, dictvar)
580 #{a: 3, b: 4}->DictFunc()
581 assert_equal(#{a: 3, b: 4}, dictvar)
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100582
583 ('text')->MyFunc()
584 assert_equal('text', var)
585 ("some")->MyFunc()
586 assert_equal('some', var)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100587 END
588 writefile(lines, 'Xcall.vim')
589 source Xcall.vim
590 delete('Xcall.vim')
591enddef
592
593def Test_vim9script_call_fail_decl()
594 let lines =<< trim END
595 vim9script
596 let var = ''
597 def MyFunc(arg: string)
598 let var = 123
599 enddef
600 END
601 writefile(lines, 'Xcall_decl.vim')
602 assert_fails('source Xcall_decl.vim', 'E1054:')
603 delete('Xcall_decl.vim')
604enddef
605
606def Test_vim9script_call_fail_const()
607 let lines =<< trim END
608 vim9script
609 const var = ''
610 def MyFunc(arg: string)
611 var = 'asdf'
612 enddef
613 END
614 writefile(lines, 'Xcall_const.vim')
615 assert_fails('source Xcall_const.vim', 'E46:')
616 delete('Xcall_const.vim')
617enddef
618
619def Test_vim9script_reload()
620 let lines =<< trim END
621 vim9script
622 const var = ''
623 let valone = 1234
624 def MyFunc(arg: string)
625 valone = 5678
626 enddef
627 END
628 let morelines =<< trim END
629 let valtwo = 222
630 export def GetValtwo(): number
631 return valtwo
632 enddef
633 END
634 writefile(lines + morelines, 'Xreload.vim')
635 source Xreload.vim
636 source Xreload.vim
637 source Xreload.vim
638
639 let testlines =<< trim END
640 vim9script
641 def TheFunc()
642 import GetValtwo from './Xreload.vim'
643 assert_equal(222, GetValtwo())
644 enddef
645 TheFunc()
646 END
647 writefile(testlines, 'Ximport.vim')
648 source Ximport.vim
649
650 " test that when not using "morelines" valtwo is still defined
651 " need to source Xreload.vim again, import doesn't reload a script
652 writefile(lines, 'Xreload.vim')
653 source Xreload.vim
654 source Ximport.vim
655
656 " cannot declare a var twice
657 lines =<< trim END
658 vim9script
659 let valone = 1234
660 let valone = 5678
661 END
662 writefile(lines, 'Xreload.vim')
663 assert_fails('source Xreload.vim', 'E1041:')
664
665 delete('Xreload.vim')
666 delete('Ximport.vim')
667enddef
668
669def Test_import_absolute()
670 let import_lines = [
671 \ 'vim9script',
672 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100673 \ 'def UseExported()',
674 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100675 \ ' exported = 8888',
676 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100677 \ 'enddef',
678 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100679 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100680 \ ]
681 writefile(import_lines, 'Ximport_abs.vim')
682 writefile(s:export_script_lines, 'Xexport_abs.vim')
683
684 source Ximport_abs.vim
685
686 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100687 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100688 assert_match('<SNR>\d\+_UseExported.*'
689 \ .. 'g:imported_abs = exported.*'
690 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100691 \ .. '1 STOREG g:imported_abs.*'
692 \ .. 'exported = 8888.*'
693 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
694 \ .. 'g:imported_after = exported.*'
695 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
696 \ .. '5 STOREG g:imported_after.*'
697 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100698 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100699 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100700
701 delete('Ximport_abs.vim')
702 delete('Xexport_abs.vim')
703enddef
704
705def Test_import_rtp()
706 let import_lines = [
707 \ 'vim9script',
708 \ 'import exported from "Xexport_rtp.vim"',
709 \ 'g:imported_rtp = exported',
710 \ ]
711 writefile(import_lines, 'Ximport_rtp.vim')
712 mkdir('import')
713 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
714
715 let save_rtp = &rtp
716 &rtp = getcwd()
717 source Ximport_rtp.vim
718 &rtp = save_rtp
719
720 assert_equal(9876, g:imported_rtp)
721 unlet g:imported_rtp
722
723 delete('Ximport_rtp.vim')
724 delete('import/Xexport_rtp.vim')
725 delete('import', 'd')
726enddef
727
728def Test_fixed_size_list()
729 " will be allocated as one piece of memory, check that changes work
730 let l = [1, 2, 3, 4]
731 l->remove(0)
732 l->add(5)
733 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100734 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100735enddef
736
Bram Moolenaar673660a2020-01-26 16:50:05 +0100737" Test that inside :function a Python function can be defined, :def is not
738" recognized.
739func Test_function_python()
740 CheckFeature python3
741 let py = 'python3'
742 execute py "<< EOF"
743def do_something():
744 return 1
745EOF
746endfunc
747
Bram Moolenaar158906c2020-02-06 20:39:45 +0100748def IfElse(what: number): string
749 let res = ''
750 if what == 1
751 res = "one"
752 elseif what == 2
753 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100754 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100755 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100756 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100757 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100758enddef
759
Bram Moolenaar158906c2020-02-06 20:39:45 +0100760def Test_if_elseif_else()
761 assert_equal('one', IfElse(1))
762 assert_equal('two', IfElse(2))
763 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100764enddef
765
Bram Moolenaar6d69bf62020-03-03 19:02:12 +0100766let g:bool_true = v:true
767let g:bool_false = v:false
768
769def Test_if_const_expr()
770 let res = false
771 if true ? true : false
772 res = true
773 endif
774 assert_equal(true, res)
775
776 res = false
777 if g:bool_true ? true : false
778 res = true
779 endif
780 assert_equal(true, res)
781
782 res = false
783 if true ? g:bool_true : false
784 res = true
785 endif
786 assert_equal(true, res)
787
788 res = false
789 if true ? true : g:bool_false
790 res = true
791 endif
792 assert_equal(true, res)
793
794 res = false
795 if true ? false : true
796 res = true
797 endif
798 assert_equal(false, res)
799
800 res = false
801 if false ? false : true
802 res = true
803 endif
804 assert_equal(true, res)
805
806 res = false
807 if false ? true : false
808 res = true
809 endif
810 assert_equal(false, res)
811
812 res = false
813 if true && true
814 res = true
815 endif
816 assert_equal(true, res)
817
818 res = false
819 if true && false
820 res = true
821 endif
822 assert_equal(false, res)
823
824 res = false
825 if g:bool_true && false
826 res = true
827 endif
828 assert_equal(false, res)
829
830 res = false
831 if true && g:bool_false
832 res = true
833 endif
834 assert_equal(false, res)
835
836 res = false
837 if false && false
838 res = true
839 endif
840 assert_equal(false, res)
841
842 res = false
843 if true || false
844 res = true
845 endif
846 assert_equal(true, res)
847
848 res = false
849 if g:bool_true || false
850 res = true
851 endif
852 assert_equal(true, res)
853
854 res = false
855 if true || g:bool_false
856 res = true
857 endif
858 assert_equal(true, res)
859
860 res = false
861 if false || false
862 res = true
863 endif
864 assert_equal(false, res)
865
866enddef
867
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100868def Test_delfunc()
869 let lines =<< trim END
870 vim9script
871 def GoneSoon()
872 echo 'hello'
873 enddef
874
875 def CallGoneSoon()
876 GoneSoon()
877 enddef
878
879 delfunc GoneSoon
880 CallGoneSoon()
881 END
882 writefile(lines, 'XToDelFunc')
883 assert_fails('so XToDelFunc', 'E933')
884 assert_fails('so XToDelFunc', 'E933')
885
886 delete('XToDelFunc')
887enddef
888
Bram Moolenaarad39c092020-02-26 18:23:43 +0100889def Test_execute_cmd()
890 new
891 setline(1, 'default')
892 execute 'call setline(1, "execute-string")'
893 assert_equal('execute-string', getline(1))
894 let cmd1 = 'call setline(1,'
895 let cmd2 = '"execute-var")'
896 execute cmd1 cmd2
897 assert_equal('execute-var', getline(1))
898 execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
899 assert_equal('execute-var-string', getline(1))
900 let cmd_first = 'call '
901 let cmd_last = 'setline(1, "execute-var-var")'
902 execute cmd_first .. cmd_last
903 assert_equal('execute-var-var', getline(1))
904 bwipe!
905enddef
906
907def Test_echo_cmd()
908 echo 'something'
909 assert_match('^something$', Screenline(&lines))
910
911 let str1 = 'some'
912 let str2 = 'more'
913 echo str1 str2
914 assert_match('^some more$', Screenline(&lines))
915enddef
916
Bram Moolenaar41fe0612020-03-01 16:22:40 +0100917def Test_for_outside_of_function()
918 let lines =<< trim END
919 vim9script
920 new
921 for var in range(0, 3)
922 append(line('$'), var)
923 endfor
924 assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
925 bwipe!
926 END
927 writefile(lines, 'Xvim9for.vim')
928 source Xvim9for.vim
929 delete('Xvim9for.vim')
930enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100931
Bram Moolenaard0df1aa2020-03-04 21:50:46 +0100932def Test_while_loop()
933 let result = ''
934 let cnt = 0
935 while cnt < 555
936 if cnt == 3
937 break
938 endif
939 cnt += 1
940 if cnt == 2
941 continue
942 endif
943 result ..= cnt .. '_'
944 endwhile
945 assert_equal('1_3_', result)
946enddef
947
Bram Moolenaar9645e2d2020-03-20 20:48:49 +0100948def Test_interrupt_loop()
Bram Moolenaar97acfc72020-03-22 13:44:28 +0100949 let caught = false
Bram Moolenaar9645e2d2020-03-20 20:48:49 +0100950 let x = 0
Bram Moolenaar97acfc72020-03-22 13:44:28 +0100951 try
952 while 1
953 x += 1
954 if x == 100
955 feedkeys("\<C-C>", 'Lt')
956 endif
957 endwhile
958 catch
959 caught = true
960 assert_equal(100, x)
961 endtry
962 assert_true(caught, 'should have caught an exception')
Bram Moolenaar9645e2d2020-03-20 20:48:49 +0100963enddef
Bram Moolenaar20431c92020-03-20 18:39:46 +0100964
Bram Moolenaard0df1aa2020-03-04 21:50:46 +0100965def Test_substitute_cmd()
966 new
967 setline(1, 'something')
968 :substitute(some(other(
969 assert_equal('otherthing', getline(1))
970 bwipe!
971
972 " also when the context is Vim9 script
973 let lines =<< trim END
974 vim9script
975 new
976 setline(1, 'something')
977 :substitute(some(other(
978 assert_equal('otherthing', getline(1))
979 bwipe!
980 END
981 writefile(lines, 'Xvim9lines')
982 source Xvim9lines
983
984 delete('Xvim9lines')
985enddef
986
Bram Moolenaar20431c92020-03-20 18:39:46 +0100987def Test_redef_failure()
988 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
989 so Xdef
990 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
991 so Xdef
992 call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
993 call assert_fails('so Xdef', 'E1027:')
994 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
995 so Xdef
996 call delete('Xdef')
997
998 call assert_equal(0, Func0())
999 call assert_equal('Func1', Func1())
1000 call assert_equal('Func2', Func2())
1001
1002 delfunc! Func0
1003 delfunc! Func1
1004 delfunc! Func2
1005enddef
1006
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001007" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker