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