blob: 5eeb19842fc322ad817f3d681d1d14d05f0e296d [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
Bram Moolenaar33fa29c2020-03-28 19:41:33 +0100104 call CheckScriptFailure(['vim9script', 'def Func()', 'let dummy = s:notfound', 'enddef'], 'E1050:')
105
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100106 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
107 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
108
109 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
110 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
111
112 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
113 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100114
115 call CheckDefFailure(['let var: dict <number>'], 'E1007:')
116 call CheckDefFailure(['let var: dict<number'], 'E1009:')
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100117endfunc
118
119func Test_wrong_type()
120 call CheckDefFailure(['let var: list<nothing>'], 'E1010:')
121 call CheckDefFailure(['let var: list<list<nothing>>'], 'E1010:')
122 call CheckDefFailure(['let var: dict<nothing>'], 'E1010:')
123 call CheckDefFailure(['let var: dict<dict<nothing>>'], 'E1010:')
124
125 call CheckDefFailure(['let var: dict<number'], 'E1009:')
126 call CheckDefFailure(['let var: dict<list<number>'], 'E1009:')
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100127
128 call CheckDefFailure(['let var: ally'], 'E1010:')
129 call CheckDefFailure(['let var: bram'], 'E1010:')
130 call CheckDefFailure(['let var: cathy'], 'E1010:')
131 call CheckDefFailure(['let var: dom'], 'E1010:')
132 call CheckDefFailure(['let var: freddy'], 'E1010:')
133 call CheckDefFailure(['let var: john'], 'E1010:')
134 call CheckDefFailure(['let var: larry'], 'E1010:')
135 call CheckDefFailure(['let var: ned'], 'E1010:')
136 call CheckDefFailure(['let var: pam'], 'E1010:')
137 call CheckDefFailure(['let var: sam'], 'E1010:')
138 call CheckDefFailure(['let var: vim'], 'E1010:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100139endfunc
140
141func Test_const()
142 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
143 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
144 call CheckDefFailure(['const two'], 'E1021:')
145endfunc
146
147def Test_block()
148 let outer = 1
149 {
150 let inner = 2
151 assert_equal(1, outer)
152 assert_equal(2, inner)
153 }
154 assert_equal(1, outer)
155enddef
156
157func Test_block_failure()
158 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
159endfunc
160
161def ReturnString(): string
162 return 'string'
163enddef
164
165def ReturnNumber(): number
166 return 123
167enddef
168
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100169let g:notNumber = 'string'
170
171def ReturnGlobal(): number
172 return g:notNumber
173enddef
174
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100175def Test_return_string()
176 assert_equal('string', ReturnString())
177 assert_equal(123, ReturnNumber())
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100178 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100179enddef
180
181func Increment()
182 let g:counter += 1
183endfunc
184
185def Test_call_ufunc_count()
186 g:counter = 1
187 Increment()
188 Increment()
189 Increment()
190 " works with and without :call
191 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100192 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100193 unlet g:counter
194enddef
195
196def MyVarargs(arg: string, ...rest: list<string>): string
197 let res = arg
198 for s in rest
199 res ..= ',' .. s
200 endfor
201 return res
202enddef
203
204def Test_call_varargs()
205 assert_equal('one', MyVarargs('one'))
206 assert_equal('one,two', MyVarargs('one', 'two'))
207 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
208enddef
209
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100210def MyDefaultArgs(name = 'string'): string
211 return name
212enddef
213
214def Test_call_default_args()
215 assert_equal('string', MyDefaultArgs())
216 assert_equal('one', MyDefaultArgs('one'))
217 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
218enddef
219
220func Test_call_default_args_from_func()
221 call assert_equal('string', MyDefaultArgs())
222 call assert_equal('one', MyDefaultArgs('one'))
223 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
224endfunc
225
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100226func TakesOneArg(arg)
227 echo a:arg
228endfunc
229
230def Test_call_wrong_arg_count()
231 call CheckDefFailure(['TakesOneArg()'], 'E119:')
232 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
233enddef
234
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100235" Default arg and varargs
236def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
237 let res = one .. ',' .. two
238 for s in rest
239 res ..= ',' .. s
240 endfor
241 return res
242enddef
243
244def Test_call_def_varargs()
245 call assert_fails('call MyDefVarargs()', 'E119:')
246 assert_equal('one,foo', MyDefVarargs('one'))
247 assert_equal('one,two', MyDefVarargs('one', 'two'))
248 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
249enddef
250
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100251def Test_using_var_as_arg()
252 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
253 call assert_fails('so Xdef', 'E1006:')
254 call delete('Xdef')
255enddef
256
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100257def Test_call_func_defined_later()
258 call assert_equal('one', DefinedLater('one'))
259 call assert_fails('call NotDefined("one")', 'E117:')
260enddef
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100261
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100262func DefinedLater(arg)
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100263 return a:arg
264endfunc
265
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100266def FuncWithForwardCall()
267 return DefinedEvenLater("yes")
268enddef
269
270def DefinedEvenLater(arg: string): string
271 return arg
272enddef
273
274def Test_error_in_nested_function()
275 " Error in called function requires unwinding the call stack.
276 assert_fails('call FuncWithForwardCall()', 'E1029')
277enddef
278
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100279def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100280 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
281 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
282 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
283 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaarcf3f8bf2020-03-26 13:15:42 +0100284
285 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
286 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100287enddef
288
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100289def Test_arg_type_wrong()
290 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
291enddef
292
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100293def Test_try_catch()
294 let l = []
295 try
296 add(l, '1')
297 throw 'wrong'
298 add(l, '2')
299 catch
300 add(l, v:exception)
301 finally
302 add(l, '3')
303 endtry
304 assert_equal(['1', 'wrong', '3'], l)
305enddef
306
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100307def ThrowFromDef()
308 throw 'getout'
309enddef
310
311func CatchInFunc()
312 try
313 call ThrowFromDef()
314 catch
315 let g:thrown_func = v:exception
316 endtry
317endfunc
318
319def CatchInDef()
320 try
321 ThrowFromDef()
322 catch
323 g:thrown_def = v:exception
324 endtry
325enddef
326
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100327def ReturnFinally(): string
328 try
329 return 'intry'
330 finally
331 g:in_finally = 'finally'
332 endtry
333 return 'end'
334enddef
335
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100336def Test_try_catch_nested()
337 CatchInFunc()
338 assert_equal('getout', g:thrown_func)
339
340 CatchInDef()
341 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100342
343 assert_equal('intry', ReturnFinally())
344 assert_equal('finally', g:in_finally)
345enddef
346
347def Test_try_catch_match()
348 let seq = 'a'
349 try
350 throw 'something'
351 catch /nothing/
352 seq ..= 'x'
353 catch /some/
354 seq ..= 'b'
355 catch /asdf/
356 seq ..= 'x'
357 finally
358 seq ..= 'c'
359 endtry
360 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100361enddef
362
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100363let s:export_script_lines =<< trim END
364 vim9script
365 let name: string = 'bob'
366 def Concat(arg: string): string
367 return name .. arg
368 enddef
369 let g:result = Concat('bie')
370 let g:localname = name
371
372 export const CONST = 1234
373 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100374 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100375 export def Exported(): string
376 return 'Exported'
377 enddef
378END
379
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100380def Test_vim9_import_export()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100381 let import_script_lines =<< trim END
382 vim9script
383 import {exported, Exported} from './Xexport.vim'
384 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100385 exported += 3
386 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100387 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100388
389 import {exp_name} from './Xexport.vim'
390 g:imported_name = exp_name
391 exp_name ..= ' Doe'
392 g:imported_name_appended = exp_name
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100393 g:imported_later = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100394 END
395
396 writefile(import_script_lines, 'Ximport.vim')
397 writefile(s:export_script_lines, 'Xexport.vim')
398
399 source Ximport.vim
400
401 assert_equal('bobbie', g:result)
402 assert_equal('bob', g:localname)
403 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100404 assert_equal(9879, g:imported_added)
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100405 assert_equal(9879, g:imported_later)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100406 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100407 assert_equal('John', g:imported_name)
408 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100409 assert_false(exists('g:name'))
410
411 unlet g:result
412 unlet g:localname
413 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100414 unlet g:imported_added
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100415 unlet g:imported_later
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100416 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100417 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100418 delete('Ximport.vim')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100419
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100420 let import_in_def_lines =<< trim END
421 vim9script
422 def ImportInDef()
423 import exported from './Xexport.vim'
424 g:imported = exported
425 exported += 7
426 g:imported_added = exported
427 enddef
428 ImportInDef()
429 END
430 writefile(import_in_def_lines, 'Ximport2.vim')
431 source Ximport2.vim
432 " TODO: this should be 9879
433 assert_equal(9876, g:imported)
434 assert_equal(9883, g:imported_added)
435 unlet g:imported
436 unlet g:imported_added
437 delete('Ximport2.vim')
438
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100439 let import_star_as_lines =<< trim END
440 vim9script
441 import * as Export from './Xexport.vim'
442 def UseExport()
443 g:imported = Export.exported
444 enddef
445 UseExport()
446 END
447 writefile(import_star_as_lines, 'Ximport.vim')
448 source Ximport.vim
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100449 assert_equal(9883, g:imported)
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100450
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100451 let import_star_as_lines_no_dot =<< trim END
452 vim9script
453 import * as Export from './Xexport.vim'
454 def Func()
455 let dummy = 1
456 let imported = Export + dummy
457 enddef
458 END
459 writefile(import_star_as_lines_no_dot, 'Ximport.vim')
460 assert_fails('source Ximport.vim', 'E1060:')
461
462 let import_star_as_lines_dot_space =<< trim END
463 vim9script
464 import * as Export from './Xexport.vim'
465 def Func()
466 let imported = Export . exported
467 enddef
468 END
469 writefile(import_star_as_lines_dot_space, 'Ximport.vim')
470 assert_fails('source Ximport.vim', 'E1074:')
471
472 let import_star_as_lines_missing_name =<< trim END
473 vim9script
474 import * as Export from './Xexport.vim'
475 def Func()
476 let imported = Export.
477 enddef
478 END
479 writefile(import_star_as_lines_missing_name, 'Ximport.vim')
480 assert_fails('source Ximport.vim', 'E1048:')
481
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100482 let import_star_lines =<< trim END
483 vim9script
484 import * from './Xexport.vim'
485 g:imported = exported
486 END
487 writefile(import_star_lines, 'Ximport.vim')
488 assert_fails('source Ximport.vim', 'E1045:')
489
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100490 " try to import something that exists but is not exported
491 let import_not_exported_lines =<< trim END
492 vim9script
493 import name from './Xexport.vim'
494 END
495 writefile(import_not_exported_lines, 'Ximport.vim')
496 assert_fails('source Ximport.vim', 'E1049:')
497
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100498 " try to import something that is already defined
499 let import_already_defined =<< trim END
500 vim9script
501 let exported = 'something'
502 import exported from './Xexport.vim'
503 END
504 writefile(import_already_defined, 'Ximport.vim')
505 assert_fails('source Ximport.vim', 'E1073:')
506
507 " try to import something that is already defined
508 import_already_defined =<< trim END
509 vim9script
510 let exported = 'something'
511 import * as exported from './Xexport.vim'
512 END
513 writefile(import_already_defined, 'Ximport.vim')
514 assert_fails('source Ximport.vim', 'E1073:')
515
516 " try to import something that is already defined
517 import_already_defined =<< trim END
518 vim9script
519 let exported = 'something'
520 import {exported} from './Xexport.vim'
521 END
522 writefile(import_already_defined, 'Ximport.vim')
523 assert_fails('source Ximport.vim', 'E1073:')
524
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100525 " import a very long name, requires making a copy
526 let import_long_name_lines =<< trim END
527 vim9script
528 import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
529 END
530 writefile(import_long_name_lines, 'Ximport.vim')
531 assert_fails('source Ximport.vim', 'E1048:')
532
533 let import_no_from_lines =<< trim END
534 vim9script
535 import name './Xexport.vim'
536 END
537 writefile(import_no_from_lines, 'Ximport.vim')
538 assert_fails('source Ximport.vim', 'E1070:')
539
540 let import_invalid_string_lines =<< trim END
541 vim9script
542 import name from Xexport.vim
543 END
544 writefile(import_invalid_string_lines, 'Ximport.vim')
545 assert_fails('source Ximport.vim', 'E1071:')
546
547 let import_wrong_name_lines =<< trim END
548 vim9script
549 import name from './XnoExport.vim'
550 END
551 writefile(import_wrong_name_lines, 'Ximport.vim')
552 assert_fails('source Ximport.vim', 'E1053:')
553
554 let import_missing_comma_lines =<< trim END
555 vim9script
556 import {exported name} from './Xexport.vim'
557 END
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100558 writefile(import_missing_comma_lines, 'Ximport3.vim')
559 assert_fails('source Ximport3.vim', 'E1046:')
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100560
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100561 delete('Ximport.vim')
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100562 delete('Ximport3.vim')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100563 delete('Xexport.vim')
564
Bram Moolenaar750802b2020-02-23 18:08:33 +0100565 " Check that in a Vim9 script 'cpo' is set to the Vim default.
566 set cpo&vi
567 let cpo_before = &cpo
568 let lines =<< trim END
569 vim9script
570 g:cpo_in_vim9script = &cpo
571 END
572 writefile(lines, 'Xvim9_script')
573 source Xvim9_script
574 assert_equal(cpo_before, &cpo)
575 set cpo&vim
576 assert_equal(&cpo, g:cpo_in_vim9script)
577 delete('Xvim9_script')
578enddef
579
580def Test_vim9script_fails()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100581 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
582 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100583 CheckScriptFailure(['export let some = 123'], 'E1042:')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100584 CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100585 CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
586 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
587
588 assert_fails('vim9script', 'E1038')
589 assert_fails('export something', 'E1042')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100590enddef
591
592def Test_vim9script_call()
593 let lines =<< trim END
594 vim9script
595 let var = ''
596 def MyFunc(arg: string)
597 var = arg
598 enddef
599 MyFunc('foobar')
600 assert_equal('foobar', var)
601
602 let str = 'barfoo'
603 str->MyFunc()
604 assert_equal('barfoo', var)
605
606 let g:value = 'value'
607 g:value->MyFunc()
608 assert_equal('value', var)
609
610 let listvar = []
611 def ListFunc(arg: list<number>)
612 listvar = arg
613 enddef
614 [1, 2, 3]->ListFunc()
615 assert_equal([1, 2, 3], listvar)
616
617 let dictvar = {}
618 def DictFunc(arg: dict<number>)
619 dictvar = arg
620 enddef
621 {'a': 1, 'b': 2}->DictFunc()
622 assert_equal(#{a: 1, b: 2}, dictvar)
Bram Moolenaar33fa29c2020-03-28 19:41:33 +0100623 def CompiledDict()
624 {'a': 3, 'b': 4}->DictFunc()
625 enddef
626 CompiledDict()
627 assert_equal(#{a: 3, b: 4}, dictvar)
628
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100629 #{a: 3, b: 4}->DictFunc()
630 assert_equal(#{a: 3, b: 4}, dictvar)
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100631
632 ('text')->MyFunc()
633 assert_equal('text', var)
634 ("some")->MyFunc()
635 assert_equal('some', var)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100636 END
637 writefile(lines, 'Xcall.vim')
638 source Xcall.vim
639 delete('Xcall.vim')
640enddef
641
642def Test_vim9script_call_fail_decl()
643 let lines =<< trim END
644 vim9script
645 let var = ''
646 def MyFunc(arg: string)
647 let var = 123
648 enddef
649 END
650 writefile(lines, 'Xcall_decl.vim')
651 assert_fails('source Xcall_decl.vim', 'E1054:')
652 delete('Xcall_decl.vim')
653enddef
654
655def Test_vim9script_call_fail_const()
656 let lines =<< trim END
657 vim9script
658 const var = ''
659 def MyFunc(arg: string)
660 var = 'asdf'
661 enddef
662 END
663 writefile(lines, 'Xcall_const.vim')
664 assert_fails('source Xcall_const.vim', 'E46:')
665 delete('Xcall_const.vim')
666enddef
667
668def Test_vim9script_reload()
669 let lines =<< trim END
670 vim9script
671 const var = ''
672 let valone = 1234
673 def MyFunc(arg: string)
674 valone = 5678
675 enddef
676 END
677 let morelines =<< trim END
678 let valtwo = 222
679 export def GetValtwo(): number
680 return valtwo
681 enddef
682 END
683 writefile(lines + morelines, 'Xreload.vim')
684 source Xreload.vim
685 source Xreload.vim
686 source Xreload.vim
687
688 let testlines =<< trim END
689 vim9script
690 def TheFunc()
691 import GetValtwo from './Xreload.vim'
692 assert_equal(222, GetValtwo())
693 enddef
694 TheFunc()
695 END
696 writefile(testlines, 'Ximport.vim')
697 source Ximport.vim
698
699 " test that when not using "morelines" valtwo is still defined
700 " need to source Xreload.vim again, import doesn't reload a script
701 writefile(lines, 'Xreload.vim')
702 source Xreload.vim
703 source Ximport.vim
704
705 " cannot declare a var twice
706 lines =<< trim END
707 vim9script
708 let valone = 1234
709 let valone = 5678
710 END
711 writefile(lines, 'Xreload.vim')
712 assert_fails('source Xreload.vim', 'E1041:')
713
714 delete('Xreload.vim')
715 delete('Ximport.vim')
716enddef
717
718def Test_import_absolute()
719 let import_lines = [
720 \ 'vim9script',
721 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100722 \ 'def UseExported()',
723 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100724 \ ' exported = 8888',
725 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100726 \ 'enddef',
727 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100728 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100729 \ ]
730 writefile(import_lines, 'Ximport_abs.vim')
731 writefile(s:export_script_lines, 'Xexport_abs.vim')
732
733 source Ximport_abs.vim
734
735 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100736 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100737 assert_match('<SNR>\d\+_UseExported.*'
738 \ .. 'g:imported_abs = exported.*'
739 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100740 \ .. '1 STOREG g:imported_abs.*'
741 \ .. 'exported = 8888.*'
742 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
743 \ .. 'g:imported_after = exported.*'
744 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
745 \ .. '5 STOREG g:imported_after.*'
746 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100747 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100748 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100749
750 delete('Ximport_abs.vim')
751 delete('Xexport_abs.vim')
752enddef
753
754def Test_import_rtp()
755 let import_lines = [
756 \ 'vim9script',
757 \ 'import exported from "Xexport_rtp.vim"',
758 \ 'g:imported_rtp = exported',
759 \ ]
760 writefile(import_lines, 'Ximport_rtp.vim')
761 mkdir('import')
762 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
763
764 let save_rtp = &rtp
765 &rtp = getcwd()
766 source Ximport_rtp.vim
767 &rtp = save_rtp
768
769 assert_equal(9876, g:imported_rtp)
770 unlet g:imported_rtp
771
772 delete('Ximport_rtp.vim')
773 delete('import/Xexport_rtp.vim')
774 delete('import', 'd')
775enddef
776
777def Test_fixed_size_list()
778 " will be allocated as one piece of memory, check that changes work
779 let l = [1, 2, 3, 4]
780 l->remove(0)
781 l->add(5)
782 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100783 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100784enddef
785
Bram Moolenaar673660a2020-01-26 16:50:05 +0100786" Test that inside :function a Python function can be defined, :def is not
787" recognized.
788func Test_function_python()
789 CheckFeature python3
790 let py = 'python3'
791 execute py "<< EOF"
792def do_something():
793 return 1
794EOF
795endfunc
796
Bram Moolenaar158906c2020-02-06 20:39:45 +0100797def IfElse(what: number): string
798 let res = ''
799 if what == 1
800 res = "one"
801 elseif what == 2
802 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100803 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100804 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100805 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100806 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100807enddef
808
Bram Moolenaar158906c2020-02-06 20:39:45 +0100809def Test_if_elseif_else()
810 assert_equal('one', IfElse(1))
811 assert_equal('two', IfElse(2))
812 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100813enddef
814
Bram Moolenaar6d69bf62020-03-03 19:02:12 +0100815let g:bool_true = v:true
816let g:bool_false = v:false
817
818def Test_if_const_expr()
819 let res = false
820 if true ? true : false
821 res = true
822 endif
823 assert_equal(true, res)
824
825 res = false
826 if g:bool_true ? true : false
827 res = true
828 endif
829 assert_equal(true, res)
830
831 res = false
832 if true ? g:bool_true : false
833 res = true
834 endif
835 assert_equal(true, res)
836
837 res = false
838 if true ? true : g:bool_false
839 res = true
840 endif
841 assert_equal(true, res)
842
843 res = false
844 if true ? false : true
845 res = true
846 endif
847 assert_equal(false, res)
848
849 res = false
850 if false ? false : true
851 res = true
852 endif
853 assert_equal(true, res)
854
855 res = false
856 if false ? true : false
857 res = true
858 endif
859 assert_equal(false, res)
860
861 res = false
862 if true && true
863 res = true
864 endif
865 assert_equal(true, res)
866
867 res = false
868 if true && false
869 res = true
870 endif
871 assert_equal(false, res)
872
873 res = false
874 if g:bool_true && false
875 res = true
876 endif
877 assert_equal(false, res)
878
879 res = false
880 if true && g:bool_false
881 res = true
882 endif
883 assert_equal(false, res)
884
885 res = false
886 if false && false
887 res = true
888 endif
889 assert_equal(false, res)
890
891 res = false
892 if true || false
893 res = true
894 endif
895 assert_equal(true, res)
896
897 res = false
898 if g:bool_true || false
899 res = true
900 endif
901 assert_equal(true, res)
902
903 res = false
904 if true || g:bool_false
905 res = true
906 endif
907 assert_equal(true, res)
908
909 res = false
910 if false || false
911 res = true
912 endif
913 assert_equal(false, res)
914
915enddef
916
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100917def Test_delfunc()
918 let lines =<< trim END
919 vim9script
920 def GoneSoon()
921 echo 'hello'
922 enddef
923
924 def CallGoneSoon()
925 GoneSoon()
926 enddef
927
928 delfunc GoneSoon
929 CallGoneSoon()
930 END
931 writefile(lines, 'XToDelFunc')
932 assert_fails('so XToDelFunc', 'E933')
933 assert_fails('so XToDelFunc', 'E933')
934
935 delete('XToDelFunc')
936enddef
937
Bram Moolenaarad39c092020-02-26 18:23:43 +0100938def Test_execute_cmd()
939 new
940 setline(1, 'default')
941 execute 'call setline(1, "execute-string")'
942 assert_equal('execute-string', getline(1))
943 let cmd1 = 'call setline(1,'
944 let cmd2 = '"execute-var")'
945 execute cmd1 cmd2
946 assert_equal('execute-var', getline(1))
947 execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
948 assert_equal('execute-var-string', getline(1))
949 let cmd_first = 'call '
950 let cmd_last = 'setline(1, "execute-var-var")'
951 execute cmd_first .. cmd_last
952 assert_equal('execute-var-var', getline(1))
953 bwipe!
954enddef
955
956def Test_echo_cmd()
957 echo 'something'
958 assert_match('^something$', Screenline(&lines))
959
960 let str1 = 'some'
961 let str2 = 'more'
962 echo str1 str2
963 assert_match('^some more$', Screenline(&lines))
964enddef
965
Bram Moolenaar41fe0612020-03-01 16:22:40 +0100966def Test_for_outside_of_function()
967 let lines =<< trim END
968 vim9script
969 new
970 for var in range(0, 3)
971 append(line('$'), var)
972 endfor
973 assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
974 bwipe!
975 END
976 writefile(lines, 'Xvim9for.vim')
977 source Xvim9for.vim
978 delete('Xvim9for.vim')
979enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100980
Bram Moolenaard0df1aa2020-03-04 21:50:46 +0100981def Test_while_loop()
982 let result = ''
983 let cnt = 0
984 while cnt < 555
985 if cnt == 3
986 break
987 endif
988 cnt += 1
989 if cnt == 2
990 continue
991 endif
992 result ..= cnt .. '_'
993 endwhile
994 assert_equal('1_3_', result)
995enddef
996
Bram Moolenaar9645e2d2020-03-20 20:48:49 +0100997def Test_interrupt_loop()
Bram Moolenaar97acfc72020-03-22 13:44:28 +0100998 let caught = false
Bram Moolenaar9645e2d2020-03-20 20:48:49 +0100999 let x = 0
Bram Moolenaar97acfc72020-03-22 13:44:28 +01001000 try
1001 while 1
1002 x += 1
1003 if x == 100
1004 feedkeys("\<C-C>", 'Lt')
1005 endif
1006 endwhile
1007 catch
1008 caught = true
1009 assert_equal(100, x)
1010 endtry
1011 assert_true(caught, 'should have caught an exception')
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001012enddef
Bram Moolenaar20431c92020-03-20 18:39:46 +01001013
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01001014def Test_substitute_cmd()
1015 new
1016 setline(1, 'something')
1017 :substitute(some(other(
1018 assert_equal('otherthing', getline(1))
1019 bwipe!
1020
1021 " also when the context is Vim9 script
1022 let lines =<< trim END
1023 vim9script
1024 new
1025 setline(1, 'something')
1026 :substitute(some(other(
1027 assert_equal('otherthing', getline(1))
1028 bwipe!
1029 END
1030 writefile(lines, 'Xvim9lines')
1031 source Xvim9lines
1032
1033 delete('Xvim9lines')
1034enddef
1035
Bram Moolenaar20431c92020-03-20 18:39:46 +01001036def Test_redef_failure()
1037 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
1038 so Xdef
1039 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
1040 so Xdef
1041 call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
1042 call assert_fails('so Xdef', 'E1027:')
1043 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
1044 so Xdef
1045 call delete('Xdef')
1046
1047 call assert_equal(0, Func0())
1048 call assert_equal('Func1', Func1())
1049 call assert_equal('Func2', Func2())
1050
1051 delfunc! Func0
1052 delfunc! Func1
1053 delfunc! Func2
1054enddef
1055
Bram Moolenaar7d941ee2020-03-26 14:11:58 +01001056" Test for internal functions returning different types
1057func Test_InternalFuncRetType()
1058 let lines =<< trim END
1059 def RetFloat(): float
1060 return ceil(1.456)
1061 enddef
1062
1063 def RetListAny(): list<any>
1064 return items({'k' : 'v'})
1065 enddef
1066
1067 def RetListString(): list<string>
1068 return split('a:b:c', ':')
1069 enddef
1070
1071 def RetListDictAny(): list<dict<any>>
1072 return getbufinfo()
1073 enddef
1074
1075 def RetDictNumber(): dict<number>
1076 return wordcount()
1077 enddef
1078
1079 def RetDictString(): dict<string>
1080 return environ()
1081 enddef
1082 END
1083 call writefile(lines, 'Xscript')
1084 source Xscript
1085
1086 call assert_equal(2.0, RetFloat())
1087 call assert_equal([['k', 'v']], RetListAny())
1088 call assert_equal(['a', 'b', 'c'], RetListString())
1089 call assert_notequal([], RetListDictAny())
1090 call assert_notequal({}, RetDictNumber())
1091 call assert_notequal({}, RetDictString())
1092 call delete('Xscript')
1093endfunc
1094
1095" Test for passing too many or too few arguments to internal functions
1096func Test_internalfunc_arg_error()
1097 let l =<< trim END
1098 def! FArgErr(): float
1099 return ceil(1.1, 2)
1100 enddef
1101 END
1102 call writefile(l, 'Xinvalidarg')
1103 call assert_fails('so Xinvalidarg', 'E118:')
1104 let l =<< trim END
1105 def! FArgErr(): float
1106 return ceil()
1107 enddef
1108 END
1109 call writefile(l, 'Xinvalidarg')
1110 call assert_fails('so Xinvalidarg', 'E119:')
1111 call delete('Xinvalidarg')
1112endfunc
1113
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001114" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker