blob: f6cb15fd4df0643181fbeca72df3e31075c0fa24 [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 Moolenaar9be61bb2020-03-30 22:51:24 +020056 let a: number = 6
57 assert_equal(6, a)
58
Bram Moolenaar42a480b2020-02-29 23:23:47 +010059 if has('channel')
60 let chan1: channel
Bram Moolenaarfbdd08e2020-03-01 14:04:46 +010061 let job1: job
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +010062 let job2: job = job_start('willfail')
Bram Moolenaar42a480b2020-02-29 23:23:47 +010063 endif
Bram Moolenaarfbdd08e2020-03-01 14:04:46 +010064 if has('float')
65 let float1: float = 3.4
66 endif
Bram Moolenaar087d2e12020-03-01 15:36:42 +010067 let funky1: func
68 let funky2: func = function('len')
69 let party1: partial
70 let party2: partial = funcref('Test_syntax')
Bram Moolenaar42a480b2020-02-29 23:23:47 +010071
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +010072 " type becomes list<any>
73 let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
Bram Moolenaar5381c7a2020-03-02 22:53:32 +010074 " type becomes dict<any>
75 let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +010076
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010077 g:newvar = 'new'
78 assert_equal('new', g:newvar)
79
80 assert_equal('yes', g:existing)
81 g:existing = 'no'
82 assert_equal('no', g:existing)
83
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010084 v:char = 'abc'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010085 assert_equal('abc', v:char)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010086
87 $ENVVAR = 'foobar'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010088 assert_equal('foobar', $ENVVAR)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010089 $ENVVAR = ''
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010090
Bram Moolenaarfd1823e2020-02-19 20:23:11 +010091 s:appendToMe ..= 'yyy'
92 assert_equal('xxxyyy', s:appendToMe)
93 s:addToMe += 222
94 assert_equal(333, s:addToMe)
Bram Moolenaar0bbf7222020-02-19 22:31:48 +010095 s:newVar = 'new'
96 assert_equal('new', s:newVar)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010097enddef
98
99func Test_assignment_failure()
100 call CheckDefFailure(['let var=234'], 'E1004:')
101 call CheckDefFailure(['let var =234'], 'E1004:')
102 call CheckDefFailure(['let var= 234'], 'E1004:')
103
104 call CheckDefFailure(['let true = 1'], 'E1034:')
105 call CheckDefFailure(['let false = 1'], 'E1034:')
106
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200107 call CheckDefFailure(['let [a; b; c] = g:list'], 'E452:')
108
109 call CheckDefFailure(['let &option'], 'E1052:')
110 call CheckDefFailure(['&g:option = 5'], 'E113:')
111
112 call CheckDefFailure(['let $VAR = 5'], 'E1065:')
113
114 call CheckDefFailure(['let @~ = 5'], 'E354:')
115 call CheckDefFailure(['let @a = 5'], 'E1066:')
116
117 call CheckDefFailure(['let g:var = 5'], 'E1016:')
118
119 call CheckDefFailure(['let anr = 4', 'anr ..= "text"'], 'E1019:')
120 call CheckDefFailure(['let xnr += 4'], 'E1020:')
121
Bram Moolenaar33fa29c2020-03-28 19:41:33 +0100122 call CheckScriptFailure(['vim9script', 'def Func()', 'let dummy = s:notfound', 'enddef'], 'E1050:')
123
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100124 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
125 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
126
127 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
128 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
129
130 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
131 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100132
133 call CheckDefFailure(['let var: dict <number>'], 'E1007:')
134 call CheckDefFailure(['let var: dict<number'], 'E1009:')
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100135endfunc
136
137func Test_wrong_type()
138 call CheckDefFailure(['let var: list<nothing>'], 'E1010:')
139 call CheckDefFailure(['let var: list<list<nothing>>'], 'E1010:')
140 call CheckDefFailure(['let var: dict<nothing>'], 'E1010:')
141 call CheckDefFailure(['let var: dict<dict<nothing>>'], 'E1010:')
142
143 call CheckDefFailure(['let var: dict<number'], 'E1009:')
144 call CheckDefFailure(['let var: dict<list<number>'], 'E1009:')
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100145
146 call CheckDefFailure(['let var: ally'], 'E1010:')
147 call CheckDefFailure(['let var: bram'], 'E1010:')
148 call CheckDefFailure(['let var: cathy'], 'E1010:')
149 call CheckDefFailure(['let var: dom'], 'E1010:')
150 call CheckDefFailure(['let var: freddy'], 'E1010:')
151 call CheckDefFailure(['let var: john'], 'E1010:')
152 call CheckDefFailure(['let var: larry'], 'E1010:')
153 call CheckDefFailure(['let var: ned'], 'E1010:')
154 call CheckDefFailure(['let var: pam'], 'E1010:')
155 call CheckDefFailure(['let var: sam'], 'E1010:')
156 call CheckDefFailure(['let var: vim'], 'E1010:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100157endfunc
158
159func Test_const()
160 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
161 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
162 call CheckDefFailure(['const two'], 'E1021:')
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200163 call CheckDefFailure(['const &option'], 'E996:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100164endfunc
165
166def Test_block()
167 let outer = 1
168 {
169 let inner = 2
170 assert_equal(1, outer)
171 assert_equal(2, inner)
172 }
173 assert_equal(1, outer)
174enddef
175
176func Test_block_failure()
177 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
178endfunc
179
180def ReturnString(): string
181 return 'string'
182enddef
183
184def ReturnNumber(): number
185 return 123
186enddef
187
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100188let g:notNumber = 'string'
189
190def ReturnGlobal(): number
191 return g:notNumber
192enddef
193
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200194def Test_return_something()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100195 assert_equal('string', ReturnString())
196 assert_equal(123, ReturnNumber())
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100197 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100198enddef
199
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200200let s:nothing = 0
201def ReturnNothing()
202 s:nothing = 1
203 if true
204 return
205 endif
206 s:nothing = 2
207enddef
208
209def Test_return_nothing()
210 ReturnNothing()
211 assert_equal(1, s:nothing)
212enddef
213
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100214func Increment()
215 let g:counter += 1
216endfunc
217
218def Test_call_ufunc_count()
219 g:counter = 1
220 Increment()
221 Increment()
222 Increment()
223 " works with and without :call
224 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100225 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100226 unlet g:counter
227enddef
228
229def MyVarargs(arg: string, ...rest: list<string>): string
230 let res = arg
231 for s in rest
232 res ..= ',' .. s
233 endfor
234 return res
235enddef
236
237def Test_call_varargs()
238 assert_equal('one', MyVarargs('one'))
239 assert_equal('one,two', MyVarargs('one', 'two'))
240 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
241enddef
242
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100243def MyDefaultArgs(name = 'string'): string
244 return name
245enddef
246
247def Test_call_default_args()
248 assert_equal('string', MyDefaultArgs())
249 assert_equal('one', MyDefaultArgs('one'))
250 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
251enddef
252
253func Test_call_default_args_from_func()
254 call assert_equal('string', MyDefaultArgs())
255 call assert_equal('one', MyDefaultArgs('one'))
256 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
257endfunc
258
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100259func TakesOneArg(arg)
260 echo a:arg
261endfunc
262
263def Test_call_wrong_arg_count()
264 call CheckDefFailure(['TakesOneArg()'], 'E119:')
265 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
266enddef
267
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100268" Default arg and varargs
269def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
270 let res = one .. ',' .. two
271 for s in rest
272 res ..= ',' .. s
273 endfor
274 return res
275enddef
276
277def Test_call_def_varargs()
278 call assert_fails('call MyDefVarargs()', 'E119:')
279 assert_equal('one,foo', MyDefVarargs('one'))
280 assert_equal('one,two', MyDefVarargs('one', 'two'))
281 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
282enddef
283
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100284def Test_using_var_as_arg()
285 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
286 call assert_fails('so Xdef', 'E1006:')
287 call delete('Xdef')
288enddef
289
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100290def Test_call_func_defined_later()
291 call assert_equal('one', DefinedLater('one'))
292 call assert_fails('call NotDefined("one")', 'E117:')
293enddef
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100294
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100295func DefinedLater(arg)
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100296 return a:arg
297endfunc
298
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100299def FuncWithForwardCall()
300 return DefinedEvenLater("yes")
301enddef
302
303def DefinedEvenLater(arg: string): string
304 return arg
305enddef
306
307def Test_error_in_nested_function()
308 " Error in called function requires unwinding the call stack.
309 assert_fails('call FuncWithForwardCall()', 'E1029')
310enddef
311
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100312def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100313 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
314 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
315 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
316 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaarcf3f8bf2020-03-26 13:15:42 +0100317
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200318 CheckScriptFailure(['def Func(): number', 'return', 'enddef'], 'E1003:')
319
Bram Moolenaarcf3f8bf2020-03-26 13:15:42 +0100320 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
321 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100322enddef
323
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100324def Test_arg_type_wrong()
325 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
326enddef
327
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100328def Test_try_catch()
329 let l = []
330 try
331 add(l, '1')
332 throw 'wrong'
333 add(l, '2')
334 catch
335 add(l, v:exception)
336 finally
337 add(l, '3')
338 endtry
339 assert_equal(['1', 'wrong', '3'], l)
340enddef
341
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100342def ThrowFromDef()
343 throw 'getout'
344enddef
345
346func CatchInFunc()
347 try
348 call ThrowFromDef()
349 catch
350 let g:thrown_func = v:exception
351 endtry
352endfunc
353
354def CatchInDef()
355 try
356 ThrowFromDef()
357 catch
358 g:thrown_def = v:exception
359 endtry
360enddef
361
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100362def ReturnFinally(): string
363 try
364 return 'intry'
365 finally
366 g:in_finally = 'finally'
367 endtry
368 return 'end'
369enddef
370
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100371def Test_try_catch_nested()
372 CatchInFunc()
373 assert_equal('getout', g:thrown_func)
374
375 CatchInDef()
376 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100377
378 assert_equal('intry', ReturnFinally())
379 assert_equal('finally', g:in_finally)
380enddef
381
382def Test_try_catch_match()
383 let seq = 'a'
384 try
385 throw 'something'
386 catch /nothing/
387 seq ..= 'x'
388 catch /some/
389 seq ..= 'b'
390 catch /asdf/
391 seq ..= 'x'
392 finally
393 seq ..= 'c'
394 endtry
395 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100396enddef
397
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100398let s:export_script_lines =<< trim END
399 vim9script
400 let name: string = 'bob'
401 def Concat(arg: string): string
402 return name .. arg
403 enddef
404 let g:result = Concat('bie')
405 let g:localname = name
406
407 export const CONST = 1234
408 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100409 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100410 export def Exported(): string
411 return 'Exported'
412 enddef
413END
414
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100415def Test_vim9_import_export()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100416 let import_script_lines =<< trim END
417 vim9script
418 import {exported, Exported} from './Xexport.vim'
419 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100420 exported += 3
421 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100422 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100423
424 import {exp_name} from './Xexport.vim'
425 g:imported_name = exp_name
426 exp_name ..= ' Doe'
427 g:imported_name_appended = exp_name
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100428 g:imported_later = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100429 END
430
431 writefile(import_script_lines, 'Ximport.vim')
432 writefile(s:export_script_lines, 'Xexport.vim')
433
434 source Ximport.vim
435
436 assert_equal('bobbie', g:result)
437 assert_equal('bob', g:localname)
438 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100439 assert_equal(9879, g:imported_added)
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100440 assert_equal(9879, g:imported_later)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100441 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100442 assert_equal('John', g:imported_name)
443 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100444 assert_false(exists('g:name'))
445
446 unlet g:result
447 unlet g:localname
448 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100449 unlet g:imported_added
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100450 unlet g:imported_later
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100451 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100452 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100453 delete('Ximport.vim')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100454
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100455 let import_in_def_lines =<< trim END
456 vim9script
457 def ImportInDef()
458 import exported from './Xexport.vim'
459 g:imported = exported
460 exported += 7
461 g:imported_added = exported
462 enddef
463 ImportInDef()
464 END
465 writefile(import_in_def_lines, 'Ximport2.vim')
466 source Ximport2.vim
467 " TODO: this should be 9879
468 assert_equal(9876, g:imported)
469 assert_equal(9883, g:imported_added)
470 unlet g:imported
471 unlet g:imported_added
472 delete('Ximport2.vim')
473
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100474 let import_star_as_lines =<< trim END
475 vim9script
476 import * as Export from './Xexport.vim'
477 def UseExport()
478 g:imported = Export.exported
479 enddef
480 UseExport()
481 END
482 writefile(import_star_as_lines, 'Ximport.vim')
483 source Ximport.vim
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100484 assert_equal(9883, g:imported)
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100485
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100486 let import_star_as_lines_no_dot =<< trim END
487 vim9script
488 import * as Export from './Xexport.vim'
489 def Func()
490 let dummy = 1
491 let imported = Export + dummy
492 enddef
493 END
494 writefile(import_star_as_lines_no_dot, 'Ximport.vim')
495 assert_fails('source Ximport.vim', 'E1060:')
496
497 let import_star_as_lines_dot_space =<< trim END
498 vim9script
499 import * as Export from './Xexport.vim'
500 def Func()
501 let imported = Export . exported
502 enddef
503 END
504 writefile(import_star_as_lines_dot_space, 'Ximport.vim')
505 assert_fails('source Ximport.vim', 'E1074:')
506
507 let import_star_as_lines_missing_name =<< trim END
508 vim9script
509 import * as Export from './Xexport.vim'
510 def Func()
511 let imported = Export.
512 enddef
513 END
514 writefile(import_star_as_lines_missing_name, 'Ximport.vim')
515 assert_fails('source Ximport.vim', 'E1048:')
516
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100517 let import_star_lines =<< trim END
518 vim9script
519 import * from './Xexport.vim'
520 g:imported = exported
521 END
522 writefile(import_star_lines, 'Ximport.vim')
523 assert_fails('source Ximport.vim', 'E1045:')
524
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100525 " try to import something that exists but is not exported
526 let import_not_exported_lines =<< trim END
527 vim9script
528 import name from './Xexport.vim'
529 END
530 writefile(import_not_exported_lines, 'Ximport.vim')
531 assert_fails('source Ximport.vim', 'E1049:')
532
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100533 " try to import something that is already defined
534 let import_already_defined =<< trim END
535 vim9script
536 let exported = 'something'
537 import exported from './Xexport.vim'
538 END
539 writefile(import_already_defined, 'Ximport.vim')
540 assert_fails('source Ximport.vim', 'E1073:')
541
542 " try to import something that is already defined
543 import_already_defined =<< trim END
544 vim9script
545 let exported = 'something'
546 import * as exported from './Xexport.vim'
547 END
548 writefile(import_already_defined, 'Ximport.vim')
549 assert_fails('source Ximport.vim', 'E1073:')
550
551 " try to import something that is already defined
552 import_already_defined =<< trim END
553 vim9script
554 let exported = 'something'
555 import {exported} from './Xexport.vim'
556 END
557 writefile(import_already_defined, 'Ximport.vim')
558 assert_fails('source Ximport.vim', 'E1073:')
559
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100560 " import a very long name, requires making a copy
561 let import_long_name_lines =<< trim END
562 vim9script
563 import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
564 END
565 writefile(import_long_name_lines, 'Ximport.vim')
566 assert_fails('source Ximport.vim', 'E1048:')
567
568 let import_no_from_lines =<< trim END
569 vim9script
570 import name './Xexport.vim'
571 END
572 writefile(import_no_from_lines, 'Ximport.vim')
573 assert_fails('source Ximport.vim', 'E1070:')
574
575 let import_invalid_string_lines =<< trim END
576 vim9script
577 import name from Xexport.vim
578 END
579 writefile(import_invalid_string_lines, 'Ximport.vim')
580 assert_fails('source Ximport.vim', 'E1071:')
581
582 let import_wrong_name_lines =<< trim END
583 vim9script
584 import name from './XnoExport.vim'
585 END
586 writefile(import_wrong_name_lines, 'Ximport.vim')
587 assert_fails('source Ximport.vim', 'E1053:')
588
589 let import_missing_comma_lines =<< trim END
590 vim9script
591 import {exported name} from './Xexport.vim'
592 END
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100593 writefile(import_missing_comma_lines, 'Ximport3.vim')
594 assert_fails('source Ximport3.vim', 'E1046:')
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100595
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100596 delete('Ximport.vim')
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100597 delete('Ximport3.vim')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100598 delete('Xexport.vim')
599
Bram Moolenaar750802b2020-02-23 18:08:33 +0100600 " Check that in a Vim9 script 'cpo' is set to the Vim default.
601 set cpo&vi
602 let cpo_before = &cpo
603 let lines =<< trim END
604 vim9script
605 g:cpo_in_vim9script = &cpo
606 END
607 writefile(lines, 'Xvim9_script')
608 source Xvim9_script
609 assert_equal(cpo_before, &cpo)
610 set cpo&vim
611 assert_equal(&cpo, g:cpo_in_vim9script)
612 delete('Xvim9_script')
613enddef
614
615def Test_vim9script_fails()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100616 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
617 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100618 CheckScriptFailure(['export let some = 123'], 'E1042:')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100619 CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100620 CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
621 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
622
623 assert_fails('vim9script', 'E1038')
624 assert_fails('export something', 'E1042')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100625enddef
626
627def Test_vim9script_call()
628 let lines =<< trim END
629 vim9script
630 let var = ''
631 def MyFunc(arg: string)
632 var = arg
633 enddef
634 MyFunc('foobar')
635 assert_equal('foobar', var)
636
637 let str = 'barfoo'
638 str->MyFunc()
639 assert_equal('barfoo', var)
640
641 let g:value = 'value'
642 g:value->MyFunc()
643 assert_equal('value', var)
644
645 let listvar = []
646 def ListFunc(arg: list<number>)
647 listvar = arg
648 enddef
649 [1, 2, 3]->ListFunc()
650 assert_equal([1, 2, 3], listvar)
651
652 let dictvar = {}
653 def DictFunc(arg: dict<number>)
654 dictvar = arg
655 enddef
656 {'a': 1, 'b': 2}->DictFunc()
657 assert_equal(#{a: 1, b: 2}, dictvar)
Bram Moolenaar33fa29c2020-03-28 19:41:33 +0100658 def CompiledDict()
659 {'a': 3, 'b': 4}->DictFunc()
660 enddef
661 CompiledDict()
662 assert_equal(#{a: 3, b: 4}, dictvar)
663
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100664 #{a: 3, b: 4}->DictFunc()
665 assert_equal(#{a: 3, b: 4}, dictvar)
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100666
667 ('text')->MyFunc()
668 assert_equal('text', var)
669 ("some")->MyFunc()
670 assert_equal('some', var)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100671 END
672 writefile(lines, 'Xcall.vim')
673 source Xcall.vim
674 delete('Xcall.vim')
675enddef
676
677def Test_vim9script_call_fail_decl()
678 let lines =<< trim END
679 vim9script
680 let var = ''
681 def MyFunc(arg: string)
682 let var = 123
683 enddef
684 END
685 writefile(lines, 'Xcall_decl.vim')
686 assert_fails('source Xcall_decl.vim', 'E1054:')
687 delete('Xcall_decl.vim')
688enddef
689
690def Test_vim9script_call_fail_const()
691 let lines =<< trim END
692 vim9script
693 const var = ''
694 def MyFunc(arg: string)
695 var = 'asdf'
696 enddef
697 END
698 writefile(lines, 'Xcall_const.vim')
699 assert_fails('source Xcall_const.vim', 'E46:')
700 delete('Xcall_const.vim')
701enddef
702
703def Test_vim9script_reload()
704 let lines =<< trim END
705 vim9script
706 const var = ''
707 let valone = 1234
708 def MyFunc(arg: string)
709 valone = 5678
710 enddef
711 END
712 let morelines =<< trim END
713 let valtwo = 222
714 export def GetValtwo(): number
715 return valtwo
716 enddef
717 END
718 writefile(lines + morelines, 'Xreload.vim')
719 source Xreload.vim
720 source Xreload.vim
721 source Xreload.vim
722
723 let testlines =<< trim END
724 vim9script
725 def TheFunc()
726 import GetValtwo from './Xreload.vim'
727 assert_equal(222, GetValtwo())
728 enddef
729 TheFunc()
730 END
731 writefile(testlines, 'Ximport.vim')
732 source Ximport.vim
733
734 " test that when not using "morelines" valtwo is still defined
735 " need to source Xreload.vim again, import doesn't reload a script
736 writefile(lines, 'Xreload.vim')
737 source Xreload.vim
738 source Ximport.vim
739
740 " cannot declare a var twice
741 lines =<< trim END
742 vim9script
743 let valone = 1234
744 let valone = 5678
745 END
746 writefile(lines, 'Xreload.vim')
747 assert_fails('source Xreload.vim', 'E1041:')
748
749 delete('Xreload.vim')
750 delete('Ximport.vim')
751enddef
752
753def Test_import_absolute()
754 let import_lines = [
755 \ 'vim9script',
756 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100757 \ 'def UseExported()',
758 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100759 \ ' exported = 8888',
760 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100761 \ 'enddef',
762 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100763 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100764 \ ]
765 writefile(import_lines, 'Ximport_abs.vim')
766 writefile(s:export_script_lines, 'Xexport_abs.vim')
767
768 source Ximport_abs.vim
769
770 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100771 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100772 assert_match('<SNR>\d\+_UseExported.*'
773 \ .. 'g:imported_abs = exported.*'
774 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100775 \ .. '1 STOREG g:imported_abs.*'
776 \ .. 'exported = 8888.*'
777 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
778 \ .. 'g:imported_after = exported.*'
779 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
780 \ .. '5 STOREG g:imported_after.*'
781 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100782 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100783 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100784
785 delete('Ximport_abs.vim')
786 delete('Xexport_abs.vim')
787enddef
788
789def Test_import_rtp()
790 let import_lines = [
791 \ 'vim9script',
792 \ 'import exported from "Xexport_rtp.vim"',
793 \ 'g:imported_rtp = exported',
794 \ ]
795 writefile(import_lines, 'Ximport_rtp.vim')
796 mkdir('import')
797 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
798
799 let save_rtp = &rtp
800 &rtp = getcwd()
801 source Ximport_rtp.vim
802 &rtp = save_rtp
803
804 assert_equal(9876, g:imported_rtp)
805 unlet g:imported_rtp
806
807 delete('Ximport_rtp.vim')
808 delete('import/Xexport_rtp.vim')
809 delete('import', 'd')
810enddef
811
812def Test_fixed_size_list()
813 " will be allocated as one piece of memory, check that changes work
814 let l = [1, 2, 3, 4]
815 l->remove(0)
816 l->add(5)
817 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100818 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100819enddef
820
Bram Moolenaar673660a2020-01-26 16:50:05 +0100821" Test that inside :function a Python function can be defined, :def is not
822" recognized.
823func Test_function_python()
824 CheckFeature python3
825 let py = 'python3'
826 execute py "<< EOF"
827def do_something():
828 return 1
829EOF
830endfunc
831
Bram Moolenaar158906c2020-02-06 20:39:45 +0100832def IfElse(what: number): string
833 let res = ''
834 if what == 1
835 res = "one"
836 elseif what == 2
837 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100838 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100839 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100840 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100841 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100842enddef
843
Bram Moolenaar158906c2020-02-06 20:39:45 +0100844def Test_if_elseif_else()
845 assert_equal('one', IfElse(1))
846 assert_equal('two', IfElse(2))
847 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100848enddef
849
Bram Moolenaar6d69bf62020-03-03 19:02:12 +0100850let g:bool_true = v:true
851let g:bool_false = v:false
852
853def Test_if_const_expr()
854 let res = false
855 if true ? true : false
856 res = true
857 endif
858 assert_equal(true, res)
859
860 res = false
861 if g:bool_true ? true : false
862 res = true
863 endif
864 assert_equal(true, res)
865
866 res = false
867 if true ? g:bool_true : false
868 res = true
869 endif
870 assert_equal(true, res)
871
872 res = false
873 if true ? true : g:bool_false
874 res = true
875 endif
876 assert_equal(true, res)
877
878 res = false
879 if true ? false : true
880 res = true
881 endif
882 assert_equal(false, res)
883
884 res = false
885 if false ? false : true
886 res = true
887 endif
888 assert_equal(true, res)
889
890 res = false
891 if false ? true : false
892 res = true
893 endif
894 assert_equal(false, res)
895
896 res = false
897 if true && true
898 res = true
899 endif
900 assert_equal(true, res)
901
902 res = false
903 if true && false
904 res = true
905 endif
906 assert_equal(false, res)
907
908 res = false
909 if g:bool_true && false
910 res = true
911 endif
912 assert_equal(false, res)
913
914 res = false
915 if true && g:bool_false
916 res = true
917 endif
918 assert_equal(false, res)
919
920 res = false
921 if false && false
922 res = true
923 endif
924 assert_equal(false, res)
925
926 res = false
927 if true || false
928 res = true
929 endif
930 assert_equal(true, res)
931
932 res = false
933 if g:bool_true || false
934 res = true
935 endif
936 assert_equal(true, res)
937
938 res = false
939 if true || g:bool_false
940 res = true
941 endif
942 assert_equal(true, res)
943
944 res = false
945 if false || false
946 res = true
947 endif
948 assert_equal(false, res)
949
950enddef
951
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100952def Test_delfunc()
953 let lines =<< trim END
954 vim9script
955 def GoneSoon()
956 echo 'hello'
957 enddef
958
959 def CallGoneSoon()
960 GoneSoon()
961 enddef
962
963 delfunc GoneSoon
964 CallGoneSoon()
965 END
966 writefile(lines, 'XToDelFunc')
967 assert_fails('so XToDelFunc', 'E933')
968 assert_fails('so XToDelFunc', 'E933')
969
970 delete('XToDelFunc')
971enddef
972
Bram Moolenaarad39c092020-02-26 18:23:43 +0100973def Test_execute_cmd()
974 new
975 setline(1, 'default')
976 execute 'call setline(1, "execute-string")'
977 assert_equal('execute-string', getline(1))
978 let cmd1 = 'call setline(1,'
979 let cmd2 = '"execute-var")'
980 execute cmd1 cmd2
981 assert_equal('execute-var', getline(1))
982 execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
983 assert_equal('execute-var-string', getline(1))
984 let cmd_first = 'call '
985 let cmd_last = 'setline(1, "execute-var-var")'
986 execute cmd_first .. cmd_last
987 assert_equal('execute-var-var', getline(1))
988 bwipe!
989enddef
990
991def Test_echo_cmd()
992 echo 'something'
993 assert_match('^something$', Screenline(&lines))
994
995 let str1 = 'some'
996 let str2 = 'more'
997 echo str1 str2
998 assert_match('^some more$', Screenline(&lines))
999enddef
1000
Bram Moolenaar41fe0612020-03-01 16:22:40 +01001001def Test_for_outside_of_function()
1002 let lines =<< trim END
1003 vim9script
1004 new
1005 for var in range(0, 3)
1006 append(line('$'), var)
1007 endfor
1008 assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
1009 bwipe!
1010 END
1011 writefile(lines, 'Xvim9for.vim')
1012 source Xvim9for.vim
1013 delete('Xvim9for.vim')
1014enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001015
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01001016def Test_while_loop()
1017 let result = ''
1018 let cnt = 0
1019 while cnt < 555
1020 if cnt == 3
1021 break
1022 endif
1023 cnt += 1
1024 if cnt == 2
1025 continue
1026 endif
1027 result ..= cnt .. '_'
1028 endwhile
1029 assert_equal('1_3_', result)
1030enddef
1031
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001032def Test_interrupt_loop()
Bram Moolenaar97acfc72020-03-22 13:44:28 +01001033 let caught = false
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001034 let x = 0
Bram Moolenaar97acfc72020-03-22 13:44:28 +01001035 try
1036 while 1
1037 x += 1
1038 if x == 100
1039 feedkeys("\<C-C>", 'Lt')
1040 endif
1041 endwhile
1042 catch
1043 caught = true
1044 assert_equal(100, x)
1045 endtry
1046 assert_true(caught, 'should have caught an exception')
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001047enddef
Bram Moolenaar20431c92020-03-20 18:39:46 +01001048
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01001049def Test_substitute_cmd()
1050 new
1051 setline(1, 'something')
1052 :substitute(some(other(
1053 assert_equal('otherthing', getline(1))
1054 bwipe!
1055
1056 " also when the context is Vim9 script
1057 let lines =<< trim END
1058 vim9script
1059 new
1060 setline(1, 'something')
1061 :substitute(some(other(
1062 assert_equal('otherthing', getline(1))
1063 bwipe!
1064 END
1065 writefile(lines, 'Xvim9lines')
1066 source Xvim9lines
1067
1068 delete('Xvim9lines')
1069enddef
1070
Bram Moolenaar20431c92020-03-20 18:39:46 +01001071def Test_redef_failure()
1072 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
1073 so Xdef
1074 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
1075 so Xdef
1076 call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
1077 call assert_fails('so Xdef', 'E1027:')
1078 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
1079 so Xdef
1080 call delete('Xdef')
1081
1082 call assert_equal(0, Func0())
1083 call assert_equal('Func1', Func1())
1084 call assert_equal('Func2', Func2())
1085
1086 delfunc! Func0
1087 delfunc! Func1
1088 delfunc! Func2
1089enddef
1090
Bram Moolenaar7d941ee2020-03-26 14:11:58 +01001091" Test for internal functions returning different types
1092func Test_InternalFuncRetType()
1093 let lines =<< trim END
1094 def RetFloat(): float
1095 return ceil(1.456)
1096 enddef
1097
1098 def RetListAny(): list<any>
1099 return items({'k' : 'v'})
1100 enddef
1101
1102 def RetListString(): list<string>
1103 return split('a:b:c', ':')
1104 enddef
1105
1106 def RetListDictAny(): list<dict<any>>
1107 return getbufinfo()
1108 enddef
1109
1110 def RetDictNumber(): dict<number>
1111 return wordcount()
1112 enddef
1113
1114 def RetDictString(): dict<string>
1115 return environ()
1116 enddef
1117 END
1118 call writefile(lines, 'Xscript')
1119 source Xscript
1120
1121 call assert_equal(2.0, RetFloat())
1122 call assert_equal([['k', 'v']], RetListAny())
1123 call assert_equal(['a', 'b', 'c'], RetListString())
1124 call assert_notequal([], RetListDictAny())
1125 call assert_notequal({}, RetDictNumber())
1126 call assert_notequal({}, RetDictString())
1127 call delete('Xscript')
1128endfunc
1129
1130" Test for passing too many or too few arguments to internal functions
1131func Test_internalfunc_arg_error()
1132 let l =<< trim END
1133 def! FArgErr(): float
1134 return ceil(1.1, 2)
1135 enddef
1136 END
1137 call writefile(l, 'Xinvalidarg')
1138 call assert_fails('so Xinvalidarg', 'E118:')
1139 let l =<< trim END
1140 def! FArgErr(): float
1141 return ceil()
1142 enddef
1143 END
1144 call writefile(l, 'Xinvalidarg')
1145 call assert_fails('so Xinvalidarg', 'E119:')
1146 call delete('Xinvalidarg')
1147endfunc
1148
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001149" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker