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