1" Test various aspects of the Vim9 script language. 2 3source check.vim 4source view_util.vim 5 6" Check that "lines" inside ":def" results in an "error" message. 7func CheckDefFailure(lines, error) 8 call writefile(['def Func()'] + a:lines + ['enddef'], 'Xdef') 9 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 19func Test_def_basic() 20 def SomeFunc(): string 21 return 'yes' 22 enddef 23 call assert_equal('yes', SomeFunc()) 24endfunc 25 26def ReturnString(): string 27 return 'string' 28enddef 29 30def ReturnNumber(): number 31 return 123 32enddef 33 34let g:notNumber = 'string' 35 36def ReturnGlobal(): number 37 return g:notNumber 38enddef 39 40def Test_return_something() 41 assert_equal('string', ReturnString()) 42 assert_equal(123, ReturnNumber()) 43 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string') 44enddef 45 46let s:nothing = 0 47def ReturnNothing() 48 s:nothing = 1 49 if true 50 return 51 endif 52 s:nothing = 2 53enddef 54 55def Test_return_nothing() 56 ReturnNothing() 57 assert_equal(1, s:nothing) 58enddef 59 60func Increment() 61 let g:counter += 1 62endfunc 63 64def Test_call_ufunc_count() 65 g:counter = 1 66 Increment() 67 Increment() 68 Increment() 69 " works with and without :call 70 assert_equal(4, g:counter) 71 call assert_equal(4, g:counter) 72 unlet g:counter 73enddef 74 75def MyVarargs(arg: string, ...rest: list<string>): string 76 let res = arg 77 for s in rest 78 res ..= ',' .. s 79 endfor 80 return res 81enddef 82 83def Test_call_varargs() 84 assert_equal('one', MyVarargs('one')) 85 assert_equal('one,two', MyVarargs('one', 'two')) 86 assert_equal('one,two,three', MyVarargs('one', 'two', 'three')) 87enddef 88 89def MyDefaultArgs(name = 'string'): string 90 return name 91enddef 92 93def Test_call_default_args() 94 assert_equal('string', MyDefaultArgs()) 95 assert_equal('one', MyDefaultArgs('one')) 96 assert_fails('call MyDefaultArgs("one", "two")', 'E118:') 97 98 call CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef'], 'E1001:') 99enddef 100 101func Test_call_default_args_from_func() 102 call assert_equal('string', MyDefaultArgs()) 103 call assert_equal('one', MyDefaultArgs('one')) 104 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:') 105endfunc 106 107func TakesOneArg(arg) 108 echo a:arg 109endfunc 110 111def Test_call_wrong_args() 112 call CheckDefFailure(['TakesOneArg()'], 'E119:') 113 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:') 114 call CheckDefFailure(['bufnr(xxx)'], 'E1001:') 115enddef 116 117" Default arg and varargs 118def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string 119 let res = one .. ',' .. two 120 for s in rest 121 res ..= ',' .. s 122 endfor 123 return res 124enddef 125 126def Test_call_def_varargs() 127 call assert_fails('call MyDefVarargs()', 'E119:') 128 assert_equal('one,foo', MyDefVarargs('one')) 129 assert_equal('one,two', MyDefVarargs('one', 'two')) 130 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three')) 131 call CheckDefFailure(['MyDefVarargs("one", 22)'], 'E1013: argument 2: type mismatch, expected string but got number') 132enddef 133 134" Only varargs 135def MyVarargsOnly(...args: list<string>): string 136 return join(args, ',') 137enddef 138 139def Test_call_varargs_only() 140 assert_equal('', MyVarargsOnly()) 141 assert_equal('one', MyVarargsOnly('one')) 142 assert_equal('one,two', MyVarargsOnly('one', 'two')) 143 call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number') 144 call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number') 145enddef 146 147def Test_using_var_as_arg() 148 call writefile(['def Func(x: number)', 'let x = 234', 'enddef'], 'Xdef') 149 call assert_fails('so Xdef', 'E1006:') 150 call delete('Xdef') 151enddef 152 153def Test_call_func_defined_later() 154 call assert_equal('one', DefinedLater('one')) 155 call assert_fails('call NotDefined("one")', 'E117:') 156enddef 157 158func DefinedLater(arg) 159 return a:arg 160endfunc 161 162def FuncWithForwardCall() 163 return DefinedEvenLater("yes") 164enddef 165 166def DefinedEvenLater(arg: string): string 167 return arg 168enddef 169 170def Test_error_in_nested_function() 171 " Error in called function requires unwinding the call stack. 172 assert_fails('call FuncWithForwardCall()', 'E1029') 173enddef 174 175def Test_return_type_wrong() 176 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string') 177 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number') 178 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string') 179 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string') 180 181 CheckScriptFailure(['def Func(): number', 'return', 'enddef'], 'E1003:') 182 183 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 184 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 185 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 186enddef 187 188def Test_arg_type_wrong() 189 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 190 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 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 def CompiledDict() 225 {'a': 3, 'b': 4}->DictFunc() 226 enddef 227 CompiledDict() 228 assert_equal(#{a: 3, b: 4}, dictvar) 229 230 #{a: 3, b: 4}->DictFunc() 231 assert_equal(#{a: 3, b: 4}, dictvar) 232 233 ('text')->MyFunc() 234 assert_equal('text', var) 235 ("some")->MyFunc() 236 assert_equal('some', var) 237 END 238 writefile(lines, 'Xcall.vim') 239 source Xcall.vim 240 delete('Xcall.vim') 241enddef 242 243def Test_vim9script_call_fail_decl() 244 let lines =<< trim END 245 vim9script 246 let var = '' 247 def MyFunc(arg: string) 248 let var = 123 249 enddef 250 END 251 writefile(lines, 'Xcall_decl.vim') 252 assert_fails('source Xcall_decl.vim', 'E1054:') 253 delete('Xcall_decl.vim') 254enddef 255 256def Test_vim9script_call_fail_const() 257 let lines =<< trim END 258 vim9script 259 const var = '' 260 def MyFunc(arg: string) 261 var = 'asdf' 262 enddef 263 END 264 writefile(lines, 'Xcall_const.vim') 265 assert_fails('source Xcall_const.vim', 'E46:') 266 delete('Xcall_const.vim') 267enddef 268 269" Test that inside :function a Python function can be defined, :def is not 270" recognized. 271func Test_function_python() 272 CheckFeature python3 273 let py = 'python3' 274 execute py "<< EOF" 275def do_something(): 276 return 1 277EOF 278endfunc 279 280def Test_delfunc() 281 let lines =<< trim END 282 vim9script 283 def GoneSoon() 284 echo 'hello' 285 enddef 286 287 def CallGoneSoon() 288 GoneSoon() 289 enddef 290 291 delfunc GoneSoon 292 CallGoneSoon() 293 END 294 writefile(lines, 'XToDelFunc') 295 assert_fails('so XToDelFunc', 'E933') 296 assert_fails('so XToDelFunc', 'E933') 297 298 delete('XToDelFunc') 299enddef 300 301def Test_redef_failure() 302 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 303 so Xdef 304 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 305 so Xdef 306 call writefile(['def! Func0(): string', 'enddef'], 'Xdef') 307 call assert_fails('so Xdef', 'E1027:') 308 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 309 so Xdef 310 call delete('Xdef') 311 312 call assert_equal(0, Func0()) 313 call assert_equal('Func1', Func1()) 314 call assert_equal('Func2', Func2()) 315 316 delfunc! Func0 317 delfunc! Func1 318 delfunc! Func2 319enddef 320 321" Test for internal functions returning different types 322func Test_InternalFuncRetType() 323 let lines =<< trim END 324 def RetFloat(): float 325 return ceil(1.456) 326 enddef 327 328 def RetListAny(): list<any> 329 return items({'k' : 'v'}) 330 enddef 331 332 def RetListString(): list<string> 333 return split('a:b:c', ':') 334 enddef 335 336 def RetListDictAny(): list<dict<any>> 337 return getbufinfo() 338 enddef 339 340 def RetDictNumber(): dict<number> 341 return wordcount() 342 enddef 343 344 def RetDictString(): dict<string> 345 return environ() 346 enddef 347 END 348 call writefile(lines, 'Xscript') 349 source Xscript 350 351 call assert_equal(2.0, RetFloat()) 352 call assert_equal([['k', 'v']], RetListAny()) 353 call assert_equal(['a', 'b', 'c'], RetListString()) 354 call assert_notequal([], RetListDictAny()) 355 call assert_notequal({}, RetDictNumber()) 356 call assert_notequal({}, RetDictString()) 357 call delete('Xscript') 358endfunc 359 360" Test for passing too many or too few arguments to internal functions 361func Test_internalfunc_arg_error() 362 let l =<< trim END 363 def! FArgErr(): float 364 return ceil(1.1, 2) 365 enddef 366 END 367 call writefile(l, 'Xinvalidarg') 368 call assert_fails('so Xinvalidarg', 'E118:') 369 let l =<< trim END 370 def! FArgErr(): float 371 return ceil() 372 enddef 373 END 374 call writefile(l, 'Xinvalidarg') 375 call assert_fails('so Xinvalidarg', 'E119:') 376 call delete('Xinvalidarg') 377endfunc 378 379let s:funcResult = 0 380 381def FuncNoArgNoRet() 382 funcResult = 11 383enddef 384 385def FuncNoArgRetNumber(): number 386 funcResult = 22 387 return 1234 388enddef 389 390def FuncNoArgRetString(): string 391 funcResult = 45 392 return 'text' 393enddef 394 395def FuncOneArgNoRet(arg: number) 396 funcResult = arg 397enddef 398 399def FuncOneArgRetNumber(arg: number): number 400 funcResult = arg 401 return arg 402enddef 403 404def FuncOneArgRetString(arg: string): string 405 return arg 406enddef 407 408def FuncOneArgRetAny(arg: any): any 409 return arg 410enddef 411 412def Test_func_type() 413 let Ref1: func() 414 funcResult = 0 415 Ref1 = FuncNoArgNoRet 416 Ref1() 417 assert_equal(11, funcResult) 418 419 let Ref2: func 420 funcResult = 0 421 Ref2 = FuncNoArgNoRet 422 Ref2() 423 assert_equal(11, funcResult) 424 425 funcResult = 0 426 Ref2 = FuncOneArgNoRet 427 Ref2(12) 428 assert_equal(12, funcResult) 429 430 funcResult = 0 431 Ref2 = FuncNoArgRetNumber 432 assert_equal(1234, Ref2()) 433 assert_equal(22, funcResult) 434 435 funcResult = 0 436 Ref2 = FuncOneArgRetNumber 437 assert_equal(13, Ref2(13)) 438 assert_equal(13, funcResult) 439enddef 440 441def Test_func_type_part() 442 let RefVoid: func: void 443 RefVoid = FuncNoArgNoRet 444 RefVoid = FuncOneArgNoRet 445 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 446 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string') 447 448 let RefAny: func(): any 449 RefAny = FuncNoArgRetNumber 450 RefAny = FuncNoArgRetString 451 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): any but got func()') 452 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1013: type mismatch, expected func(): any but got func(number)') 453 454 let RefNr: func: number 455 RefNr = FuncNoArgRetNumber 456 RefNr = FuncOneArgRetNumber 457 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()') 458 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string') 459 460 let RefStr: func: string 461 RefStr = FuncNoArgRetString 462 RefStr = FuncOneArgRetString 463 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): string but got func()') 464 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got func(): number') 465enddef 466 467def Test_func_type_fails() 468 CheckDefFailure(['let ref1: func()'], 'E704:') 469 470 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 471 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)') 472 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number') 473enddef 474 475def Test_func_return_type() 476 let nr: number 477 nr = FuncNoArgRetNumber() 478 assert_equal(1234, nr) 479 480 nr = FuncOneArgRetAny(122) 481 assert_equal(122, nr) 482 483 let str: string 484 str = FuncOneArgRetAny('yes') 485 assert_equal('yes', str) 486 487 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1013: type mismatch, expected string but got number') 488enddef 489 490" When using CheckScriptFailure() for the below test, E1010 is generated instead 491" of E1056. 492func Test_E1056_1059() 493 let caught_1056 = 0 494 try 495 def F(): 496 return 1 497 enddef 498 catch /E1056:/ 499 let caught_1056 = 1 500 endtry 501 call assert_equal(1, caught_1056) 502 503 let caught_1059 = 0 504 try 505 def F5(items : list) 506 echo 'a' 507 enddef 508 catch /E1059:/ 509 let caught_1059 = 1 510 endtry 511 call assert_equal(1, caught_1059) 512endfunc 513 514" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 515