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 MyDefaultSecond(name: string, second: bool = true): string 108 return second ? name : 'none' 109enddef 110 111def Test_call_default_args() 112 assert_equal('string', MyDefaultArgs()) 113 assert_equal('one', MyDefaultArgs('one')) 114 assert_fails('call MyDefaultArgs("one", "two")', 'E118:') 115 116 assert_equal('test', MyDefaultSecond('test')) 117 assert_equal('test', MyDefaultSecond('test', true)) 118 assert_equal('none', MyDefaultSecond('test', false)) 119 120 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:') 121 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: argument 1: type mismatch, expected number but got string') 122enddef 123 124def Test_nested_function() 125 def Nested(arg: string): string 126 return 'nested ' .. arg 127 enddef 128 assert_equal('nested function', Nested('function')) 129 130 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:') 131 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:') 132 133 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:') 134enddef 135 136func Test_call_default_args_from_func() 137 call assert_equal('string', MyDefaultArgs()) 138 call assert_equal('one', MyDefaultArgs('one')) 139 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:') 140endfunc 141 142def Test_nested_global_function() 143 let lines =<< trim END 144 vim9script 145 def Outer() 146 def g:Inner(): string 147 return 'inner' 148 enddef 149 enddef 150 defcompile 151 Outer() 152 assert_equal('inner', g:Inner()) 153 delfunc g:Inner 154 Outer() 155 assert_equal('inner', g:Inner()) 156 delfunc g:Inner 157 Outer() 158 assert_equal('inner', g:Inner()) 159 delfunc g:Inner 160 END 161 CheckScriptSuccess(lines) 162enddef 163 164func TakesOneArg(arg) 165 echo a:arg 166endfunc 167 168def Test_call_wrong_args() 169 call CheckDefFailure(['TakesOneArg()'], 'E119:') 170 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:') 171 call CheckDefFailure(['bufnr(xxx)'], 'E1001:') 172 call CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:') 173enddef 174 175" Default arg and varargs 176def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string 177 let res = one .. ',' .. two 178 for s in rest 179 res ..= ',' .. s 180 endfor 181 return res 182enddef 183 184def Test_call_def_varargs() 185 call assert_fails('call MyDefVarargs()', 'E119:') 186 assert_equal('one,foo', MyDefVarargs('one')) 187 assert_equal('one,two', MyDefVarargs('one', 'two')) 188 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three')) 189 CheckDefFailure(['MyDefVarargs("one", 22)'], 190 'E1013: argument 2: type mismatch, expected string but got number') 191 CheckDefFailure(['MyDefVarargs("one", "two", 123)'], 192 'E1013: argument 3: type mismatch, expected string but got number') 193 194 let lines =<< trim END 195 vim9script 196 def Func(...l: list<string>) 197 echo l 198 enddef 199 Func('a', 'b', 'c') 200 END 201 CheckScriptSuccess(lines) 202 203 lines =<< trim END 204 vim9script 205 def Func(...l: list<string>) 206 echo l 207 enddef 208 Func() 209 END 210 CheckScriptSuccess(lines) 211 212 lines =<< trim END 213 vim9script 214 def Func(...l: list<string>) 215 echo l 216 enddef 217 Func(1, 2, 3) 218 END 219 CheckScriptFailure(lines, 'E1013:') 220 221 lines =<< trim END 222 vim9script 223 def Func(...l: list<string>) 224 echo l 225 enddef 226 Func('a', 9) 227 END 228 CheckScriptFailure(lines, 'E1013:') 229 230 lines =<< trim END 231 vim9script 232 def Func(...l: list<string>) 233 echo l 234 enddef 235 Func(1, 'a') 236 END 237 CheckScriptFailure(lines, 'E1013:') 238enddef 239 240let s:value = '' 241 242def FuncOneDefArg(opt = 'text') 243 s:value = opt 244enddef 245 246def FuncTwoDefArg(nr = 123, opt = 'text'): string 247 return nr .. opt 248enddef 249 250def FuncVarargs(...arg: list<string>): string 251 return join(arg, ',') 252enddef 253 254def Test_func_type_varargs() 255 let RefDefArg: func(?string) 256 RefDefArg = FuncOneDefArg 257 RefDefArg() 258 assert_equal('text', s:value) 259 RefDefArg('some') 260 assert_equal('some', s:value) 261 262 let RefDef2Arg: func(?number, ?string): string 263 RefDef2Arg = FuncTwoDefArg 264 assert_equal('123text', RefDef2Arg()) 265 assert_equal('99text', RefDef2Arg(99)) 266 assert_equal('77some', RefDef2Arg(77, 'some')) 267 268 call CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:') 269 call CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:') 270 271 let RefVarargs: func(...list<string>): string 272 RefVarargs = FuncVarargs 273 assert_equal('', RefVarargs()) 274 assert_equal('one', RefVarargs('one')) 275 assert_equal('one,two', RefVarargs('one', 'two')) 276 277 call CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:') 278 call CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:') 279enddef 280 281" Only varargs 282def MyVarargsOnly(...args: list<string>): string 283 return join(args, ',') 284enddef 285 286def Test_call_varargs_only() 287 assert_equal('', MyVarargsOnly()) 288 assert_equal('one', MyVarargsOnly('one')) 289 assert_equal('one,two', MyVarargsOnly('one', 'two')) 290 call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number') 291 call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number') 292enddef 293 294def Test_using_var_as_arg() 295 call writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef') 296 call assert_fails('so Xdef', 'E1006:') 297 call delete('Xdef') 298enddef 299 300def DictArg(arg: dict<string>) 301 arg['key'] = 'value' 302enddef 303 304def ListArg(arg: list<string>) 305 arg[0] = 'value' 306enddef 307 308def Test_assign_to_argument() 309 # works for dict and list 310 let d: dict<string> = {} 311 DictArg(d) 312 assert_equal('value', d['key']) 313 let l: list<string> = [] 314 ListArg(l) 315 assert_equal('value', l[0]) 316 317 call CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:') 318enddef 319 320def Test_call_func_defined_later() 321 call assert_equal('one', g:DefinedLater('one')) 322 call assert_fails('call NotDefined("one")', 'E117:') 323enddef 324 325func DefinedLater(arg) 326 return a:arg 327endfunc 328 329def Test_call_funcref() 330 assert_equal(3, g:SomeFunc('abc')) 331 assert_fails('NotAFunc()', 'E117:') # comment after call 332 assert_fails('g:NotAFunc()', 'E117:') 333 334 let lines =<< trim END 335 vim9script 336 def RetNumber(): number 337 return 123 338 enddef 339 let Funcref: func: number = function('RetNumber') 340 assert_equal(123, Funcref()) 341 END 342 CheckScriptSuccess(lines) 343 344 lines =<< trim END 345 vim9script 346 def RetNumber(): number 347 return 123 348 enddef 349 def Bar(F: func: number): number 350 return F() 351 enddef 352 let Funcref = function('RetNumber') 353 assert_equal(123, Bar(Funcref)) 354 END 355 CheckScriptSuccess(lines) 356 357 lines =<< trim END 358 vim9script 359 def UseNumber(nr: number) 360 echo nr 361 enddef 362 let Funcref: func(number) = function('UseNumber') 363 Funcref(123) 364 END 365 CheckScriptSuccess(lines) 366 367 lines =<< trim END 368 vim9script 369 def UseNumber(nr: number) 370 echo nr 371 enddef 372 let Funcref: func(string) = function('UseNumber') 373 END 374 CheckScriptFailure(lines, 'E1013: type mismatch, expected func(string) but got func(number)') 375 376 lines =<< trim END 377 vim9script 378 def EchoNr(nr = 34) 379 g:echo = nr 380 enddef 381 let Funcref: func(?number) = function('EchoNr') 382 Funcref() 383 assert_equal(34, g:echo) 384 Funcref(123) 385 assert_equal(123, g:echo) 386 END 387 CheckScriptSuccess(lines) 388 389 lines =<< trim END 390 vim9script 391 def EchoList(...l: list<number>) 392 g:echo = l 393 enddef 394 let Funcref: func(...list<number>) = function('EchoList') 395 Funcref() 396 assert_equal([], g:echo) 397 Funcref(1, 2, 3) 398 assert_equal([1, 2, 3], g:echo) 399 END 400 CheckScriptSuccess(lines) 401 402 lines =<< trim END 403 vim9script 404 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number 405 g:optarg = opt 406 g:listarg = l 407 return nr 408 enddef 409 let Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar') 410 assert_equal(10, Funcref(10)) 411 assert_equal(12, g:optarg) 412 assert_equal([], g:listarg) 413 414 assert_equal(11, Funcref(11, 22)) 415 assert_equal(22, g:optarg) 416 assert_equal([], g:listarg) 417 418 assert_equal(17, Funcref(17, 18, 1, 2, 3)) 419 assert_equal(18, g:optarg) 420 assert_equal([1, 2, 3], g:listarg) 421 END 422 CheckScriptSuccess(lines) 423enddef 424 425let SomeFunc = function('len') 426let NotAFunc = 'text' 427 428def CombineFuncrefTypes() 429 # same arguments, different return type 430 let Ref1: func(bool): string 431 let Ref2: func(bool): number 432 let Ref3: func(bool): any 433 Ref3 = g:cond ? Ref1 : Ref2 434 435 # different number of arguments 436 let Refa1: func(bool): number 437 let Refa2: func(bool, number): number 438 let Refa3: func: number 439 Refa3 = g:cond ? Refa1 : Refa2 440 441 # different argument types 442 let Refb1: func(bool, string): number 443 let Refb2: func(string, number): number 444 let Refb3: func(any, any): number 445 Refb3 = g:cond ? Refb1 : Refb2 446enddef 447 448def FuncWithForwardCall() 449 return g:DefinedEvenLater("yes") 450enddef 451 452def DefinedEvenLater(arg: string): string 453 return arg 454enddef 455 456def Test_error_in_nested_function() 457 # Error in called function requires unwinding the call stack. 458 assert_fails('call FuncWithForwardCall()', 'E1096') 459enddef 460 461def Test_return_type_wrong() 462 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef', 'defcompile'], 'expected number but got string') 463 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef', 'defcompile'], 'expected string but got number') 464 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef', 'defcompile'], 'E1096: Returning a value in a function without a return type') 465 CheckScriptFailure(['def Func()', 'return "a"', 'enddef', 'defcompile'], 'E1096: Returning a value in a function without a return type') 466 467 CheckScriptFailure(['def Func(): number', 'return', 'enddef', 'defcompile'], 'E1003:') 468 469 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 470 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 471 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 472enddef 473 474def Test_arg_type_wrong() 475 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 476 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 477 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 478 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 479enddef 480 481def Test_vim9script_call() 482 let lines =<< trim END 483 vim9script 484 let var = '' 485 def MyFunc(arg: string) 486 var = arg 487 enddef 488 MyFunc('foobar') 489 assert_equal('foobar', var) 490 491 let str = 'barfoo' 492 str->MyFunc() 493 assert_equal('barfoo', var) 494 495 g:value = 'value' 496 g:value->MyFunc() 497 assert_equal('value', var) 498 499 let listvar = [] 500 def ListFunc(arg: list<number>) 501 listvar = arg 502 enddef 503 [1, 2, 3]->ListFunc() 504 assert_equal([1, 2, 3], listvar) 505 506 let dictvar = {} 507 def DictFunc(arg: dict<number>) 508 dictvar = arg 509 enddef 510 {'a': 1, 'b': 2}->DictFunc() 511 assert_equal(#{a: 1, b: 2}, dictvar) 512 def CompiledDict() 513 {'a': 3, 'b': 4}->DictFunc() 514 enddef 515 CompiledDict() 516 assert_equal(#{a: 3, b: 4}, dictvar) 517 518 #{a: 3, b: 4}->DictFunc() 519 assert_equal(#{a: 3, b: 4}, dictvar) 520 521 ('text')->MyFunc() 522 assert_equal('text', var) 523 ("some")->MyFunc() 524 assert_equal('some', var) 525 526 # line starting with single quote is not a mark 527 # line starting with double quote can be a method call 528 'asdfasdf'->MyFunc() 529 assert_equal('asdfasdf', var) 530 "xyz"->MyFunc() 531 assert_equal('xyz', var) 532 533 def UseString() 534 'xyork'->MyFunc() 535 enddef 536 UseString() 537 assert_equal('xyork', var) 538 539 def UseString2() 540 "knife"->MyFunc() 541 enddef 542 UseString2() 543 assert_equal('knife', var) 544 545 # prepending a colon makes it a mark 546 new 547 setline(1, ['aaa', 'bbb', 'ccc']) 548 normal! 3Gmt1G 549 :'t 550 assert_equal(3, getcurpos()[1]) 551 bwipe! 552 553 MyFunc( 554 'continued' 555 ) 556 assert_equal('continued', 557 var 558 ) 559 560 call MyFunc( 561 'more' 562 .. 563 'lines' 564 ) 565 assert_equal( 566 'morelines', 567 var) 568 END 569 writefile(lines, 'Xcall.vim') 570 source Xcall.vim 571 delete('Xcall.vim') 572enddef 573 574def Test_vim9script_call_fail_decl() 575 let lines =<< trim END 576 vim9script 577 let var = '' 578 def MyFunc(arg: string) 579 let var = 123 580 enddef 581 defcompile 582 END 583 CheckScriptFailure(lines, 'E1054:') 584enddef 585 586def Test_vim9script_call_fail_type() 587 let lines =<< trim END 588 vim9script 589 def MyFunc(arg: string) 590 echo arg 591 enddef 592 MyFunc(1234) 593 END 594 CheckScriptFailure(lines, 'E1013: type mismatch, expected string but got number') 595enddef 596 597def Test_vim9script_call_fail_const() 598 let lines =<< trim END 599 vim9script 600 const var = '' 601 def MyFunc(arg: string) 602 var = 'asdf' 603 enddef 604 defcompile 605 END 606 writefile(lines, 'Xcall_const.vim') 607 assert_fails('source Xcall_const.vim', 'E46:') 608 delete('Xcall_const.vim') 609enddef 610 611" Test that inside :function a Python function can be defined, :def is not 612" recognized. 613func Test_function_python() 614 CheckFeature python3 615 let py = 'python3' 616 execute py "<< EOF" 617def do_something(): 618 return 1 619EOF 620endfunc 621 622def Test_delfunc() 623 let lines =<< trim END 624 vim9script 625 def g:GoneSoon() 626 echo 'hello' 627 enddef 628 629 def CallGoneSoon() 630 GoneSoon() 631 enddef 632 defcompile 633 634 delfunc g:GoneSoon 635 CallGoneSoon() 636 END 637 writefile(lines, 'XToDelFunc') 638 assert_fails('so XToDelFunc', 'E933') 639 assert_fails('so XToDelFunc', 'E933') 640 641 delete('XToDelFunc') 642enddef 643 644def Test_redef_failure() 645 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 646 so Xdef 647 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 648 so Xdef 649 call writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 650 call assert_fails('so Xdef', 'E1027:') 651 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 652 so Xdef 653 call delete('Xdef') 654 655 call assert_equal(0, g:Func0()) 656 call assert_equal('Func1', g:Func1()) 657 call assert_equal('Func2', g:Func2()) 658 659 delfunc! Func0 660 delfunc! Func1 661 delfunc! Func2 662enddef 663 664def Test_vim9script_func() 665 let lines =<< trim END 666 vim9script 667 func Func(arg) 668 echo a:arg 669 endfunc 670 Func('text') 671 END 672 writefile(lines, 'XVim9Func') 673 so XVim9Func 674 675 delete('XVim9Func') 676enddef 677 678" Test for internal functions returning different types 679func Test_InternalFuncRetType() 680 let lines =<< trim END 681 def RetFloat(): float 682 return ceil(1.456) 683 enddef 684 685 def RetListAny(): list<any> 686 return items({'k' : 'v'}) 687 enddef 688 689 def RetListString(): list<string> 690 return split('a:b:c', ':') 691 enddef 692 693 def RetListDictAny(): list<dict<any>> 694 return getbufinfo() 695 enddef 696 697 def RetDictNumber(): dict<number> 698 return wordcount() 699 enddef 700 701 def RetDictString(): dict<string> 702 return environ() 703 enddef 704 END 705 call writefile(lines, 'Xscript') 706 source Xscript 707 708 call assert_equal(2.0, RetFloat()) 709 call assert_equal([['k', 'v']], RetListAny()) 710 call assert_equal(['a', 'b', 'c'], RetListString()) 711 call assert_notequal([], RetListDictAny()) 712 call assert_notequal({}, RetDictNumber()) 713 call assert_notequal({}, RetDictString()) 714 call delete('Xscript') 715endfunc 716 717" Test for passing too many or too few arguments to internal functions 718func Test_internalfunc_arg_error() 719 let l =<< trim END 720 def! FArgErr(): float 721 return ceil(1.1, 2) 722 enddef 723 defcompile 724 END 725 call writefile(l, 'Xinvalidarg') 726 call assert_fails('so Xinvalidarg', 'E118:') 727 let l =<< trim END 728 def! FArgErr(): float 729 return ceil() 730 enddef 731 defcompile 732 END 733 call writefile(l, 'Xinvalidarg') 734 call assert_fails('so Xinvalidarg', 'E119:') 735 call delete('Xinvalidarg') 736endfunc 737 738let s:funcResult = 0 739 740def FuncNoArgNoRet() 741 funcResult = 11 742enddef 743 744def FuncNoArgRetNumber(): number 745 funcResult = 22 746 return 1234 747enddef 748 749def FuncNoArgRetString(): string 750 funcResult = 45 751 return 'text' 752enddef 753 754def FuncOneArgNoRet(arg: number) 755 funcResult = arg 756enddef 757 758def FuncOneArgRetNumber(arg: number): number 759 funcResult = arg 760 return arg 761enddef 762 763def FuncTwoArgNoRet(one: bool, two: number) 764 funcResult = two 765enddef 766 767def FuncOneArgRetString(arg: string): string 768 return arg 769enddef 770 771def FuncOneArgRetAny(arg: any): any 772 return arg 773enddef 774 775def Test_func_type() 776 let Ref1: func() 777 funcResult = 0 778 Ref1 = FuncNoArgNoRet 779 Ref1() 780 assert_equal(11, funcResult) 781 782 let Ref2: func 783 funcResult = 0 784 Ref2 = FuncNoArgNoRet 785 Ref2() 786 assert_equal(11, funcResult) 787 788 funcResult = 0 789 Ref2 = FuncOneArgNoRet 790 Ref2(12) 791 assert_equal(12, funcResult) 792 793 funcResult = 0 794 Ref2 = FuncNoArgRetNumber 795 assert_equal(1234, Ref2()) 796 assert_equal(22, funcResult) 797 798 funcResult = 0 799 Ref2 = FuncOneArgRetNumber 800 assert_equal(13, Ref2(13)) 801 assert_equal(13, funcResult) 802enddef 803 804def Test_repeat_return_type() 805 let res = 0 806 for n in repeat([1], 3) 807 res += n 808 endfor 809 assert_equal(3, res) 810 811 res = 0 812 for n in add([1, 2], 3) 813 res += n 814 endfor 815 assert_equal(6, res) 816enddef 817 818def Test_argv_return_type() 819 next fileone filetwo 820 let res = '' 821 for name in argv() 822 res ..= name 823 endfor 824 assert_equal('fileonefiletwo', res) 825enddef 826 827def Test_func_type_part() 828 let RefVoid: func: void 829 RefVoid = FuncNoArgNoRet 830 RefVoid = FuncOneArgNoRet 831 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 832 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string') 833 834 let RefAny: func(): any 835 RefAny = FuncNoArgRetNumber 836 RefAny = FuncNoArgRetString 837 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): any but got func()') 838 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1013: type mismatch, expected func(): any but got func(number)') 839 840 let RefNr: func: number 841 RefNr = FuncNoArgRetNumber 842 RefNr = FuncOneArgRetNumber 843 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()') 844 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string') 845 846 let RefStr: func: string 847 RefStr = FuncNoArgRetString 848 RefStr = FuncOneArgRetString 849 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): string but got func()') 850 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got func(): number') 851enddef 852 853def Test_func_type_fails() 854 CheckDefFailure(['let ref1: func()'], 'E704:') 855 856 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 857 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)') 858 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number') 859 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)') 860 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)') 861 CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)') 862 863 call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') 864 call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') 865 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:') 866 call CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:') 867enddef 868 869def Test_func_return_type() 870 let nr: number 871 nr = FuncNoArgRetNumber() 872 assert_equal(1234, nr) 873 874 nr = FuncOneArgRetAny(122) 875 assert_equal(122, nr) 876 877 let str: string 878 str = FuncOneArgRetAny('yes') 879 assert_equal('yes', str) 880 881 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1013: type mismatch, expected string but got number') 882enddef 883 884def MultiLine( 885 arg1: string, 886 arg2 = 1234, 887 ...rest: list<string> 888 ): string 889 return arg1 .. arg2 .. join(rest, '-') 890enddef 891 892def MultiLineComment( 893 arg1: string, # comment 894 arg2 = 1234, # comment 895 ...rest: list<string> # comment 896 ): string # comment 897 return arg1 .. arg2 .. join(rest, '-') 898enddef 899 900def Test_multiline() 901 assert_equal('text1234', MultiLine('text')) 902 assert_equal('text777', MultiLine('text', 777)) 903 assert_equal('text777one', MultiLine('text', 777, 'one')) 904 assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 905enddef 906 907func Test_multiline_not_vim9() 908 call assert_equal('text1234', MultiLine('text')) 909 call assert_equal('text777', MultiLine('text', 777)) 910 call assert_equal('text777one', MultiLine('text', 777, 'one')) 911 call assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 912endfunc 913 914 915" When using CheckScriptFailure() for the below test, E1010 is generated instead 916" of E1056. 917func Test_E1056_1059() 918 let caught_1056 = 0 919 try 920 def F(): 921 return 1 922 enddef 923 catch /E1056:/ 924 let caught_1056 = 1 925 endtry 926 call assert_equal(1, caught_1056) 927 928 let caught_1059 = 0 929 try 930 def F5(items : list) 931 echo 'a' 932 enddef 933 catch /E1059:/ 934 let caught_1059 = 1 935 endtry 936 call assert_equal(1, caught_1059) 937endfunc 938 939func DelMe() 940 echo 'DelMe' 941endfunc 942 943def Test_deleted_function() 944 CheckDefExecFailure([ 945 'let RefMe: func = function("g:DelMe")', 946 'delfunc g:DelMe', 947 'echo RefMe()'], 'E117:') 948enddef 949 950def Test_unknown_function() 951 CheckDefExecFailure([ 952 'let Ref: func = function("NotExist")', 953 'delfunc g:NotExist'], 'E700:') 954enddef 955 956def RefFunc(Ref: func(string): string): string 957 return Ref('more') 958enddef 959 960def Test_closure_simple() 961 let local = 'some ' 962 assert_equal('some more', RefFunc({s -> local .. s})) 963enddef 964 965def MakeRef() 966 let local = 'some ' 967 g:Ref = {s -> local .. s} 968enddef 969 970def Test_closure_ref_after_return() 971 MakeRef() 972 assert_equal('some thing', g:Ref('thing')) 973 unlet g:Ref 974enddef 975 976def MakeTwoRefs() 977 let local = ['some'] 978 g:Extend = {s -> local->add(s)} 979 g:Read = {-> local} 980enddef 981 982def Test_closure_two_refs() 983 MakeTwoRefs() 984 assert_equal('some', join(g:Read(), ' ')) 985 g:Extend('more') 986 assert_equal('some more', join(g:Read(), ' ')) 987 g:Extend('even') 988 assert_equal('some more even', join(g:Read(), ' ')) 989 990 unlet g:Extend 991 unlet g:Read 992enddef 993 994def ReadRef(Ref: func(): list<string>): string 995 return join(Ref(), ' ') 996enddef 997 998def ExtendRef(Ref: func(string), add: string) 999 Ref(add) 1000enddef 1001 1002def Test_closure_two_indirect_refs() 1003 MakeTwoRefs() 1004 assert_equal('some', ReadRef(g:Read)) 1005 ExtendRef(g:Extend, 'more') 1006 assert_equal('some more', ReadRef(g:Read)) 1007 ExtendRef(g:Extend, 'even') 1008 assert_equal('some more even', ReadRef(g:Read)) 1009 1010 unlet g:Extend 1011 unlet g:Read 1012enddef 1013 1014def MakeArgRefs(theArg: string) 1015 let local = 'loc_val' 1016 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 1017enddef 1018 1019def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 1020 let local = 'the_loc' 1021 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)} 1022enddef 1023 1024def Test_closure_using_argument() 1025 MakeArgRefs('arg_val') 1026 assert_equal('arg_val/loc_val/call_val', g:UseArg('call_val')) 1027 1028 MakeArgRefsVarargs('arg_val', 'one', 'two') 1029 assert_equal('arg_val/the_loc/call_val/one two', g:UseVararg('call_val')) 1030 1031 unlet g:UseArg 1032 unlet g:UseVararg 1033enddef 1034 1035def MakeGetAndAppendRefs() 1036 let local = 'a' 1037 1038 def Append(arg: string) 1039 local ..= arg 1040 enddef 1041 g:Append = Append 1042 1043 def Get(): string 1044 return local 1045 enddef 1046 g:Get = Get 1047enddef 1048 1049def Test_closure_append_get() 1050 MakeGetAndAppendRefs() 1051 assert_equal('a', g:Get()) 1052 g:Append('-b') 1053 assert_equal('a-b', g:Get()) 1054 g:Append('-c') 1055 assert_equal('a-b-c', g:Get()) 1056 1057 unlet g:Append 1058 unlet g:Get 1059enddef 1060 1061def Test_nested_closure() 1062 let local = 'text' 1063 def Closure(arg: string): string 1064 return local .. arg 1065 enddef 1066 assert_equal('text!!!', Closure('!!!')) 1067enddef 1068 1069func GetResult(Ref) 1070 return a:Ref('some') 1071endfunc 1072 1073def Test_call_closure_not_compiled() 1074 let text = 'text' 1075 g:Ref = {s -> s .. text} 1076 assert_equal('sometext', GetResult(g:Ref)) 1077enddef 1078 1079def Test_sort_return_type() 1080 let res: list<number> 1081 res = [1, 2, 3]->sort() 1082enddef 1083 1084def Test_getqflist_return_type() 1085 let l = getqflist() 1086 assert_equal([], l) 1087 1088 let d = getqflist(#{items: 0}) 1089 assert_equal(#{items: []}, d) 1090enddef 1091 1092def Test_getloclist_return_type() 1093 let l = getloclist(1) 1094 assert_equal([], l) 1095 1096 let d = getloclist(1, #{items: 0}) 1097 assert_equal(#{items: []}, d) 1098enddef 1099 1100def Test_copy_return_type() 1101 let l = copy([1, 2, 3]) 1102 let res = 0 1103 for n in l 1104 res += n 1105 endfor 1106 assert_equal(6, res) 1107 1108 let dl = deepcopy([1, 2, 3]) 1109 res = 0 1110 for n in dl 1111 res += n 1112 endfor 1113 assert_equal(6, res) 1114enddef 1115 1116def Test_extend_return_type() 1117 let l = extend([1, 2], [3]) 1118 let res = 0 1119 for n in l 1120 res += n 1121 endfor 1122 assert_equal(6, res) 1123enddef 1124 1125def Test_insert_return_type() 1126 let l = insert([2, 1], 3) 1127 let res = 0 1128 for n in l 1129 res += n 1130 endfor 1131 assert_equal(6, res) 1132enddef 1133 1134def Test_reverse_return_type() 1135 let l = reverse([1, 2, 3]) 1136 let res = 0 1137 for n in l 1138 res += n 1139 endfor 1140 assert_equal(6, res) 1141enddef 1142 1143def Test_remove_return_type() 1144 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one') 1145 let res = 0 1146 for n in l 1147 res += n 1148 endfor 1149 assert_equal(3, res) 1150enddef 1151 1152def Test_filter_return_type() 1153 let l = filter([1, 2, 3], {-> 1}) 1154 let res = 0 1155 for n in l 1156 res += n 1157 endfor 1158 assert_equal(6, res) 1159enddef 1160 1161def Wrong_dict_key_type(items: list<number>): list<number> 1162 return filter(items, {_, val -> get({val: 1}, 'x')}) 1163enddef 1164 1165def Test_wrong_dict_key_type() 1166 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:') 1167enddef 1168 1169def Line_continuation_in_def(dir: string = ''): string 1170 let path: string = empty(dir) 1171 \ ? 'empty' 1172 \ : 'full' 1173 return path 1174enddef 1175 1176def Test_line_continuation_in_def() 1177 assert_equal('full', Line_continuation_in_def('.')) 1178enddef 1179 1180def Line_continuation_in_lambda(): list<number> 1181 let x = range(97, 100) 1182 ->map({_, v -> nr2char(v) 1183 ->toupper()}) 1184 ->reverse() 1185 return x 1186enddef 1187 1188def Test_line_continuation_in_lambda() 1189 assert_equal(['D', 'C', 'B', 'A'], Line_continuation_in_lambda()) 1190enddef 1191 1192func Test_silent_echo() 1193 CheckScreendump 1194 1195 let lines =<< trim END 1196 vim9script 1197 def EchoNothing() 1198 silent echo '' 1199 enddef 1200 defcompile 1201 END 1202 call writefile(lines, 'XTest_silent_echo') 1203 1204 " Check that the balloon shows up after a mouse move 1205 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 1206 call term_sendkeys(buf, ":abc") 1207 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 1208 1209 " clean up 1210 call StopVimInTerminal(buf) 1211 call delete('XTest_silent_echo') 1212endfunc 1213 1214def Fibonacci(n: number): number 1215 if n < 2 1216 return n 1217 else 1218 return Fibonacci(n - 1) + Fibonacci(n - 2) 1219 endif 1220enddef 1221 1222def Test_recursive_call() 1223 assert_equal(6765, Fibonacci(20)) 1224enddef 1225 1226def TreeWalk(dir: string): list<any> 1227 return readdir(dir)->map({_, val -> 1228 fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 1229 ? {val : TreeWalk(dir .. '/' .. val)} 1230 : val 1231 }) 1232enddef 1233 1234def Test_closure_in_map() 1235 mkdir('XclosureDir/tdir', 'p') 1236 writefile(['111'], 'XclosureDir/file1') 1237 writefile(['222'], 'XclosureDir/file2') 1238 writefile(['333'], 'XclosureDir/tdir/file3') 1239 1240 assert_equal(['file1', 'file2', {'tdir': ['file3']}], TreeWalk('XclosureDir')) 1241 1242 delete('XclosureDir', 'rf') 1243enddef 1244 1245def Test_partial_call() 1246 let Xsetlist = function('setloclist', [0]) 1247 Xsetlist([], ' ', {'title': 'test'}) 1248 assert_equal({'title': 'test'}, getloclist(0, {'title': 1})) 1249 1250 Xsetlist = function('setloclist', [0, [], ' ']) 1251 Xsetlist({'title': 'test'}) 1252 assert_equal({'title': 'test'}, getloclist(0, {'title': 1})) 1253 1254 Xsetlist = function('setqflist') 1255 Xsetlist([], ' ', {'title': 'test'}) 1256 assert_equal({'title': 'test'}, getqflist({'title': 1})) 1257 1258 Xsetlist = function('setqflist', [[], ' ']) 1259 Xsetlist({'title': 'test'}) 1260 assert_equal({'title': 'test'}, getqflist({'title': 1})) 1261enddef 1262 1263 1264" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 1265