1" Test various aspects of the Vim9 script language. 2 3source check.vim 4source term_util.vim 5source view_util.vim 6source vim9.vim 7source screendump.vim 8 9func Test_def_basic() 10 def SomeFunc(): string 11 return 'yes' 12 enddef 13 call SomeFunc()->assert_equal('yes') 14endfunc 15 16def ReturnString(): string 17 return 'string' 18enddef 19 20def ReturnNumber(): number 21 return 123 22enddef 23 24let g:notNumber = 'string' 25 26def ReturnGlobal(): number 27 return g:notNumber 28enddef 29 30def Test_return_something() 31 ReturnString()->assert_equal('string') 32 ReturnNumber()->assert_equal(123) 33 assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal') 34enddef 35 36def Test_missing_return() 37 CheckDefFailure(['def Missing(): number', 38 ' if g:cond', 39 ' echo "no return"', 40 ' else', 41 ' return 0', 42 ' endif' 43 'enddef'], 'E1027:') 44 CheckDefFailure(['def Missing(): number', 45 ' if g:cond', 46 ' return 1', 47 ' else', 48 ' echo "no return"', 49 ' endif' 50 'enddef'], 'E1027:') 51 CheckDefFailure(['def Missing(): number', 52 ' if g:cond', 53 ' return 1', 54 ' else', 55 ' return 2', 56 ' endif' 57 ' return 3' 58 'enddef'], 'E1095:') 59enddef 60 61let s:nothing = 0 62def ReturnNothing() 63 s:nothing = 1 64 if true 65 return 66 endif 67 s:nothing = 2 68enddef 69 70def Test_return_nothing() 71 ReturnNothing() 72 s:nothing->assert_equal(1) 73enddef 74 75func Increment() 76 let g:counter += 1 77endfunc 78 79def Test_call_ufunc_count() 80 g:counter = 1 81 Increment() 82 Increment() 83 Increment() 84 # works with and without :call 85 g:counter->assert_equal(4) 86 eval g:counter->assert_equal(4) 87 unlet g:counter 88enddef 89 90def MyVarargs(arg: string, ...rest: list<string>): string 91 let res = arg 92 for s in rest 93 res ..= ',' .. s 94 endfor 95 return res 96enddef 97 98def Test_call_varargs() 99 MyVarargs('one')->assert_equal('one') 100 MyVarargs('one', 'two')->assert_equal('one,two') 101 MyVarargs('one', 'two', 'three')->assert_equal('one,two,three') 102enddef 103 104def MyDefaultArgs(name = 'string'): string 105 return name 106enddef 107 108def MyDefaultSecond(name: string, second: bool = true): string 109 return second ? name : 'none' 110enddef 111 112def Test_call_default_args() 113 MyDefaultArgs()->assert_equal('string') 114 MyDefaultArgs('one')->assert_equal('one') 115 assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args') 116 117 MyDefaultSecond('test')->assert_equal('test') 118 MyDefaultSecond('test', true)->assert_equal('test') 119 MyDefaultSecond('test', false)->assert_equal('none') 120 121 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:') 122 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string') 123enddef 124 125def Test_nested_function() 126 def Nested(arg: string): string 127 return 'nested ' .. arg 128 enddef 129 Nested('function')->assert_equal('nested function') 130 131 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:') 132 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:') 133 134 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:') 135 CheckDefFailure(['def s:Nested()', 'enddef'], 'E1075:') 136 CheckDefFailure(['def b:Nested()', 'enddef'], 'E1075:') 137 138 CheckDefFailure([ 139 'def Outer()', 140 ' def Inner()', 141 ' # comment', 142 ' enddef', 143 ' def Inner()', 144 ' enddef', 145 'enddef'], 'E1073:') 146 CheckDefFailure([ 147 'def Outer()', 148 ' def Inner()', 149 ' # comment', 150 ' enddef', 151 ' def! Inner()', 152 ' enddef', 153 'enddef'], 'E1117:') 154enddef 155 156func Test_call_default_args_from_func() 157 call MyDefaultArgs()->assert_equal('string') 158 call MyDefaultArgs('one')->assert_equal('one') 159 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func') 160endfunc 161 162def Test_nested_global_function() 163 let lines =<< trim END 164 vim9script 165 def Outer() 166 def g:Inner(): string 167 return 'inner' 168 enddef 169 enddef 170 defcompile 171 Outer() 172 g:Inner()->assert_equal('inner') 173 delfunc g:Inner 174 Outer() 175 g:Inner()->assert_equal('inner') 176 delfunc g:Inner 177 Outer() 178 g:Inner()->assert_equal('inner') 179 delfunc g:Inner 180 END 181 CheckScriptSuccess(lines) 182 183 lines =<< trim END 184 vim9script 185 def Outer() 186 def g:Inner(): string 187 return 'inner' 188 enddef 189 enddef 190 defcompile 191 Outer() 192 Outer() 193 END 194 CheckScriptFailure(lines, "E122:") 195 196 lines =<< trim END 197 vim9script 198 def Func() 199 echo 'script' 200 enddef 201 def Outer() 202 def Func() 203 echo 'inner' 204 enddef 205 enddef 206 defcompile 207 END 208 CheckScriptFailure(lines, "E1073:") 209enddef 210 211def Test_global_local_function() 212 let lines =<< trim END 213 vim9script 214 def g:Func(): string 215 return 'global' 216 enddef 217 def Func(): string 218 return 'local' 219 enddef 220 g:Func()->assert_equal('global') 221 Func()->assert_equal('local') 222 END 223 CheckScriptSuccess(lines) 224 225 lines =<< trim END 226 vim9script 227 def g:Funcy() 228 echo 'funcy' 229 enddef 230 s:Funcy() 231 END 232 CheckScriptFailure(lines, 'E117:') 233enddef 234 235def Test_local_function_shadows_global() 236 let lines =<< trim END 237 vim9script 238 def g:Gfunc(): string 239 return 'global' 240 enddef 241 def AnotherFunc(): number 242 let Gfunc = function('len') 243 return Gfunc('testing') 244 enddef 245 g:Gfunc()->assert_equal('global') 246 AnotherFunc()->assert_equal(7) 247 delfunc g:Gfunc 248 END 249 CheckScriptSuccess(lines) 250 251 lines =<< trim END 252 vim9script 253 def g:Func(): string 254 return 'global' 255 enddef 256 def AnotherFunc() 257 g:Func = function('len') 258 enddef 259 AnotherFunc() 260 END 261 CheckScriptFailure(lines, 'E705:') 262 delfunc g:Func 263enddef 264 265func TakesOneArg(arg) 266 echo a:arg 267endfunc 268 269def Test_call_wrong_args() 270 CheckDefFailure(['TakesOneArg()'], 'E119:') 271 CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:') 272 CheckDefFailure(['bufnr(xxx)'], 'E1001:') 273 CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:') 274 275 let lines =<< trim END 276 vim9script 277 def Func(s: string) 278 echo s 279 enddef 280 Func([]) 281 END 282 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 5) 283 284 lines =<< trim END 285 vim9script 286 def FuncOne(nr: number) 287 echo nr 288 enddef 289 def FuncTwo() 290 FuncOne() 291 enddef 292 defcompile 293 END 294 writefile(lines, 'Xscript') 295 let didCatch = false 296 try 297 source Xscript 298 catch 299 assert_match('E119: Not enough arguments for function: <SNR>\d\+_FuncOne', v:exception) 300 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 301 didCatch = true 302 endtry 303 assert_true(didCatch) 304 305 lines =<< trim END 306 vim9script 307 def FuncOne(nr: number) 308 echo nr 309 enddef 310 def FuncTwo() 311 FuncOne(1, 2) 312 enddef 313 defcompile 314 END 315 writefile(lines, 'Xscript') 316 didCatch = false 317 try 318 source Xscript 319 catch 320 assert_match('E118: Too many arguments for function: <SNR>\d\+_FuncOne', v:exception) 321 assert_match('Xscript\[8\]..function <SNR>\d\+_FuncTwo, line 1', v:throwpoint) 322 didCatch = true 323 endtry 324 assert_true(didCatch) 325 326 delete('Xscript') 327enddef 328 329" Default arg and varargs 330def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string 331 let res = one .. ',' .. two 332 for s in rest 333 res ..= ',' .. s 334 endfor 335 return res 336enddef 337 338def Test_call_def_varargs() 339 assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs') 340 MyDefVarargs('one')->assert_equal('one,foo') 341 MyDefVarargs('one', 'two')->assert_equal('one,two') 342 MyDefVarargs('one', 'two', 'three')->assert_equal('one,two,three') 343 CheckDefFailure(['MyDefVarargs("one", 22)'], 344 'E1013: Argument 2: type mismatch, expected string but got number') 345 CheckDefFailure(['MyDefVarargs("one", "two", 123)'], 346 'E1013: Argument 3: type mismatch, expected string but got number') 347 348 let lines =<< trim END 349 vim9script 350 def Func(...l: list<string>) 351 echo l 352 enddef 353 Func('a', 'b', 'c') 354 END 355 CheckScriptSuccess(lines) 356 357 lines =<< trim END 358 vim9script 359 def Func(...l: list<string>) 360 echo l 361 enddef 362 Func() 363 END 364 CheckScriptSuccess(lines) 365 366 lines =<< trim END 367 vim9script 368 def Func(...l: any) 369 echo l 370 enddef 371 Func(0) 372 END 373 CheckScriptSuccess(lines) 374 375 lines =<< trim END 376 vim9script 377 def Func(...l: list<string>) 378 echo l 379 enddef 380 Func(1, 2, 3) 381 END 382 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 383 384 lines =<< trim END 385 vim9script 386 def Func(...l: list<string>) 387 echo l 388 enddef 389 Func('a', 9) 390 END 391 CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch') 392 393 lines =<< trim END 394 vim9script 395 def Func(...l: list<string>) 396 echo l 397 enddef 398 Func(1, 'a') 399 END 400 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') 401enddef 402 403def Test_call_call() 404 let l = [3, 2, 1] 405 call('reverse', [l]) 406 l->assert_equal([1, 2, 3]) 407enddef 408 409let s:value = '' 410 411def FuncOneDefArg(opt = 'text') 412 s:value = opt 413enddef 414 415def FuncTwoDefArg(nr = 123, opt = 'text'): string 416 return nr .. opt 417enddef 418 419def FuncVarargs(...arg: list<string>): string 420 return join(arg, ',') 421enddef 422 423def Test_func_type_varargs() 424 let RefDefArg: func(?string) 425 RefDefArg = FuncOneDefArg 426 RefDefArg() 427 s:value->assert_equal('text') 428 RefDefArg('some') 429 s:value->assert_equal('some') 430 431 let RefDef2Arg: func(?number, ?string): string 432 RefDef2Arg = FuncTwoDefArg 433 RefDef2Arg()->assert_equal('123text') 434 RefDef2Arg(99)->assert_equal('99text') 435 RefDef2Arg(77, 'some')->assert_equal('77some') 436 437 CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:') 438 CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:') 439 440 let RefVarargs: func(...list<string>): string 441 RefVarargs = FuncVarargs 442 RefVarargs()->assert_equal('') 443 RefVarargs('one')->assert_equal('one') 444 RefVarargs('one', 'two')->assert_equal('one,two') 445 446 CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:') 447 CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:') 448enddef 449 450" Only varargs 451def MyVarargsOnly(...args: list<string>): string 452 return join(args, ',') 453enddef 454 455def Test_call_varargs_only() 456 MyVarargsOnly()->assert_equal('') 457 MyVarargsOnly('one')->assert_equal('one') 458 MyVarargsOnly('one', 'two')->assert_equal('one,two') 459 CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: Argument 1: type mismatch, expected string but got number') 460 CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number') 461enddef 462 463def Test_using_var_as_arg() 464 writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef') 465 assert_fails('so Xdef', 'E1006:', '', 1, 'Func') 466 delete('Xdef') 467enddef 468 469def DictArg(arg: dict<string>) 470 arg['key'] = 'value' 471enddef 472 473def ListArg(arg: list<string>) 474 arg[0] = 'value' 475enddef 476 477def Test_assign_to_argument() 478 # works for dict and list 479 let d: dict<string> = {} 480 DictArg(d) 481 d['key']->assert_equal('value') 482 let l: list<string> = [] 483 ListArg(l) 484 l[0]->assert_equal('value') 485 486 CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:') 487enddef 488 489" These argument names are reserved in legacy functions. 490def WithReservedNames(firstline: string, lastline: string): string 491 return firstline .. lastline 492enddef 493 494def Test_argument_names() 495 assert_equal('OK', WithReservedNames('O', 'K')) 496enddef 497 498def Test_call_func_defined_later() 499 g:DefinedLater('one')->assert_equal('one') 500 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later') 501enddef 502 503func DefinedLater(arg) 504 return a:arg 505endfunc 506 507def Test_call_funcref() 508 g:SomeFunc('abc')->assert_equal(3) 509 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call 510 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref') 511 512 let lines =<< trim END 513 vim9script 514 def RetNumber(): number 515 return 123 516 enddef 517 let Funcref: func: number = function('RetNumber') 518 Funcref()->assert_equal(123) 519 END 520 CheckScriptSuccess(lines) 521 522 lines =<< trim END 523 vim9script 524 def RetNumber(): number 525 return 123 526 enddef 527 def Bar(F: func: number): number 528 return F() 529 enddef 530 let Funcref = function('RetNumber') 531 Bar(Funcref)->assert_equal(123) 532 END 533 CheckScriptSuccess(lines) 534 535 lines =<< trim END 536 vim9script 537 def UseNumber(nr: number) 538 echo nr 539 enddef 540 let Funcref: func(number) = function('UseNumber') 541 Funcref(123) 542 END 543 CheckScriptSuccess(lines) 544 545 lines =<< trim END 546 vim9script 547 def UseNumber(nr: number) 548 echo nr 549 enddef 550 let Funcref: func(string) = function('UseNumber') 551 END 552 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)') 553 554 lines =<< trim END 555 vim9script 556 def EchoNr(nr = 34) 557 g:echo = nr 558 enddef 559 let Funcref: func(?number) = function('EchoNr') 560 Funcref() 561 g:echo->assert_equal(34) 562 Funcref(123) 563 g:echo->assert_equal(123) 564 END 565 CheckScriptSuccess(lines) 566 567 lines =<< trim END 568 vim9script 569 def EchoList(...l: list<number>) 570 g:echo = l 571 enddef 572 let Funcref: func(...list<number>) = function('EchoList') 573 Funcref() 574 g:echo->assert_equal([]) 575 Funcref(1, 2, 3) 576 g:echo->assert_equal([1, 2, 3]) 577 END 578 CheckScriptSuccess(lines) 579 580 lines =<< trim END 581 vim9script 582 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number 583 g:optarg = opt 584 g:listarg = l 585 return nr 586 enddef 587 let Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar') 588 Funcref(10)->assert_equal(10) 589 g:optarg->assert_equal(12) 590 g:listarg->assert_equal([]) 591 592 Funcref(11, 22)->assert_equal(11) 593 g:optarg->assert_equal(22) 594 g:listarg->assert_equal([]) 595 596 Funcref(17, 18, 1, 2, 3)->assert_equal(17) 597 g:optarg->assert_equal(18) 598 g:listarg->assert_equal([1, 2, 3]) 599 END 600 CheckScriptSuccess(lines) 601enddef 602 603let SomeFunc = function('len') 604let NotAFunc = 'text' 605 606def CombineFuncrefTypes() 607 # same arguments, different return type 608 let Ref1: func(bool): string 609 let Ref2: func(bool): number 610 let Ref3: func(bool): any 611 Ref3 = g:cond ? Ref1 : Ref2 612 613 # different number of arguments 614 let Refa1: func(bool): number 615 let Refa2: func(bool, number): number 616 let Refa3: func: number 617 Refa3 = g:cond ? Refa1 : Refa2 618 619 # different argument types 620 let Refb1: func(bool, string): number 621 let Refb2: func(string, number): number 622 let Refb3: func(any, any): number 623 Refb3 = g:cond ? Refb1 : Refb2 624enddef 625 626def FuncWithForwardCall() 627 return g:DefinedEvenLater("yes") 628enddef 629 630def DefinedEvenLater(arg: string): string 631 return arg 632enddef 633 634def Test_error_in_nested_function() 635 # Error in called function requires unwinding the call stack. 636 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall') 637enddef 638 639def Test_return_type_wrong() 640 CheckScriptFailure([ 641 'def Func(): number', 642 'return "a"', 643 'enddef', 644 'defcompile'], 'expected number but got string') 645 CheckScriptFailure([ 646 'def Func(): string', 647 'return 1', 648 'enddef', 649 'defcompile'], 'expected string but got number') 650 CheckScriptFailure([ 651 'def Func(): void', 652 'return "a"', 653 'enddef', 654 'defcompile'], 655 'E1096: Returning a value in a function without a return type') 656 CheckScriptFailure([ 657 'def Func()', 658 'return "a"', 659 'enddef', 660 'defcompile'], 661 'E1096: Returning a value in a function without a return type') 662 663 CheckScriptFailure([ 664 'def Func(): number', 665 'return', 666 'enddef', 667 'defcompile'], 'E1003:') 668 669 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 670 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 671 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 672 673 CheckScriptFailure([ 674 'vim9script', 675 'def FuncB()', 676 ' return 123', 677 'enddef', 678 'def FuncA()', 679 ' FuncB()', 680 'enddef', 681 'defcompile'], 'E1096:') 682enddef 683 684def Test_arg_type_wrong() 685 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 686 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 687 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 688 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 689enddef 690 691def Test_vim9script_call() 692 let lines =<< trim END 693 vim9script 694 let var = '' 695 def MyFunc(arg: string) 696 var = arg 697 enddef 698 MyFunc('foobar') 699 var->assert_equal('foobar') 700 701 let str = 'barfoo' 702 str->MyFunc() 703 var->assert_equal('barfoo') 704 705 g:value = 'value' 706 g:value->MyFunc() 707 var->assert_equal('value') 708 709 let listvar = [] 710 def ListFunc(arg: list<number>) 711 listvar = arg 712 enddef 713 [1, 2, 3]->ListFunc() 714 listvar->assert_equal([1, 2, 3]) 715 716 let dictvar = {} 717 def DictFunc(arg: dict<number>) 718 dictvar = arg 719 enddef 720 {'a': 1, 'b': 2}->DictFunc() 721 dictvar->assert_equal(#{a: 1, b: 2}) 722 def CompiledDict() 723 {'a': 3, 'b': 4}->DictFunc() 724 enddef 725 CompiledDict() 726 dictvar->assert_equal(#{a: 3, b: 4}) 727 728 #{a: 3, b: 4}->DictFunc() 729 dictvar->assert_equal(#{a: 3, b: 4}) 730 731 ('text')->MyFunc() 732 var->assert_equal('text') 733 ("some")->MyFunc() 734 var->assert_equal('some') 735 736 # line starting with single quote is not a mark 737 # line starting with double quote can be a method call 738 'asdfasdf'->MyFunc() 739 var->assert_equal('asdfasdf') 740 "xyz"->MyFunc() 741 var->assert_equal('xyz') 742 743 def UseString() 744 'xyork'->MyFunc() 745 enddef 746 UseString() 747 var->assert_equal('xyork') 748 749 def UseString2() 750 "knife"->MyFunc() 751 enddef 752 UseString2() 753 var->assert_equal('knife') 754 755 # prepending a colon makes it a mark 756 new 757 setline(1, ['aaa', 'bbb', 'ccc']) 758 normal! 3Gmt1G 759 :'t 760 getcurpos()[1]->assert_equal(3) 761 bwipe! 762 763 MyFunc( 764 'continued' 765 ) 766 assert_equal('continued', 767 var 768 ) 769 770 call MyFunc( 771 'more' 772 .. 773 'lines' 774 ) 775 assert_equal( 776 'morelines', 777 var) 778 END 779 writefile(lines, 'Xcall.vim') 780 source Xcall.vim 781 delete('Xcall.vim') 782enddef 783 784def Test_vim9script_call_fail_decl() 785 let lines =<< trim END 786 vim9script 787 let var = '' 788 def MyFunc(arg: string) 789 let var = 123 790 enddef 791 defcompile 792 END 793 CheckScriptFailure(lines, 'E1054:') 794enddef 795 796def Test_vim9script_call_fail_type() 797 let lines =<< trim END 798 vim9script 799 def MyFunc(arg: string) 800 echo arg 801 enddef 802 MyFunc(1234) 803 END 804 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number') 805enddef 806 807def Test_vim9script_call_fail_const() 808 let lines =<< trim END 809 vim9script 810 const var = '' 811 def MyFunc(arg: string) 812 var = 'asdf' 813 enddef 814 defcompile 815 END 816 writefile(lines, 'Xcall_const.vim') 817 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc') 818 delete('Xcall_const.vim') 819enddef 820 821" Test that inside :function a Python function can be defined, :def is not 822" recognized. 823func Test_function_python() 824 CheckFeature python3 825 let py = 'python3' 826 execute py "<< EOF" 827def do_something(): 828 return 1 829EOF 830endfunc 831 832def Test_delfunc() 833 let lines =<< trim END 834 vim9script 835 def g:GoneSoon() 836 echo 'hello' 837 enddef 838 839 def CallGoneSoon() 840 GoneSoon() 841 enddef 842 defcompile 843 844 delfunc g:GoneSoon 845 CallGoneSoon() 846 END 847 writefile(lines, 'XToDelFunc') 848 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 849 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 850 851 delete('XToDelFunc') 852enddef 853 854def Test_redef_failure() 855 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 856 so Xdef 857 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 858 so Xdef 859 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 860 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0') 861 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 862 so Xdef 863 delete('Xdef') 864 865 g:Func0()->assert_equal(0) 866 g:Func1()->assert_equal('Func1') 867 g:Func2()->assert_equal('Func2') 868 869 delfunc! Func0 870 delfunc! Func1 871 delfunc! Func2 872enddef 873 874def Test_vim9script_func() 875 let lines =<< trim END 876 vim9script 877 func Func(arg) 878 echo a:arg 879 endfunc 880 Func('text') 881 END 882 writefile(lines, 'XVim9Func') 883 so XVim9Func 884 885 delete('XVim9Func') 886enddef 887 888" Test for internal functions returning different types 889func Test_InternalFuncRetType() 890 let lines =<< trim END 891 def RetFloat(): float 892 return ceil(1.456) 893 enddef 894 895 def RetListAny(): list<any> 896 return items({'k': 'v'}) 897 enddef 898 899 def RetListString(): list<string> 900 return split('a:b:c', ':') 901 enddef 902 903 def RetListDictAny(): list<dict<any>> 904 return getbufinfo() 905 enddef 906 907 def RetDictNumber(): dict<number> 908 return wordcount() 909 enddef 910 911 def RetDictString(): dict<string> 912 return environ() 913 enddef 914 END 915 call writefile(lines, 'Xscript') 916 source Xscript 917 918 call RetFloat()->assert_equal(2.0) 919 call RetListAny()->assert_equal([['k', 'v']]) 920 call RetListString()->assert_equal(['a', 'b', 'c']) 921 call RetListDictAny()->assert_notequal([]) 922 call RetDictNumber()->assert_notequal({}) 923 call RetDictString()->assert_notequal({}) 924 call delete('Xscript') 925endfunc 926 927" Test for passing too many or too few arguments to internal functions 928func Test_internalfunc_arg_error() 929 let l =<< trim END 930 def! FArgErr(): float 931 return ceil(1.1, 2) 932 enddef 933 defcompile 934 END 935 call writefile(l, 'Xinvalidarg') 936 call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr') 937 let l =<< trim END 938 def! FArgErr(): float 939 return ceil() 940 enddef 941 defcompile 942 END 943 call writefile(l, 'Xinvalidarg') 944 call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr') 945 call delete('Xinvalidarg') 946endfunc 947 948let s:funcResult = 0 949 950def FuncNoArgNoRet() 951 s:funcResult = 11 952enddef 953 954def FuncNoArgRetNumber(): number 955 s:funcResult = 22 956 return 1234 957enddef 958 959def FuncNoArgRetString(): string 960 s:funcResult = 45 961 return 'text' 962enddef 963 964def FuncOneArgNoRet(arg: number) 965 s:funcResult = arg 966enddef 967 968def FuncOneArgRetNumber(arg: number): number 969 s:funcResult = arg 970 return arg 971enddef 972 973def FuncTwoArgNoRet(one: bool, two: number) 974 s:funcResult = two 975enddef 976 977def FuncOneArgRetString(arg: string): string 978 return arg 979enddef 980 981def FuncOneArgRetAny(arg: any): any 982 return arg 983enddef 984 985def Test_func_type() 986 let Ref1: func() 987 s:funcResult = 0 988 Ref1 = FuncNoArgNoRet 989 Ref1() 990 s:funcResult->assert_equal(11) 991 992 let Ref2: func 993 s:funcResult = 0 994 Ref2 = FuncNoArgNoRet 995 Ref2() 996 s:funcResult->assert_equal(11) 997 998 s:funcResult = 0 999 Ref2 = FuncOneArgNoRet 1000 Ref2(12) 1001 s:funcResult->assert_equal(12) 1002 1003 s:funcResult = 0 1004 Ref2 = FuncNoArgRetNumber 1005 Ref2()->assert_equal(1234) 1006 s:funcResult->assert_equal(22) 1007 1008 s:funcResult = 0 1009 Ref2 = FuncOneArgRetNumber 1010 Ref2(13)->assert_equal(13) 1011 s:funcResult->assert_equal(13) 1012enddef 1013 1014def Test_repeat_return_type() 1015 let res = 0 1016 for n in repeat([1], 3) 1017 res += n 1018 endfor 1019 res->assert_equal(3) 1020 1021 res = 0 1022 for n in add([1, 2], 3) 1023 res += n 1024 endfor 1025 res->assert_equal(6) 1026enddef 1027 1028def Test_argv_return_type() 1029 next fileone filetwo 1030 let res = '' 1031 for name in argv() 1032 res ..= name 1033 endfor 1034 res->assert_equal('fileonefiletwo') 1035enddef 1036 1037def Test_func_type_part() 1038 let RefVoid: func: void 1039 RefVoid = FuncNoArgNoRet 1040 RefVoid = FuncOneArgNoRet 1041 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number') 1042 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string') 1043 1044 let RefAny: func(): any 1045 RefAny = FuncNoArgRetNumber 1046 RefAny = FuncNoArgRetString 1047 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()') 1048 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)') 1049 1050 let RefNr: func: number 1051 RefNr = FuncNoArgRetNumber 1052 RefNr = FuncOneArgRetNumber 1053 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()') 1054 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string') 1055 1056 let RefStr: func: string 1057 RefStr = FuncNoArgRetString 1058 RefStr = FuncOneArgRetString 1059 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()') 1060 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number') 1061enddef 1062 1063def Test_func_type_fails() 1064 CheckDefFailure(['let ref1: func()'], 'E704:') 1065 1066 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number') 1067 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)') 1068 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number') 1069 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)') 1070 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)') 1071 CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)') 1072 1073 CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') 1074 CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') 1075 CheckDefFailure(['let RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E1005:') 1076 CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:') 1077enddef 1078 1079def Test_func_return_type() 1080 let nr: number 1081 nr = FuncNoArgRetNumber() 1082 nr->assert_equal(1234) 1083 1084 nr = FuncOneArgRetAny(122) 1085 nr->assert_equal(122) 1086 1087 let str: string 1088 str = FuncOneArgRetAny('yes') 1089 str->assert_equal('yes') 1090 1091 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number') 1092enddef 1093 1094def MultiLine( 1095 arg1: string, 1096 arg2 = 1234, 1097 ...rest: list<string> 1098 ): string 1099 return arg1 .. arg2 .. join(rest, '-') 1100enddef 1101 1102def MultiLineComment( 1103 arg1: string, # comment 1104 arg2 = 1234, # comment 1105 ...rest: list<string> # comment 1106 ): string # comment 1107 return arg1 .. arg2 .. join(rest, '-') 1108enddef 1109 1110def Test_multiline() 1111 MultiLine('text')->assert_equal('text1234') 1112 MultiLine('text', 777)->assert_equal('text777') 1113 MultiLine('text', 777, 'one')->assert_equal('text777one') 1114 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1115enddef 1116 1117func Test_multiline_not_vim9() 1118 call MultiLine('text')->assert_equal('text1234') 1119 call MultiLine('text', 777)->assert_equal('text777') 1120 call MultiLine('text', 777, 'one')->assert_equal('text777one') 1121 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1122endfunc 1123 1124 1125" When using CheckScriptFailure() for the below test, E1010 is generated instead 1126" of E1056. 1127func Test_E1056_1059() 1128 let caught_1056 = 0 1129 try 1130 def F(): 1131 return 1 1132 enddef 1133 catch /E1056:/ 1134 let caught_1056 = 1 1135 endtry 1136 eval caught_1056->assert_equal(1) 1137 1138 let caught_1059 = 0 1139 try 1140 def F5(items : list) 1141 echo 'a' 1142 enddef 1143 catch /E1059:/ 1144 let caught_1059 = 1 1145 endtry 1146 eval caught_1059->assert_equal(1) 1147endfunc 1148 1149func DelMe() 1150 echo 'DelMe' 1151endfunc 1152 1153def Test_error_reporting() 1154 # comment lines at the start of the function 1155 let lines =<< trim END 1156 " comment 1157 def Func() 1158 # comment 1159 # comment 1160 invalid 1161 enddef 1162 defcompile 1163 END 1164 writefile(lines, 'Xdef') 1165 try 1166 source Xdef 1167 assert_report('should have failed') 1168 catch /E476:/ 1169 v:exception->assert_match('Invalid command: invalid') 1170 v:throwpoint->assert_match(', line 3$') 1171 endtry 1172 1173 # comment lines after the start of the function 1174 lines =<< trim END 1175 " comment 1176 def Func() 1177 let x = 1234 1178 # comment 1179 # comment 1180 invalid 1181 enddef 1182 defcompile 1183 END 1184 writefile(lines, 'Xdef') 1185 try 1186 source Xdef 1187 assert_report('should have failed') 1188 catch /E476:/ 1189 v:exception->assert_match('Invalid command: invalid') 1190 v:throwpoint->assert_match(', line 4$') 1191 endtry 1192 1193 lines =<< trim END 1194 vim9script 1195 def Func() 1196 let db = #{foo: 1, bar: 2} 1197 # comment 1198 let x = db.asdf 1199 enddef 1200 defcompile 1201 Func() 1202 END 1203 writefile(lines, 'Xdef') 1204 try 1205 source Xdef 1206 assert_report('should have failed') 1207 catch /E716:/ 1208 v:throwpoint->assert_match('_Func, line 3$') 1209 endtry 1210 1211 delete('Xdef') 1212enddef 1213 1214def Test_deleted_function() 1215 CheckDefExecFailure([ 1216 'let RefMe: func = function("g:DelMe")', 1217 'delfunc g:DelMe', 1218 'echo RefMe()'], 'E117:') 1219enddef 1220 1221def Test_unknown_function() 1222 CheckDefExecFailure([ 1223 'let Ref: func = function("NotExist")', 1224 'delfunc g:NotExist'], 'E700:') 1225enddef 1226 1227def RefFunc(Ref: func(string): string): string 1228 return Ref('more') 1229enddef 1230 1231def Test_closure_simple() 1232 let local = 'some ' 1233 RefFunc({s -> local .. s})->assert_equal('some more') 1234enddef 1235 1236def MakeRef() 1237 let local = 'some ' 1238 g:Ref = {s -> local .. s} 1239enddef 1240 1241def Test_closure_ref_after_return() 1242 MakeRef() 1243 g:Ref('thing')->assert_equal('some thing') 1244 unlet g:Ref 1245enddef 1246 1247def MakeTwoRefs() 1248 let local = ['some'] 1249 g:Extend = {s -> local->add(s)} 1250 g:Read = {-> local} 1251enddef 1252 1253def Test_closure_two_refs() 1254 MakeTwoRefs() 1255 join(g:Read(), ' ')->assert_equal('some') 1256 g:Extend('more') 1257 join(g:Read(), ' ')->assert_equal('some more') 1258 g:Extend('even') 1259 join(g:Read(), ' ')->assert_equal('some more even') 1260 1261 unlet g:Extend 1262 unlet g:Read 1263enddef 1264 1265def ReadRef(Ref: func(): list<string>): string 1266 return join(Ref(), ' ') 1267enddef 1268 1269def ExtendRef(Ref: func(string): list<string>, add: string) 1270 Ref(add) 1271enddef 1272 1273def Test_closure_two_indirect_refs() 1274 MakeTwoRefs() 1275 ReadRef(g:Read)->assert_equal('some') 1276 ExtendRef(g:Extend, 'more') 1277 ReadRef(g:Read)->assert_equal('some more') 1278 ExtendRef(g:Extend, 'even') 1279 ReadRef(g:Read)->assert_equal('some more even') 1280 1281 unlet g:Extend 1282 unlet g:Read 1283enddef 1284 1285def MakeArgRefs(theArg: string) 1286 let local = 'loc_val' 1287 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 1288enddef 1289 1290def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 1291 let local = 'the_loc' 1292 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)} 1293enddef 1294 1295def Test_closure_using_argument() 1296 MakeArgRefs('arg_val') 1297 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val') 1298 1299 MakeArgRefsVarargs('arg_val', 'one', 'two') 1300 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two') 1301 1302 unlet g:UseArg 1303 unlet g:UseVararg 1304enddef 1305 1306def MakeGetAndAppendRefs() 1307 let local = 'a' 1308 1309 def Append(arg: string) 1310 local ..= arg 1311 enddef 1312 g:Append = Append 1313 1314 def Get(): string 1315 return local 1316 enddef 1317 g:Get = Get 1318enddef 1319 1320def Test_closure_append_get() 1321 MakeGetAndAppendRefs() 1322 g:Get()->assert_equal('a') 1323 g:Append('-b') 1324 g:Get()->assert_equal('a-b') 1325 g:Append('-c') 1326 g:Get()->assert_equal('a-b-c') 1327 1328 unlet g:Append 1329 unlet g:Get 1330enddef 1331 1332def Test_nested_closure() 1333 let local = 'text' 1334 def Closure(arg: string): string 1335 return local .. arg 1336 enddef 1337 Closure('!!!')->assert_equal('text!!!') 1338enddef 1339 1340func GetResult(Ref) 1341 return a:Ref('some') 1342endfunc 1343 1344def Test_call_closure_not_compiled() 1345 let text = 'text' 1346 g:Ref = {s -> s .. text} 1347 GetResult(g:Ref)->assert_equal('sometext') 1348enddef 1349 1350def Test_double_closure_fails() 1351 let lines =<< trim END 1352 vim9script 1353 def Func() 1354 let var = 0 1355 for i in range(2) 1356 timer_start(0, {-> var}) 1357 endfor 1358 enddef 1359 Func() 1360 END 1361 CheckScriptFailure(lines, 'Multiple closures not supported yet') 1362enddef 1363 1364def Test_sort_return_type() 1365 let res: list<number> 1366 res = [1, 2, 3]->sort() 1367enddef 1368 1369def Test_sort_argument() 1370 let res = ['b', 'a', 'c']->sort('i') 1371 res->assert_equal(['a', 'b', 'c']) 1372enddef 1373 1374def Test_getqflist_return_type() 1375 let l = getqflist() 1376 l->assert_equal([]) 1377 1378 let d = getqflist(#{items: 0}) 1379 d->assert_equal(#{items: []}) 1380enddef 1381 1382def Test_getloclist_return_type() 1383 let l = getloclist(1) 1384 l->assert_equal([]) 1385 1386 let d = getloclist(1, #{items: 0}) 1387 d->assert_equal(#{items: []}) 1388enddef 1389 1390def Test_copy_return_type() 1391 let l = copy([1, 2, 3]) 1392 let res = 0 1393 for n in l 1394 res += n 1395 endfor 1396 res->assert_equal(6) 1397 1398 let dl = deepcopy([1, 2, 3]) 1399 res = 0 1400 for n in dl 1401 res += n 1402 endfor 1403 res->assert_equal(6) 1404 1405 dl = deepcopy([1, 2, 3], true) 1406enddef 1407 1408def Test_extend_return_type() 1409 let l = extend([1, 2], [3]) 1410 let res = 0 1411 for n in l 1412 res += n 1413 endfor 1414 res->assert_equal(6) 1415enddef 1416 1417def Test_garbagecollect() 1418 garbagecollect(true) 1419enddef 1420 1421def Test_insert_return_type() 1422 let l = insert([2, 1], 3) 1423 let res = 0 1424 for n in l 1425 res += n 1426 endfor 1427 res->assert_equal(6) 1428enddef 1429 1430def Test_keys_return_type() 1431 const var: list<string> = #{a: 1, b: 2}->keys() 1432 var->assert_equal(['a', 'b']) 1433enddef 1434 1435def Test_reverse_return_type() 1436 let l = reverse([1, 2, 3]) 1437 let res = 0 1438 for n in l 1439 res += n 1440 endfor 1441 res->assert_equal(6) 1442enddef 1443 1444def Test_remove_return_type() 1445 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one') 1446 let res = 0 1447 for n in l 1448 res += n 1449 endfor 1450 res->assert_equal(3) 1451enddef 1452 1453def Test_filter_return_type() 1454 let l = filter([1, 2, 3], {-> 1}) 1455 let res = 0 1456 for n in l 1457 res += n 1458 endfor 1459 res->assert_equal(6) 1460enddef 1461 1462def Test_bufnr() 1463 let buf = bufnr() 1464 bufnr('%')->assert_equal(buf) 1465 1466 buf = bufnr('Xdummy', true) 1467 buf->assert_notequal(-1) 1468 exe 'bwipe! ' .. buf 1469enddef 1470 1471def Test_col() 1472 new 1473 setline(1, 'asdf') 1474 col([1, '$'])->assert_equal(5) 1475enddef 1476 1477def Test_char2nr() 1478 char2nr('あ', true)->assert_equal(12354) 1479enddef 1480 1481def Test_getreg_return_type() 1482 let s1: string = getreg('"') 1483 let s2: string = getreg('"', 1) 1484 let s3: list<string> = getreg('"', 1, 1) 1485enddef 1486 1487def Wrong_dict_key_type(items: list<number>): list<number> 1488 return filter(items, {_, val -> get({val: 1}, 'x')}) 1489enddef 1490 1491def Test_wrong_dict_key_type() 1492 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:') 1493enddef 1494 1495def Line_continuation_in_def(dir: string = ''): string 1496 let path: string = empty(dir) 1497 \ ? 'empty' 1498 \ : 'full' 1499 return path 1500enddef 1501 1502def Test_line_continuation_in_def() 1503 Line_continuation_in_def('.')->assert_equal('full') 1504enddef 1505 1506def Line_continuation_in_lambda(): list<string> 1507 let x = range(97, 100) 1508 ->map({_, v -> nr2char(v) 1509 ->toupper()}) 1510 ->reverse() 1511 return x 1512enddef 1513 1514def Test_line_continuation_in_lambda() 1515 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A']) 1516enddef 1517 1518func Test_silent_echo() 1519 CheckScreendump 1520 1521 let lines =<< trim END 1522 vim9script 1523 def EchoNothing() 1524 silent echo '' 1525 enddef 1526 defcompile 1527 END 1528 call writefile(lines, 'XTest_silent_echo') 1529 1530 " Check that the balloon shows up after a mouse move 1531 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 1532 call term_sendkeys(buf, ":abc") 1533 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 1534 1535 " clean up 1536 call StopVimInTerminal(buf) 1537 call delete('XTest_silent_echo') 1538endfunc 1539 1540""""""" builtin functions that behave differently in Vim9 1541 1542def Test_bufname() 1543 split SomeFile 1544 bufname('%')->assert_equal('SomeFile') 1545 edit OtherFile 1546 bufname('#')->assert_equal('SomeFile') 1547 close 1548enddef 1549 1550def Test_bufwinid() 1551 let origwin = win_getid() 1552 below split SomeFile 1553 let SomeFileID = win_getid() 1554 below split OtherFile 1555 below split SomeFile 1556 bufwinid('SomeFile')->assert_equal(SomeFileID) 1557 1558 win_gotoid(origwin) 1559 only 1560 bwipe SomeFile 1561 bwipe OtherFile 1562enddef 1563 1564def Test_count() 1565 count('ABC ABC ABC', 'b', true)->assert_equal(3) 1566 count('ABC ABC ABC', 'b', false)->assert_equal(0) 1567enddef 1568 1569def Test_expand() 1570 split SomeFile 1571 expand('%', true, true)->assert_equal(['SomeFile']) 1572 close 1573enddef 1574 1575def Test_getbufinfo() 1576 let bufinfo = getbufinfo(bufnr()) 1577 getbufinfo('%')->assert_equal(bufinfo) 1578 1579 edit Xtestfile1 1580 hide edit Xtestfile2 1581 hide enew 1582 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false}) 1583 ->len()->assert_equal(3) 1584 bwipe Xtestfile1 Xtestfile2 1585enddef 1586 1587def Test_getbufline() 1588 e SomeFile 1589 let buf = bufnr() 1590 e # 1591 let lines = ['aaa', 'bbb', 'ccc'] 1592 setbufline(buf, 1, lines) 1593 getbufline('#', 1, '$')->assert_equal(lines) 1594 1595 bwipe! 1596enddef 1597 1598def Test_getchangelist() 1599 new 1600 setline(1, 'some text') 1601 let changelist = bufnr()->getchangelist() 1602 getchangelist('%')->assert_equal(changelist) 1603 bwipe! 1604enddef 1605 1606def Test_getchar() 1607 while getchar(0) 1608 endwhile 1609 getchar(true)->assert_equal(0) 1610enddef 1611 1612def Test_getcompletion() 1613 set wildignore=*.vim,*~ 1614 let l = getcompletion('run', 'file', true) 1615 l->assert_equal([]) 1616 set wildignore& 1617enddef 1618 1619def Test_getreg() 1620 let lines = ['aaa', 'bbb', 'ccc'] 1621 setreg('a', lines) 1622 getreg('a', true, true)->assert_equal(lines) 1623enddef 1624 1625def Test_glob() 1626 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim']) 1627enddef 1628 1629def Test_globpath() 1630 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim']) 1631enddef 1632 1633def Test_has() 1634 has('eval', true)->assert_equal(1) 1635enddef 1636 1637def Test_hasmapto() 1638 hasmapto('foobar', 'i', true)->assert_equal(0) 1639 iabbrev foo foobar 1640 hasmapto('foobar', 'i', true)->assert_equal(1) 1641 iunabbrev foo 1642enddef 1643 1644def Test_index() 1645 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3) 1646enddef 1647 1648def Test_list2str_str2list_utf8() 1649 let s = "\u3042\u3044" 1650 let l = [0x3042, 0x3044] 1651 str2list(s, true)->assert_equal(l) 1652 list2str(l, true)->assert_equal(s) 1653enddef 1654 1655def SID(): number 1656 return expand('<SID>') 1657 ->matchstr('<SNR>\zs\d\+\ze_$') 1658 ->str2nr() 1659enddef 1660 1661def Test_maparg() 1662 let lnum = str2nr(expand('<sflnum>')) 1663 map foo bar 1664 maparg('foo', '', false, true)->assert_equal(#{ 1665 lnum: lnum + 1, 1666 script: 0, 1667 mode: ' ', 1668 silent: 0, 1669 noremap: 0, 1670 lhs: 'foo', 1671 lhsraw: 'foo', 1672 nowait: 0, 1673 expr: 0, 1674 sid: SID(), 1675 rhs: 'bar', 1676 buffer: 0}) 1677 unmap foo 1678enddef 1679 1680def Test_mapcheck() 1681 iabbrev foo foobar 1682 mapcheck('foo', 'i', true)->assert_equal('foobar') 1683 iunabbrev foo 1684enddef 1685 1686def Test_nr2char() 1687 nr2char(97, true)->assert_equal('a') 1688enddef 1689 1690def Test_readdir() 1691 eval expand('sautest')->readdir({e -> e[0] !=# '.'}) 1692 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'}) 1693enddef 1694 1695def Test_search() 1696 new 1697 setline(1, ['foo', 'bar']) 1698 let val = 0 1699 # skip expr returns boolean 1700 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2) 1701 :1 1702 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0) 1703 # skip expr returns number, only 0 and 1 are accepted 1704 :1 1705 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2) 1706 :1 1707 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0) 1708 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 1709 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 1710enddef 1711 1712def Test_searchcount() 1713 new 1714 setline(1, "foo bar") 1715 :/foo 1716 searchcount(#{recompute: true}) 1717 ->assert_equal(#{ 1718 exact_match: 1, 1719 current: 1, 1720 total: 1, 1721 maxcount: 99, 1722 incomplete: 0}) 1723 bwipe! 1724enddef 1725 1726def Test_searchdecl() 1727 searchdecl('blah', true, true)->assert_equal(1) 1728enddef 1729 1730def Test_setbufvar() 1731 setbufvar(bufnr('%'), '&syntax', 'vim') 1732 &syntax->assert_equal('vim') 1733 setbufvar(bufnr('%'), '&ts', 16) 1734 &ts->assert_equal(16) 1735 settabwinvar(1, 1, '&syntax', 'vam') 1736 &syntax->assert_equal('vam') 1737 settabwinvar(1, 1, '&ts', 15) 1738 &ts->assert_equal(15) 1739 setlocal ts=8 1740 1741 setbufvar('%', 'myvar', 123) 1742 getbufvar('%', 'myvar')->assert_equal(123) 1743enddef 1744 1745def Test_setloclist() 1746 let items = [#{filename: '/tmp/file', lnum: 1, valid: true}] 1747 let what = #{items: items} 1748 setqflist([], ' ', what) 1749 setloclist(0, [], ' ', what) 1750enddef 1751 1752def Test_setreg() 1753 setreg('a', ['aaa', 'bbb', 'ccc']) 1754 let reginfo = getreginfo('a') 1755 setreg('a', reginfo) 1756 getreginfo('a')->assert_equal(reginfo) 1757enddef 1758 1759def Test_spellsuggest() 1760 if !has('spell') 1761 MissingFeature 'spell' 1762 else 1763 spellsuggest('marrch', 1, true)->assert_equal(['March']) 1764 endif 1765enddef 1766 1767def Test_split() 1768 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', '']) 1769enddef 1770 1771def Test_str2nr() 1772 str2nr("1'000'000", 10, true)->assert_equal(1000000) 1773enddef 1774 1775def Test_strchars() 1776 strchars("A\u20dd", true)->assert_equal(1) 1777enddef 1778 1779def Test_submatch() 1780 let pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)' 1781 let Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()} 1782 let actual = substitute('A123456789', pat, Rep, '') 1783 let expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]" 1784 actual->assert_equal(expected) 1785enddef 1786 1787def Test_synID() 1788 new 1789 setline(1, "text") 1790 synID(1, 1, true)->assert_equal(0) 1791 bwipe! 1792enddef 1793 1794def Test_term_gettty() 1795 if !has('terminal') 1796 MissingFeature 'terminal' 1797 else 1798 let buf = Run_shell_in_terminal({}) 1799 term_gettty(buf, true)->assert_notequal('') 1800 StopShellInTerminal(buf) 1801 endif 1802enddef 1803 1804def Test_term_start() 1805 if !has('terminal') 1806 MissingFeature 'terminal' 1807 else 1808 botright new 1809 let winnr = winnr() 1810 term_start(&shell, #{curwin: true}) 1811 winnr()->assert_equal(winnr) 1812 bwipe! 1813 endif 1814enddef 1815 1816def Test_timer_paused() 1817 let id = timer_start(50, {-> 0}) 1818 timer_pause(id, true) 1819 let info = timer_info(id) 1820 info[0]['paused']->assert_equal(1) 1821 timer_stop(id) 1822enddef 1823 1824def Test_win_splitmove() 1825 split 1826 win_splitmove(1, 2, #{vertical: true, rightbelow: true}) 1827 close 1828enddef 1829 1830""""""" end of builtin functions 1831 1832def Fibonacci(n: number): number 1833 if n < 2 1834 return n 1835 else 1836 return Fibonacci(n - 1) + Fibonacci(n - 2) 1837 endif 1838enddef 1839 1840def Test_recursive_call() 1841 Fibonacci(20)->assert_equal(6765) 1842enddef 1843 1844def TreeWalk(dir: string): list<any> 1845 return readdir(dir)->map({_, val -> 1846 fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 1847 ? {val: TreeWalk(dir .. '/' .. val)} 1848 : val 1849 }) 1850enddef 1851 1852def Test_closure_in_map() 1853 mkdir('XclosureDir/tdir', 'p') 1854 writefile(['111'], 'XclosureDir/file1') 1855 writefile(['222'], 'XclosureDir/file2') 1856 writefile(['333'], 'XclosureDir/tdir/file3') 1857 1858 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}]) 1859 1860 delete('XclosureDir', 'rf') 1861enddef 1862 1863def Test_partial_call() 1864 let Xsetlist = function('setloclist', [0]) 1865 Xsetlist([], ' ', {'title': 'test'}) 1866 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1867 1868 Xsetlist = function('setloclist', [0, [], ' ']) 1869 Xsetlist({'title': 'test'}) 1870 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1871 1872 Xsetlist = function('setqflist') 1873 Xsetlist([], ' ', {'title': 'test'}) 1874 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1875 1876 Xsetlist = function('setqflist', [[], ' ']) 1877 Xsetlist({'title': 'test'}) 1878 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1879enddef 1880 1881def Test_cmd_modifier() 1882 tab echo '0' 1883 CheckDefFailure(['5tab echo 3'], 'E16:') 1884enddef 1885 1886def Test_restore_modifiers() 1887 # check that when compiling a :def function command modifiers are not messed 1888 # up. 1889 let lines =<< trim END 1890 vim9script 1891 set eventignore= 1892 autocmd QuickFixCmdPost * copen 1893 def AutocmdsDisabled() 1894 eval 0 1895 enddef 1896 func Func() 1897 noautocmd call s:AutocmdsDisabled() 1898 let g:ei_after = &eventignore 1899 endfunc 1900 Func() 1901 END 1902 CheckScriptSuccess(lines) 1903 g:ei_after->assert_equal('') 1904enddef 1905 1906def StackTop() 1907 eval 1 1908 eval 2 1909 # call not on fourth line 1910 StackBot() 1911enddef 1912 1913def StackBot() 1914 # throw an error 1915 eval [][0] 1916enddef 1917 1918def Test_callstack_def() 1919 try 1920 StackTop() 1921 catch 1922 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2') 1923 endtry 1924enddef 1925 1926 1927" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 1928