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 'asdfasdf'->MyFunc() 506 assert_equal('asdfasdf', var) 507 508 def UseString() 509 'xyork'->MyFunc() 510 enddef 511 UseString() 512 assert_equal('xyork', var) 513 514 # prepending a colon makes it a mark 515 new 516 setline(1, ['aaa', 'bbb', 'ccc']) 517 normal! 3Gmt1G 518 :'t 519 assert_equal(3, getcurpos()[1]) 520 bwipe! 521 522 MyFunc( 523 'continued' 524 ) 525 assert_equal('continued', 526 var 527 ) 528 529 call MyFunc( 530 'more' 531 .. 532 'lines' 533 ) 534 assert_equal( 535 'morelines', 536 var) 537 END 538 writefile(lines, 'Xcall.vim') 539 source Xcall.vim 540 delete('Xcall.vim') 541enddef 542 543def Test_vim9script_call_fail_decl() 544 let lines =<< trim END 545 vim9script 546 let var = '' 547 def MyFunc(arg: string) 548 let var = 123 549 enddef 550 defcompile 551 END 552 CheckScriptFailure(lines, 'E1054:') 553enddef 554 555def Test_vim9script_call_fail_type() 556 let lines =<< trim END 557 vim9script 558 def MyFunc(arg: string) 559 echo arg 560 enddef 561 MyFunc(1234) 562 END 563 CheckScriptFailure(lines, 'E1013: type mismatch, expected string but got number') 564enddef 565 566def Test_vim9script_call_fail_const() 567 let lines =<< trim END 568 vim9script 569 const var = '' 570 def MyFunc(arg: string) 571 var = 'asdf' 572 enddef 573 defcompile 574 END 575 writefile(lines, 'Xcall_const.vim') 576 assert_fails('source Xcall_const.vim', 'E46:') 577 delete('Xcall_const.vim') 578enddef 579 580" Test that inside :function a Python function can be defined, :def is not 581" recognized. 582func Test_function_python() 583 CheckFeature python3 584 let py = 'python3' 585 execute py "<< EOF" 586def do_something(): 587 return 1 588EOF 589endfunc 590 591def Test_delfunc() 592 let lines =<< trim END 593 vim9script 594 def g:GoneSoon() 595 echo 'hello' 596 enddef 597 598 def CallGoneSoon() 599 GoneSoon() 600 enddef 601 defcompile 602 603 delfunc g:GoneSoon 604 CallGoneSoon() 605 END 606 writefile(lines, 'XToDelFunc') 607 assert_fails('so XToDelFunc', 'E933') 608 assert_fails('so XToDelFunc', 'E933') 609 610 delete('XToDelFunc') 611enddef 612 613def Test_redef_failure() 614 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 615 so Xdef 616 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 617 so Xdef 618 call writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 619 call assert_fails('so Xdef', 'E1027:') 620 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 621 so Xdef 622 call delete('Xdef') 623 624 call assert_equal(0, g:Func0()) 625 call assert_equal('Func1', g:Func1()) 626 call assert_equal('Func2', g:Func2()) 627 628 delfunc! Func0 629 delfunc! Func1 630 delfunc! Func2 631enddef 632 633def Test_vim9script_func() 634 let lines =<< trim END 635 vim9script 636 func Func(arg) 637 echo a:arg 638 endfunc 639 Func('text') 640 END 641 writefile(lines, 'XVim9Func') 642 so XVim9Func 643 644 delete('XVim9Func') 645enddef 646 647" Test for internal functions returning different types 648func Test_InternalFuncRetType() 649 let lines =<< trim END 650 def RetFloat(): float 651 return ceil(1.456) 652 enddef 653 654 def RetListAny(): list<any> 655 return items({'k' : 'v'}) 656 enddef 657 658 def RetListString(): list<string> 659 return split('a:b:c', ':') 660 enddef 661 662 def RetListDictAny(): list<dict<any>> 663 return getbufinfo() 664 enddef 665 666 def RetDictNumber(): dict<number> 667 return wordcount() 668 enddef 669 670 def RetDictString(): dict<string> 671 return environ() 672 enddef 673 END 674 call writefile(lines, 'Xscript') 675 source Xscript 676 677 call assert_equal(2.0, RetFloat()) 678 call assert_equal([['k', 'v']], RetListAny()) 679 call assert_equal(['a', 'b', 'c'], RetListString()) 680 call assert_notequal([], RetListDictAny()) 681 call assert_notequal({}, RetDictNumber()) 682 call assert_notequal({}, RetDictString()) 683 call delete('Xscript') 684endfunc 685 686" Test for passing too many or too few arguments to internal functions 687func Test_internalfunc_arg_error() 688 let l =<< trim END 689 def! FArgErr(): float 690 return ceil(1.1, 2) 691 enddef 692 defcompile 693 END 694 call writefile(l, 'Xinvalidarg') 695 call assert_fails('so Xinvalidarg', 'E118:') 696 let l =<< trim END 697 def! FArgErr(): float 698 return ceil() 699 enddef 700 defcompile 701 END 702 call writefile(l, 'Xinvalidarg') 703 call assert_fails('so Xinvalidarg', 'E119:') 704 call delete('Xinvalidarg') 705endfunc 706 707let s:funcResult = 0 708 709def FuncNoArgNoRet() 710 funcResult = 11 711enddef 712 713def FuncNoArgRetNumber(): number 714 funcResult = 22 715 return 1234 716enddef 717 718def FuncNoArgRetString(): string 719 funcResult = 45 720 return 'text' 721enddef 722 723def FuncOneArgNoRet(arg: number) 724 funcResult = arg 725enddef 726 727def FuncOneArgRetNumber(arg: number): number 728 funcResult = arg 729 return arg 730enddef 731 732def FuncTwoArgNoRet(one: bool, two: number) 733 funcResult = two 734enddef 735 736def FuncOneArgRetString(arg: string): string 737 return arg 738enddef 739 740def FuncOneArgRetAny(arg: any): any 741 return arg 742enddef 743 744def Test_func_type() 745 let Ref1: func() 746 funcResult = 0 747 Ref1 = FuncNoArgNoRet 748 Ref1() 749 assert_equal(11, funcResult) 750 751 let Ref2: func 752 funcResult = 0 753 Ref2 = FuncNoArgNoRet 754 Ref2() 755 assert_equal(11, funcResult) 756 757 funcResult = 0 758 Ref2 = FuncOneArgNoRet 759 Ref2(12) 760 assert_equal(12, funcResult) 761 762 funcResult = 0 763 Ref2 = FuncNoArgRetNumber 764 assert_equal(1234, Ref2()) 765 assert_equal(22, funcResult) 766 767 funcResult = 0 768 Ref2 = FuncOneArgRetNumber 769 assert_equal(13, Ref2(13)) 770 assert_equal(13, funcResult) 771enddef 772 773def Test_repeat_return_type() 774 let res = 0 775 for n in repeat([1], 3) 776 res += n 777 endfor 778 assert_equal(3, res) 779 780 res = 0 781 for n in add([1, 2], 3) 782 res += n 783 endfor 784 assert_equal(6, res) 785enddef 786 787def Test_argv_return_type() 788 next fileone filetwo 789 let res = '' 790 for name in argv() 791 res ..= name 792 endfor 793 assert_equal('fileonefiletwo', res) 794enddef 795 796def Test_func_type_part() 797 let RefVoid: func: void 798 RefVoid = FuncNoArgNoRet 799 RefVoid = FuncOneArgNoRet 800 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 801 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string') 802 803 let RefAny: func(): any 804 RefAny = FuncNoArgRetNumber 805 RefAny = FuncNoArgRetString 806 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): any but got func()') 807 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1013: type mismatch, expected func(): any but got func(number)') 808 809 let RefNr: func: number 810 RefNr = FuncNoArgRetNumber 811 RefNr = FuncOneArgRetNumber 812 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()') 813 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string') 814 815 let RefStr: func: string 816 RefStr = FuncNoArgRetString 817 RefStr = FuncOneArgRetString 818 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): string but got func()') 819 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got func(): number') 820enddef 821 822def Test_func_type_fails() 823 CheckDefFailure(['let ref1: func()'], 'E704:') 824 825 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 826 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)') 827 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number') 828 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)') 829 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)') 830 CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)') 831 832 call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') 833 call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') 834 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:') 835 call CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:') 836enddef 837 838def Test_func_return_type() 839 let nr: number 840 nr = FuncNoArgRetNumber() 841 assert_equal(1234, nr) 842 843 nr = FuncOneArgRetAny(122) 844 assert_equal(122, nr) 845 846 let str: string 847 str = FuncOneArgRetAny('yes') 848 assert_equal('yes', str) 849 850 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1013: type mismatch, expected string but got number') 851enddef 852 853def MultiLine( 854 arg1: string, 855 arg2 = 1234, 856 ...rest: list<string> 857 ): string 858 return arg1 .. arg2 .. join(rest, '-') 859enddef 860 861def MultiLineComment( 862 arg1: string, # comment 863 arg2 = 1234, # comment 864 ...rest: list<string> # comment 865 ): string # comment 866 return arg1 .. arg2 .. join(rest, '-') 867enddef 868 869def Test_multiline() 870 assert_equal('text1234', MultiLine('text')) 871 assert_equal('text777', MultiLine('text', 777)) 872 assert_equal('text777one', MultiLine('text', 777, 'one')) 873 assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 874enddef 875 876func Test_multiline_not_vim9() 877 call assert_equal('text1234', MultiLine('text')) 878 call assert_equal('text777', MultiLine('text', 777)) 879 call assert_equal('text777one', MultiLine('text', 777, 'one')) 880 call assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 881endfunc 882 883 884" When using CheckScriptFailure() for the below test, E1010 is generated instead 885" of E1056. 886func Test_E1056_1059() 887 let caught_1056 = 0 888 try 889 def F(): 890 return 1 891 enddef 892 catch /E1056:/ 893 let caught_1056 = 1 894 endtry 895 call assert_equal(1, caught_1056) 896 897 let caught_1059 = 0 898 try 899 def F5(items : list) 900 echo 'a' 901 enddef 902 catch /E1059:/ 903 let caught_1059 = 1 904 endtry 905 call assert_equal(1, caught_1059) 906endfunc 907 908func DelMe() 909 echo 'DelMe' 910endfunc 911 912def Test_deleted_function() 913 CheckDefExecFailure([ 914 'let RefMe: func = function("g:DelMe")', 915 'delfunc g:DelMe', 916 'echo RefMe()'], 'E117:') 917enddef 918 919def Test_unknown_function() 920 CheckDefExecFailure([ 921 'let Ref: func = function("NotExist")', 922 'delfunc g:NotExist'], 'E700:') 923enddef 924 925def RefFunc(Ref: func(string): string): string 926 return Ref('more') 927enddef 928 929def Test_closure_simple() 930 let local = 'some ' 931 assert_equal('some more', RefFunc({s -> local .. s})) 932enddef 933 934def MakeRef() 935 let local = 'some ' 936 g:Ref = {s -> local .. s} 937enddef 938 939def Test_closure_ref_after_return() 940 MakeRef() 941 assert_equal('some thing', g:Ref('thing')) 942 unlet g:Ref 943enddef 944 945def MakeTwoRefs() 946 let local = ['some'] 947 g:Extend = {s -> local->add(s)} 948 g:Read = {-> local} 949enddef 950 951def Test_closure_two_refs() 952 MakeTwoRefs() 953 assert_equal('some', join(g:Read(), ' ')) 954 g:Extend('more') 955 assert_equal('some more', join(g:Read(), ' ')) 956 g:Extend('even') 957 assert_equal('some more even', join(g:Read(), ' ')) 958 959 unlet g:Extend 960 unlet g:Read 961enddef 962 963def ReadRef(Ref: func(): list<string>): string 964 return join(Ref(), ' ') 965enddef 966 967def ExtendRef(Ref: func(string), add: string) 968 Ref(add) 969enddef 970 971def Test_closure_two_indirect_refs() 972 MakeTwoRefs() 973 assert_equal('some', ReadRef(g:Read)) 974 ExtendRef(g:Extend, 'more') 975 assert_equal('some more', ReadRef(g:Read)) 976 ExtendRef(g:Extend, 'even') 977 assert_equal('some more even', ReadRef(g:Read)) 978 979 unlet g:Extend 980 unlet g:Read 981enddef 982 983def MakeArgRefs(theArg: string) 984 let local = 'loc_val' 985 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 986enddef 987 988def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 989 let local = 'the_loc' 990 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)} 991enddef 992 993def Test_closure_using_argument() 994 MakeArgRefs('arg_val') 995 assert_equal('arg_val/loc_val/call_val', g:UseArg('call_val')) 996 997 MakeArgRefsVarargs('arg_val', 'one', 'two') 998 assert_equal('arg_val/the_loc/call_val/one two', g:UseVararg('call_val')) 999 1000 unlet g:UseArg 1001 unlet g:UseVararg 1002enddef 1003 1004def MakeGetAndAppendRefs() 1005 let local = 'a' 1006 1007 def Append(arg: string) 1008 local ..= arg 1009 enddef 1010 g:Append = Append 1011 1012 def Get(): string 1013 return local 1014 enddef 1015 g:Get = Get 1016enddef 1017 1018def Test_closure_append_get() 1019 MakeGetAndAppendRefs() 1020 assert_equal('a', g:Get()) 1021 g:Append('-b') 1022 assert_equal('a-b', g:Get()) 1023 g:Append('-c') 1024 assert_equal('a-b-c', g:Get()) 1025 1026 unlet g:Append 1027 unlet g:Get 1028enddef 1029 1030def Test_nested_closure() 1031 let local = 'text' 1032 def Closure(arg: string): string 1033 return local .. arg 1034 enddef 1035 assert_equal('text!!!', Closure('!!!')) 1036enddef 1037 1038func GetResult(Ref) 1039 return a:Ref('some') 1040endfunc 1041 1042def Test_call_closure_not_compiled() 1043 let text = 'text' 1044 g:Ref = {s -> s .. text} 1045 assert_equal('sometext', GetResult(g:Ref)) 1046enddef 1047 1048def Test_sort_return_type() 1049 let res: list<number> 1050 res = [1, 2, 3]->sort() 1051enddef 1052 1053def Test_getqflist_return_type() 1054 let l = getqflist() 1055 assert_equal([], l) 1056 1057 let d = getqflist(#{items: 0}) 1058 assert_equal(#{items: []}, d) 1059enddef 1060 1061def Test_getloclist_return_type() 1062 let l = getloclist(1) 1063 assert_equal([], l) 1064 1065 let d = getloclist(1, #{items: 0}) 1066 assert_equal(#{items: []}, d) 1067enddef 1068 1069def Test_copy_return_type() 1070 let l = copy([1, 2, 3]) 1071 let res = 0 1072 for n in l 1073 res += n 1074 endfor 1075 assert_equal(6, res) 1076 1077 let dl = deepcopy([1, 2, 3]) 1078 res = 0 1079 for n in dl 1080 res += n 1081 endfor 1082 assert_equal(6, res) 1083enddef 1084 1085def Test_extend_return_type() 1086 let l = extend([1, 2], [3]) 1087 let res = 0 1088 for n in l 1089 res += n 1090 endfor 1091 assert_equal(6, res) 1092enddef 1093 1094def Test_insert_return_type() 1095 let l = insert([2, 1], 3) 1096 let res = 0 1097 for n in l 1098 res += n 1099 endfor 1100 assert_equal(6, res) 1101enddef 1102 1103def Test_reverse_return_type() 1104 let l = reverse([1, 2, 3]) 1105 let res = 0 1106 for n in l 1107 res += n 1108 endfor 1109 assert_equal(6, res) 1110enddef 1111 1112def Test_remove_return_type() 1113 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one') 1114 let res = 0 1115 for n in l 1116 res += n 1117 endfor 1118 assert_equal(3, res) 1119enddef 1120 1121def Test_filter_return_type() 1122 let l = filter([1, 2, 3], {-> 1}) 1123 let res = 0 1124 for n in l 1125 res += n 1126 endfor 1127 assert_equal(6, res) 1128enddef 1129 1130def Wrong_dict_key_type(items: list<number>): list<number> 1131 return filter(items, {_, val -> get({val: 1}, 'x')}) 1132enddef 1133 1134def Test_wrong_dict_key_type() 1135 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1029:') 1136enddef 1137 1138def Line_continuation_in_def(dir: string = ''): string 1139 let path: string = empty(dir) 1140 \ ? 'empty' 1141 \ : 'full' 1142 return path 1143enddef 1144 1145def Test_line_continuation_in_def() 1146 assert_equal('full', Line_continuation_in_def('.')) 1147enddef 1148 1149def Line_continuation_in_lambda(): list<number> 1150 let x = range(97, 100) 1151 ->map({_, v -> nr2char(v) 1152 ->toupper()}) 1153 ->reverse() 1154 return x 1155enddef 1156 1157def Test_line_continuation_in_lambda() 1158 assert_equal(['D', 'C', 'B', 'A'], Line_continuation_in_lambda()) 1159enddef 1160 1161func Test_silent_echo() 1162 CheckScreendump 1163 1164 let lines =<< trim END 1165 vim9script 1166 def EchoNothing() 1167 silent echo '' 1168 enddef 1169 defcompile 1170 END 1171 call writefile(lines, 'XTest_silent_echo') 1172 1173 " Check that the balloon shows up after a mouse move 1174 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 1175 call term_sendkeys(buf, ":abc") 1176 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 1177 1178 " clean up 1179 call StopVimInTerminal(buf) 1180 call delete('XTest_silent_echo') 1181endfunc 1182 1183def Fibonacci(n: number): number 1184 if n < 2 1185 return n 1186 else 1187 return Fibonacci(n - 1) + Fibonacci(n - 2) 1188 endif 1189enddef 1190 1191def Test_recursive_call() 1192 assert_equal(6765, Fibonacci(20)) 1193enddef 1194 1195def TreeWalk(dir: string): list<any> 1196 return readdir(dir)->map({_, val -> 1197 fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 1198 ? {val : TreeWalk(dir .. '/' .. val)} 1199 : val 1200 }) 1201enddef 1202 1203def Test_closure_in_map() 1204 mkdir('XclosureDir/tdir', 'p') 1205 writefile(['111'], 'XclosureDir/file1') 1206 writefile(['222'], 'XclosureDir/file2') 1207 writefile(['333'], 'XclosureDir/tdir/file3') 1208 1209 assert_equal(['file1', 'file2', {'tdir': ['file3']}], TreeWalk('XclosureDir')) 1210 1211 delete('XclosureDir', 'rf') 1212enddef 1213 1214def Test_partial_call() 1215 let Xsetlist = function('setloclist', [0]) 1216 Xsetlist([], ' ', {'title': 'test'}) 1217 assert_equal({'title': 'test'}, getloclist(0, {'title': 1})) 1218 1219 Xsetlist = function('setloclist', [0, [], ' ']) 1220 Xsetlist({'title': 'test'}) 1221 assert_equal({'title': 'test'}, getloclist(0, {'title': 1})) 1222 1223 Xsetlist = function('setqflist') 1224 Xsetlist([], ' ', {'title': 'test'}) 1225 assert_equal({'title': 'test'}, getqflist({'title': 1})) 1226 1227 Xsetlist = function('setqflist', [[], ' ']) 1228 Xsetlist({'title': 'test'}) 1229 assert_equal({'title': 'test'}, getqflist({'title': 1})) 1230enddef 1231 1232 1233" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 1234