blob: 19df73c5ef28ee966823266acf7572ba40d897cb [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
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200263def Test_call_wrong_args()
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100264 call CheckDefFailure(['TakesOneArg()'], 'E119:')
265 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200266 call CheckDefFailure(['bufnr(xxx)'], 'E1001:')
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100267enddef
268
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100269" Default arg and varargs
270def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
271 let res = one .. ',' .. two
272 for s in rest
273 res ..= ',' .. s
274 endfor
275 return res
276enddef
277
278def Test_call_def_varargs()
279 call assert_fails('call MyDefVarargs()', 'E119:')
280 assert_equal('one,foo', MyDefVarargs('one'))
281 assert_equal('one,two', MyDefVarargs('one', 'two'))
282 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
283enddef
284
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100285def Test_using_var_as_arg()
286 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
287 call assert_fails('so Xdef', 'E1006:')
288 call delete('Xdef')
289enddef
290
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100291def Test_call_func_defined_later()
292 call assert_equal('one', DefinedLater('one'))
293 call assert_fails('call NotDefined("one")', 'E117:')
294enddef
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100295
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100296func DefinedLater(arg)
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100297 return a:arg
298endfunc
299
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100300def FuncWithForwardCall()
301 return DefinedEvenLater("yes")
302enddef
303
304def DefinedEvenLater(arg: string): string
305 return arg
306enddef
307
308def Test_error_in_nested_function()
309 " Error in called function requires unwinding the call stack.
310 assert_fails('call FuncWithForwardCall()', 'E1029')
311enddef
312
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100313def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100314 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
315 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
316 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
317 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaarcf3f8bf2020-03-26 13:15:42 +0100318
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200319 CheckScriptFailure(['def Func(): number', 'return', 'enddef'], 'E1003:')
320
Bram Moolenaarcf3f8bf2020-03-26 13:15:42 +0100321 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
322 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100323enddef
324
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100325def Test_arg_type_wrong()
326 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
327enddef
328
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100329def Test_try_catch()
330 let l = []
331 try
332 add(l, '1')
333 throw 'wrong'
334 add(l, '2')
335 catch
336 add(l, v:exception)
337 finally
338 add(l, '3')
339 endtry
340 assert_equal(['1', 'wrong', '3'], l)
341enddef
342
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100343def ThrowFromDef()
344 throw 'getout'
345enddef
346
347func CatchInFunc()
348 try
349 call ThrowFromDef()
350 catch
351 let g:thrown_func = v:exception
352 endtry
353endfunc
354
355def CatchInDef()
356 try
357 ThrowFromDef()
358 catch
359 g:thrown_def = v:exception
360 endtry
361enddef
362
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100363def ReturnFinally(): string
364 try
365 return 'intry'
366 finally
367 g:in_finally = 'finally'
368 endtry
369 return 'end'
370enddef
371
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100372def Test_try_catch_nested()
373 CatchInFunc()
374 assert_equal('getout', g:thrown_func)
375
376 CatchInDef()
377 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100378
379 assert_equal('intry', ReturnFinally())
380 assert_equal('finally', g:in_finally)
381enddef
382
383def Test_try_catch_match()
384 let seq = 'a'
385 try
386 throw 'something'
387 catch /nothing/
388 seq ..= 'x'
389 catch /some/
390 seq ..= 'b'
391 catch /asdf/
392 seq ..= 'x'
393 finally
394 seq ..= 'c'
395 endtry
396 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100397enddef
398
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100399let s:export_script_lines =<< trim END
400 vim9script
401 let name: string = 'bob'
402 def Concat(arg: string): string
403 return name .. arg
404 enddef
405 let g:result = Concat('bie')
406 let g:localname = name
407
408 export const CONST = 1234
409 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100410 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100411 export def Exported(): string
412 return 'Exported'
413 enddef
414END
415
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100416def Test_vim9_import_export()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100417 let import_script_lines =<< trim END
418 vim9script
419 import {exported, Exported} from './Xexport.vim'
420 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100421 exported += 3
422 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100423 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100424
425 import {exp_name} from './Xexport.vim'
426 g:imported_name = exp_name
427 exp_name ..= ' Doe'
428 g:imported_name_appended = exp_name
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100429 g:imported_later = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100430 END
431
432 writefile(import_script_lines, 'Ximport.vim')
433 writefile(s:export_script_lines, 'Xexport.vim')
434
435 source Ximport.vim
436
437 assert_equal('bobbie', g:result)
438 assert_equal('bob', g:localname)
439 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100440 assert_equal(9879, g:imported_added)
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100441 assert_equal(9879, g:imported_later)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100442 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100443 assert_equal('John', g:imported_name)
444 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100445 assert_false(exists('g:name'))
446
447 unlet g:result
448 unlet g:localname
449 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100450 unlet g:imported_added
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100451 unlet g:imported_later
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100452 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100453 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100454 delete('Ximport.vim')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100455
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100456 let import_in_def_lines =<< trim END
457 vim9script
458 def ImportInDef()
459 import exported from './Xexport.vim'
460 g:imported = exported
461 exported += 7
462 g:imported_added = exported
463 enddef
464 ImportInDef()
465 END
466 writefile(import_in_def_lines, 'Ximport2.vim')
467 source Ximport2.vim
468 " TODO: this should be 9879
469 assert_equal(9876, g:imported)
470 assert_equal(9883, g:imported_added)
471 unlet g:imported
472 unlet g:imported_added
473 delete('Ximport2.vim')
474
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100475 let import_star_as_lines =<< trim END
476 vim9script
477 import * as Export from './Xexport.vim'
478 def UseExport()
479 g:imported = Export.exported
480 enddef
481 UseExport()
482 END
483 writefile(import_star_as_lines, 'Ximport.vim')
484 source Ximport.vim
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100485 assert_equal(9883, g:imported)
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100486
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100487 let import_star_as_lines_no_dot =<< trim END
488 vim9script
489 import * as Export from './Xexport.vim'
490 def Func()
491 let dummy = 1
492 let imported = Export + dummy
493 enddef
494 END
495 writefile(import_star_as_lines_no_dot, 'Ximport.vim')
496 assert_fails('source Ximport.vim', 'E1060:')
497
498 let import_star_as_lines_dot_space =<< trim END
499 vim9script
500 import * as Export from './Xexport.vim'
501 def Func()
502 let imported = Export . exported
503 enddef
504 END
505 writefile(import_star_as_lines_dot_space, 'Ximport.vim')
506 assert_fails('source Ximport.vim', 'E1074:')
507
508 let import_star_as_lines_missing_name =<< trim END
509 vim9script
510 import * as Export from './Xexport.vim'
511 def Func()
512 let imported = Export.
513 enddef
514 END
515 writefile(import_star_as_lines_missing_name, 'Ximport.vim')
516 assert_fails('source Ximport.vim', 'E1048:')
517
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100518 let import_star_lines =<< trim END
519 vim9script
520 import * from './Xexport.vim'
521 g:imported = exported
522 END
523 writefile(import_star_lines, 'Ximport.vim')
524 assert_fails('source Ximport.vim', 'E1045:')
525
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100526 " try to import something that exists but is not exported
527 let import_not_exported_lines =<< trim END
528 vim9script
529 import name from './Xexport.vim'
530 END
531 writefile(import_not_exported_lines, 'Ximport.vim')
532 assert_fails('source Ximport.vim', 'E1049:')
533
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100534 " try to import something that is already defined
535 let import_already_defined =<< trim END
536 vim9script
537 let exported = 'something'
538 import exported from './Xexport.vim'
539 END
540 writefile(import_already_defined, 'Ximport.vim')
541 assert_fails('source Ximport.vim', 'E1073:')
542
543 " try to import something that is already defined
544 import_already_defined =<< trim END
545 vim9script
546 let exported = 'something'
547 import * as exported from './Xexport.vim'
548 END
549 writefile(import_already_defined, 'Ximport.vim')
550 assert_fails('source Ximport.vim', 'E1073:')
551
552 " try to import something that is already defined
553 import_already_defined =<< trim END
554 vim9script
555 let exported = 'something'
556 import {exported} from './Xexport.vim'
557 END
558 writefile(import_already_defined, 'Ximport.vim')
559 assert_fails('source Ximport.vim', 'E1073:')
560
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100561 " import a very long name, requires making a copy
562 let import_long_name_lines =<< trim END
563 vim9script
564 import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
565 END
566 writefile(import_long_name_lines, 'Ximport.vim')
567 assert_fails('source Ximport.vim', 'E1048:')
568
569 let import_no_from_lines =<< trim END
570 vim9script
571 import name './Xexport.vim'
572 END
573 writefile(import_no_from_lines, 'Ximport.vim')
574 assert_fails('source Ximport.vim', 'E1070:')
575
576 let import_invalid_string_lines =<< trim END
577 vim9script
578 import name from Xexport.vim
579 END
580 writefile(import_invalid_string_lines, 'Ximport.vim')
581 assert_fails('source Ximport.vim', 'E1071:')
582
583 let import_wrong_name_lines =<< trim END
584 vim9script
585 import name from './XnoExport.vim'
586 END
587 writefile(import_wrong_name_lines, 'Ximport.vim')
588 assert_fails('source Ximport.vim', 'E1053:')
589
590 let import_missing_comma_lines =<< trim END
591 vim9script
592 import {exported name} from './Xexport.vim'
593 END
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100594 writefile(import_missing_comma_lines, 'Ximport3.vim')
595 assert_fails('source Ximport3.vim', 'E1046:')
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100596
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100597 delete('Ximport.vim')
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100598 delete('Ximport3.vim')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100599 delete('Xexport.vim')
600
Bram Moolenaar750802b2020-02-23 18:08:33 +0100601 " Check that in a Vim9 script 'cpo' is set to the Vim default.
602 set cpo&vi
603 let cpo_before = &cpo
604 let lines =<< trim END
605 vim9script
606 g:cpo_in_vim9script = &cpo
607 END
608 writefile(lines, 'Xvim9_script')
609 source Xvim9_script
610 assert_equal(cpo_before, &cpo)
611 set cpo&vim
612 assert_equal(&cpo, g:cpo_in_vim9script)
613 delete('Xvim9_script')
614enddef
615
616def Test_vim9script_fails()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100617 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
618 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100619 CheckScriptFailure(['export let some = 123'], 'E1042:')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100620 CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100621 CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
622 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
623
624 assert_fails('vim9script', 'E1038')
625 assert_fails('export something', 'E1042')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100626enddef
627
628def Test_vim9script_call()
629 let lines =<< trim END
630 vim9script
631 let var = ''
632 def MyFunc(arg: string)
633 var = arg
634 enddef
635 MyFunc('foobar')
636 assert_equal('foobar', var)
637
638 let str = 'barfoo'
639 str->MyFunc()
640 assert_equal('barfoo', var)
641
642 let g:value = 'value'
643 g:value->MyFunc()
644 assert_equal('value', var)
645
646 let listvar = []
647 def ListFunc(arg: list<number>)
648 listvar = arg
649 enddef
650 [1, 2, 3]->ListFunc()
651 assert_equal([1, 2, 3], listvar)
652
653 let dictvar = {}
654 def DictFunc(arg: dict<number>)
655 dictvar = arg
656 enddef
657 {'a': 1, 'b': 2}->DictFunc()
658 assert_equal(#{a: 1, b: 2}, dictvar)
Bram Moolenaar33fa29c2020-03-28 19:41:33 +0100659 def CompiledDict()
660 {'a': 3, 'b': 4}->DictFunc()
661 enddef
662 CompiledDict()
663 assert_equal(#{a: 3, b: 4}, dictvar)
664
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100665 #{a: 3, b: 4}->DictFunc()
666 assert_equal(#{a: 3, b: 4}, dictvar)
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100667
668 ('text')->MyFunc()
669 assert_equal('text', var)
670 ("some")->MyFunc()
671 assert_equal('some', var)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100672 END
673 writefile(lines, 'Xcall.vim')
674 source Xcall.vim
675 delete('Xcall.vim')
676enddef
677
678def Test_vim9script_call_fail_decl()
679 let lines =<< trim END
680 vim9script
681 let var = ''
682 def MyFunc(arg: string)
683 let var = 123
684 enddef
685 END
686 writefile(lines, 'Xcall_decl.vim')
687 assert_fails('source Xcall_decl.vim', 'E1054:')
688 delete('Xcall_decl.vim')
689enddef
690
691def Test_vim9script_call_fail_const()
692 let lines =<< trim END
693 vim9script
694 const var = ''
695 def MyFunc(arg: string)
696 var = 'asdf'
697 enddef
698 END
699 writefile(lines, 'Xcall_const.vim')
700 assert_fails('source Xcall_const.vim', 'E46:')
701 delete('Xcall_const.vim')
702enddef
703
704def Test_vim9script_reload()
705 let lines =<< trim END
706 vim9script
707 const var = ''
708 let valone = 1234
709 def MyFunc(arg: string)
710 valone = 5678
711 enddef
712 END
713 let morelines =<< trim END
714 let valtwo = 222
715 export def GetValtwo(): number
716 return valtwo
717 enddef
718 END
719 writefile(lines + morelines, 'Xreload.vim')
720 source Xreload.vim
721 source Xreload.vim
722 source Xreload.vim
723
724 let testlines =<< trim END
725 vim9script
726 def TheFunc()
727 import GetValtwo from './Xreload.vim'
728 assert_equal(222, GetValtwo())
729 enddef
730 TheFunc()
731 END
732 writefile(testlines, 'Ximport.vim')
733 source Ximport.vim
734
735 " test that when not using "morelines" valtwo is still defined
736 " need to source Xreload.vim again, import doesn't reload a script
737 writefile(lines, 'Xreload.vim')
738 source Xreload.vim
739 source Ximport.vim
740
741 " cannot declare a var twice
742 lines =<< trim END
743 vim9script
744 let valone = 1234
745 let valone = 5678
746 END
747 writefile(lines, 'Xreload.vim')
748 assert_fails('source Xreload.vim', 'E1041:')
749
750 delete('Xreload.vim')
751 delete('Ximport.vim')
752enddef
753
754def Test_import_absolute()
755 let import_lines = [
756 \ 'vim9script',
757 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100758 \ 'def UseExported()',
759 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100760 \ ' exported = 8888',
761 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100762 \ 'enddef',
763 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100764 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100765 \ ]
766 writefile(import_lines, 'Ximport_abs.vim')
767 writefile(s:export_script_lines, 'Xexport_abs.vim')
768
769 source Ximport_abs.vim
770
771 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100772 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100773 assert_match('<SNR>\d\+_UseExported.*'
774 \ .. 'g:imported_abs = exported.*'
775 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100776 \ .. '1 STOREG g:imported_abs.*'
777 \ .. 'exported = 8888.*'
778 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
779 \ .. 'g:imported_after = exported.*'
780 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
781 \ .. '5 STOREG g:imported_after.*'
782 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100783 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100784 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100785
786 delete('Ximport_abs.vim')
787 delete('Xexport_abs.vim')
788enddef
789
790def Test_import_rtp()
791 let import_lines = [
792 \ 'vim9script',
793 \ 'import exported from "Xexport_rtp.vim"',
794 \ 'g:imported_rtp = exported',
795 \ ]
796 writefile(import_lines, 'Ximport_rtp.vim')
797 mkdir('import')
798 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
799
800 let save_rtp = &rtp
801 &rtp = getcwd()
802 source Ximport_rtp.vim
803 &rtp = save_rtp
804
805 assert_equal(9876, g:imported_rtp)
806 unlet g:imported_rtp
807
808 delete('Ximport_rtp.vim')
809 delete('import/Xexport_rtp.vim')
810 delete('import', 'd')
811enddef
812
813def Test_fixed_size_list()
814 " will be allocated as one piece of memory, check that changes work
815 let l = [1, 2, 3, 4]
816 l->remove(0)
817 l->add(5)
818 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100819 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100820enddef
821
Bram Moolenaar673660a2020-01-26 16:50:05 +0100822" Test that inside :function a Python function can be defined, :def is not
823" recognized.
824func Test_function_python()
825 CheckFeature python3
826 let py = 'python3'
827 execute py "<< EOF"
828def do_something():
829 return 1
830EOF
831endfunc
832
Bram Moolenaar158906c2020-02-06 20:39:45 +0100833def IfElse(what: number): string
834 let res = ''
835 if what == 1
836 res = "one"
837 elseif what == 2
838 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100839 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100840 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100841 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100842 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100843enddef
844
Bram Moolenaar158906c2020-02-06 20:39:45 +0100845def Test_if_elseif_else()
846 assert_equal('one', IfElse(1))
847 assert_equal('two', IfElse(2))
848 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100849enddef
850
Bram Moolenaar6d69bf62020-03-03 19:02:12 +0100851let g:bool_true = v:true
852let g:bool_false = v:false
853
854def Test_if_const_expr()
855 let res = false
856 if true ? true : false
857 res = true
858 endif
859 assert_equal(true, res)
860
861 res = false
862 if g:bool_true ? true : false
863 res = true
864 endif
865 assert_equal(true, res)
866
867 res = false
868 if true ? g:bool_true : false
869 res = true
870 endif
871 assert_equal(true, res)
872
873 res = false
874 if true ? true : g:bool_false
875 res = true
876 endif
877 assert_equal(true, res)
878
879 res = false
880 if true ? false : true
881 res = true
882 endif
883 assert_equal(false, res)
884
885 res = false
886 if false ? false : true
887 res = true
888 endif
889 assert_equal(true, res)
890
891 res = false
892 if false ? true : false
893 res = true
894 endif
895 assert_equal(false, res)
896
897 res = false
898 if true && true
899 res = true
900 endif
901 assert_equal(true, res)
902
903 res = false
904 if true && false
905 res = true
906 endif
907 assert_equal(false, res)
908
909 res = false
910 if g:bool_true && false
911 res = true
912 endif
913 assert_equal(false, res)
914
915 res = false
916 if true && g:bool_false
917 res = true
918 endif
919 assert_equal(false, res)
920
921 res = false
922 if false && false
923 res = true
924 endif
925 assert_equal(false, res)
926
927 res = false
928 if true || false
929 res = true
930 endif
931 assert_equal(true, res)
932
933 res = false
934 if g:bool_true || false
935 res = true
936 endif
937 assert_equal(true, res)
938
939 res = false
940 if true || g:bool_false
941 res = true
942 endif
943 assert_equal(true, res)
944
945 res = false
946 if false || false
947 res = true
948 endif
949 assert_equal(false, res)
950
951enddef
952
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100953def Test_delfunc()
954 let lines =<< trim END
955 vim9script
956 def GoneSoon()
957 echo 'hello'
958 enddef
959
960 def CallGoneSoon()
961 GoneSoon()
962 enddef
963
964 delfunc GoneSoon
965 CallGoneSoon()
966 END
967 writefile(lines, 'XToDelFunc')
968 assert_fails('so XToDelFunc', 'E933')
969 assert_fails('so XToDelFunc', 'E933')
970
971 delete('XToDelFunc')
972enddef
973
Bram Moolenaarad39c092020-02-26 18:23:43 +0100974def Test_execute_cmd()
975 new
976 setline(1, 'default')
977 execute 'call setline(1, "execute-string")'
978 assert_equal('execute-string', getline(1))
979 let cmd1 = 'call setline(1,'
980 let cmd2 = '"execute-var")'
981 execute cmd1 cmd2
982 assert_equal('execute-var', getline(1))
983 execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
984 assert_equal('execute-var-string', getline(1))
985 let cmd_first = 'call '
986 let cmd_last = 'setline(1, "execute-var-var")'
987 execute cmd_first .. cmd_last
988 assert_equal('execute-var-var', getline(1))
989 bwipe!
990enddef
991
992def Test_echo_cmd()
993 echo 'something'
994 assert_match('^something$', Screenline(&lines))
995
996 let str1 = 'some'
997 let str2 = 'more'
998 echo str1 str2
999 assert_match('^some more$', Screenline(&lines))
1000enddef
1001
Bram Moolenaar41fe0612020-03-01 16:22:40 +01001002def Test_for_outside_of_function()
1003 let lines =<< trim END
1004 vim9script
1005 new
1006 for var in range(0, 3)
1007 append(line('$'), var)
1008 endfor
1009 assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
1010 bwipe!
1011 END
1012 writefile(lines, 'Xvim9for.vim')
1013 source Xvim9for.vim
1014 delete('Xvim9for.vim')
1015enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001016
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01001017def Test_while_loop()
1018 let result = ''
1019 let cnt = 0
1020 while cnt < 555
1021 if cnt == 3
1022 break
1023 endif
1024 cnt += 1
1025 if cnt == 2
1026 continue
1027 endif
1028 result ..= cnt .. '_'
1029 endwhile
1030 assert_equal('1_3_', result)
1031enddef
1032
Bram Moolenaarbd5da372020-03-31 23:13:10 +02001033def Test_for_loop_fails()
1034 call CheckDefFailure(['for # in range(5)'], 'E690:')
1035 call CheckDefFailure(['for i In range(5)'], 'E690:')
1036 call CheckDefFailure(['let x = 5', 'for x in range(5)'], 'E1023:')
1037 call CheckScriptFailure(['def Func(arg)', 'for arg in range(5)', 'enddef'], 'E1006:')
1038 call CheckDefFailure(['for i in "text"'], 'E1024:')
1039enddef
1040
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001041def Test_interrupt_loop()
Bram Moolenaar97acfc72020-03-22 13:44:28 +01001042 let caught = false
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001043 let x = 0
Bram Moolenaar97acfc72020-03-22 13:44:28 +01001044 try
1045 while 1
1046 x += 1
1047 if x == 100
1048 feedkeys("\<C-C>", 'Lt')
1049 endif
1050 endwhile
1051 catch
1052 caught = true
1053 assert_equal(100, x)
1054 endtry
1055 assert_true(caught, 'should have caught an exception')
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001056enddef
Bram Moolenaar20431c92020-03-20 18:39:46 +01001057
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01001058def Test_substitute_cmd()
1059 new
1060 setline(1, 'something')
1061 :substitute(some(other(
1062 assert_equal('otherthing', getline(1))
1063 bwipe!
1064
1065 " also when the context is Vim9 script
1066 let lines =<< trim END
1067 vim9script
1068 new
1069 setline(1, 'something')
1070 :substitute(some(other(
1071 assert_equal('otherthing', getline(1))
1072 bwipe!
1073 END
1074 writefile(lines, 'Xvim9lines')
1075 source Xvim9lines
1076
1077 delete('Xvim9lines')
1078enddef
1079
Bram Moolenaar20431c92020-03-20 18:39:46 +01001080def Test_redef_failure()
1081 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
1082 so Xdef
1083 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
1084 so Xdef
1085 call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
1086 call assert_fails('so Xdef', 'E1027:')
1087 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
1088 so Xdef
1089 call delete('Xdef')
1090
1091 call assert_equal(0, Func0())
1092 call assert_equal('Func1', Func1())
1093 call assert_equal('Func2', Func2())
1094
1095 delfunc! Func0
1096 delfunc! Func1
1097 delfunc! Func2
1098enddef
1099
Bram Moolenaar7d941ee2020-03-26 14:11:58 +01001100" Test for internal functions returning different types
1101func Test_InternalFuncRetType()
1102 let lines =<< trim END
1103 def RetFloat(): float
1104 return ceil(1.456)
1105 enddef
1106
1107 def RetListAny(): list<any>
1108 return items({'k' : 'v'})
1109 enddef
1110
1111 def RetListString(): list<string>
1112 return split('a:b:c', ':')
1113 enddef
1114
1115 def RetListDictAny(): list<dict<any>>
1116 return getbufinfo()
1117 enddef
1118
1119 def RetDictNumber(): dict<number>
1120 return wordcount()
1121 enddef
1122
1123 def RetDictString(): dict<string>
1124 return environ()
1125 enddef
1126 END
1127 call writefile(lines, 'Xscript')
1128 source Xscript
1129
1130 call assert_equal(2.0, RetFloat())
1131 call assert_equal([['k', 'v']], RetListAny())
1132 call assert_equal(['a', 'b', 'c'], RetListString())
1133 call assert_notequal([], RetListDictAny())
1134 call assert_notequal({}, RetDictNumber())
1135 call assert_notequal({}, RetDictString())
1136 call delete('Xscript')
1137endfunc
1138
1139" Test for passing too many or too few arguments to internal functions
1140func Test_internalfunc_arg_error()
1141 let l =<< trim END
1142 def! FArgErr(): float
1143 return ceil(1.1, 2)
1144 enddef
1145 END
1146 call writefile(l, 'Xinvalidarg')
1147 call assert_fails('so Xinvalidarg', 'E118:')
1148 let l =<< trim END
1149 def! FArgErr(): float
1150 return ceil()
1151 enddef
1152 END
1153 call writefile(l, 'Xinvalidarg')
1154 call assert_fails('so Xinvalidarg', 'E119:')
1155 call delete('Xinvalidarg')
1156endfunc
1157
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001158" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker