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 489def Test_call_func_defined_later() 490 g:DefinedLater('one')->assert_equal('one') 491 assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later') 492enddef 493 494func DefinedLater(arg) 495 return a:arg 496endfunc 497 498def Test_call_funcref() 499 g:SomeFunc('abc')->assert_equal(3) 500 assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call 501 assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref') 502 503 let lines =<< trim END 504 vim9script 505 def RetNumber(): number 506 return 123 507 enddef 508 let Funcref: func: number = function('RetNumber') 509 Funcref()->assert_equal(123) 510 END 511 CheckScriptSuccess(lines) 512 513 lines =<< trim END 514 vim9script 515 def RetNumber(): number 516 return 123 517 enddef 518 def Bar(F: func: number): number 519 return F() 520 enddef 521 let Funcref = function('RetNumber') 522 Bar(Funcref)->assert_equal(123) 523 END 524 CheckScriptSuccess(lines) 525 526 lines =<< trim END 527 vim9script 528 def UseNumber(nr: number) 529 echo nr 530 enddef 531 let Funcref: func(number) = function('UseNumber') 532 Funcref(123) 533 END 534 CheckScriptSuccess(lines) 535 536 lines =<< trim END 537 vim9script 538 def UseNumber(nr: number) 539 echo nr 540 enddef 541 let Funcref: func(string) = function('UseNumber') 542 END 543 CheckScriptFailure(lines, 'E1012: Type mismatch; expected func(string) but got func(number)') 544 545 lines =<< trim END 546 vim9script 547 def EchoNr(nr = 34) 548 g:echo = nr 549 enddef 550 let Funcref: func(?number) = function('EchoNr') 551 Funcref() 552 g:echo->assert_equal(34) 553 Funcref(123) 554 g:echo->assert_equal(123) 555 END 556 CheckScriptSuccess(lines) 557 558 lines =<< trim END 559 vim9script 560 def EchoList(...l: list<number>) 561 g:echo = l 562 enddef 563 let Funcref: func(...list<number>) = function('EchoList') 564 Funcref() 565 g:echo->assert_equal([]) 566 Funcref(1, 2, 3) 567 g:echo->assert_equal([1, 2, 3]) 568 END 569 CheckScriptSuccess(lines) 570 571 lines =<< trim END 572 vim9script 573 def OptAndVar(nr: number, opt = 12, ...l: list<number>): number 574 g:optarg = opt 575 g:listarg = l 576 return nr 577 enddef 578 let Funcref: func(number, ?number, ...list<number>): number = function('OptAndVar') 579 Funcref(10)->assert_equal(10) 580 g:optarg->assert_equal(12) 581 g:listarg->assert_equal([]) 582 583 Funcref(11, 22)->assert_equal(11) 584 g:optarg->assert_equal(22) 585 g:listarg->assert_equal([]) 586 587 Funcref(17, 18, 1, 2, 3)->assert_equal(17) 588 g:optarg->assert_equal(18) 589 g:listarg->assert_equal([1, 2, 3]) 590 END 591 CheckScriptSuccess(lines) 592enddef 593 594let SomeFunc = function('len') 595let NotAFunc = 'text' 596 597def CombineFuncrefTypes() 598 # same arguments, different return type 599 let Ref1: func(bool): string 600 let Ref2: func(bool): number 601 let Ref3: func(bool): any 602 Ref3 = g:cond ? Ref1 : Ref2 603 604 # different number of arguments 605 let Refa1: func(bool): number 606 let Refa2: func(bool, number): number 607 let Refa3: func: number 608 Refa3 = g:cond ? Refa1 : Refa2 609 610 # different argument types 611 let Refb1: func(bool, string): number 612 let Refb2: func(string, number): number 613 let Refb3: func(any, any): number 614 Refb3 = g:cond ? Refb1 : Refb2 615enddef 616 617def FuncWithForwardCall() 618 return g:DefinedEvenLater("yes") 619enddef 620 621def DefinedEvenLater(arg: string): string 622 return arg 623enddef 624 625def Test_error_in_nested_function() 626 # Error in called function requires unwinding the call stack. 627 assert_fails('FuncWithForwardCall()', 'E1096:', '', 1, 'FuncWithForwardCall') 628enddef 629 630def Test_return_type_wrong() 631 CheckScriptFailure([ 632 'def Func(): number', 633 'return "a"', 634 'enddef', 635 'defcompile'], 'expected number but got string') 636 CheckScriptFailure([ 637 'def Func(): string', 638 'return 1', 639 'enddef', 640 'defcompile'], 'expected string but got number') 641 CheckScriptFailure([ 642 'def Func(): void', 643 'return "a"', 644 'enddef', 645 'defcompile'], 646 'E1096: Returning a value in a function without a return type') 647 CheckScriptFailure([ 648 'def Func()', 649 'return "a"', 650 'enddef', 651 'defcompile'], 652 'E1096: Returning a value in a function without a return type') 653 654 CheckScriptFailure([ 655 'def Func(): number', 656 'return', 657 'enddef', 658 'defcompile'], 'E1003:') 659 660 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 661 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 662 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 663 664 CheckScriptFailure([ 665 'vim9script', 666 'def FuncB()', 667 ' return 123', 668 'enddef', 669 'def FuncA()', 670 ' FuncB()', 671 'enddef', 672 'defcompile'], 'E1096:') 673enddef 674 675def Test_arg_type_wrong() 676 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 677 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 678 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 679 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 680enddef 681 682def Test_vim9script_call() 683 let lines =<< trim END 684 vim9script 685 let var = '' 686 def MyFunc(arg: string) 687 var = arg 688 enddef 689 MyFunc('foobar') 690 var->assert_equal('foobar') 691 692 let str = 'barfoo' 693 str->MyFunc() 694 var->assert_equal('barfoo') 695 696 g:value = 'value' 697 g:value->MyFunc() 698 var->assert_equal('value') 699 700 let listvar = [] 701 def ListFunc(arg: list<number>) 702 listvar = arg 703 enddef 704 [1, 2, 3]->ListFunc() 705 listvar->assert_equal([1, 2, 3]) 706 707 let dictvar = {} 708 def DictFunc(arg: dict<number>) 709 dictvar = arg 710 enddef 711 {'a': 1, 'b': 2}->DictFunc() 712 dictvar->assert_equal(#{a: 1, b: 2}) 713 def CompiledDict() 714 {'a': 3, 'b': 4}->DictFunc() 715 enddef 716 CompiledDict() 717 dictvar->assert_equal(#{a: 3, b: 4}) 718 719 #{a: 3, b: 4}->DictFunc() 720 dictvar->assert_equal(#{a: 3, b: 4}) 721 722 ('text')->MyFunc() 723 var->assert_equal('text') 724 ("some")->MyFunc() 725 var->assert_equal('some') 726 727 # line starting with single quote is not a mark 728 # line starting with double quote can be a method call 729 'asdfasdf'->MyFunc() 730 var->assert_equal('asdfasdf') 731 "xyz"->MyFunc() 732 var->assert_equal('xyz') 733 734 def UseString() 735 'xyork'->MyFunc() 736 enddef 737 UseString() 738 var->assert_equal('xyork') 739 740 def UseString2() 741 "knife"->MyFunc() 742 enddef 743 UseString2() 744 var->assert_equal('knife') 745 746 # prepending a colon makes it a mark 747 new 748 setline(1, ['aaa', 'bbb', 'ccc']) 749 normal! 3Gmt1G 750 :'t 751 getcurpos()[1]->assert_equal(3) 752 bwipe! 753 754 MyFunc( 755 'continued' 756 ) 757 assert_equal('continued', 758 var 759 ) 760 761 call MyFunc( 762 'more' 763 .. 764 'lines' 765 ) 766 assert_equal( 767 'morelines', 768 var) 769 END 770 writefile(lines, 'Xcall.vim') 771 source Xcall.vim 772 delete('Xcall.vim') 773enddef 774 775def Test_vim9script_call_fail_decl() 776 let lines =<< trim END 777 vim9script 778 let var = '' 779 def MyFunc(arg: string) 780 let var = 123 781 enddef 782 defcompile 783 END 784 CheckScriptFailure(lines, 'E1054:') 785enddef 786 787def Test_vim9script_call_fail_type() 788 let lines =<< trim END 789 vim9script 790 def MyFunc(arg: string) 791 echo arg 792 enddef 793 MyFunc(1234) 794 END 795 CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected string but got number') 796enddef 797 798def Test_vim9script_call_fail_const() 799 let lines =<< trim END 800 vim9script 801 const var = '' 802 def MyFunc(arg: string) 803 var = 'asdf' 804 enddef 805 defcompile 806 END 807 writefile(lines, 'Xcall_const.vim') 808 assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc') 809 delete('Xcall_const.vim') 810enddef 811 812" Test that inside :function a Python function can be defined, :def is not 813" recognized. 814func Test_function_python() 815 CheckFeature python3 816 let py = 'python3' 817 execute py "<< EOF" 818def do_something(): 819 return 1 820EOF 821endfunc 822 823def Test_delfunc() 824 let lines =<< trim END 825 vim9script 826 def g:GoneSoon() 827 echo 'hello' 828 enddef 829 830 def CallGoneSoon() 831 GoneSoon() 832 enddef 833 defcompile 834 835 delfunc g:GoneSoon 836 CallGoneSoon() 837 END 838 writefile(lines, 'XToDelFunc') 839 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 840 assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') 841 842 delete('XToDelFunc') 843enddef 844 845def Test_redef_failure() 846 writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 847 so Xdef 848 writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 849 so Xdef 850 writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 851 assert_fails('so Xdef', 'E1027:', '', 1, 'Func0') 852 writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 853 so Xdef 854 delete('Xdef') 855 856 g:Func0()->assert_equal(0) 857 g:Func1()->assert_equal('Func1') 858 g:Func2()->assert_equal('Func2') 859 860 delfunc! Func0 861 delfunc! Func1 862 delfunc! Func2 863enddef 864 865def Test_vim9script_func() 866 let lines =<< trim END 867 vim9script 868 func Func(arg) 869 echo a:arg 870 endfunc 871 Func('text') 872 END 873 writefile(lines, 'XVim9Func') 874 so XVim9Func 875 876 delete('XVim9Func') 877enddef 878 879" Test for internal functions returning different types 880func Test_InternalFuncRetType() 881 let lines =<< trim END 882 def RetFloat(): float 883 return ceil(1.456) 884 enddef 885 886 def RetListAny(): list<any> 887 return items({'k': 'v'}) 888 enddef 889 890 def RetListString(): list<string> 891 return split('a:b:c', ':') 892 enddef 893 894 def RetListDictAny(): list<dict<any>> 895 return getbufinfo() 896 enddef 897 898 def RetDictNumber(): dict<number> 899 return wordcount() 900 enddef 901 902 def RetDictString(): dict<string> 903 return environ() 904 enddef 905 END 906 call writefile(lines, 'Xscript') 907 source Xscript 908 909 call RetFloat()->assert_equal(2.0) 910 call RetListAny()->assert_equal([['k', 'v']]) 911 call RetListString()->assert_equal(['a', 'b', 'c']) 912 call RetListDictAny()->assert_notequal([]) 913 call RetDictNumber()->assert_notequal({}) 914 call RetDictString()->assert_notequal({}) 915 call delete('Xscript') 916endfunc 917 918" Test for passing too many or too few arguments to internal functions 919func Test_internalfunc_arg_error() 920 let l =<< trim END 921 def! FArgErr(): float 922 return ceil(1.1, 2) 923 enddef 924 defcompile 925 END 926 call writefile(l, 'Xinvalidarg') 927 call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr') 928 let l =<< trim END 929 def! FArgErr(): float 930 return ceil() 931 enddef 932 defcompile 933 END 934 call writefile(l, 'Xinvalidarg') 935 call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr') 936 call delete('Xinvalidarg') 937endfunc 938 939let s:funcResult = 0 940 941def FuncNoArgNoRet() 942 s:funcResult = 11 943enddef 944 945def FuncNoArgRetNumber(): number 946 s:funcResult = 22 947 return 1234 948enddef 949 950def FuncNoArgRetString(): string 951 s:funcResult = 45 952 return 'text' 953enddef 954 955def FuncOneArgNoRet(arg: number) 956 s:funcResult = arg 957enddef 958 959def FuncOneArgRetNumber(arg: number): number 960 s:funcResult = arg 961 return arg 962enddef 963 964def FuncTwoArgNoRet(one: bool, two: number) 965 s:funcResult = two 966enddef 967 968def FuncOneArgRetString(arg: string): string 969 return arg 970enddef 971 972def FuncOneArgRetAny(arg: any): any 973 return arg 974enddef 975 976def Test_func_type() 977 let Ref1: func() 978 s:funcResult = 0 979 Ref1 = FuncNoArgNoRet 980 Ref1() 981 s:funcResult->assert_equal(11) 982 983 let Ref2: func 984 s:funcResult = 0 985 Ref2 = FuncNoArgNoRet 986 Ref2() 987 s:funcResult->assert_equal(11) 988 989 s:funcResult = 0 990 Ref2 = FuncOneArgNoRet 991 Ref2(12) 992 s:funcResult->assert_equal(12) 993 994 s:funcResult = 0 995 Ref2 = FuncNoArgRetNumber 996 Ref2()->assert_equal(1234) 997 s:funcResult->assert_equal(22) 998 999 s:funcResult = 0 1000 Ref2 = FuncOneArgRetNumber 1001 Ref2(13)->assert_equal(13) 1002 s:funcResult->assert_equal(13) 1003enddef 1004 1005def Test_repeat_return_type() 1006 let res = 0 1007 for n in repeat([1], 3) 1008 res += n 1009 endfor 1010 res->assert_equal(3) 1011 1012 res = 0 1013 for n in add([1, 2], 3) 1014 res += n 1015 endfor 1016 res->assert_equal(6) 1017enddef 1018 1019def Test_argv_return_type() 1020 next fileone filetwo 1021 let res = '' 1022 for name in argv() 1023 res ..= name 1024 endfor 1025 res->assert_equal('fileonefiletwo') 1026enddef 1027 1028def Test_func_type_part() 1029 let RefVoid: func: void 1030 RefVoid = FuncNoArgNoRet 1031 RefVoid = FuncOneArgNoRet 1032 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...) but got func(): number') 1033 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...) but got func(): string') 1034 1035 let RefAny: func(): any 1036 RefAny = FuncNoArgRetNumber 1037 RefAny = FuncNoArgRetString 1038 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func()') 1039 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func(): any but got func(number)') 1040 1041 let RefNr: func: number 1042 RefNr = FuncNoArgRetNumber 1043 RefNr = FuncOneArgRetNumber 1044 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): number but got func()') 1045 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1012: Type mismatch; expected func(...): number but got func(): string') 1046 1047 let RefStr: func: string 1048 RefStr = FuncNoArgRetString 1049 RefStr = FuncOneArgRetString 1050 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1012: Type mismatch; expected func(...): string but got func()') 1051 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func(...): string but got func(): number') 1052enddef 1053 1054def Test_func_type_fails() 1055 CheckDefFailure(['let ref1: func()'], 'E704:') 1056 1057 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(): number') 1058 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1012: Type mismatch; expected func() but got func(number)') 1059 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1012: Type mismatch; expected func() but got func(number): number') 1060 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(bool) but got func(bool, number)') 1061 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(?bool) but got func(bool, number)') 1062 CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1012: Type mismatch; expected func(...bool) but got func(bool, number)') 1063 1064 CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') 1065 CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') 1066 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:') 1067 CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:') 1068enddef 1069 1070def Test_func_return_type() 1071 let nr: number 1072 nr = FuncNoArgRetNumber() 1073 nr->assert_equal(1234) 1074 1075 nr = FuncOneArgRetAny(122) 1076 nr->assert_equal(122) 1077 1078 let str: string 1079 str = FuncOneArgRetAny('yes') 1080 str->assert_equal('yes') 1081 1082 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1012: Type mismatch; expected string but got number') 1083enddef 1084 1085def MultiLine( 1086 arg1: string, 1087 arg2 = 1234, 1088 ...rest: list<string> 1089 ): string 1090 return arg1 .. arg2 .. join(rest, '-') 1091enddef 1092 1093def MultiLineComment( 1094 arg1: string, # comment 1095 arg2 = 1234, # comment 1096 ...rest: list<string> # comment 1097 ): string # comment 1098 return arg1 .. arg2 .. join(rest, '-') 1099enddef 1100 1101def Test_multiline() 1102 MultiLine('text')->assert_equal('text1234') 1103 MultiLine('text', 777)->assert_equal('text777') 1104 MultiLine('text', 777, 'one')->assert_equal('text777one') 1105 MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1106enddef 1107 1108func Test_multiline_not_vim9() 1109 call MultiLine('text')->assert_equal('text1234') 1110 call MultiLine('text', 777)->assert_equal('text777') 1111 call MultiLine('text', 777, 'one')->assert_equal('text777one') 1112 call MultiLine('text', 777, 'one', 'two')->assert_equal('text777one-two') 1113endfunc 1114 1115 1116" When using CheckScriptFailure() for the below test, E1010 is generated instead 1117" of E1056. 1118func Test_E1056_1059() 1119 let caught_1056 = 0 1120 try 1121 def F(): 1122 return 1 1123 enddef 1124 catch /E1056:/ 1125 let caught_1056 = 1 1126 endtry 1127 eval caught_1056->assert_equal(1) 1128 1129 let caught_1059 = 0 1130 try 1131 def F5(items : list) 1132 echo 'a' 1133 enddef 1134 catch /E1059:/ 1135 let caught_1059 = 1 1136 endtry 1137 eval caught_1059->assert_equal(1) 1138endfunc 1139 1140func DelMe() 1141 echo 'DelMe' 1142endfunc 1143 1144def Test_error_reporting() 1145 # comment lines at the start of the function 1146 let lines =<< trim END 1147 " comment 1148 def Func() 1149 # comment 1150 # comment 1151 invalid 1152 enddef 1153 defcompile 1154 END 1155 writefile(lines, 'Xdef') 1156 try 1157 source Xdef 1158 assert_report('should have failed') 1159 catch /E476:/ 1160 v:exception->assert_match('Invalid command: invalid') 1161 v:throwpoint->assert_match(', line 3$') 1162 endtry 1163 1164 # comment lines after the start of the function 1165 lines =<< trim END 1166 " comment 1167 def Func() 1168 let x = 1234 1169 # comment 1170 # comment 1171 invalid 1172 enddef 1173 defcompile 1174 END 1175 writefile(lines, 'Xdef') 1176 try 1177 source Xdef 1178 assert_report('should have failed') 1179 catch /E476:/ 1180 v:exception->assert_match('Invalid command: invalid') 1181 v:throwpoint->assert_match(', line 4$') 1182 endtry 1183 1184 lines =<< trim END 1185 vim9script 1186 def Func() 1187 let db = #{foo: 1, bar: 2} 1188 # comment 1189 let x = db.asdf 1190 enddef 1191 defcompile 1192 Func() 1193 END 1194 writefile(lines, 'Xdef') 1195 try 1196 source Xdef 1197 assert_report('should have failed') 1198 catch /E716:/ 1199 v:throwpoint->assert_match('_Func, line 3$') 1200 endtry 1201 1202 delete('Xdef') 1203enddef 1204 1205def Test_deleted_function() 1206 CheckDefExecFailure([ 1207 'let RefMe: func = function("g:DelMe")', 1208 'delfunc g:DelMe', 1209 'echo RefMe()'], 'E117:') 1210enddef 1211 1212def Test_unknown_function() 1213 CheckDefExecFailure([ 1214 'let Ref: func = function("NotExist")', 1215 'delfunc g:NotExist'], 'E700:') 1216enddef 1217 1218def RefFunc(Ref: func(string): string): string 1219 return Ref('more') 1220enddef 1221 1222def Test_closure_simple() 1223 let local = 'some ' 1224 RefFunc({s -> local .. s})->assert_equal('some more') 1225enddef 1226 1227def MakeRef() 1228 let local = 'some ' 1229 g:Ref = {s -> local .. s} 1230enddef 1231 1232def Test_closure_ref_after_return() 1233 MakeRef() 1234 g:Ref('thing')->assert_equal('some thing') 1235 unlet g:Ref 1236enddef 1237 1238def MakeTwoRefs() 1239 let local = ['some'] 1240 g:Extend = {s -> local->add(s)} 1241 g:Read = {-> local} 1242enddef 1243 1244def Test_closure_two_refs() 1245 MakeTwoRefs() 1246 join(g:Read(), ' ')->assert_equal('some') 1247 g:Extend('more') 1248 join(g:Read(), ' ')->assert_equal('some more') 1249 g:Extend('even') 1250 join(g:Read(), ' ')->assert_equal('some more even') 1251 1252 unlet g:Extend 1253 unlet g:Read 1254enddef 1255 1256def ReadRef(Ref: func(): list<string>): string 1257 return join(Ref(), ' ') 1258enddef 1259 1260def ExtendRef(Ref: func(string): list<string>, add: string) 1261 Ref(add) 1262enddef 1263 1264def Test_closure_two_indirect_refs() 1265 MakeTwoRefs() 1266 ReadRef(g:Read)->assert_equal('some') 1267 ExtendRef(g:Extend, 'more') 1268 ReadRef(g:Read)->assert_equal('some more') 1269 ExtendRef(g:Extend, 'even') 1270 ReadRef(g:Read)->assert_equal('some more even') 1271 1272 unlet g:Extend 1273 unlet g:Read 1274enddef 1275 1276def MakeArgRefs(theArg: string) 1277 let local = 'loc_val' 1278 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 1279enddef 1280 1281def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 1282 let local = 'the_loc' 1283 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)} 1284enddef 1285 1286def Test_closure_using_argument() 1287 MakeArgRefs('arg_val') 1288 g:UseArg('call_val')->assert_equal('arg_val/loc_val/call_val') 1289 1290 MakeArgRefsVarargs('arg_val', 'one', 'two') 1291 g:UseVararg('call_val')->assert_equal('arg_val/the_loc/call_val/one two') 1292 1293 unlet g:UseArg 1294 unlet g:UseVararg 1295enddef 1296 1297def MakeGetAndAppendRefs() 1298 let local = 'a' 1299 1300 def Append(arg: string) 1301 local ..= arg 1302 enddef 1303 g:Append = Append 1304 1305 def Get(): string 1306 return local 1307 enddef 1308 g:Get = Get 1309enddef 1310 1311def Test_closure_append_get() 1312 MakeGetAndAppendRefs() 1313 g:Get()->assert_equal('a') 1314 g:Append('-b') 1315 g:Get()->assert_equal('a-b') 1316 g:Append('-c') 1317 g:Get()->assert_equal('a-b-c') 1318 1319 unlet g:Append 1320 unlet g:Get 1321enddef 1322 1323def Test_nested_closure() 1324 let local = 'text' 1325 def Closure(arg: string): string 1326 return local .. arg 1327 enddef 1328 Closure('!!!')->assert_equal('text!!!') 1329enddef 1330 1331func GetResult(Ref) 1332 return a:Ref('some') 1333endfunc 1334 1335def Test_call_closure_not_compiled() 1336 let text = 'text' 1337 g:Ref = {s -> s .. text} 1338 GetResult(g:Ref)->assert_equal('sometext') 1339enddef 1340 1341def Test_double_closure_fails() 1342 let lines =<< trim END 1343 vim9script 1344 def Func() 1345 let var = 0 1346 for i in range(2) 1347 timer_start(0, {-> var}) 1348 endfor 1349 enddef 1350 Func() 1351 END 1352 CheckScriptFailure(lines, 'Multiple closures not supported yet') 1353enddef 1354 1355def Test_sort_return_type() 1356 let res: list<number> 1357 res = [1, 2, 3]->sort() 1358enddef 1359 1360def Test_sort_argument() 1361 let res = ['b', 'a', 'c']->sort('i') 1362 res->assert_equal(['a', 'b', 'c']) 1363enddef 1364 1365def Test_getqflist_return_type() 1366 let l = getqflist() 1367 l->assert_equal([]) 1368 1369 let d = getqflist(#{items: 0}) 1370 d->assert_equal(#{items: []}) 1371enddef 1372 1373def Test_getloclist_return_type() 1374 let l = getloclist(1) 1375 l->assert_equal([]) 1376 1377 let d = getloclist(1, #{items: 0}) 1378 d->assert_equal(#{items: []}) 1379enddef 1380 1381def Test_copy_return_type() 1382 let l = copy([1, 2, 3]) 1383 let res = 0 1384 for n in l 1385 res += n 1386 endfor 1387 res->assert_equal(6) 1388 1389 let dl = deepcopy([1, 2, 3]) 1390 res = 0 1391 for n in dl 1392 res += n 1393 endfor 1394 res->assert_equal(6) 1395 1396 dl = deepcopy([1, 2, 3], true) 1397enddef 1398 1399def Test_extend_return_type() 1400 let l = extend([1, 2], [3]) 1401 let res = 0 1402 for n in l 1403 res += n 1404 endfor 1405 res->assert_equal(6) 1406enddef 1407 1408def Test_garbagecollect() 1409 garbagecollect(true) 1410enddef 1411 1412def Test_insert_return_type() 1413 let l = insert([2, 1], 3) 1414 let res = 0 1415 for n in l 1416 res += n 1417 endfor 1418 res->assert_equal(6) 1419enddef 1420 1421def Test_keys_return_type() 1422 const var: list<string> = #{a: 1, b: 2}->keys() 1423 var->assert_equal(['a', 'b']) 1424enddef 1425 1426def Test_reverse_return_type() 1427 let l = reverse([1, 2, 3]) 1428 let res = 0 1429 for n in l 1430 res += n 1431 endfor 1432 res->assert_equal(6) 1433enddef 1434 1435def Test_remove_return_type() 1436 let l = remove(#{one: [1, 2], two: [3, 4]}, 'one') 1437 let res = 0 1438 for n in l 1439 res += n 1440 endfor 1441 res->assert_equal(3) 1442enddef 1443 1444def Test_filter_return_type() 1445 let l = filter([1, 2, 3], {-> 1}) 1446 let res = 0 1447 for n in l 1448 res += n 1449 endfor 1450 res->assert_equal(6) 1451enddef 1452 1453def Test_bufnr() 1454 let buf = bufnr() 1455 bufnr('%')->assert_equal(buf) 1456 1457 buf = bufnr('Xdummy', true) 1458 buf->assert_notequal(-1) 1459 exe 'bwipe! ' .. buf 1460enddef 1461 1462def Test_col() 1463 new 1464 setline(1, 'asdf') 1465 col([1, '$'])->assert_equal(5) 1466enddef 1467 1468def Test_char2nr() 1469 char2nr('あ', true)->assert_equal(12354) 1470enddef 1471 1472def Test_getreg_return_type() 1473 let s1: string = getreg('"') 1474 let s2: string = getreg('"', 1) 1475 let s3: list<string> = getreg('"', 1, 1) 1476enddef 1477 1478def Wrong_dict_key_type(items: list<number>): list<number> 1479 return filter(items, {_, val -> get({val: 1}, 'x')}) 1480enddef 1481 1482def Test_wrong_dict_key_type() 1483 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:') 1484enddef 1485 1486def Line_continuation_in_def(dir: string = ''): string 1487 let path: string = empty(dir) 1488 \ ? 'empty' 1489 \ : 'full' 1490 return path 1491enddef 1492 1493def Test_line_continuation_in_def() 1494 Line_continuation_in_def('.')->assert_equal('full') 1495enddef 1496 1497def Line_continuation_in_lambda(): list<string> 1498 let x = range(97, 100) 1499 ->map({_, v -> nr2char(v) 1500 ->toupper()}) 1501 ->reverse() 1502 return x 1503enddef 1504 1505def Test_line_continuation_in_lambda() 1506 Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A']) 1507enddef 1508 1509func Test_silent_echo() 1510 CheckScreendump 1511 1512 let lines =<< trim END 1513 vim9script 1514 def EchoNothing() 1515 silent echo '' 1516 enddef 1517 defcompile 1518 END 1519 call writefile(lines, 'XTest_silent_echo') 1520 1521 " Check that the balloon shows up after a mouse move 1522 let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6}) 1523 call term_sendkeys(buf, ":abc") 1524 call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {}) 1525 1526 " clean up 1527 call StopVimInTerminal(buf) 1528 call delete('XTest_silent_echo') 1529endfunc 1530 1531""""""" builtin functions that behave differently in Vim9 1532 1533def Test_bufname() 1534 split SomeFile 1535 bufname('%')->assert_equal('SomeFile') 1536 edit OtherFile 1537 bufname('#')->assert_equal('SomeFile') 1538 close 1539enddef 1540 1541def Test_bufwinid() 1542 let origwin = win_getid() 1543 below split SomeFile 1544 let SomeFileID = win_getid() 1545 below split OtherFile 1546 below split SomeFile 1547 bufwinid('SomeFile')->assert_equal(SomeFileID) 1548 1549 win_gotoid(origwin) 1550 only 1551 bwipe SomeFile 1552 bwipe OtherFile 1553enddef 1554 1555def Test_count() 1556 count('ABC ABC ABC', 'b', true)->assert_equal(3) 1557 count('ABC ABC ABC', 'b', false)->assert_equal(0) 1558enddef 1559 1560def Test_expand() 1561 split SomeFile 1562 expand('%', true, true)->assert_equal(['SomeFile']) 1563 close 1564enddef 1565 1566def Test_getbufinfo() 1567 let bufinfo = getbufinfo(bufnr()) 1568 getbufinfo('%')->assert_equal(bufinfo) 1569 1570 edit Xtestfile1 1571 hide edit Xtestfile2 1572 hide enew 1573 getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false}) 1574 ->len()->assert_equal(3) 1575 bwipe Xtestfile1 Xtestfile2 1576enddef 1577 1578def Test_getbufline() 1579 e SomeFile 1580 let buf = bufnr() 1581 e # 1582 let lines = ['aaa', 'bbb', 'ccc'] 1583 setbufline(buf, 1, lines) 1584 getbufline('#', 1, '$')->assert_equal(lines) 1585 1586 bwipe! 1587enddef 1588 1589def Test_getchangelist() 1590 new 1591 setline(1, 'some text') 1592 let changelist = bufnr()->getchangelist() 1593 getchangelist('%')->assert_equal(changelist) 1594 bwipe! 1595enddef 1596 1597def Test_getchar() 1598 while getchar(0) 1599 endwhile 1600 getchar(true)->assert_equal(0) 1601enddef 1602 1603def Test_getcompletion() 1604 set wildignore=*.vim,*~ 1605 let l = getcompletion('run', 'file', true) 1606 l->assert_equal([]) 1607 set wildignore& 1608enddef 1609 1610def Test_getreg() 1611 let lines = ['aaa', 'bbb', 'ccc'] 1612 setreg('a', lines) 1613 getreg('a', true, true)->assert_equal(lines) 1614enddef 1615 1616def Test_glob() 1617 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim']) 1618enddef 1619 1620def Test_globpath() 1621 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim']) 1622enddef 1623 1624def Test_has() 1625 has('eval', true)->assert_equal(1) 1626enddef 1627 1628def Test_hasmapto() 1629 hasmapto('foobar', 'i', true)->assert_equal(0) 1630 iabbrev foo foobar 1631 hasmapto('foobar', 'i', true)->assert_equal(1) 1632 iunabbrev foo 1633enddef 1634 1635def Test_index() 1636 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3) 1637enddef 1638 1639def Test_list2str_str2list_utf8() 1640 let s = "\u3042\u3044" 1641 let l = [0x3042, 0x3044] 1642 str2list(s, true)->assert_equal(l) 1643 list2str(l, true)->assert_equal(s) 1644enddef 1645 1646def SID(): number 1647 return expand('<SID>') 1648 ->matchstr('<SNR>\zs\d\+\ze_$') 1649 ->str2nr() 1650enddef 1651 1652def Test_maparg() 1653 let lnum = str2nr(expand('<sflnum>')) 1654 map foo bar 1655 maparg('foo', '', false, true)->assert_equal(#{ 1656 lnum: lnum + 1, 1657 script: 0, 1658 mode: ' ', 1659 silent: 0, 1660 noremap: 0, 1661 lhs: 'foo', 1662 lhsraw: 'foo', 1663 nowait: 0, 1664 expr: 0, 1665 sid: SID(), 1666 rhs: 'bar', 1667 buffer: 0}) 1668 unmap foo 1669enddef 1670 1671def Test_mapcheck() 1672 iabbrev foo foobar 1673 mapcheck('foo', 'i', true)->assert_equal('foobar') 1674 iunabbrev foo 1675enddef 1676 1677def Test_nr2char() 1678 nr2char(97, true)->assert_equal('a') 1679enddef 1680 1681def Test_readdir() 1682 eval expand('sautest')->readdir({e -> e[0] !=# '.'}) 1683 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'}) 1684enddef 1685 1686def Test_search() 1687 new 1688 setline(1, ['foo', 'bar']) 1689 let val = 0 1690 # skip expr returns boolean 1691 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2) 1692 :1 1693 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0) 1694 # skip expr returns number, only 0 and 1 are accepted 1695 :1 1696 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2) 1697 :1 1698 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0) 1699 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 1700 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 1701enddef 1702 1703def Test_searchcount() 1704 new 1705 setline(1, "foo bar") 1706 :/foo 1707 searchcount(#{recompute: true}) 1708 ->assert_equal(#{ 1709 exact_match: 1, 1710 current: 1, 1711 total: 1, 1712 maxcount: 99, 1713 incomplete: 0}) 1714 bwipe! 1715enddef 1716 1717def Test_searchdecl() 1718 searchdecl('blah', true, true)->assert_equal(1) 1719enddef 1720 1721def Test_setbufvar() 1722 setbufvar(bufnr('%'), '&syntax', 'vim') 1723 &syntax->assert_equal('vim') 1724 setbufvar(bufnr('%'), '&ts', 16) 1725 &ts->assert_equal(16) 1726 settabwinvar(1, 1, '&syntax', 'vam') 1727 &syntax->assert_equal('vam') 1728 settabwinvar(1, 1, '&ts', 15) 1729 &ts->assert_equal(15) 1730 setlocal ts=8 1731 1732 setbufvar('%', 'myvar', 123) 1733 getbufvar('%', 'myvar')->assert_equal(123) 1734enddef 1735 1736def Test_setloclist() 1737 let items = [#{filename: '/tmp/file', lnum: 1, valid: true}] 1738 let what = #{items: items} 1739 setqflist([], ' ', what) 1740 setloclist(0, [], ' ', what) 1741enddef 1742 1743def Test_setreg() 1744 setreg('a', ['aaa', 'bbb', 'ccc']) 1745 let reginfo = getreginfo('a') 1746 setreg('a', reginfo) 1747 getreginfo('a')->assert_equal(reginfo) 1748enddef 1749 1750def Test_spellsuggest() 1751 if !has('spell') 1752 MissingFeature 'spell' 1753 else 1754 spellsuggest('marrch', 1, true)->assert_equal(['March']) 1755 endif 1756enddef 1757 1758def Test_split() 1759 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', '']) 1760enddef 1761 1762def Test_str2nr() 1763 str2nr("1'000'000", 10, true)->assert_equal(1000000) 1764enddef 1765 1766def Test_strchars() 1767 strchars("A\u20dd", true)->assert_equal(1) 1768enddef 1769 1770def Test_submatch() 1771 let pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)' 1772 let Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()} 1773 let actual = substitute('A123456789', pat, Rep, '') 1774 let expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]" 1775 actual->assert_equal(expected) 1776enddef 1777 1778def Test_synID() 1779 new 1780 setline(1, "text") 1781 synID(1, 1, true)->assert_equal(0) 1782 bwipe! 1783enddef 1784 1785def Test_term_gettty() 1786 if !has('terminal') 1787 MissingFeature 'terminal' 1788 else 1789 let buf = Run_shell_in_terminal({}) 1790 term_gettty(buf, true)->assert_notequal('') 1791 StopShellInTerminal(buf) 1792 endif 1793enddef 1794 1795def Test_term_start() 1796 if !has('terminal') 1797 MissingFeature 'terminal' 1798 else 1799 botright new 1800 let winnr = winnr() 1801 term_start(&shell, #{curwin: true}) 1802 winnr()->assert_equal(winnr) 1803 bwipe! 1804 endif 1805enddef 1806 1807def Test_timer_paused() 1808 let id = timer_start(50, {-> 0}) 1809 timer_pause(id, true) 1810 let info = timer_info(id) 1811 info[0]['paused']->assert_equal(1) 1812 timer_stop(id) 1813enddef 1814 1815def Test_win_splitmove() 1816 split 1817 win_splitmove(1, 2, #{vertical: true, rightbelow: true}) 1818 close 1819enddef 1820 1821""""""" end of builtin functions 1822 1823def Fibonacci(n: number): number 1824 if n < 2 1825 return n 1826 else 1827 return Fibonacci(n - 1) + Fibonacci(n - 2) 1828 endif 1829enddef 1830 1831def Test_recursive_call() 1832 Fibonacci(20)->assert_equal(6765) 1833enddef 1834 1835def TreeWalk(dir: string): list<any> 1836 return readdir(dir)->map({_, val -> 1837 fnamemodify(dir .. '/' .. val, ':p')->isdirectory() 1838 ? {val: TreeWalk(dir .. '/' .. val)} 1839 : val 1840 }) 1841enddef 1842 1843def Test_closure_in_map() 1844 mkdir('XclosureDir/tdir', 'p') 1845 writefile(['111'], 'XclosureDir/file1') 1846 writefile(['222'], 'XclosureDir/file2') 1847 writefile(['333'], 'XclosureDir/tdir/file3') 1848 1849 TreeWalk('XclosureDir')->assert_equal(['file1', 'file2', {'tdir': ['file3']}]) 1850 1851 delete('XclosureDir', 'rf') 1852enddef 1853 1854def Test_partial_call() 1855 let Xsetlist = function('setloclist', [0]) 1856 Xsetlist([], ' ', {'title': 'test'}) 1857 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1858 1859 Xsetlist = function('setloclist', [0, [], ' ']) 1860 Xsetlist({'title': 'test'}) 1861 getloclist(0, {'title': 1})->assert_equal({'title': 'test'}) 1862 1863 Xsetlist = function('setqflist') 1864 Xsetlist([], ' ', {'title': 'test'}) 1865 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1866 1867 Xsetlist = function('setqflist', [[], ' ']) 1868 Xsetlist({'title': 'test'}) 1869 getqflist({'title': 1})->assert_equal({'title': 'test'}) 1870enddef 1871 1872def Test_cmd_modifier() 1873 tab echo '0' 1874 CheckDefFailure(['5tab echo 3'], 'E16:') 1875enddef 1876 1877def Test_restore_modifiers() 1878 # check that when compiling a :def function command modifiers are not messed 1879 # up. 1880 let lines =<< trim END 1881 vim9script 1882 set eventignore= 1883 autocmd QuickFixCmdPost * copen 1884 def AutocmdsDisabled() 1885 eval 0 1886 enddef 1887 func Func() 1888 noautocmd call s:AutocmdsDisabled() 1889 let g:ei_after = &eventignore 1890 endfunc 1891 Func() 1892 END 1893 CheckScriptSuccess(lines) 1894 g:ei_after->assert_equal('') 1895enddef 1896 1897def StackTop() 1898 eval 1 1899 eval 2 1900 # call not on fourth line 1901 StackBot() 1902enddef 1903 1904def StackBot() 1905 # throw an error 1906 eval [][0] 1907enddef 1908 1909def Test_callstack_def() 1910 try 1911 StackTop() 1912 catch 1913 v:throwpoint->assert_match('Test_callstack_def\[2\]..StackTop\[4\]..StackBot, line 2') 1914 endtry 1915enddef 1916 1917 1918" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 1919