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