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