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