blob: ce1ab34d6df0565da16d7ace7beee9de20a9c0f2 [file] [log] [blame]
Bram Moolenaar8a7d6542020-01-26 15:56:19 +01001" Test various aspects of the Vim9 script language.
2
3" Check that "lines" inside ":def" results in an "error" message.
4func CheckDefFailure(lines, error)
5 call writefile(['def! Func()'] + a:lines + ['enddef'], 'Xdef')
6 call assert_fails('so Xdef', a:error, a:lines)
7 call delete('Xdef')
8endfunc
9
10func CheckScriptFailure(lines, error)
11 call writefile(a:lines, 'Xdef')
12 call assert_fails('so Xdef', a:error, a:lines)
13 call delete('Xdef')
14endfunc
15
16def Test_syntax()
17 let var = 234
18 let other: list<string> = ['asdf']
19enddef
20
21func Test_def_basic()
22 def SomeFunc(): string
23 return 'yes'
24 enddef
25 call assert_equal('yes', SomeFunc())
26endfunc
27
28def Test_assignment()
29 let bool1: bool = true
30 assert_equal(v:true, bool1)
31 let bool2: bool = false
32 assert_equal(v:false, bool2)
33
34 let list1: list<string> = ['sdf', 'asdf']
35 let list2: list<number> = [1, 2, 3]
36
37 " TODO: does not work yet
38 " let listS: list<string> = []
39 " let listN: list<number> = []
40
41 let dict1: dict<string> = #{key: 'value'}
42 let dict2: dict<number> = #{one: 1, two: 2}
43enddef
44
45func Test_assignment_failure()
46 call CheckDefFailure(['let var=234'], 'E1004:')
47 call CheckDefFailure(['let var =234'], 'E1004:')
48 call CheckDefFailure(['let var= 234'], 'E1004:')
49
50 call CheckDefFailure(['let true = 1'], 'E1034:')
51 call CheckDefFailure(['let false = 1'], 'E1034:')
52
53 call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
54 call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
55
56 call CheckDefFailure(['let var: dict<string> = #{key: 123}'], 'expected dict<string> but got dict<number>')
57 call CheckDefFailure(['let var: dict<number> = #{key: "xx"}'], 'expected dict<number> but got dict<string>')
58
59 call CheckDefFailure(['let var = feedkeys("0")'], 'E1031:')
60 call CheckDefFailure(['let var: number = feedkeys("0")'], 'expected number but got void')
61endfunc
62
63func Test_const()
64 call CheckDefFailure(['const var = 234', 'var = 99'], 'E1018:')
65 call CheckDefFailure(['const one = 234', 'let one = 99'], 'E1017:')
66 call CheckDefFailure(['const two'], 'E1021:')
67endfunc
68
69def Test_block()
70 let outer = 1
71 {
72 let inner = 2
73 assert_equal(1, outer)
74 assert_equal(2, inner)
75 }
76 assert_equal(1, outer)
77enddef
78
79func Test_block_failure()
80 call CheckDefFailure(['{', 'let inner = 1', '}', 'echo inner'], 'E1001:')
81endfunc
82
83def ReturnString(): string
84 return 'string'
85enddef
86
87def ReturnNumber(): number
88 return 123
89enddef
90
91def Test_return_string()
92 assert_equal('string', ReturnString())
93 assert_equal(123, ReturnNumber())
94enddef
95
96func Increment()
97 let g:counter += 1
98endfunc
99
100def Test_call_ufunc_count()
101 g:counter = 1
102 Increment()
103 Increment()
104 Increment()
105 " works with and without :call
106 assert_equal(4, g:counter)
107 call assert_equal(4, g:counter)
108 unlet g:counter
109enddef
110
111def MyVarargs(arg: string, ...rest: list<string>): string
112 let res = arg
113 for s in rest
114 res ..= ',' .. s
115 endfor
116 return res
117enddef
118
119def Test_call_varargs()
120 assert_equal('one', MyVarargs('one'))
121 assert_equal('one,two', MyVarargs('one', 'two'))
122 assert_equal('one,two,three', MyVarargs('one', 'two', 'three'))
123enddef
124
125def Test_return_type_wrong()
126 " TODO: why is ! needed for Mac and FreeBSD?
127 CheckScriptFailure(['def! Func(): number', 'return "a"', 'enddef'], 'expected number but got string')
128 CheckScriptFailure(['def! Func(): string', 'return 1', 'enddef'], 'expected string but got number')
129 CheckScriptFailure(['def! Func(): void', 'return "a"', 'enddef'], 'expected void but got string')
130 CheckScriptFailure(['def! Func()', 'return "a"', 'enddef'], 'expected void but got string')
131enddef
132
133def Test_try_catch()
134 let l = []
135 try
136 add(l, '1')
137 throw 'wrong'
138 add(l, '2')
139 catch
140 add(l, v:exception)
141 finally
142 add(l, '3')
143 endtry
144 assert_equal(['1', 'wrong', '3'], l)
145enddef
146
147let s:export_script_lines =<< trim END
148 vim9script
149 let name: string = 'bob'
150 def Concat(arg: string): string
151 return name .. arg
152 enddef
153 let g:result = Concat('bie')
154 let g:localname = name
155
156 export const CONST = 1234
157 export let exported = 9876
158 export def Exported(): string
159 return 'Exported'
160 enddef
161END
162
163def Test_vim9script()
164 let import_script_lines =<< trim END
165 vim9script
166 import {exported, Exported} from './Xexport.vim'
167 g:imported = exported
168 g:imported_func = Exported()
169 END
170
171 writefile(import_script_lines, 'Ximport.vim')
172 writefile(s:export_script_lines, 'Xexport.vim')
173
174 source Ximport.vim
175
176 assert_equal('bobbie', g:result)
177 assert_equal('bob', g:localname)
178 assert_equal(9876, g:imported)
179 assert_equal('Exported', g:imported_func)
180 assert_false(exists('g:name'))
181
182 unlet g:result
183 unlet g:localname
184 unlet g:imported
185 unlet g:imported_func
186 delete('Ximport.vim')
187 delete('Xexport.vim')
188
189 CheckScriptFailure(['scriptversion 2', 'vim9script'], 'E1039:')
190 CheckScriptFailure(['vim9script', 'scriptversion 2'], 'E1040:')
191enddef
192
193def Test_vim9script_call()
194 let lines =<< trim END
195 vim9script
196 let var = ''
197 def MyFunc(arg: string)
198 var = arg
199 enddef
200 MyFunc('foobar')
201 assert_equal('foobar', var)
202
203 let str = 'barfoo'
204 str->MyFunc()
205 assert_equal('barfoo', var)
206
207 let g:value = 'value'
208 g:value->MyFunc()
209 assert_equal('value', var)
210
211 let listvar = []
212 def ListFunc(arg: list<number>)
213 listvar = arg
214 enddef
215 [1, 2, 3]->ListFunc()
216 assert_equal([1, 2, 3], listvar)
217
218 let dictvar = {}
219 def DictFunc(arg: dict<number>)
220 dictvar = arg
221 enddef
222 {'a': 1, 'b': 2}->DictFunc()
223 assert_equal(#{a: 1, b: 2}, dictvar)
224 #{a: 3, b: 4}->DictFunc()
225 assert_equal(#{a: 3, b: 4}, dictvar)
226 END
227 writefile(lines, 'Xcall.vim')
228 source Xcall.vim
229 delete('Xcall.vim')
230enddef
231
232def Test_vim9script_call_fail_decl()
233 let lines =<< trim END
234 vim9script
235 let var = ''
236 def MyFunc(arg: string)
237 let var = 123
238 enddef
239 END
240 writefile(lines, 'Xcall_decl.vim')
241 assert_fails('source Xcall_decl.vim', 'E1054:')
242 delete('Xcall_decl.vim')
243enddef
244
245def Test_vim9script_call_fail_const()
246 let lines =<< trim END
247 vim9script
248 const var = ''
249 def MyFunc(arg: string)
250 var = 'asdf'
251 enddef
252 END
253 writefile(lines, 'Xcall_const.vim')
254 assert_fails('source Xcall_const.vim', 'E46:')
255 delete('Xcall_const.vim')
256enddef
257
258def Test_vim9script_reload()
259 let lines =<< trim END
260 vim9script
261 const var = ''
262 let valone = 1234
263 def MyFunc(arg: string)
264 valone = 5678
265 enddef
266 END
267 let morelines =<< trim END
268 let valtwo = 222
269 export def GetValtwo(): number
270 return valtwo
271 enddef
272 END
273 writefile(lines + morelines, 'Xreload.vim')
274 source Xreload.vim
275 source Xreload.vim
276 source Xreload.vim
277
278 let testlines =<< trim END
279 vim9script
280 def TheFunc()
281 import GetValtwo from './Xreload.vim'
282 assert_equal(222, GetValtwo())
283 enddef
284 TheFunc()
285 END
286 writefile(testlines, 'Ximport.vim')
287 source Ximport.vim
288
289 " test that when not using "morelines" valtwo is still defined
290 " need to source Xreload.vim again, import doesn't reload a script
291 writefile(lines, 'Xreload.vim')
292 source Xreload.vim
293 source Ximport.vim
294
295 " cannot declare a var twice
296 lines =<< trim END
297 vim9script
298 let valone = 1234
299 let valone = 5678
300 END
301 writefile(lines, 'Xreload.vim')
302 assert_fails('source Xreload.vim', 'E1041:')
303
304 delete('Xreload.vim')
305 delete('Ximport.vim')
306enddef
307
308def Test_import_absolute()
309 let import_lines = [
310 \ 'vim9script',
311 \ 'import exported from "' .. escape(getcwd(), '\') .. '/Xexport_abs.vim"',
312 \ 'g:imported_abs = exported',
313 \ ]
314 writefile(import_lines, 'Ximport_abs.vim')
315 writefile(s:export_script_lines, 'Xexport_abs.vim')
316
317 source Ximport_abs.vim
318
319 assert_equal(9876, g:imported_abs)
320 unlet g:imported_abs
321
322 delete('Ximport_abs.vim')
323 delete('Xexport_abs.vim')
324enddef
325
326def Test_import_rtp()
327 let import_lines = [
328 \ 'vim9script',
329 \ 'import exported from "Xexport_rtp.vim"',
330 \ 'g:imported_rtp = exported',
331 \ ]
332 writefile(import_lines, 'Ximport_rtp.vim')
333 mkdir('import')
334 writefile(s:export_script_lines, 'import/Xexport_rtp.vim')
335
336 let save_rtp = &rtp
337 &rtp = getcwd()
338 source Ximport_rtp.vim
339 &rtp = save_rtp
340
341 assert_equal(9876, g:imported_rtp)
342 unlet g:imported_rtp
343
344 delete('Ximport_rtp.vim')
345 delete('import/Xexport_rtp.vim')
346 delete('import', 'd')
347enddef
348
349def Test_fixed_size_list()
350 " will be allocated as one piece of memory, check that changes work
351 let l = [1, 2, 3, 4]
352 l->remove(0)
353 l->add(5)
354 l->insert(99, 1)
355 call assert_equal([2, 99, 3, 4, 5], l)
356enddef
357
358
359" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker