1" Test various aspects of the Vim9 script language. 2 3source check.vim 4source view_util.vim 5source vim9.vim 6 7func Test_def_basic() 8 def SomeFunc(): string 9 return 'yes' 10 enddef 11 call assert_equal('yes', SomeFunc()) 12endfunc 13 14def ReturnString(): string 15 return 'string' 16enddef 17 18def ReturnNumber(): number 19 return 123 20enddef 21 22let g:notNumber = 'string' 23 24def ReturnGlobal(): number 25 return g:notNumber 26enddef 27 28def Test_return_something() 29 assert_equal('string', ReturnString()) 30 assert_equal(123, ReturnNumber()) 31 assert_fails('call ReturnGlobal()', 'E1029: Expected number but got string') 32enddef 33 34def Test_missing_return() 35 CheckDefFailure(['def Missing(): number', 36 ' if g:cond', 37 ' echo "no return"', 38 ' else', 39 ' return 0', 40 ' endif' 41 'enddef'], 'E1027:') 42 CheckDefFailure(['def Missing(): number', 43 ' if g:cond', 44 ' return 1', 45 ' else', 46 ' echo "no return"', 47 ' endif' 48 'enddef'], 'E1027:') 49 CheckDefFailure(['def Missing(): number', 50 ' if g:cond', 51 ' return 1', 52 ' else', 53 ' return 2', 54 ' endif' 55 ' return 3' 56 'enddef'], 'E1095:') 57enddef 58 59let s:nothing = 0 60def ReturnNothing() 61 s:nothing = 1 62 if true 63 return 64 endif 65 s:nothing = 2 66enddef 67 68def Test_return_nothing() 69 ReturnNothing() 70 assert_equal(1, s:nothing) 71enddef 72 73func Increment() 74 let g:counter += 1 75endfunc 76 77def Test_call_ufunc_count() 78 g:counter = 1 79 Increment() 80 Increment() 81 Increment() 82 " works with and without :call 83 assert_equal(4, g:counter) 84 call assert_equal(4, g:counter) 85 unlet g:counter 86enddef 87 88def MyVarargs(arg: string, ...rest: list<string>): string 89 let res = arg 90 for s in rest 91 res ..= ',' .. s 92 endfor 93 return res 94enddef 95 96def Test_call_varargs() 97 assert_equal('one', MyVarargs('one')) 98 assert_equal('one,two', MyVarargs('one', 'two')) 99 assert_equal('one,two,three', MyVarargs('one', 'two', 'three')) 100enddef 101 102def MyDefaultArgs(name = 'string'): string 103 return name 104enddef 105 106def Test_call_default_args() 107 assert_equal('string', MyDefaultArgs()) 108 assert_equal('one', MyDefaultArgs('one')) 109 assert_fails('call MyDefaultArgs("one", "two")', 'E118:') 110 111 CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:') 112 CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: argument 1: type mismatch, expected number but got string') 113enddef 114 115def Test_nested_function() 116 def Nested(arg: string): string 117 return 'nested ' .. arg 118 enddef 119 assert_equal('nested function', Nested('function')) 120 121 CheckDefFailure(['def Nested()', 'enddef', 'Nested(66)'], 'E118:') 122 CheckDefFailure(['def Nested(arg: string)', 'enddef', 'Nested()'], 'E119:') 123 124 CheckDefFailure(['func Nested()', 'endfunc'], 'E1086:') 125enddef 126 127func Test_call_default_args_from_func() 128 call assert_equal('string', MyDefaultArgs()) 129 call assert_equal('one', MyDefaultArgs('one')) 130 call assert_fails('call MyDefaultArgs("one", "two")', 'E118:') 131endfunc 132 133func TakesOneArg(arg) 134 echo a:arg 135endfunc 136 137def Test_call_wrong_args() 138 call CheckDefFailure(['TakesOneArg()'], 'E119:') 139 call CheckDefFailure(['TakesOneArg(11, 22)'], 'E118:') 140 call CheckDefFailure(['bufnr(xxx)'], 'E1001:') 141 call CheckScriptFailure(['def Func(Ref: func(s: string))'], 'E475:') 142enddef 143 144" Default arg and varargs 145def MyDefVarargs(one: string, two = 'foo', ...rest: list<string>): string 146 let res = one .. ',' .. two 147 for s in rest 148 res ..= ',' .. s 149 endfor 150 return res 151enddef 152 153def Test_call_def_varargs() 154 call assert_fails('call MyDefVarargs()', 'E119:') 155 assert_equal('one,foo', MyDefVarargs('one')) 156 assert_equal('one,two', MyDefVarargs('one', 'two')) 157 assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three')) 158 call CheckDefFailure(['MyDefVarargs("one", 22)'], 'E1013: argument 2: type mismatch, expected string but got number') 159enddef 160 161let s:value = '' 162 163def FuncOneDefArg(opt = 'text') 164 s:value = opt 165enddef 166 167def FuncTwoDefArg(nr = 123, opt = 'text'): string 168 return nr .. opt 169enddef 170 171def FuncVarargs(...arg: list<string>): string 172 return join(arg, ',') 173enddef 174 175def Test_func_type_varargs() 176 let RefDefArg: func(?string) 177 RefDefArg = FuncOneDefArg 178 RefDefArg() 179 assert_equal('text', s:value) 180 RefDefArg('some') 181 assert_equal('some', s:value) 182 183 let RefDef2Arg: func(?number, ?string): string 184 RefDef2Arg = FuncTwoDefArg 185 assert_equal('123text', RefDef2Arg()) 186 assert_equal('99text', RefDef2Arg(99)) 187 assert_equal('77some', RefDef2Arg(77, 'some')) 188 189 call CheckDefFailure(['let RefWrong: func(string?)'], 'E1010:') 190 call CheckDefFailure(['let RefWrong: func(?string, string)'], 'E1007:') 191 192 let RefVarargs: func(...list<string>): string 193 RefVarargs = FuncVarargs 194 assert_equal('', RefVarargs()) 195 assert_equal('one', RefVarargs('one')) 196 assert_equal('one,two', RefVarargs('one', 'two')) 197 198 call CheckDefFailure(['let RefWrong: func(...list<string>, string)'], 'E110:') 199 call CheckDefFailure(['let RefWrong: func(...list<string>, ?string)'], 'E110:') 200enddef 201 202" Only varargs 203def MyVarargsOnly(...args: list<string>): string 204 return join(args, ',') 205enddef 206 207def Test_call_varargs_only() 208 assert_equal('', MyVarargsOnly()) 209 assert_equal('one', MyVarargsOnly('one')) 210 assert_equal('one,two', MyVarargsOnly('one', 'two')) 211 call CheckDefFailure(['MyVarargsOnly(1)'], 'E1013: argument 1: type mismatch, expected string but got number') 212 call CheckDefFailure(['MyVarargsOnly("one", 2)'], 'E1013: argument 2: type mismatch, expected string but got number') 213enddef 214 215def Test_using_var_as_arg() 216 call writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef') 217 call assert_fails('so Xdef', 'E1006:') 218 call delete('Xdef') 219enddef 220 221def DictArg(arg: dict<string>) 222 arg['key'] = 'value' 223enddef 224 225def ListArg(arg: list<string>) 226 arg[0] = 'value' 227enddef 228 229def Test_assign_to_argument() 230 " works for dict and list 231 let d: dict<string> = {} 232 DictArg(d) 233 assert_equal('value', d['key']) 234 let l: list<string> = [] 235 ListArg(l) 236 assert_equal('value', l[0]) 237 238 call CheckScriptFailure(['def Func(arg: number)', 'arg = 3', 'enddef', 'defcompile'], 'E1090:') 239enddef 240 241def Test_call_func_defined_later() 242 call assert_equal('one', g:DefinedLater('one')) 243 call assert_fails('call NotDefined("one")', 'E117:') 244enddef 245 246func DefinedLater(arg) 247 return a:arg 248endfunc 249 250def Test_call_funcref() 251 assert_equal(3, g:SomeFunc('abc')) 252 assert_fails('NotAFunc()', 'E117:') 253 assert_fails('g:NotAFunc()', 'E117:') 254enddef 255 256let SomeFunc = function('len') 257let NotAFunc = 'text' 258 259def CombineFuncrefTypes() 260 " same arguments, different return type 261 let Ref1: func(bool): string 262 let Ref2: func(bool): number 263 let Ref3: func(bool): any 264 Ref3 = g:cond ? Ref1 : Ref2 265 266 " different number of arguments 267 let Refa1: func(bool): number 268 let Refa2: func(bool, number): number 269 let Refa3: func: number 270 Refa3 = g:cond ? Refa1 : Refa2 271 272 " different argument types 273 let Refb1: func(bool, string): number 274 let Refb2: func(string, number): number 275 let Refb3: func(any, any): number 276 Refb3 = g:cond ? Refb1 : Refb2 277enddef 278 279def FuncWithForwardCall() 280 return g:DefinedEvenLater("yes") 281enddef 282 283def DefinedEvenLater(arg: string): string 284 return arg 285enddef 286 287def Test_error_in_nested_function() 288 " Error in called function requires unwinding the call stack. 289 assert_fails('call FuncWithForwardCall()', 'E1013') 290enddef 291 292def Test_return_type_wrong() 293 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef', 'defcompile'], 'expected number but got string') 294 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef', 'defcompile'], 'expected string but got number') 295 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef', 'defcompile'], 'expected void but got string') 296 CheckScriptFailure(['def Func()', 'return "a"', 'enddef', 'defcompile'], 'expected void but got string') 297 298 CheckScriptFailure(['def Func(): number', 'return', 'enddef', 'defcompile'], 'E1003:') 299 300 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 301 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 302 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 303enddef 304 305def Test_arg_type_wrong() 306 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 307 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 308 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 309 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 310enddef 311 312def Test_vim9script_call() 313 let lines =<< trim END 314 vim9script 315 let var = '' 316 def MyFunc(arg: string) 317 var = arg 318 enddef 319 MyFunc('foobar') 320 assert_equal('foobar', var) 321 322 let str = 'barfoo' 323 str->MyFunc() 324 assert_equal('barfoo', var) 325 326 let g:value = 'value' 327 g:value->MyFunc() 328 assert_equal('value', var) 329 330 let listvar = [] 331 def ListFunc(arg: list<number>) 332 listvar = arg 333 enddef 334 [1, 2, 3]->ListFunc() 335 assert_equal([1, 2, 3], listvar) 336 337 let dictvar = {} 338 def DictFunc(arg: dict<number>) 339 dictvar = arg 340 enddef 341 {'a': 1, 'b': 2}->DictFunc() 342 assert_equal(#{a: 1, b: 2}, dictvar) 343 def CompiledDict() 344 {'a': 3, 'b': 4}->DictFunc() 345 enddef 346 CompiledDict() 347 assert_equal(#{a: 3, b: 4}, dictvar) 348 349 #{a: 3, b: 4}->DictFunc() 350 assert_equal(#{a: 3, b: 4}, dictvar) 351 352 ('text')->MyFunc() 353 assert_equal('text', var) 354 ("some")->MyFunc() 355 assert_equal('some', var) 356 END 357 writefile(lines, 'Xcall.vim') 358 source Xcall.vim 359 delete('Xcall.vim') 360enddef 361 362def Test_vim9script_call_fail_decl() 363 let lines =<< trim END 364 vim9script 365 let var = '' 366 def MyFunc(arg: string) 367 let var = 123 368 enddef 369 defcompile 370 END 371 writefile(lines, 'Xcall_decl.vim') 372 assert_fails('source Xcall_decl.vim', 'E1054:') 373 delete('Xcall_decl.vim') 374enddef 375 376def Test_vim9script_call_fail_const() 377 let lines =<< trim END 378 vim9script 379 const var = '' 380 def MyFunc(arg: string) 381 var = 'asdf' 382 enddef 383 defcompile 384 END 385 writefile(lines, 'Xcall_const.vim') 386 assert_fails('source Xcall_const.vim', 'E46:') 387 delete('Xcall_const.vim') 388enddef 389 390" Test that inside :function a Python function can be defined, :def is not 391" recognized. 392func Test_function_python() 393 CheckFeature python3 394 let py = 'python3' 395 execute py "<< EOF" 396def do_something(): 397 return 1 398EOF 399endfunc 400 401def Test_delfunc() 402 let lines =<< trim END 403 vim9script 404 def g:GoneSoon() 405 echo 'hello' 406 enddef 407 408 def CallGoneSoon() 409 GoneSoon() 410 enddef 411 defcompile 412 413 delfunc g:GoneSoon 414 CallGoneSoon() 415 END 416 writefile(lines, 'XToDelFunc') 417 assert_fails('so XToDelFunc', 'E933') 418 assert_fails('so XToDelFunc', 'E933') 419 420 delete('XToDelFunc') 421enddef 422 423def Test_redef_failure() 424 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 425 so Xdef 426 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 427 so Xdef 428 call writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') 429 call assert_fails('so Xdef', 'E1027:') 430 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 431 so Xdef 432 call delete('Xdef') 433 434 call assert_equal(0, g:Func0()) 435 call assert_equal('Func1', g:Func1()) 436 call assert_equal('Func2', g:Func2()) 437 438 delfunc! Func0 439 delfunc! Func1 440 delfunc! Func2 441enddef 442 443def Test_vim9script_func() 444 let lines =<< trim END 445 vim9script 446 func Func(arg) 447 echo a:arg 448 endfunc 449 Func('text') 450 END 451 writefile(lines, 'XVim9Func') 452 so XVim9Func 453 454 delete('XVim9Func') 455enddef 456 457" Test for internal functions returning different types 458func Test_InternalFuncRetType() 459 let lines =<< trim END 460 def RetFloat(): float 461 return ceil(1.456) 462 enddef 463 464 def RetListAny(): list<any> 465 return items({'k' : 'v'}) 466 enddef 467 468 def RetListString(): list<string> 469 return split('a:b:c', ':') 470 enddef 471 472 def RetListDictAny(): list<dict<any>> 473 return getbufinfo() 474 enddef 475 476 def RetDictNumber(): dict<number> 477 return wordcount() 478 enddef 479 480 def RetDictString(): dict<string> 481 return environ() 482 enddef 483 END 484 call writefile(lines, 'Xscript') 485 source Xscript 486 487 call assert_equal(2.0, RetFloat()) 488 call assert_equal([['k', 'v']], RetListAny()) 489 call assert_equal(['a', 'b', 'c'], RetListString()) 490 call assert_notequal([], RetListDictAny()) 491 call assert_notequal({}, RetDictNumber()) 492 call assert_notequal({}, RetDictString()) 493 call delete('Xscript') 494endfunc 495 496" Test for passing too many or too few arguments to internal functions 497func Test_internalfunc_arg_error() 498 let l =<< trim END 499 def! FArgErr(): float 500 return ceil(1.1, 2) 501 enddef 502 defcompile 503 END 504 call writefile(l, 'Xinvalidarg') 505 call assert_fails('so Xinvalidarg', 'E118:') 506 let l =<< trim END 507 def! FArgErr(): float 508 return ceil() 509 enddef 510 defcompile 511 END 512 call writefile(l, 'Xinvalidarg') 513 call assert_fails('so Xinvalidarg', 'E119:') 514 call delete('Xinvalidarg') 515endfunc 516 517let s:funcResult = 0 518 519def FuncNoArgNoRet() 520 funcResult = 11 521enddef 522 523def FuncNoArgRetNumber(): number 524 funcResult = 22 525 return 1234 526enddef 527 528def FuncNoArgRetString(): string 529 funcResult = 45 530 return 'text' 531enddef 532 533def FuncOneArgNoRet(arg: number) 534 funcResult = arg 535enddef 536 537def FuncOneArgRetNumber(arg: number): number 538 funcResult = arg 539 return arg 540enddef 541 542def FuncTwoArgNoRet(one: bool, two: number) 543 funcResult = two 544enddef 545 546def FuncOneArgRetString(arg: string): string 547 return arg 548enddef 549 550def FuncOneArgRetAny(arg: any): any 551 return arg 552enddef 553 554def Test_func_type() 555 let Ref1: func() 556 funcResult = 0 557 Ref1 = FuncNoArgNoRet 558 Ref1() 559 assert_equal(11, funcResult) 560 561 let Ref2: func 562 funcResult = 0 563 Ref2 = FuncNoArgNoRet 564 Ref2() 565 assert_equal(11, funcResult) 566 567 funcResult = 0 568 Ref2 = FuncOneArgNoRet 569 Ref2(12) 570 assert_equal(12, funcResult) 571 572 funcResult = 0 573 Ref2 = FuncNoArgRetNumber 574 assert_equal(1234, Ref2()) 575 assert_equal(22, funcResult) 576 577 funcResult = 0 578 Ref2 = FuncOneArgRetNumber 579 assert_equal(13, Ref2(13)) 580 assert_equal(13, funcResult) 581enddef 582 583def Test_func_type_part() 584 let RefVoid: func: void 585 RefVoid = FuncNoArgNoRet 586 RefVoid = FuncOneArgNoRet 587 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 588 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string') 589 590 let RefAny: func(): any 591 RefAny = FuncNoArgRetNumber 592 RefAny = FuncNoArgRetString 593 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): any but got func()') 594 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1013: type mismatch, expected func(): any but got func(number)') 595 596 let RefNr: func: number 597 RefNr = FuncNoArgRetNumber 598 RefNr = FuncOneArgRetNumber 599 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()') 600 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string') 601 602 let RefStr: func: string 603 RefStr = FuncNoArgRetString 604 RefStr = FuncOneArgRetString 605 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): string but got func()') 606 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got func(): number') 607enddef 608 609def Test_func_type_fails() 610 CheckDefFailure(['let ref1: func()'], 'E704:') 611 612 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 613 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)') 614 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number') 615 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)') 616 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)') 617 CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)') 618 619 call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') 620 call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') 621 call CheckDefFailure(['let RefWrong: func(bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool, bool)'], 'E740:') 622 call CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:') 623enddef 624 625def Test_func_return_type() 626 let nr: number 627 nr = FuncNoArgRetNumber() 628 assert_equal(1234, nr) 629 630 nr = FuncOneArgRetAny(122) 631 assert_equal(122, nr) 632 633 let str: string 634 str = FuncOneArgRetAny('yes') 635 assert_equal('yes', str) 636 637 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1013: type mismatch, expected string but got number') 638enddef 639 640def MultiLine( 641 arg1: string, 642 arg2 = 1234, 643 ...rest: list<string> 644 ): string 645 return arg1 .. arg2 .. join(rest, '-') 646enddef 647 648def MultiLineComment( 649 arg1: string, # comment 650 arg2 = 1234, # comment 651 ...rest: list<string> # comment 652 ): string # comment 653 return arg1 .. arg2 .. join(rest, '-') 654enddef 655 656def Test_multiline() 657 assert_equal('text1234', MultiLine('text')) 658 assert_equal('text777', MultiLine('text', 777)) 659 assert_equal('text777one', MultiLine('text', 777, 'one')) 660 assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 661enddef 662 663func Test_multiline_not_vim9() 664 call assert_equal('text1234', MultiLine('text')) 665 call assert_equal('text777', MultiLine('text', 777)) 666 call assert_equal('text777one', MultiLine('text', 777, 'one')) 667 call assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 668endfunc 669 670 671" When using CheckScriptFailure() for the below test, E1010 is generated instead 672" of E1056. 673func Test_E1056_1059() 674 let caught_1056 = 0 675 try 676 def F(): 677 return 1 678 enddef 679 catch /E1056:/ 680 let caught_1056 = 1 681 endtry 682 call assert_equal(1, caught_1056) 683 684 let caught_1059 = 0 685 try 686 def F5(items : list) 687 echo 'a' 688 enddef 689 catch /E1059:/ 690 let caught_1059 = 1 691 endtry 692 call assert_equal(1, caught_1059) 693endfunc 694 695func DelMe() 696 echo 'DelMe' 697endfunc 698 699def Test_deleted_function() 700 CheckDefExecFailure([ 701 'let RefMe: func = function("g:DelMe")', 702 'delfunc g:DelMe', 703 'echo RefMe()'], 'E117:') 704enddef 705 706def Test_unknown_function() 707 CheckDefExecFailure([ 708 'let Ref: func = function("NotExist")', 709 'delfunc g:NotExist'], 'E130:') 710enddef 711 712def RefFunc(Ref: func(string): string): string 713 return Ref('more') 714enddef 715 716def Test_closure_simple() 717 let local = 'some ' 718 assert_equal('some more', RefFunc({s -> local .. s})) 719enddef 720 721def MakeRef() 722 let local = 'some ' 723 g:Ref = {s -> local .. s} 724enddef 725 726def Test_closure_ref_after_return() 727 MakeRef() 728 assert_equal('some thing', g:Ref('thing')) 729 unlet g:Ref 730enddef 731 732def MakeTwoRefs() 733 let local = ['some'] 734 g:Extend = {s -> local->add(s)} 735 g:Read = {-> local} 736enddef 737 738def Test_closure_two_refs() 739 MakeTwoRefs() 740 assert_equal('some', join(g:Read(), ' ')) 741 g:Extend('more') 742 assert_equal('some more', join(g:Read(), ' ')) 743 g:Extend('even') 744 assert_equal('some more even', join(g:Read(), ' ')) 745 746 unlet g:Extend 747 unlet g:Read 748enddef 749 750def ReadRef(Ref: func(): list<string>): string 751 return join(Ref(), ' ') 752enddef 753 754def ExtendRef(Ref: func(string), add: string) 755 Ref(add) 756enddef 757 758def Test_closure_two_indirect_refs() 759 MakeTwoRefs() 760 assert_equal('some', ReadRef(g:Read)) 761 ExtendRef(g:Extend, 'more') 762 assert_equal('some more', ReadRef(g:Read)) 763 ExtendRef(g:Extend, 'even') 764 assert_equal('some more even', ReadRef(g:Read)) 765 766 unlet g:Extend 767 unlet g:Read 768enddef 769 770def MakeArgRefs(theArg: string) 771 let local = 'loc_val' 772 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 773enddef 774 775def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 776 let local = 'the_loc' 777 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)} 778enddef 779 780def Test_closure_using_argument() 781 MakeArgRefs('arg_val') 782 assert_equal('arg_val/loc_val/call_val', g:UseArg('call_val')) 783 784 MakeArgRefsVarargs('arg_val', 'one', 'two') 785 assert_equal('arg_val/the_loc/call_val/one two', g:UseVararg('call_val')) 786 787 unlet g:UseArg 788 unlet g:UseVararg 789enddef 790 791def MakeGetAndAppendRefs() 792 let local = 'a' 793 794 def Append(arg: string) 795 local ..= arg 796 enddef 797 g:Append = Append 798 799 def Get(): string 800 return local 801 enddef 802 g:Get = Get 803enddef 804 805def Test_closure_append_get() 806 MakeGetAndAppendRefs() 807 assert_equal('a', g:Get()) 808 g:Append('-b') 809 assert_equal('a-b', g:Get()) 810 g:Append('-c') 811 assert_equal('a-b-c', g:Get()) 812 813 unlet g:Append 814 unlet g:Get 815enddef 816 817def Test_nested_closure() 818 let local = 'text' 819 def Closure(arg: string): string 820 return local .. arg 821 enddef 822 assert_equal('text!!!', Closure('!!!')) 823enddef 824 825func GetResult(Ref) 826 return a:Ref('some') 827endfunc 828 829def Test_call_closure_not_compiled() 830 let text = 'text' 831 g:Ref = {s -> s .. text} 832 assert_equal('sometext', GetResult(g:Ref)) 833enddef 834 835def Test_sort_return_type() 836 let res: list<number> 837 res = [1, 2, 3]->sort() 838enddef 839 840 841" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 842