blob: 15b26403b7995dbc2ca4812930996759fa1457a6 [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:')
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100115endfunc
116
117func Test_wrong_type()
118 call CheckDefFailure(['let var: list<nothing>'], 'E1010:')
119 call CheckDefFailure(['let var: list<list<nothing>>'], 'E1010:')
120 call CheckDefFailure(['let var: dict<nothing>'], 'E1010:')
121 call CheckDefFailure(['let var: dict<dict<nothing>>'], 'E1010:')
122
123 call CheckDefFailure(['let var: dict<number'], 'E1009:')
124 call CheckDefFailure(['let var: dict<list<number>'], 'E1009:')
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100125
126 call CheckDefFailure(['let var: ally'], 'E1010:')
127 call CheckDefFailure(['let var: bram'], 'E1010:')
128 call CheckDefFailure(['let var: cathy'], 'E1010:')
129 call CheckDefFailure(['let var: dom'], 'E1010:')
130 call CheckDefFailure(['let var: freddy'], 'E1010:')
131 call CheckDefFailure(['let var: john'], 'E1010:')
132 call CheckDefFailure(['let var: larry'], 'E1010:')
133 call CheckDefFailure(['let var: ned'], 'E1010:')
134 call CheckDefFailure(['let var: pam'], 'E1010:')
135 call CheckDefFailure(['let var: sam'], 'E1010:')
136 call CheckDefFailure(['let var: vim'], 'E1010:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100137endfunc
138
139func Test_const()
140 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
141 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
142 call CheckDefFailure(['const two'], 'E1021:')
143endfunc
144
145def Test_block()
146 let outer = 1
147 {
148 let inner = 2
149 assert_equal(1, outer)
150 assert_equal(2, inner)
151 }
152 assert_equal(1, outer)
153enddef
154
155func Test_block_failure()
156 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
157endfunc
158
159def ReturnString(): string
160 return 'string'
161enddef
162
163def ReturnNumber(): number
164 return 123
165enddef
166
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100167let g:notNumber = 'string'
168
169def ReturnGlobal(): number
170 return g:notNumber
171enddef
172
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100173def Test_return_string()
174 assert_equal('string', ReturnString())
175 assert_equal(123, ReturnNumber())
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100176 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100177enddef
178
179func Increment()
180 let g:counter += 1
181endfunc
182
183def Test_call_ufunc_count()
184 g:counter = 1
185 Increment()
186 Increment()
187 Increment()
188 " works with and without :call
189 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100190 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100191 unlet g:counter
192enddef
193
194def MyVarargs(arg: string, ...rest: list<string>): string
195 let res = arg
196 for s in rest
197 res ..= ',' .. s
198 endfor
199 return res
200enddef
201
202def Test_call_varargs()
203 assert_equal('one', MyVarargs('one'))
204 assert_equal('one,two', MyVarargs('one', 'two'))
205 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
206enddef
207
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100208def MyDefaultArgs(name = 'string'): string
209 return name
210enddef
211
212def Test_call_default_args()
213 assert_equal('string', MyDefaultArgs())
214 assert_equal('one', MyDefaultArgs('one'))
215 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
216enddef
217
218func Test_call_default_args_from_func()
219 call assert_equal('string', MyDefaultArgs())
220 call assert_equal('one', MyDefaultArgs('one'))
221 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
222endfunc
223
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100224func TakesOneArg(arg)
225 echo a:arg
226endfunc
227
228def Test_call_wrong_arg_count()
229 call CheckDefFailure(['TakesOneArg()'], 'E119:')
230 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
231enddef
232
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100233" Default arg and varargs
234def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
235 let res = one .. ',' .. two
236 for s in rest
237 res ..= ',' .. s
238 endfor
239 return res
240enddef
241
242def Test_call_def_varargs()
243 call assert_fails('call MyDefVarargs()', 'E119:')
244 assert_equal('one,foo', MyDefVarargs('one'))
245 assert_equal('one,two', MyDefVarargs('one', 'two'))
246 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
247enddef
248
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100249def Test_using_var_as_arg()
250 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
251 call assert_fails('so Xdef', 'E1006:')
252 call delete('Xdef')
253enddef
254
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100255def Test_call_func_defined_later()
256 call assert_equal('one', DefinedLater('one'))
257 call assert_fails('call NotDefined("one")', 'E117:')
258enddef
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100259
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100260func DefinedLater(arg)
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100261 return a:arg
262endfunc
263
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100264def FuncWithForwardCall()
265 return DefinedEvenLater("yes")
266enddef
267
268def DefinedEvenLater(arg: string): string
269 return arg
270enddef
271
272def Test_error_in_nested_function()
273 " Error in called function requires unwinding the call stack.
274 assert_fails('call FuncWithForwardCall()', 'E1029')
275enddef
276
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100277def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100278 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
279 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
280 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
281 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaarcf3f8bf2020-03-26 13:15:42 +0100282
283 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
284 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100285enddef
286
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100287def Test_arg_type_wrong()
288 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
289enddef
290
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100291def Test_try_catch()
292 let l = []
293 try
294 add(l, '1')
295 throw 'wrong'
296 add(l, '2')
297 catch
298 add(l, v:exception)
299 finally
300 add(l, '3')
301 endtry
302 assert_equal(['1', 'wrong', '3'], l)
303enddef
304
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100305def ThrowFromDef()
306 throw 'getout'
307enddef
308
309func CatchInFunc()
310 try
311 call ThrowFromDef()
312 catch
313 let g:thrown_func = v:exception
314 endtry
315endfunc
316
317def CatchInDef()
318 try
319 ThrowFromDef()
320 catch
321 g:thrown_def = v:exception
322 endtry
323enddef
324
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100325def ReturnFinally(): string
326 try
327 return 'intry'
328 finally
329 g:in_finally = 'finally'
330 endtry
331 return 'end'
332enddef
333
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100334def Test_try_catch_nested()
335 CatchInFunc()
336 assert_equal('getout', g:thrown_func)
337
338 CatchInDef()
339 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100340
341 assert_equal('intry', ReturnFinally())
342 assert_equal('finally', g:in_finally)
343enddef
344
345def Test_try_catch_match()
346 let seq = 'a'
347 try
348 throw 'something'
349 catch /nothing/
350 seq ..= 'x'
351 catch /some/
352 seq ..= 'b'
353 catch /asdf/
354 seq ..= 'x'
355 finally
356 seq ..= 'c'
357 endtry
358 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100359enddef
360
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100361let s:export_script_lines =<< trim END
362 vim9script
363 let name: string = 'bob'
364 def Concat(arg: string): string
365 return name .. arg
366 enddef
367 let g:result = Concat('bie')
368 let g:localname = name
369
370 export const CONST = 1234
371 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100372 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100373 export def Exported(): string
374 return 'Exported'
375 enddef
376END
377
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100378def Test_vim9_import_export()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100379 let import_script_lines =<< trim END
380 vim9script
381 import {exported, Exported} from './Xexport.vim'
382 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100383 exported += 3
384 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100385 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100386
387 import {exp_name} from './Xexport.vim'
388 g:imported_name = exp_name
389 exp_name ..= ' Doe'
390 g:imported_name_appended = exp_name
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100391 g:imported_later = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100392 END
393
394 writefile(import_script_lines, 'Ximport.vim')
395 writefile(s:export_script_lines, 'Xexport.vim')
396
397 source Ximport.vim
398
399 assert_equal('bobbie', g:result)
400 assert_equal('bob', g:localname)
401 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100402 assert_equal(9879, g:imported_added)
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100403 assert_equal(9879, g:imported_later)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100404 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100405 assert_equal('John', g:imported_name)
406 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100407 assert_false(exists('g:name'))
408
409 unlet g:result
410 unlet g:localname
411 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100412 unlet g:imported_added
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100413 unlet g:imported_later
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100414 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100415 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100416 delete('Ximport.vim')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100417
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100418 let import_in_def_lines =<< trim END
419 vim9script
420 def ImportInDef()
421 import exported from './Xexport.vim'
422 g:imported = exported
423 exported += 7
424 g:imported_added = exported
425 enddef
426 ImportInDef()
427 END
428 writefile(import_in_def_lines, 'Ximport2.vim')
429 source Ximport2.vim
430 " TODO: this should be 9879
431 assert_equal(9876, g:imported)
432 assert_equal(9883, g:imported_added)
433 unlet g:imported
434 unlet g:imported_added
435 delete('Ximport2.vim')
436
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100437 let import_star_as_lines =<< trim END
438 vim9script
439 import * as Export from './Xexport.vim'
440 def UseExport()
441 g:imported = Export.exported
442 enddef
443 UseExport()
444 END
445 writefile(import_star_as_lines, 'Ximport.vim')
446 source Ximport.vim
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100447 assert_equal(9883, g:imported)
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100448
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100449 let import_star_as_lines_no_dot =<< trim END
450 vim9script
451 import * as Export from './Xexport.vim'
452 def Func()
453 let dummy = 1
454 let imported = Export + dummy
455 enddef
456 END
457 writefile(import_star_as_lines_no_dot, 'Ximport.vim')
458 assert_fails('source Ximport.vim', 'E1060:')
459
460 let import_star_as_lines_dot_space =<< trim END
461 vim9script
462 import * as Export from './Xexport.vim'
463 def Func()
464 let imported = Export . exported
465 enddef
466 END
467 writefile(import_star_as_lines_dot_space, 'Ximport.vim')
468 assert_fails('source Ximport.vim', 'E1074:')
469
470 let import_star_as_lines_missing_name =<< trim END
471 vim9script
472 import * as Export from './Xexport.vim'
473 def Func()
474 let imported = Export.
475 enddef
476 END
477 writefile(import_star_as_lines_missing_name, 'Ximport.vim')
478 assert_fails('source Ximport.vim', 'E1048:')
479
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100480 let import_star_lines =<< trim END
481 vim9script
482 import * from './Xexport.vim'
483 g:imported = exported
484 END
485 writefile(import_star_lines, 'Ximport.vim')
486 assert_fails('source Ximport.vim', 'E1045:')
487
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100488 " try to import something that exists but is not exported
489 let import_not_exported_lines =<< trim END
490 vim9script
491 import name from './Xexport.vim'
492 END
493 writefile(import_not_exported_lines, 'Ximport.vim')
494 assert_fails('source Ximport.vim', 'E1049:')
495
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100496 " try to import something that is already defined
497 let import_already_defined =<< trim END
498 vim9script
499 let exported = 'something'
500 import exported from './Xexport.vim'
501 END
502 writefile(import_already_defined, 'Ximport.vim')
503 assert_fails('source Ximport.vim', 'E1073:')
504
505 " try to import something that is already defined
506 import_already_defined =<< trim END
507 vim9script
508 let exported = 'something'
509 import * as exported from './Xexport.vim'
510 END
511 writefile(import_already_defined, 'Ximport.vim')
512 assert_fails('source Ximport.vim', 'E1073:')
513
514 " try to import something that is already defined
515 import_already_defined =<< trim END
516 vim9script
517 let exported = 'something'
518 import {exported} from './Xexport.vim'
519 END
520 writefile(import_already_defined, 'Ximport.vim')
521 assert_fails('source Ximport.vim', 'E1073:')
522
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100523 " import a very long name, requires making a copy
524 let import_long_name_lines =<< trim END
525 vim9script
526 import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
527 END
528 writefile(import_long_name_lines, 'Ximport.vim')
529 assert_fails('source Ximport.vim', 'E1048:')
530
531 let import_no_from_lines =<< trim END
532 vim9script
533 import name './Xexport.vim'
534 END
535 writefile(import_no_from_lines, 'Ximport.vim')
536 assert_fails('source Ximport.vim', 'E1070:')
537
538 let import_invalid_string_lines =<< trim END
539 vim9script
540 import name from Xexport.vim
541 END
542 writefile(import_invalid_string_lines, 'Ximport.vim')
543 assert_fails('source Ximport.vim', 'E1071:')
544
545 let import_wrong_name_lines =<< trim END
546 vim9script
547 import name from './XnoExport.vim'
548 END
549 writefile(import_wrong_name_lines, 'Ximport.vim')
550 assert_fails('source Ximport.vim', 'E1053:')
551
552 let import_missing_comma_lines =<< trim END
553 vim9script
554 import {exported name} from './Xexport.vim'
555 END
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100556 writefile(import_missing_comma_lines, 'Ximport3.vim')
557 assert_fails('source Ximport3.vim', 'E1046:')
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100558
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100559 delete('Ximport.vim')
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100560 delete('Ximport3.vim')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100561 delete('Xexport.vim')
562
Bram Moolenaar750802b2020-02-23 18:08:33 +0100563 " Check that in a Vim9 script 'cpo' is set to the Vim default.
564 set cpo&vi
565 let cpo_before = &cpo
566 let lines =<< trim END
567 vim9script
568 g:cpo_in_vim9script = &cpo
569 END
570 writefile(lines, 'Xvim9_script')
571 source Xvim9_script
572 assert_equal(cpo_before, &cpo)
573 set cpo&vim
574 assert_equal(&cpo, g:cpo_in_vim9script)
575 delete('Xvim9_script')
576enddef
577
578def Test_vim9script_fails()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100579 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
580 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100581 CheckScriptFailure(['export let some = 123'], 'E1042:')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100582 CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100583 CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
584 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
585
586 assert_fails('vim9script', 'E1038')
587 assert_fails('export something', 'E1042')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100588enddef
589
590def Test_vim9script_call()
591 let lines =<< trim END
592 vim9script
593 let var = ''
594 def MyFunc(arg: string)
595 var = arg
596 enddef
597 MyFunc('foobar')
598 assert_equal('foobar', var)
599
600 let str = 'barfoo'
601 str->MyFunc()
602 assert_equal('barfoo', var)
603
604 let g:value = 'value'
605 g:value->MyFunc()
606 assert_equal('value', var)
607
608 let listvar = []
609 def ListFunc(arg: list<number>)
610 listvar = arg
611 enddef
612 [1, 2, 3]->ListFunc()
613 assert_equal([1, 2, 3], listvar)
614
615 let dictvar = {}
616 def DictFunc(arg: dict<number>)
617 dictvar = arg
618 enddef
619 {'a': 1, 'b': 2}->DictFunc()
620 assert_equal(#{a: 1, b: 2}, dictvar)
621 #{a: 3, b: 4}->DictFunc()
622 assert_equal(#{a: 3, b: 4}, dictvar)
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100623
624 ('text')->MyFunc()
625 assert_equal('text', var)
626 ("some")->MyFunc()
627 assert_equal('some', var)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100628 END
629 writefile(lines, 'Xcall.vim')
630 source Xcall.vim
631 delete('Xcall.vim')
632enddef
633
634def Test_vim9script_call_fail_decl()
635 let lines =<< trim END
636 vim9script
637 let var = ''
638 def MyFunc(arg: string)
639 let var = 123
640 enddef
641 END
642 writefile(lines, 'Xcall_decl.vim')
643 assert_fails('source Xcall_decl.vim', 'E1054:')
644 delete('Xcall_decl.vim')
645enddef
646
647def Test_vim9script_call_fail_const()
648 let lines =<< trim END
649 vim9script
650 const var = ''
651 def MyFunc(arg: string)
652 var = 'asdf'
653 enddef
654 END
655 writefile(lines, 'Xcall_const.vim')
656 assert_fails('source Xcall_const.vim', 'E46:')
657 delete('Xcall_const.vim')
658enddef
659
660def Test_vim9script_reload()
661 let lines =<< trim END
662 vim9script
663 const var = ''
664 let valone = 1234
665 def MyFunc(arg: string)
666 valone = 5678
667 enddef
668 END
669 let morelines =<< trim END
670 let valtwo = 222
671 export def GetValtwo(): number
672 return valtwo
673 enddef
674 END
675 writefile(lines + morelines, 'Xreload.vim')
676 source Xreload.vim
677 source Xreload.vim
678 source Xreload.vim
679
680 let testlines =<< trim END
681 vim9script
682 def TheFunc()
683 import GetValtwo from './Xreload.vim'
684 assert_equal(222, GetValtwo())
685 enddef
686 TheFunc()
687 END
688 writefile(testlines, 'Ximport.vim')
689 source Ximport.vim
690
691 " test that when not using "morelines" valtwo is still defined
692 " need to source Xreload.vim again, import doesn't reload a script
693 writefile(lines, 'Xreload.vim')
694 source Xreload.vim
695 source Ximport.vim
696
697 " cannot declare a var twice
698 lines =<< trim END
699 vim9script
700 let valone = 1234
701 let valone = 5678
702 END
703 writefile(lines, 'Xreload.vim')
704 assert_fails('source Xreload.vim', 'E1041:')
705
706 delete('Xreload.vim')
707 delete('Ximport.vim')
708enddef
709
710def Test_import_absolute()
711 let import_lines = [
712 \ 'vim9script',
713 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100714 \ 'def UseExported()',
715 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100716 \ ' exported = 8888',
717 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100718 \ 'enddef',
719 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100720 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100721 \ ]
722 writefile(import_lines, 'Ximport_abs.vim')
723 writefile(s:export_script_lines, 'Xexport_abs.vim')
724
725 source Ximport_abs.vim
726
727 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100728 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100729 assert_match('<SNR>\d\+_UseExported.*'
730 \ .. 'g:imported_abs = exported.*'
731 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100732 \ .. '1 STOREG g:imported_abs.*'
733 \ .. 'exported = 8888.*'
734 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
735 \ .. 'g:imported_after = exported.*'
736 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
737 \ .. '5 STOREG g:imported_after.*'
738 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100739 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100740 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100741
742 delete('Ximport_abs.vim')
743 delete('Xexport_abs.vim')
744enddef
745
746def Test_import_rtp()
747 let import_lines = [
748 \ 'vim9script',
749 \ 'import exported from "Xexport_rtp.vim"',
750 \ 'g:imported_rtp = exported',
751 \ ]
752 writefile(import_lines, 'Ximport_rtp.vim')
753 mkdir('import')
754 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
755
756 let save_rtp = &rtp
757 &rtp = getcwd()
758 source Ximport_rtp.vim
759 &rtp = save_rtp
760
761 assert_equal(9876, g:imported_rtp)
762 unlet g:imported_rtp
763
764 delete('Ximport_rtp.vim')
765 delete('import/Xexport_rtp.vim')
766 delete('import', 'd')
767enddef
768
769def Test_fixed_size_list()
770 " will be allocated as one piece of memory, check that changes work
771 let l = [1, 2, 3, 4]
772 l->remove(0)
773 l->add(5)
774 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100775 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100776enddef
777
Bram Moolenaar673660a2020-01-26 16:50:05 +0100778" Test that inside :function a Python function can be defined, :def is not
779" recognized.
780func Test_function_python()
781 CheckFeature python3
782 let py = 'python3'
783 execute py "<< EOF"
784def do_something():
785 return 1
786EOF
787endfunc
788
Bram Moolenaar158906c2020-02-06 20:39:45 +0100789def IfElse(what: number): string
790 let res = ''
791 if what == 1
792 res = "one"
793 elseif what == 2
794 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100795 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100796 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100797 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100798 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100799enddef
800
Bram Moolenaar158906c2020-02-06 20:39:45 +0100801def Test_if_elseif_else()
802 assert_equal('one', IfElse(1))
803 assert_equal('two', IfElse(2))
804 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100805enddef
806
Bram Moolenaar6d69bf62020-03-03 19:02:12 +0100807let g:bool_true = v:true
808let g:bool_false = v:false
809
810def Test_if_const_expr()
811 let res = false
812 if true ? true : false
813 res = true
814 endif
815 assert_equal(true, res)
816
817 res = false
818 if g:bool_true ? true : false
819 res = true
820 endif
821 assert_equal(true, res)
822
823 res = false
824 if true ? g:bool_true : false
825 res = true
826 endif
827 assert_equal(true, res)
828
829 res = false
830 if true ? true : g:bool_false
831 res = true
832 endif
833 assert_equal(true, res)
834
835 res = false
836 if true ? false : true
837 res = true
838 endif
839 assert_equal(false, res)
840
841 res = false
842 if false ? false : true
843 res = true
844 endif
845 assert_equal(true, res)
846
847 res = false
848 if false ? true : false
849 res = true
850 endif
851 assert_equal(false, res)
852
853 res = false
854 if true && true
855 res = true
856 endif
857 assert_equal(true, res)
858
859 res = false
860 if true && false
861 res = true
862 endif
863 assert_equal(false, res)
864
865 res = false
866 if g:bool_true && false
867 res = true
868 endif
869 assert_equal(false, res)
870
871 res = false
872 if true && g:bool_false
873 res = true
874 endif
875 assert_equal(false, res)
876
877 res = false
878 if false && false
879 res = true
880 endif
881 assert_equal(false, res)
882
883 res = false
884 if true || false
885 res = true
886 endif
887 assert_equal(true, res)
888
889 res = false
890 if g:bool_true || false
891 res = true
892 endif
893 assert_equal(true, res)
894
895 res = false
896 if true || g:bool_false
897 res = true
898 endif
899 assert_equal(true, res)
900
901 res = false
902 if false || false
903 res = true
904 endif
905 assert_equal(false, res)
906
907enddef
908
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100909def Test_delfunc()
910 let lines =<< trim END
911 vim9script
912 def GoneSoon()
913 echo 'hello'
914 enddef
915
916 def CallGoneSoon()
917 GoneSoon()
918 enddef
919
920 delfunc GoneSoon
921 CallGoneSoon()
922 END
923 writefile(lines, 'XToDelFunc')
924 assert_fails('so XToDelFunc', 'E933')
925 assert_fails('so XToDelFunc', 'E933')
926
927 delete('XToDelFunc')
928enddef
929
Bram Moolenaarad39c092020-02-26 18:23:43 +0100930def Test_execute_cmd()
931 new
932 setline(1, 'default')
933 execute 'call setline(1, "execute-string")'
934 assert_equal('execute-string', getline(1))
935 let cmd1 = 'call setline(1,'
936 let cmd2 = '"execute-var")'
937 execute cmd1 cmd2
938 assert_equal('execute-var', getline(1))
939 execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
940 assert_equal('execute-var-string', getline(1))
941 let cmd_first = 'call '
942 let cmd_last = 'setline(1, "execute-var-var")'
943 execute cmd_first .. cmd_last
944 assert_equal('execute-var-var', getline(1))
945 bwipe!
946enddef
947
948def Test_echo_cmd()
949 echo 'something'
950 assert_match('^something$', Screenline(&lines))
951
952 let str1 = 'some'
953 let str2 = 'more'
954 echo str1 str2
955 assert_match('^some more$', Screenline(&lines))
956enddef
957
Bram Moolenaar41fe0612020-03-01 16:22:40 +0100958def Test_for_outside_of_function()
959 let lines =<< trim END
960 vim9script
961 new
962 for var in range(0, 3)
963 append(line('$'), var)
964 endfor
965 assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
966 bwipe!
967 END
968 writefile(lines, 'Xvim9for.vim')
969 source Xvim9for.vim
970 delete('Xvim9for.vim')
971enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100972
Bram Moolenaard0df1aa2020-03-04 21:50:46 +0100973def Test_while_loop()
974 let result = ''
975 let cnt = 0
976 while cnt < 555
977 if cnt == 3
978 break
979 endif
980 cnt += 1
981 if cnt == 2
982 continue
983 endif
984 result ..= cnt .. '_'
985 endwhile
986 assert_equal('1_3_', result)
987enddef
988
Bram Moolenaar9645e2d2020-03-20 20:48:49 +0100989def Test_interrupt_loop()
Bram Moolenaar97acfc72020-03-22 13:44:28 +0100990 let caught = false
Bram Moolenaar9645e2d2020-03-20 20:48:49 +0100991 let x = 0
Bram Moolenaar97acfc72020-03-22 13:44:28 +0100992 try
993 while 1
994 x += 1
995 if x == 100
996 feedkeys("\<C-C>", 'Lt')
997 endif
998 endwhile
999 catch
1000 caught = true
1001 assert_equal(100, x)
1002 endtry
1003 assert_true(caught, 'should have caught an exception')
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001004enddef
Bram Moolenaar20431c92020-03-20 18:39:46 +01001005
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01001006def Test_substitute_cmd()
1007 new
1008 setline(1, 'something')
1009 :substitute(some(other(
1010 assert_equal('otherthing', getline(1))
1011 bwipe!
1012
1013 " also when the context is Vim9 script
1014 let lines =<< trim END
1015 vim9script
1016 new
1017 setline(1, 'something')
1018 :substitute(some(other(
1019 assert_equal('otherthing', getline(1))
1020 bwipe!
1021 END
1022 writefile(lines, 'Xvim9lines')
1023 source Xvim9lines
1024
1025 delete('Xvim9lines')
1026enddef
1027
Bram Moolenaar20431c92020-03-20 18:39:46 +01001028def Test_redef_failure()
1029 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
1030 so Xdef
1031 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
1032 so Xdef
1033 call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
1034 call assert_fails('so Xdef', 'E1027:')
1035 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
1036 so Xdef
1037 call delete('Xdef')
1038
1039 call assert_equal(0, Func0())
1040 call assert_equal('Func1', Func1())
1041 call assert_equal('Func2', Func2())
1042
1043 delfunc! Func0
1044 delfunc! Func1
1045 delfunc! Func2
1046enddef
1047
Bram Moolenaar7d941ee2020-03-26 14:11:58 +01001048" Test for internal functions returning different types
1049func Test_InternalFuncRetType()
1050 let lines =<< trim END
1051 def RetFloat(): float
1052 return ceil(1.456)
1053 enddef
1054
1055 def RetListAny(): list<any>
1056 return items({'k' : 'v'})
1057 enddef
1058
1059 def RetListString(): list<string>
1060 return split('a:b:c', ':')
1061 enddef
1062
1063 def RetListDictAny(): list<dict<any>>
1064 return getbufinfo()
1065 enddef
1066
1067 def RetDictNumber(): dict<number>
1068 return wordcount()
1069 enddef
1070
1071 def RetDictString(): dict<string>
1072 return environ()
1073 enddef
1074 END
1075 call writefile(lines, 'Xscript')
1076 source Xscript
1077
1078 call assert_equal(2.0, RetFloat())
1079 call assert_equal([['k', 'v']], RetListAny())
1080 call assert_equal(['a', 'b', 'c'], RetListString())
1081 call assert_notequal([], RetListDictAny())
1082 call assert_notequal({}, RetDictNumber())
1083 call assert_notequal({}, RetDictString())
1084 call delete('Xscript')
1085endfunc
1086
1087" Test for passing too many or too few arguments to internal functions
1088func Test_internalfunc_arg_error()
1089 let l =<< trim END
1090 def! FArgErr(): float
1091 return ceil(1.1, 2)
1092 enddef
1093 END
1094 call writefile(l, 'Xinvalidarg')
1095 call assert_fails('so Xinvalidarg', 'E118:')
1096 let l =<< trim END
1097 def! FArgErr(): float
1098 return ceil()
1099 enddef
1100 END
1101 call writefile(l, 'Xinvalidarg')
1102 call assert_fails('so Xinvalidarg', 'E119:')
1103 call delete('Xinvalidarg')
1104endfunc
1105
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001106" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker