1" Test various aspects of the Vim9 script language. 2 3source check.vim 4source view_util.vim 5source vim9.vim 6source screendump.vim 7 8func Test_def_basic() 9 def SomeFunc(): string 10 return 'yes' 11 enddef 12 call assert_equal('yes', SomeFunc()) 13endfunc 14 15def ReturnString(): string 16 return 'string' 17enddef 18 19def ReturnNumber(): number 20 return 123 21enddef 22 23let g:notNumber = 'string' 24 25def ReturnGlobal(): number 26 return g:notNumber 27enddef 28 29def Test_return_something() 30 assert_equal('string', ReturnString()) 31 assert_equal(123, ReturnNumber()) 32 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string') 33enddef 34 35def Test_missing_return() 36 CheckDefFailure(['def Missing(): number', 37 ' if g:cond', 38 ' echo "no return"', 39 ' else', 40 ' return 0', 41 ' endif' 42 'enddef'], 'E1027:') 43 CheckDefFailure(['def Missing(): number', 44 ' if g:cond', 45 ' return 1', 46 ' else', 47 ' echo "no return"', 48 ' endif' 49 'enddef'], 'E1027:') 50 CheckDefFailure(['def Missing(): number', 51 ' if g:cond', 52 ' return 1', 53 ' else', 54 ' return 2', 55 ' endif' 56 ' return 3' 57 'enddef'], 'E1095:') 58enddef 59 60let s:nothing = 0 61def ReturnNothing() 62 s:nothing = 1 63 if true 64 return 65 endif 66 s:nothing = 2 67enddef 68 69def Test_return_nothing() 70 ReturnNothing() 71 assert_equal(1, s:nothing) 72enddef 73 74func Increment() 75 let g:counter += 1 76endfunc 77 78def Test_call_ufunc_count() 79 g:counter = 1 80 Increment() 81 Increment() 82 Increment() 83 " works with and without :call 84 assert_equal(4, g:counter) 85 call assert_equal(4, g:counter) 86 unlet g:counter 87enddef 88 89def MyVarargs(arg: string, ...rest: list<string>): string 90 let res = arg 91 for s in rest 92 res ..= ',' .. s 93 endfor 94 return res 95enddef 96 97def Test_call_varargs() 98 assert_equal('one', MyVarargs('one')) 99 assert_equal('one,two', MyVarargs('one', 'two')) 100 assert_equal('one,two,three', MyVarargs('one', 'two', 'three')) 101enddef 102 103def MyDefaultArgs(name = 'string'): string 104 return name 105enddef 106 107def Test_call_default_args() 108 assert_equal('string', MyDefaultArgs()) 109 assert_equal('one', MyDefaultArgs('one')) 110 assert_fails('call MyDefaultArgs("one", "two")', 'E118:') 111 112 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:') 113 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: argument 1: type mismatch, expected number but got string') 114enddef 115 116def Test_nested_function() 117 def Nested(arg: string): string 118 return 'nested ' .. arg 119 enddef 120 assert_equal('nested function', Nested('function')) 121 122 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:') 123 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:') 124 125 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:') 126enddef 127 128func Test_call_default_args_from_func() 129 call assert_equal('string', MyDefaultArgs()) 130 call assert_equal('one', MyDefaultArgs('one')) 131 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:') 132endfunc 133 134func TakesOneArg(arg) 135 echo a:arg 136endfunc 137 138def Test_call_wrong_args() 139 call CheckDefFailure(['TakesOneArg()'], 'E119:') 140 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:') 141 call CheckDefFailure(['bufnr(xxx)'], 'E1001:') 142 call CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:') 143enddef 144 145" Default arg and varargs 146def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string 147 let res = one .. ',' .. two 148 for s in rest 149 res ..= ',' .. s 150 endfor 151 return res 152enddef 153 154def Test_call_def_varargs() 155 call assert_fails('call MyDefVarargs()', 'E119:') 156 assert_equal('one,foo', MyDefVarargs('one')) 157 assert_equal('one,two', MyDefVarargs('one', 'two')) 158 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three')) 159 call CheckDefFailure(['MyDefVarargs("one", 22)'], 'E1013: argument 2: type mismatch, expected string but got number') 160enddef 161 162let s:value = '' 163 164def FuncOneDefArg(opt = 'text') 165 s:value = opt 166enddef 167 168def FuncTwoDefArg(nr = 123, opt = 'text'): string 169 return nr .. opt 170enddef 171 172def FuncVarargs(...arg: list<string>): string 173 return join(arg, ',') 174enddef 175 176def Test_func_type_varargs() 177 let RefDefArg: func(?string) 178 RefDefArg = FuncOneDefArg 179 RefDefArg() 180 assert_equal('text', s:value) 181 RefDefArg('some') 182 assert_equal('some', s:value) 183 184 let RefDef2Arg: func(?number, ?string): string 185 RefDef2Arg = FuncTwoDefArg 186 assert_equal('123text', RefDef2Arg()) 187 assert_equal('99text', RefDef2Arg(99)) 188 assert_equal('77some', RefDef2Arg(77, 'some')) 189 190 call CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:') 191 call CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:') 192 193 let RefVarargs: func(...list<string>): string 194 RefVarargs = FuncVarargs 195 assert_equal('', RefVarargs()) 196 assert_equal('one', RefVarargs('one')) 197 assert_equal('one,two', RefVarargs('one', 'two')) 198 199 call CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:') 200 call CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:') 201enddef 202 203" Only varargs 204def MyVarargsOnly(...args: list<string>): string 205 return join(args, ',') 206enddef 207 208def Test_call_varargs_only() 209 assert_equal('', MyVarargsOnly()) 210 assert_equal('one', MyVarargsOnly('one')) 211 assert_equal('one,two', MyVarargsOnly('one', 'two')) 212 call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number') 213 call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number') 214enddef 215 216def Test_using_var_as_arg() 217 call writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef') 218 call assert_fails('so Xdef', 'E1006:') 219 call delete('Xdef') 220enddef 221 222def DictArg(arg: dict<string>) 223 arg['key'] = 'value' 224enddef 225 226def ListArg(arg: list<string>) 227 arg[0] = 'value' 228enddef 229 230def Test_assign_to_argument() 231 " works for dict and list 232 let d: dict<string> = {} 233 DictArg(d) 234 assert_equal('value', d['key']) 235 let l: list<string> = [] 236 ListArg(l) 237 assert_equal('value', l[0]) 238 239 call CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:') 240enddef 241 242def Test_call_func_defined_later() 243 call assert_equal('one', g:DefinedLater('one')) 244 call assert_fails('call NotDefined("one")', 'E117:') 245enddef 246 247func DefinedLater(arg) 248 return a:arg 249endfunc 250 251def Test_call_funcref() 252 assert_equal(3, g:SomeFunc('abc')) 253 assert_fails('NotAFunc()', 'E117:') 254 assert_fails('g:NotAFunc()', 'E117:') 255enddef 256 257let SomeFunc = function('len') 258let NotAFunc = 'text' 259 260def CombineFuncrefTypes() 261 " same arguments, different return type 262 let Ref1: func(bool): string 263 let Ref2: func(bool): number 264 let Ref3: func(bool): any 265 Ref3 = g:cond ? Ref1 : Ref2 266 267 " different number of arguments 268 let Refa1: func(bool): number 269 let Refa2: func(bool, number): number 270 let Refa3: func: number 271 Refa3 = g:cond ? Refa1 : Refa2 272 273 " different argument types 274 let Refb1: func(bool, string): number 275 let Refb2: func(string, number): number 276 let Refb3: func(any, any): number 277 Refb3 = g:cond ? Refb1 : Refb2 278enddef 279 280def FuncWithForwardCall() 281 return g:DefinedEvenLater("yes") 282enddef 283 284def DefinedEvenLater(arg: string): string 285 return arg 286enddef 287 288def Test_error_in_nested_function() 289 " Error in called function requires unwinding the call stack. 290 assert_fails('call FuncWithForwardCall()', 'E1096') 291enddef 292 293def Test_return_type_wrong() 294 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef', 'defcompile'], 'expected number but got string') 295 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef', 'defcompile'], 'expected string but got number') 296 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef', 'defcompile'], 'E1096: Returning a value in a function without a return type') 297 CheckScriptFailure(['def Func()', 'return "a"', 'enddef', 'defcompile'], 'E1096: Returning a value in a function without a return type') 298 299 CheckScriptFailure(['def Func(): number', 'return', 'enddef', 'defcompile'], 'E1003:') 300 301 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 302 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 303 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 304enddef 305 306def Test_arg_type_wrong() 307 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 308 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 309 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 310 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 311enddef 312 313def Test_vim9script_call() 314 let lines =<< trim END 315 vim9script 316 let var = '' 317 def MyFunc(arg: string) 318 var = arg 319 enddef 320 MyFunc('foobar') 321 assert_equal('foobar', var) 322 323 let str = 'barfoo' 324 str->MyFunc() 325 assert_equal('barfoo', var) 326 327 g:value = 'value' 328 g:value->MyFunc() 329 assert_equal('value', var) 330 331 let listvar = [] 332 def ListFunc(arg: list<number>) 333 listvar = arg 334 enddef 335 [1, 2, 3]->ListFunc() 336 assert_equal([1, 2, 3], listvar) 337 338 let dictvar = {} 339 def DictFunc(arg: dict<number>) 340 dictvar = arg 341 enddef 342 {'a': 1, 'b': 2}->DictFunc() 343 assert_equal(#{a: 1, b: 2}, dictvar) 344 def CompiledDict() 345 {'a': 3, 'b': 4}->DictFunc() 346 enddef 347 CompiledDict() 348 assert_equal(#{a: 3, b: 4}, dictvar) 349 350 #{a: 3, b: 4}->DictFunc() 351 assert_equal(#{a: 3, b: 4}, dictvar) 352 353 ('text')->MyFunc() 354 assert_equal('text', var) 355 ("some")->MyFunc() 356 assert_equal('some', var) 357 358 MyFunc( 359 'continued' 360 ) 361 assert_equal('continued', 362 var 363 ) 364 365 call MyFunc( 366 'more' 367 .. 368 'lines' 369 ) 370 assert_equal( 371 'morelines', 372 var) 373 END 374 writefile(lines, 'Xcall.vim') 375 source Xcall.vim 376 delete('Xcall.vim') 377enddef 378 379def Test_vim9script_call_fail_decl() 380 let lines =<< trim END 381 vim9script 382 let var = '' 383 def MyFunc(arg: string) 384 let var = 123 385 enddef 386 defcompile 387 END 388 writefile(lines, 'Xcall_decl.vim') 389 assert_fails('source Xcall_decl.vim', 'E1054:') 390 delete('Xcall_decl.vim') 391enddef 392 393def Test_vim9script_call_fail_const() 394 let lines =<< trim END 395 vim9script 396 const var = '' 397 def MyFunc(arg: string) 398 var = 'asdf' 399 enddef 400 defcompile 401 END 402 writefile(lines, 'Xcall_const.vim') 403 assert_fails('source Xcall_const.vim', 'E46:') 404 delete('Xcall_const.vim') 405enddef 406 407" Test that inside :function a Python function can be defined, :def is not 408" recognized. 409func Test_function_python() 410 CheckFeature python3 411 let py = 'python3' 412 execute py "<< EOF" 413def do_something(): 414 return 1 415EOF 416endfunc 417 418def Test_delfunc() 419 let lines =<< trim END 420 vim9script 421 def g:GoneSoon() 422 echo 'hello' 423 enddef 424 425 def CallGoneSoon() 426 GoneSoon() 427 enddef 428 defcompile 429 430 delfunc g:GoneSoon 431 CallGoneSoon() 432 END 433 writefile(lines, 'XToDelFunc') 434 assert_fails('so XToDelFunc', 'E933') 435 assert_fails('so XToDelFunc', 'E933') 436 437 delete('XToDelFunc') 438enddef 439 440def Test_redef_failure() 441 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 442 so Xdef 443 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 444 so Xdef 445 call writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 446 call assert_fails('so Xdef', 'E1027:') 447 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 448 so Xdef 449 call delete('Xdef') 450 451 call assert_equal(0, g:Func0()) 452 call assert_equal('Func1', g:Func1()) 453 call assert_equal('Func2', g:Func2()) 454 455 delfunc! Func0 456 delfunc! Func1 457 delfunc! Func2 458enddef 459 460def Test_vim9script_func() 461 let lines =<< trim END 462 vim9script 463 func Func(arg) 464 echo a:arg 465 endfunc 466 Func('text') 467 END 468 writefile(lines, 'XVim9Func') 469 so XVim9Func 470 471 delete('XVim9Func') 472enddef 473 474" Test for internal functions returning different types 475func Test_InternalFuncRetType() 476 let lines =<< trim END 477 def RetFloat(): float 478 return ceil(1.456) 479 enddef 480 481 def RetListAny(): list<any> 482 return items({'k' : 'v'}) 483 enddef 484 485 def RetListString(): list<string> 486 return split('a:b:c', ':') 487 enddef 488 489 def RetListDictAny(): list<dict<any>> 490 return getbufinfo() 491 enddef 492 493 def RetDictNumber(): dict<number> 494 return wordcount() 495 enddef 496 497 def RetDictString(): dict<string> 498 return environ() 499 enddef 500 END 501 call writefile(lines, 'Xscript') 502 source Xscript 503 504 call assert_equal(2.0, RetFloat()) 505 call assert_equal([['k', 'v']], RetListAny()) 506 call assert_equal(['a', 'b', 'c'], RetListString()) 507 call assert_notequal([], RetListDictAny()) 508 call assert_notequal({}, RetDictNumber()) 509 call assert_notequal({}, RetDictString()) 510 call delete('Xscript') 511endfunc 512 513" Test for passing too many or too few arguments to internal functions 514func Test_internalfunc_arg_error() 515 let l =<< trim END 516 def! FArgErr(): float 517 return ceil(1.1, 2) 518 enddef 519 defcompile 520 END 521 call writefile(l, 'Xinvalidarg') 522 call assert_fails('so Xinvalidarg', 'E118:') 523 let l =<< trim END 524 def! FArgErr(): float 525 return ceil() 526 enddef 527 defcompile 528 END 529 call writefile(l, 'Xinvalidarg') 530 call assert_fails('so Xinvalidarg', 'E119:') 531 call delete('Xinvalidarg') 532endfunc 533 534let s:funcResult = 0 535 536def FuncNoArgNoRet() 537 funcResult = 11 538enddef 539 540def FuncNoArgRetNumber(): number 541 funcResult = 22 542 return 1234 543enddef 544 545def FuncNoArgRetString(): string 546 funcResult = 45 547 return 'text' 548enddef 549 550def FuncOneArgNoRet(arg: number) 551 funcResult = arg 552enddef 553 554def FuncOneArgRetNumber(arg: number): number 555 funcResult = arg 556 return arg 557enddef 558 559def FuncTwoArgNoRet(one: bool, two: number) 560 funcResult = two 561enddef 562 563def FuncOneArgRetString(arg: string): string 564 return arg 565enddef 566 567def FuncOneArgRetAny(arg: any): any 568 return arg 569enddef 570 571def Test_func_type() 572 let Ref1: func() 573 funcResult = 0 574 Ref1 = FuncNoArgNoRet 575 Ref1() 576 assert_equal(11, funcResult) 577 578 let Ref2: func 579 funcResult = 0 580 Ref2 = FuncNoArgNoRet 581 Ref2() 582 assert_equal(11, funcResult) 583 584 funcResult = 0 585 Ref2 = FuncOneArgNoRet 586 Ref2(12) 587 assert_equal(12, funcResult) 588 589 funcResult = 0 590 Ref2 = FuncNoArgRetNumber 591 assert_equal(1234, Ref2()) 592 assert_equal(22, funcResult) 593 594 funcResult = 0 595 Ref2 = FuncOneArgRetNumber 596 assert_equal(13, Ref2(13)) 597 assert_equal(13, funcResult) 598enddef 599 600def Test_repeat_return_type() 601 let res = 0 602 for n in repeat([1], 3) 603 res += n 604 endfor 605 assert_equal(3, res) 606 607 res = 0 608 for n in add([1, 2], 3) 609 res += n 610 endfor 611 assert_equal(6, res) 612enddef 613 614def Test_argv_return_type() 615 next fileone filetwo 616 let res = '' 617 for name in argv() 618 res ..= name 619 endfor 620 assert_equal('fileonefiletwo', res) 621enddef 622 623def Test_func_type_part() 624 let RefVoid: func: void 625 RefVoid = FuncNoArgNoRet 626 RefVoid = FuncOneArgNoRet 627 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 628 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string') 629 630 let RefAny: func(): any 631 RefAny = FuncNoArgRetNumber 632 RefAny = FuncNoArgRetString 633 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): any but got func()') 634 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1013: type mismatch, expected func(): any but got func(number)') 635 636 let RefNr: func: number 637 RefNr = FuncNoArgRetNumber 638 RefNr = FuncOneArgRetNumber 639 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()') 640 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string') 641 642 let RefStr: func: string 643 RefStr = FuncNoArgRetString 644 RefStr = FuncOneArgRetString 645 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): string but got func()') 646 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got func(): number') 647enddef 648 649def Test_func_type_fails() 650 CheckDefFailure(['let ref1: func()'], 'E704:') 651 652 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 653 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)') 654 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number') 655 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)') 656 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)') 657 CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)') 658 659 call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') 660 call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') 661 call CheckDefFailure(['let RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E740:') 662 call CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:') 663enddef 664 665def Test_func_return_type() 666 let nr: number 667 nr = FuncNoArgRetNumber() 668 assert_equal(1234, nr) 669 670 nr = FuncOneArgRetAny(122) 671 assert_equal(122, nr) 672 673 let str: string 674 str = FuncOneArgRetAny('yes') 675 assert_equal('yes', str) 676 677 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1013: type mismatch, expected string but got number') 678enddef 679 680def MultiLine( 681 arg1: string, 682 arg2 = 1234, 683 ...rest: list<string> 684 ): string 685 return arg1 .. arg2 .. join(rest, '-') 686enddef 687 688def MultiLineComment( 689 arg1: string, # comment 690 arg2 = 1234, # comment 691 ...rest: list<string> # comment 692 ): string # comment 693 return arg1 .. arg2 .. join(rest, '-') 694enddef 695 696def Test_multiline() 697 assert_equal('text1234', MultiLine('text')) 698 assert_equal('text777', MultiLine('text', 777)) 699 assert_equal('text777one', MultiLine('text', 777, 'one')) 700 assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 701enddef 702 703func Test_multiline_not_vim9() 704 call assert_equal('text1234', MultiLine('text')) 705 call assert_equal('text777', MultiLine('text', 777)) 706 call assert_equal('text777one', MultiLine('text', 777, 'one')) 707 call assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 708endfunc 709 710 711" When using CheckScriptFailure() for the below test, E1010 is generated instead 712" of E1056. 713func Test_E1056_1059() 714 let caught_1056 = 0 715 try 716 def F(): 717 return 1 718 enddef 719 catch /E1056:/ 720 let caught_1056 = 1 721 endtry 722 call assert_equal(1, caught_1056) 723 724 let caught_1059 = 0 725 try 726 def F5(items : list) 727 echo 'a' 728 enddef 729 catch /E1059:/ 730 let caught_1059 = 1 731 endtry 732 call assert_equal(1, caught_1059) 733endfunc 734 735func DelMe() 736 echo 'DelMe' 737endfunc 738 739def Test_deleted_function() 740 CheckDefExecFailure([ 741 'let RefMe: func = function("g:DelMe")', 742 'delfunc g:DelMe', 743 'echo RefMe()'], 'E117:') 744enddef 745 746def Test_unknown_function() 747 CheckDefExecFailure([ 748 'let Ref: func = function("NotExist")', 749 'delfunc g:NotExist'], 'E700:') 750enddef 751 752def RefFunc(Ref: func(string): string): string 753 return Ref('more') 754enddef 755 756def Test_closure_simple() 757 let local = 'some ' 758 assert_equal('some more', RefFunc({s -> local .. s})) 759enddef 760 761def MakeRef() 762 let local = 'some ' 763 g:Ref = {s -> local .. s} 764enddef 765 766def Test_closure_ref_after_return() 767 MakeRef() 768 assert_equal('some thing', g:Ref('thing')) 769 unlet g:Ref 770enddef 771 772def MakeTwoRefs() 773 let local = ['some'] 774 g:Extend = {s -> local->add(s)} 775 g:Read = {-> local} 776enddef 777 778def Test_closure_two_refs() 779 MakeTwoRefs() 780 assert_equal('some', join(g:Read(), ' ')) 781 g:Extend('more') 782 assert_equal('some more', join(g:Read(), ' ')) 783 g:Extend('even') 784 assert_equal('some more even', join(g:Read(), ' ')) 785 786 unlet g:Extend 787 unlet g:Read 788enddef 789 790def ReadRef(Ref: func(): list<string>): string 791 return join(Ref(), ' ') 792enddef 793 794def ExtendRef(Ref: func(string), add: string) 795 Ref(add) 796enddef 797 798def Test_closure_two_indirect_refs() 799 MakeTwoRefs() 800 assert_equal('some', ReadRef(g:Read)) 801 ExtendRef(g:Extend, 'more') 802 assert_equal('some more', ReadRef(g:Read)) 803 ExtendRef(g:Extend, 'even') 804 assert_equal('some more even', ReadRef(g:Read)) 805 806 unlet g:Extend 807 unlet g:Read 808enddef 809 810def MakeArgRefs(theArg: string) 811 let local = 'loc_val' 812 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 813enddef 814 815def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 816 let local = 'the_loc' 817 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)} 818enddef 819 820def Test_closure_using_argument() 821 MakeArgRefs('arg_val') 822 assert_equal('arg_val/loc_val/call_val', g:UseArg('call_val')) 823 824 MakeArgRefsVarargs('arg_val', 'one', 'two') 825 assert_equal('arg_val/the_loc/call_val/one two', g:UseVararg('call_val')) 826 827 unlet g:UseArg 828 unlet g:UseVararg 829enddef 830 831def MakeGetAndAppendRefs() 832 let local = 'a' 833 834 def Append(arg: string) 835 local ..= arg 836 enddef 837 g:Append = Append 838 839 def Get(): string 840 return local 841 enddef 842 g:Get = Get 843enddef 844 845def Test_closure_append_get() 846 MakeGetAndAppendRefs() 847 assert_equal('a', g:Get()) 848 g:Append('-b') 849 assert_equal('a-b', g:Get()) 850 g:Append('-c') 851 assert_equal('a-b-c', g:Get()) 852 853 unlet g:Append 854 unlet g:Get 855enddef 856 857def Test_nested_closure() 858 let local = 'text' 859 def Closure(arg: string): string 860 return local .. arg 861 enddef 862 assert_equal('text!!!', Closure('!!!')) 863enddef 864 865func GetResult(Ref) 866 return a:Ref('some') 867endfunc 868 869def Test_call_closure_not_compiled() 870 let text = 'text' 871 g:Ref = {s -> s .. text} 872 assert_equal('sometext', GetResult(g:Ref)) 873enddef 874 875def Test_sort_return_type() 876 let res: list<number> 877 res = [1, 2, 3]->sort() 878enddef 879 880def Test_getqflist_return_type() 881 let l = getqflist() 882 assert_equal([], l) 883 884 let d = getqflist(#{items: 0}) 885 assert_equal(#{items: []}, d) 886enddef 887 888def Test_getloclist_return_type() 889 let l = getloclist(1) 890 assert_equal([], l) 891 892 let d = getloclist(1, #{items: 0}) 893 assert_equal(#{items: []}, d) 894enddef 895 896def Test_copy_return_type() 897 let l = copy([1, 2, 3]) 898 let res = 0 899 for n in l 900 res += n 901 endfor 902 assert_equal(6, res) 903 904 let dl = deepcopy([1, 2, 3]) 905 res = 0 906 for n in dl 907 res += n 908 endfor 909 assert_equal(6, res) 910enddef 911 912def Test_extend_return_type() 913 let l = extend([1, 2], [3]) 914 let res = 0 915 for n in l 916 res += n 917 endfor 918 assert_equal(6, res) 919enddef 920 921def Test_insert_return_type() 922 let l = insert([2, 1], 3) 923 let res = 0 924 for n in l 925 res += n 926 endfor 927 assert_equal(6, res) 928enddef 929 930def Test_reverse_return_type() 931 let l = reverse([1, 2, 3]) 932 let res = 0 933 for n in l 934 res += n 935 endfor 936 assert_equal(6, res) 937enddef 938 939def Test_remove_return_type() 940 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one') 941 let res = 0 942 for n in l 943 res += n 944 endfor 945 assert_equal(3, res) 946enddef 947 948def Test_filter_return_type() 949 let l = filter([1, 2, 3], {-> 1}) 950 let res = 0 951 for n in l 952 res += n 953 endfor 954 assert_equal(6, res) 955enddef 956 957def Wrong_dict_key_type(items: list<number>): list<number> 958 return filter(items, {_, val -> get({val: 1}, 'x')}) 959enddef 960 961def Test_wrong_dict_key_type() 962 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:') 963enddef 964 965def Line_continuation_in_def(dir: string = ''): string 966 let path: string = empty(dir) 967 \ ? 'empty' 968 \ : 'full' 969 return path 970enddef 971 972def Test_line_continuation_in_def() 973 assert_equal('full', Line_continuation_in_def('.')) 974enddef 975 976def Line_continuation_in_lambda(): list<number> 977 let x = range(97, 100) 978 ->map({_, v -> nr2char(v) 979 ->toupper()}) 980 ->reverse() 981 return x 982enddef 983 984def Test_line_continuation_in_lambda() 985 assert_equal(['D', 'C', 'B', 'A'], Line_continuation_in_lambda()) 986enddef 987 988func Test_silent_echo() 989 CheckScreendump 990 991 let lines =<< trim END 992 vim9script 993 def EchoNothing() 994 silent echo '' 995 enddef 996 defcompile 997 END 998 call writefile(lines, 'XTest_silent_echo') 999 1000 " Check that the balloon shows up after a mouse move 1001 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 1002 call term_sendkeys(buf, ":abc") 1003 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 1004 1005 " clean up 1006 call StopVimInTerminal(buf) 1007 call delete('XTest_silent_echo') 1008endfunc 1009 1010def Fibonacci(n: number): number 1011 if n < 2 1012 return n 1013 else 1014 return Fibonacci(n - 1) + Fibonacci(n - 2) 1015 endif 1016enddef 1017 1018def Test_recursive_call() 1019 assert_equal(6765, Fibonacci(20)) 1020enddef 1021 1022def TreeWalk(dir: string): list<any> 1023 return readdir(dir)->map({_, val -> 1024 fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 1025 ? {val : TreeWalk(dir .. '/' .. val)} 1026 : val 1027 }) 1028enddef 1029 1030def Test_closure_in_map() 1031 mkdir('XclosureDir/tdir', 'p') 1032 writefile(['111'], 'XclosureDir/file1') 1033 writefile(['222'], 'XclosureDir/file2') 1034 writefile(['333'], 'XclosureDir/tdir/file3') 1035 1036 assert_equal(['file1', 'file2', {'tdir': ['file3']}], TreeWalk('XclosureDir')) 1037 1038 delete('XclosureDir', 'rf') 1039enddef 1040 1041 1042" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 1043