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