blob: 0c0bf83a860743ce812cacf38ef644e838d225aa [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 Moolenaara8c17702020-04-01 21:17:24 +020034let g:inc_counter = 1
35let $SOME_ENV_VAR = 'some'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010036
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010037def Test_assignment()
38 let bool1: bool = true
39 assert_equal(v:true, bool1)
40 let bool2: bool = false
41 assert_equal(v:false, bool2)
42
Bram Moolenaar0c2ca582020-02-25 22:58:29 +010043 let list1: list<bool> = [false, true, false]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010044 let list2: list<number> = [1, 2, 3]
Bram Moolenaar0c2ca582020-02-25 22:58:29 +010045 let list3: list<string> = ['sdf', 'asdf']
46 let list4: list<any> = ['yes', true, 1234]
47 let list5: list<blob> = [0z01, 0z02]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010048
Bram Moolenaar436472f2020-02-20 22:54:43 +010049 let listS: list<string> = []
50 let listN: list<number> = []
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010051
Bram Moolenaar0c2ca582020-02-25 22:58:29 +010052 let dict1: dict<bool> = #{one: false, two: true}
Bram Moolenaar8a7d6542020-01-26 15:56:19 +010053 let dict2: dict<number> = #{one: 1, two: 2}
Bram Moolenaar0c2ca582020-02-25 22:58:29 +010054 let dict3: dict<string> = #{key: 'value'}
55 let dict4: dict<any> = #{one: 1, two: '2'}
56 let dict5: dict<blob> = #{one: 0z01, tw: 0z02}
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010057
Bram Moolenaar9be61bb2020-03-30 22:51:24 +020058 let a: number = 6
59 assert_equal(6, a)
60
Bram Moolenaar42a480b2020-02-29 23:23:47 +010061 if has('channel')
62 let chan1: channel
Bram Moolenaarfbdd08e2020-03-01 14:04:46 +010063 let job1: job
Bram Moolenaarf51cb4e2020-03-01 17:55:14 +010064 let job2: job = job_start('willfail')
Bram Moolenaar42a480b2020-02-29 23:23:47 +010065 endif
Bram Moolenaarfbdd08e2020-03-01 14:04:46 +010066 if has('float')
67 let float1: float = 3.4
68 endif
Bram Moolenaar087d2e12020-03-01 15:36:42 +010069 let funky1: func
70 let funky2: func = function('len')
71 let party1: partial
72 let party2: partial = funcref('Test_syntax')
Bram Moolenaar42a480b2020-02-29 23:23:47 +010073
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +010074 " type becomes list<any>
75 let somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c']
Bram Moolenaar5381c7a2020-03-02 22:53:32 +010076 " type becomes dict<any>
77 let somedict = rand() > 0 ? #{a: 1, b: 2} : #{a: 'a', b: 'b'}
Bram Moolenaar61a6d4e2020-03-01 23:32:25 +010078
Bram Moolenaar401d9ff2020-02-19 18:14:44 +010079 g:newvar = 'new'
80 assert_equal('new', g:newvar)
81
82 assert_equal('yes', g:existing)
83 g:existing = 'no'
84 assert_equal('no', g:existing)
85
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010086 v:char = 'abc'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010087 assert_equal('abc', v:char)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010088
89 $ENVVAR = 'foobar'
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010090 assert_equal('foobar', $ENVVAR)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +010091 $ENVVAR = ''
Bram Moolenaar6e587dc2020-02-06 13:15:52 +010092
Bram Moolenaarfd1823e2020-02-19 20:23:11 +010093 s:appendToMe ..= 'yyy'
94 assert_equal('xxxyyy', s:appendToMe)
95 s:addToMe += 222
96 assert_equal(333, s:addToMe)
Bram Moolenaar0bbf7222020-02-19 22:31:48 +010097 s:newVar = 'new'
98 assert_equal('new', s:newVar)
Bram Moolenaara8c17702020-04-01 21:17:24 +020099
100 set ts=7
101 &ts += 1
102 assert_equal(8, &ts)
103 call CheckDefFailure(['&notex += 3'], 'E113:')
104 call CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
105 call CheckDefFailure(['&path += 3'], 'E1013:')
106
107 g:inc_counter += 1
108 assert_equal(2, g:inc_counter)
109
110 $SOME_ENV_VAR ..= 'more'
111 assert_equal('somemore', $SOME_ENV_VAR)
112 call CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1013:')
113 call CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1013:')
114
115 @a = 'areg'
116 @a ..= 'add'
117 assert_equal('aregadd', @a)
118 call CheckDefFailure(['@a += "more"'], 'E1013:')
119 call CheckDefFailure(['@a += 123'], 'E1013:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100120enddef
121
122func Test_assignment_failure()
123 call CheckDefFailure(['let var=234'], 'E1004:')
124 call CheckDefFailure(['let var =234'], 'E1004:')
125 call CheckDefFailure(['let var= 234'], 'E1004:')
126
127 call CheckDefFailure(['let true = 1'], 'E1034:')
128 call CheckDefFailure(['let false = 1'], 'E1034:')
129
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200130 call CheckDefFailure(['let [a; b; c] = g:list'], 'E452:')
131
132 call CheckDefFailure(['let &option'], 'E1052:')
133 call CheckDefFailure(['&g:option = 5'], 'E113:')
134
135 call CheckDefFailure(['let $VAR = 5'], 'E1065:')
136
137 call CheckDefFailure(['let @~ = 5'], 'E354:')
138 call CheckDefFailure(['let @a = 5'], 'E1066:')
139
140 call CheckDefFailure(['let g:var = 5'], 'E1016:')
141
142 call CheckDefFailure(['let anr = 4', 'anr ..= "text"'], 'E1019:')
143 call CheckDefFailure(['let xnr += 4'], 'E1020:')
144
Bram Moolenaar33fa29c2020-03-28 19:41:33 +0100145 call CheckScriptFailure(['vim9script', 'def Func()', 'let dummy = s:notfound', 'enddef'], 'E1050:')
146
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100147 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
148 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
149
150 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
151 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
152
153 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
154 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100155
156 call CheckDefFailure(['let var: dict <number>'], 'E1007:')
157 call CheckDefFailure(['let var: dict<number'], 'E1009:')
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100158endfunc
159
160func Test_wrong_type()
161 call CheckDefFailure(['let var: list<nothing>'], 'E1010:')
162 call CheckDefFailure(['let var: list<list<nothing>>'], 'E1010:')
163 call CheckDefFailure(['let var: dict<nothing>'], 'E1010:')
164 call CheckDefFailure(['let var: dict<dict<nothing>>'], 'E1010:')
165
166 call CheckDefFailure(['let var: dict<number'], 'E1009:')
167 call CheckDefFailure(['let var: dict<list<number>'], 'E1009:')
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100168
169 call CheckDefFailure(['let var: ally'], 'E1010:')
170 call CheckDefFailure(['let var: bram'], 'E1010:')
171 call CheckDefFailure(['let var: cathy'], 'E1010:')
172 call CheckDefFailure(['let var: dom'], 'E1010:')
173 call CheckDefFailure(['let var: freddy'], 'E1010:')
174 call CheckDefFailure(['let var: john'], 'E1010:')
175 call CheckDefFailure(['let var: larry'], 'E1010:')
176 call CheckDefFailure(['let var: ned'], 'E1010:')
177 call CheckDefFailure(['let var: pam'], 'E1010:')
178 call CheckDefFailure(['let var: sam'], 'E1010:')
179 call CheckDefFailure(['let var: vim'], 'E1010:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100180endfunc
181
182func Test_const()
183 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
184 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
185 call CheckDefFailure(['const two'], 'E1021:')
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200186 call CheckDefFailure(['const &option'], 'E996:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100187endfunc
188
189def Test_block()
190 let outer = 1
191 {
192 let inner = 2
193 assert_equal(1, outer)
194 assert_equal(2, inner)
195 }
196 assert_equal(1, outer)
197enddef
198
199func Test_block_failure()
200 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
201endfunc
202
203def ReturnString(): string
204 return 'string'
205enddef
206
207def ReturnNumber(): number
208 return 123
209enddef
210
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100211let g:notNumber = 'string'
212
213def ReturnGlobal(): number
214 return g:notNumber
215enddef
216
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200217def Test_return_something()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100218 assert_equal('string', ReturnString())
219 assert_equal(123, ReturnNumber())
Bram Moolenaar09f28f42020-02-20 23:08:34 +0100220 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100221enddef
222
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200223let s:nothing = 0
224def ReturnNothing()
225 s:nothing = 1
226 if true
227 return
228 endif
229 s:nothing = 2
230enddef
231
232def Test_return_nothing()
233 ReturnNothing()
234 assert_equal(1, s:nothing)
235enddef
236
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100237func Increment()
238 let g:counter += 1
239endfunc
240
241def Test_call_ufunc_count()
242 g:counter = 1
243 Increment()
244 Increment()
245 Increment()
246 " works with and without :call
247 assert_equal(4, g:counter)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100248 call assert_equal(4, g:counter)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100249 unlet g:counter
250enddef
251
252def MyVarargs(arg: string, ...rest: list<string>): string
253 let res = arg
254 for s in rest
255 res ..= ',' .. s
256 endfor
257 return res
258enddef
259
260def Test_call_varargs()
261 assert_equal('one', MyVarargs('one'))
262 assert_equal('one,two', MyVarargs('one', 'two'))
263 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
264enddef
265
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100266def MyDefaultArgs(name = 'string'): string
267 return name
268enddef
269
270def Test_call_default_args()
271 assert_equal('string', MyDefaultArgs())
272 assert_equal('one', MyDefaultArgs('one'))
273 assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
274enddef
275
276func Test_call_default_args_from_func()
277 call assert_equal('string', MyDefaultArgs())
278 call assert_equal('one', MyDefaultArgs('one'))
279 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
280endfunc
281
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100282func TakesOneArg(arg)
283 echo a:arg
284endfunc
285
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200286def Test_call_wrong_args()
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100287 call CheckDefFailure(['TakesOneArg()'], 'E119:')
288 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:')
Bram Moolenaarbd5da372020-03-31 23:13:10 +0200289 call CheckDefFailure(['bufnr(xxx)'], 'E1001:')
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100290enddef
291
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100292" Default arg and varargs
293def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string
294 let res = one .. ',' .. two
295 for s in rest
296 res ..= ',' .. s
297 endfor
298 return res
299enddef
300
301def Test_call_def_varargs()
302 call assert_fails('call MyDefVarargs()', 'E119:')
303 assert_equal('one,foo', MyDefVarargs('one'))
304 assert_equal('one,two', MyDefVarargs('one', 'two'))
305 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three'))
306enddef
307
Bram Moolenaar42a480b2020-02-29 23:23:47 +0100308def Test_using_var_as_arg()
309 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef')
310 call assert_fails('so Xdef', 'E1006:')
311 call delete('Xdef')
312enddef
313
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100314def Test_call_func_defined_later()
315 call assert_equal('one', DefinedLater('one'))
316 call assert_fails('call NotDefined("one")', 'E117:')
317enddef
Bram Moolenaar170fcfc2020-02-06 17:51:35 +0100318
Bram Moolenaarb35efa52020-02-26 20:15:18 +0100319func DefinedLater(arg)
Bram Moolenaar26e117e2020-02-04 21:24:15 +0100320 return a:arg
321endfunc
322
Bram Moolenaar7eeefd42020-02-26 21:24:23 +0100323def FuncWithForwardCall()
324 return DefinedEvenLater("yes")
325enddef
326
327def DefinedEvenLater(arg: string): string
328 return arg
329enddef
330
331def Test_error_in_nested_function()
332 " Error in called function requires unwinding the call stack.
333 assert_fails('call FuncWithForwardCall()', 'E1029')
334enddef
335
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100336def Test_return_type_wrong()
Bram Moolenaar978d1702020-01-26 17:38:12 +0100337 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
338 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number')
339 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
340 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string')
Bram Moolenaarcf3f8bf2020-03-26 13:15:42 +0100341
Bram Moolenaar9be61bb2020-03-30 22:51:24 +0200342 CheckScriptFailure(['def Func(): number', 'return', 'enddef'], 'E1003:')
343
Bram Moolenaarcf3f8bf2020-03-26 13:15:42 +0100344 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:')
345 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100346enddef
347
Bram Moolenaarbfe12042020-02-04 21:54:07 +0100348def Test_arg_type_wrong()
349 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>')
350enddef
351
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100352def Test_try_catch()
353 let l = []
354 try
355 add(l, '1')
356 throw 'wrong'
357 add(l, '2')
358 catch
359 add(l, v:exception)
360 finally
361 add(l, '3')
362 endtry
363 assert_equal(['1', 'wrong', '3'], l)
364enddef
365
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100366def ThrowFromDef()
367 throw 'getout'
368enddef
369
370func CatchInFunc()
371 try
372 call ThrowFromDef()
373 catch
374 let g:thrown_func = v:exception
375 endtry
376endfunc
377
378def CatchInDef()
379 try
380 ThrowFromDef()
381 catch
382 g:thrown_def = v:exception
383 endtry
384enddef
385
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100386def ReturnFinally(): string
387 try
388 return 'intry'
389 finally
390 g:in_finally = 'finally'
391 endtry
392 return 'end'
393enddef
394
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100395def Test_try_catch_nested()
396 CatchInFunc()
397 assert_equal('getout', g:thrown_func)
398
399 CatchInDef()
400 assert_equal('getout', g:thrown_def)
Bram Moolenaarf575adf2020-02-20 20:41:06 +0100401
402 assert_equal('intry', ReturnFinally())
403 assert_equal('finally', g:in_finally)
404enddef
405
406def Test_try_catch_match()
407 let seq = 'a'
408 try
409 throw 'something'
410 catch /nothing/
411 seq ..= 'x'
412 catch /some/
413 seq ..= 'b'
414 catch /asdf/
415 seq ..= 'x'
416 finally
417 seq ..= 'c'
418 endtry
419 assert_equal('abc', seq)
Bram Moolenaar257cc5e2020-02-19 17:06:11 +0100420enddef
421
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100422let s:export_script_lines =<< trim END
423 vim9script
424 let name: string = 'bob'
425 def Concat(arg: string): string
426 return name .. arg
427 enddef
428 let g:result = Concat('bie')
429 let g:localname = name
430
431 export const CONST = 1234
432 export let exported = 9876
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100433 export let exp_name = 'John'
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100434 export def Exported(): string
435 return 'Exported'
436 enddef
437END
438
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100439def Test_vim9_import_export()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100440 let import_script_lines =<< trim END
441 vim9script
442 import {exported, Exported} from './Xexport.vim'
443 g:imported = exported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100444 exported += 3
445 g:imported_added = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100446 g:imported_func = Exported()
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100447
448 import {exp_name} from './Xexport.vim'
449 g:imported_name = exp_name
450 exp_name ..= ' Doe'
451 g:imported_name_appended = exp_name
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100452 g:imported_later = exported
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100453 END
454
455 writefile(import_script_lines, 'Ximport.vim')
456 writefile(s:export_script_lines, 'Xexport.vim')
457
458 source Ximport.vim
459
460 assert_equal('bobbie', g:result)
461 assert_equal('bob', g:localname)
462 assert_equal(9876, g:imported)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100463 assert_equal(9879, g:imported_added)
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100464 assert_equal(9879, g:imported_later)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100465 assert_equal('Exported', g:imported_func)
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100466 assert_equal('John', g:imported_name)
467 assert_equal('John Doe', g:imported_name_appended)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100468 assert_false(exists('g:name'))
469
470 unlet g:result
471 unlet g:localname
472 unlet g:imported
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100473 unlet g:imported_added
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100474 unlet g:imported_later
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100475 unlet g:imported_func
Bram Moolenaar6e587dc2020-02-06 13:15:52 +0100476 unlet g:imported_name g:imported_name_appended
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100477 delete('Ximport.vim')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100478
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100479 let import_in_def_lines =<< trim END
480 vim9script
481 def ImportInDef()
482 import exported from './Xexport.vim'
483 g:imported = exported
484 exported += 7
485 g:imported_added = exported
486 enddef
487 ImportInDef()
488 END
489 writefile(import_in_def_lines, 'Ximport2.vim')
490 source Ximport2.vim
491 " TODO: this should be 9879
492 assert_equal(9876, g:imported)
493 assert_equal(9883, g:imported_added)
494 unlet g:imported
495 unlet g:imported_added
496 delete('Ximport2.vim')
497
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100498 let import_star_as_lines =<< trim END
499 vim9script
500 import * as Export from './Xexport.vim'
501 def UseExport()
502 g:imported = Export.exported
503 enddef
504 UseExport()
505 END
506 writefile(import_star_as_lines, 'Ximport.vim')
507 source Ximport.vim
Bram Moolenaar5381c7a2020-03-02 22:53:32 +0100508 assert_equal(9883, g:imported)
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100509
Bram Moolenaar599c89c2020-03-28 14:53:20 +0100510 let import_star_as_lines_no_dot =<< trim END
511 vim9script
512 import * as Export from './Xexport.vim'
513 def Func()
514 let dummy = 1
515 let imported = Export + dummy
516 enddef
517 END
518 writefile(import_star_as_lines_no_dot, 'Ximport.vim')
519 assert_fails('source Ximport.vim', 'E1060:')
520
521 let import_star_as_lines_dot_space =<< trim END
522 vim9script
523 import * as Export from './Xexport.vim'
524 def Func()
525 let imported = Export . exported
526 enddef
527 END
528 writefile(import_star_as_lines_dot_space, 'Ximport.vim')
529 assert_fails('source Ximport.vim', 'E1074:')
530
531 let import_star_as_lines_missing_name =<< trim END
532 vim9script
533 import * as Export from './Xexport.vim'
534 def Func()
535 let imported = Export.
536 enddef
537 END
538 writefile(import_star_as_lines_missing_name, 'Ximport.vim')
539 assert_fails('source Ximport.vim', 'E1048:')
540
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100541 let import_star_lines =<< trim END
542 vim9script
543 import * from './Xexport.vim'
544 g:imported = exported
545 END
546 writefile(import_star_lines, 'Ximport.vim')
547 assert_fails('source Ximport.vim', 'E1045:')
548
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100549 " try to import something that exists but is not exported
550 let import_not_exported_lines =<< trim END
551 vim9script
552 import name from './Xexport.vim'
553 END
554 writefile(import_not_exported_lines, 'Ximport.vim')
555 assert_fails('source Ximport.vim', 'E1049:')
556
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100557 " try to import something that is already defined
558 let import_already_defined =<< trim END
559 vim9script
560 let exported = 'something'
561 import exported from './Xexport.vim'
562 END
563 writefile(import_already_defined, 'Ximport.vim')
564 assert_fails('source Ximport.vim', 'E1073:')
565
566 " try to import something that is already defined
567 import_already_defined =<< trim END
568 vim9script
569 let exported = 'something'
570 import * as exported from './Xexport.vim'
571 END
572 writefile(import_already_defined, 'Ximport.vim')
573 assert_fails('source Ximport.vim', 'E1073:')
574
575 " try to import something that is already defined
576 import_already_defined =<< trim END
577 vim9script
578 let exported = 'something'
579 import {exported} from './Xexport.vim'
580 END
581 writefile(import_already_defined, 'Ximport.vim')
582 assert_fails('source Ximport.vim', 'E1073:')
583
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100584 " import a very long name, requires making a copy
585 let import_long_name_lines =<< trim END
586 vim9script
587 import name012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 from './Xexport.vim'
588 END
589 writefile(import_long_name_lines, 'Ximport.vim')
590 assert_fails('source Ximport.vim', 'E1048:')
591
592 let import_no_from_lines =<< trim END
593 vim9script
594 import name './Xexport.vim'
595 END
596 writefile(import_no_from_lines, 'Ximport.vim')
597 assert_fails('source Ximport.vim', 'E1070:')
598
599 let import_invalid_string_lines =<< trim END
600 vim9script
601 import name from Xexport.vim
602 END
603 writefile(import_invalid_string_lines, 'Ximport.vim')
604 assert_fails('source Ximport.vim', 'E1071:')
605
606 let import_wrong_name_lines =<< trim END
607 vim9script
608 import name from './XnoExport.vim'
609 END
610 writefile(import_wrong_name_lines, 'Ximport.vim')
611 assert_fails('source Ximport.vim', 'E1053:')
612
613 let import_missing_comma_lines =<< trim END
614 vim9script
615 import {exported name} from './Xexport.vim'
616 END
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100617 writefile(import_missing_comma_lines, 'Ximport3.vim')
618 assert_fails('source Ximport3.vim', 'E1046:')
Bram Moolenaarfa29c8a2020-02-23 22:35:05 +0100619
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100620 delete('Ximport.vim')
Bram Moolenaar5269bd22020-03-09 19:25:27 +0100621 delete('Ximport3.vim')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100622 delete('Xexport.vim')
623
Bram Moolenaar750802b2020-02-23 18:08:33 +0100624 " Check that in a Vim9 script 'cpo' is set to the Vim default.
625 set cpo&vi
626 let cpo_before = &cpo
627 let lines =<< trim END
628 vim9script
629 g:cpo_in_vim9script = &cpo
630 END
631 writefile(lines, 'Xvim9_script')
632 source Xvim9_script
633 assert_equal(cpo_before, &cpo)
634 set cpo&vim
635 assert_equal(&cpo, g:cpo_in_vim9script)
636 delete('Xvim9_script')
637enddef
638
639def Test_vim9script_fails()
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100640 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
641 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100642 CheckScriptFailure(['export let some = 123'], 'E1042:')
Bram Moolenaarf2d5c242020-02-23 21:25:54 +0100643 CheckScriptFailure(['import some from "./Xexport.vim"'], 'E1042:')
Bram Moolenaar750802b2020-02-23 18:08:33 +0100644 CheckScriptFailure(['vim9script', 'export let g:some'], 'E1044:')
645 CheckScriptFailure(['vim9script', 'export echo 134'], 'E1043:')
646
647 assert_fails('vim9script', 'E1038')
648 assert_fails('export something', 'E1042')
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100649enddef
650
651def Test_vim9script_call()
652 let lines =<< trim END
653 vim9script
654 let var = ''
655 def MyFunc(arg: string)
656 var = arg
657 enddef
658 MyFunc('foobar')
659 assert_equal('foobar', var)
660
661 let str = 'barfoo'
662 str->MyFunc()
663 assert_equal('barfoo', var)
664
665 let g:value = 'value'
666 g:value->MyFunc()
667 assert_equal('value', var)
668
669 let listvar = []
670 def ListFunc(arg: list<number>)
671 listvar = arg
672 enddef
673 [1, 2, 3]->ListFunc()
674 assert_equal([1, 2, 3], listvar)
675
676 let dictvar = {}
677 def DictFunc(arg: dict<number>)
678 dictvar = arg
679 enddef
680 {'a': 1, 'b': 2}->DictFunc()
681 assert_equal(#{a: 1, b: 2}, dictvar)
Bram Moolenaar33fa29c2020-03-28 19:41:33 +0100682 def CompiledDict()
683 {'a': 3, 'b': 4}->DictFunc()
684 enddef
685 CompiledDict()
686 assert_equal(#{a: 3, b: 4}, dictvar)
687
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100688 #{a: 3, b: 4}->DictFunc()
689 assert_equal(#{a: 3, b: 4}, dictvar)
Bram Moolenaar0c6ceaf2020-02-22 18:36:32 +0100690
691 ('text')->MyFunc()
692 assert_equal('text', var)
693 ("some")->MyFunc()
694 assert_equal('some', var)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100695 END
696 writefile(lines, 'Xcall.vim')
697 source Xcall.vim
698 delete('Xcall.vim')
699enddef
700
701def Test_vim9script_call_fail_decl()
702 let lines =<< trim END
703 vim9script
704 let var = ''
705 def MyFunc(arg: string)
706 let var = 123
707 enddef
708 END
709 writefile(lines, 'Xcall_decl.vim')
710 assert_fails('source Xcall_decl.vim', 'E1054:')
711 delete('Xcall_decl.vim')
712enddef
713
714def Test_vim9script_call_fail_const()
715 let lines =<< trim END
716 vim9script
717 const var = ''
718 def MyFunc(arg: string)
719 var = 'asdf'
720 enddef
721 END
722 writefile(lines, 'Xcall_const.vim')
723 assert_fails('source Xcall_const.vim', 'E46:')
724 delete('Xcall_const.vim')
725enddef
726
727def Test_vim9script_reload()
728 let lines =<< trim END
729 vim9script
730 const var = ''
731 let valone = 1234
732 def MyFunc(arg: string)
733 valone = 5678
734 enddef
735 END
736 let morelines =<< trim END
737 let valtwo = 222
738 export def GetValtwo(): number
739 return valtwo
740 enddef
741 END
742 writefile(lines + morelines, 'Xreload.vim')
743 source Xreload.vim
744 source Xreload.vim
745 source Xreload.vim
746
747 let testlines =<< trim END
748 vim9script
749 def TheFunc()
750 import GetValtwo from './Xreload.vim'
751 assert_equal(222, GetValtwo())
752 enddef
753 TheFunc()
754 END
755 writefile(testlines, 'Ximport.vim')
756 source Ximport.vim
757
758 " test that when not using "morelines" valtwo is still defined
759 " need to source Xreload.vim again, import doesn't reload a script
760 writefile(lines, 'Xreload.vim')
761 source Xreload.vim
762 source Ximport.vim
763
764 " cannot declare a var twice
765 lines =<< trim END
766 vim9script
767 let valone = 1234
768 let valone = 5678
769 END
770 writefile(lines, 'Xreload.vim')
771 assert_fails('source Xreload.vim', 'E1041:')
772
773 delete('Xreload.vim')
774 delete('Ximport.vim')
775enddef
776
777def Test_import_absolute()
778 let import_lines = [
779 \ 'vim9script',
780 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100781 \ 'def UseExported()',
782 \ ' g:imported_abs = exported',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100783 \ ' exported = 8888',
784 \ ' g:imported_after = exported',
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100785 \ 'enddef',
786 \ 'UseExported()',
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100787 \ 'g:import_disassembled = execute("disass UseExported")',
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100788 \ ]
789 writefile(import_lines, 'Ximport_abs.vim')
790 writefile(s:export_script_lines, 'Xexport_abs.vim')
791
792 source Ximport_abs.vim
793
794 assert_equal(9876, g:imported_abs)
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100795 assert_equal(8888, g:imported_after)
Bram Moolenaarb283a8a2020-02-02 22:24:04 +0100796 assert_match('<SNR>\d\+_UseExported.*'
797 \ .. 'g:imported_abs = exported.*'
798 \ .. '0 LOADSCRIPT exported from .*Xexport_abs.vim.*'
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100799 \ .. '1 STOREG g:imported_abs.*'
800 \ .. 'exported = 8888.*'
801 \ .. '3 STORESCRIPT exported in .*Xexport_abs.vim.*'
802 \ .. 'g:imported_after = exported.*'
803 \ .. '4 LOADSCRIPT exported from .*Xexport_abs.vim.*'
804 \ .. '5 STOREG g:imported_after.*'
805 \, g:import_disassembled)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100806 unlet g:imported_abs
Bram Moolenaar4e12a5d2020-02-03 20:50:59 +0100807 unlet g:import_disassembled
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100808
809 delete('Ximport_abs.vim')
810 delete('Xexport_abs.vim')
811enddef
812
813def Test_import_rtp()
814 let import_lines = [
815 \ 'vim9script',
816 \ 'import exported from "Xexport_rtp.vim"',
817 \ 'g:imported_rtp = exported',
818 \ ]
819 writefile(import_lines, 'Ximport_rtp.vim')
820 mkdir('import')
821 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
822
823 let save_rtp = &rtp
824 &rtp = getcwd()
825 source Ximport_rtp.vim
826 &rtp = save_rtp
827
828 assert_equal(9876, g:imported_rtp)
829 unlet g:imported_rtp
830
831 delete('Ximport_rtp.vim')
832 delete('import/Xexport_rtp.vim')
833 delete('import', 'd')
834enddef
835
836def Test_fixed_size_list()
837 " will be allocated as one piece of memory, check that changes work
838 let l = [1, 2, 3, 4]
839 l->remove(0)
840 l->add(5)
841 l->insert(99, 1)
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100842 assert_equal([2, 99, 3, 4, 5], l)
Bram Moolenaar8a7d6542020-01-26 15:56:19 +0100843enddef
844
Bram Moolenaar673660a2020-01-26 16:50:05 +0100845" Test that inside :function a Python function can be defined, :def is not
846" recognized.
847func Test_function_python()
848 CheckFeature python3
849 let py = 'python3'
850 execute py "<< EOF"
851def do_something():
852 return 1
853EOF
854endfunc
855
Bram Moolenaar158906c2020-02-06 20:39:45 +0100856def IfElse(what: number): string
857 let res = ''
858 if what == 1
859 res = "one"
860 elseif what == 2
861 res = "two"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100862 else
Bram Moolenaar158906c2020-02-06 20:39:45 +0100863 res = "three"
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100864 endif
Bram Moolenaar158906c2020-02-06 20:39:45 +0100865 return res
Bram Moolenaara259d8d2020-01-31 20:10:50 +0100866enddef
867
Bram Moolenaar158906c2020-02-06 20:39:45 +0100868def Test_if_elseif_else()
869 assert_equal('one', IfElse(1))
870 assert_equal('two', IfElse(2))
871 assert_equal('three', IfElse(3))
Bram Moolenaar0f18b6d2020-02-02 17:22:27 +0100872enddef
873
Bram Moolenaar6d69bf62020-03-03 19:02:12 +0100874let g:bool_true = v:true
875let g:bool_false = v:false
876
877def Test_if_const_expr()
878 let res = false
879 if true ? true : false
880 res = true
881 endif
882 assert_equal(true, res)
883
884 res = false
885 if g:bool_true ? true : false
886 res = true
887 endif
888 assert_equal(true, res)
889
890 res = false
891 if true ? g:bool_true : false
892 res = true
893 endif
894 assert_equal(true, res)
895
896 res = false
897 if true ? true : g:bool_false
898 res = true
899 endif
900 assert_equal(true, res)
901
902 res = false
903 if true ? false : true
904 res = true
905 endif
906 assert_equal(false, res)
907
908 res = false
909 if false ? false : true
910 res = true
911 endif
912 assert_equal(true, res)
913
914 res = false
915 if false ? true : false
916 res = true
917 endif
918 assert_equal(false, res)
919
920 res = false
921 if true && true
922 res = true
923 endif
924 assert_equal(true, res)
925
926 res = false
927 if true && false
928 res = true
929 endif
930 assert_equal(false, res)
931
932 res = false
933 if g:bool_true && false
934 res = true
935 endif
936 assert_equal(false, res)
937
938 res = false
939 if true && g:bool_false
940 res = true
941 endif
942 assert_equal(false, res)
943
944 res = false
945 if false && false
946 res = true
947 endif
948 assert_equal(false, res)
949
950 res = false
951 if true || false
952 res = true
953 endif
954 assert_equal(true, res)
955
956 res = false
957 if g:bool_true || false
958 res = true
959 endif
960 assert_equal(true, res)
961
962 res = false
963 if true || g:bool_false
964 res = true
965 endif
966 assert_equal(true, res)
967
968 res = false
969 if false || false
970 res = true
971 endif
972 assert_equal(false, res)
973
974enddef
975
Bram Moolenaar63ce4842020-02-19 15:46:48 +0100976def Test_delfunc()
977 let lines =<< trim END
978 vim9script
979 def GoneSoon()
980 echo 'hello'
981 enddef
982
983 def CallGoneSoon()
984 GoneSoon()
985 enddef
986
987 delfunc GoneSoon
988 CallGoneSoon()
989 END
990 writefile(lines, 'XToDelFunc')
991 assert_fails('so XToDelFunc', 'E933')
992 assert_fails('so XToDelFunc', 'E933')
993
994 delete('XToDelFunc')
995enddef
996
Bram Moolenaarad39c092020-02-26 18:23:43 +0100997def Test_execute_cmd()
998 new
999 setline(1, 'default')
1000 execute 'call setline(1, "execute-string")'
1001 assert_equal('execute-string', getline(1))
1002 let cmd1 = 'call setline(1,'
1003 let cmd2 = '"execute-var")'
1004 execute cmd1 cmd2
1005 assert_equal('execute-var', getline(1))
1006 execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
1007 assert_equal('execute-var-string', getline(1))
1008 let cmd_first = 'call '
1009 let cmd_last = 'setline(1, "execute-var-var")'
1010 execute cmd_first .. cmd_last
1011 assert_equal('execute-var-var', getline(1))
1012 bwipe!
1013enddef
1014
1015def Test_echo_cmd()
1016 echo 'something'
1017 assert_match('^something$', Screenline(&lines))
1018
1019 let str1 = 'some'
1020 let str2 = 'more'
1021 echo str1 str2
1022 assert_match('^some more$', Screenline(&lines))
1023enddef
1024
Bram Moolenaar41fe0612020-03-01 16:22:40 +01001025def Test_for_outside_of_function()
1026 let lines =<< trim END
1027 vim9script
1028 new
1029 for var in range(0, 3)
1030 append(line('$'), var)
1031 endfor
1032 assert_equal(['', '0', '1', '2', '3'], getline(1, '$'))
1033 bwipe!
1034 END
1035 writefile(lines, 'Xvim9for.vim')
1036 source Xvim9for.vim
1037 delete('Xvim9for.vim')
1038enddef
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001039
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01001040def Test_while_loop()
1041 let result = ''
1042 let cnt = 0
1043 while cnt < 555
1044 if cnt == 3
1045 break
1046 endif
1047 cnt += 1
1048 if cnt == 2
1049 continue
1050 endif
1051 result ..= cnt .. '_'
1052 endwhile
1053 assert_equal('1_3_', result)
1054enddef
1055
Bram Moolenaarbd5da372020-03-31 23:13:10 +02001056def Test_for_loop_fails()
1057 call CheckDefFailure(['for # in range(5)'], 'E690:')
1058 call CheckDefFailure(['for i In range(5)'], 'E690:')
1059 call CheckDefFailure(['let x = 5', 'for x in range(5)'], 'E1023:')
1060 call CheckScriptFailure(['def Func(arg)', 'for arg in range(5)', 'enddef'], 'E1006:')
1061 call CheckDefFailure(['for i in "text"'], 'E1024:')
1062enddef
1063
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001064def Test_interrupt_loop()
Bram Moolenaar97acfc72020-03-22 13:44:28 +01001065 let caught = false
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001066 let x = 0
Bram Moolenaar97acfc72020-03-22 13:44:28 +01001067 try
1068 while 1
1069 x += 1
1070 if x == 100
1071 feedkeys("\<C-C>", 'Lt')
1072 endif
1073 endwhile
1074 catch
1075 caught = true
1076 assert_equal(100, x)
1077 endtry
1078 assert_true(caught, 'should have caught an exception')
Bram Moolenaar9645e2d2020-03-20 20:48:49 +01001079enddef
Bram Moolenaar20431c92020-03-20 18:39:46 +01001080
Bram Moolenaard0df1aa2020-03-04 21:50:46 +01001081def Test_substitute_cmd()
1082 new
1083 setline(1, 'something')
1084 :substitute(some(other(
1085 assert_equal('otherthing', getline(1))
1086 bwipe!
1087
1088 " also when the context is Vim9 script
1089 let lines =<< trim END
1090 vim9script
1091 new
1092 setline(1, 'something')
1093 :substitute(some(other(
1094 assert_equal('otherthing', getline(1))
1095 bwipe!
1096 END
1097 writefile(lines, 'Xvim9lines')
1098 source Xvim9lines
1099
1100 delete('Xvim9lines')
1101enddef
1102
Bram Moolenaar20431c92020-03-20 18:39:46 +01001103def Test_redef_failure()
1104 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef')
1105 so Xdef
1106 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef')
1107 so Xdef
1108 call writefile(['def! Func0(): string', 'enddef'], 'Xdef')
1109 call assert_fails('so Xdef', 'E1027:')
1110 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef')
1111 so Xdef
1112 call delete('Xdef')
1113
1114 call assert_equal(0, Func0())
1115 call assert_equal('Func1', Func1())
1116 call assert_equal('Func2', Func2())
1117
1118 delfunc! Func0
1119 delfunc! Func1
1120 delfunc! Func2
1121enddef
1122
Bram Moolenaar7d941ee2020-03-26 14:11:58 +01001123" Test for internal functions returning different types
1124func Test_InternalFuncRetType()
1125 let lines =<< trim END
1126 def RetFloat(): float
1127 return ceil(1.456)
1128 enddef
1129
1130 def RetListAny(): list<any>
1131 return items({'k' : 'v'})
1132 enddef
1133
1134 def RetListString(): list<string>
1135 return split('a:b:c', ':')
1136 enddef
1137
1138 def RetListDictAny(): list<dict<any>>
1139 return getbufinfo()
1140 enddef
1141
1142 def RetDictNumber(): dict<number>
1143 return wordcount()
1144 enddef
1145
1146 def RetDictString(): dict<string>
1147 return environ()
1148 enddef
1149 END
1150 call writefile(lines, 'Xscript')
1151 source Xscript
1152
1153 call assert_equal(2.0, RetFloat())
1154 call assert_equal([['k', 'v']], RetListAny())
1155 call assert_equal(['a', 'b', 'c'], RetListString())
1156 call assert_notequal([], RetListDictAny())
1157 call assert_notequal({}, RetDictNumber())
1158 call assert_notequal({}, RetDictString())
1159 call delete('Xscript')
1160endfunc
1161
1162" Test for passing too many or too few arguments to internal functions
1163func Test_internalfunc_arg_error()
1164 let l =<< trim END
1165 def! FArgErr(): float
1166 return ceil(1.1, 2)
1167 enddef
1168 END
1169 call writefile(l, 'Xinvalidarg')
1170 call assert_fails('so Xinvalidarg', 'E118:')
1171 let l =<< trim END
1172 def! FArgErr(): float
1173 return ceil()
1174 enddef
1175 END
1176 call writefile(l, 'Xinvalidarg')
1177 call assert_fails('so Xinvalidarg', 'E119:')
1178 call delete('Xinvalidarg')
1179endfunc
1180
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001181" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker