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