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 Test_call_func_defined_later() 197 call assert_equal('one', g:DefinedLater('one')) 198 call assert_fails('call NotDefined("one")', 'E117:') 199enddef 200 201func DefinedLater(arg) 202 return a:arg 203endfunc 204 205def Test_call_funcref() 206 assert_equal(3, g:SomeFunc('abc')) 207 assert_fails('NotAFunc()', 'E117:') 208 assert_fails('g:NotAFunc()', 'E117:') 209enddef 210 211let SomeFunc = function('len') 212let NotAFunc = 'text' 213 214def CombineFuncrefTypes() 215 " same arguments, different return type 216 let Ref1: func(bool): string 217 let Ref2: func(bool): number 218 let Ref3: func(bool): any 219 Ref3 = g:cond ? Ref1 : Ref2 220 221 " different number of arguments 222 let Refa1: func(bool): number 223 let Refa2: func(bool, number): number 224 let Refa3: func: number 225 Refa3 = g:cond ? Refa1 : Refa2 226 227 " different argument types 228 let Refb1: func(bool, string): number 229 let Refb2: func(string, number): number 230 let Refb3: func(any, any): number 231 Refb3 = g:cond ? Refb1 : Refb2 232enddef 233 234def FuncWithForwardCall() 235 return g:DefinedEvenLater("yes") 236enddef 237 238def DefinedEvenLater(arg: string): string 239 return arg 240enddef 241 242def Test_error_in_nested_function() 243 " Error in called function requires unwinding the call stack. 244 assert_fails('call FuncWithForwardCall()', 'E1029') 245enddef 246 247def Test_return_type_wrong() 248 CheckScriptFailure(['def Func(): number', 'return "a"', 'enddef'], 'expected number but got string') 249 CheckScriptFailure(['def Func(): string', 'return 1', 'enddef'], 'expected string but got number') 250 CheckScriptFailure(['def Func(): void', 'return "a"', 'enddef'], 'expected void but got string') 251 CheckScriptFailure(['def Func()', 'return "a"', 'enddef'], 'expected void but got string') 252 253 CheckScriptFailure(['def Func(): number', 'return', 'enddef'], 'E1003:') 254 255 CheckScriptFailure(['def Func(): list', 'return []', 'enddef'], 'E1008:') 256 CheckScriptFailure(['def Func(): dict', 'return {}', 'enddef'], 'E1008:') 257 CheckScriptFailure(['def Func()', 'return 1'], 'E1057:') 258enddef 259 260def Test_arg_type_wrong() 261 CheckScriptFailure(['def Func3(items: list)', 'echo "a"', 'enddef'], 'E1008: Missing <type>') 262 CheckScriptFailure(['def Func4(...)', 'echo "a"', 'enddef'], 'E1055: Missing name after ...') 263 CheckScriptFailure(['def Func5(items:string)', 'echo "a"'], 'E1069:') 264 CheckScriptFailure(['def Func5(items)', 'echo "a"'], 'E1077:') 265enddef 266 267def Test_vim9script_call() 268 let lines =<< trim END 269 vim9script 270 let var = '' 271 def MyFunc(arg: string) 272 var = arg 273 enddef 274 MyFunc('foobar') 275 assert_equal('foobar', var) 276 277 let str = 'barfoo' 278 str->MyFunc() 279 assert_equal('barfoo', var) 280 281 let g:value = 'value' 282 g:value->MyFunc() 283 assert_equal('value', var) 284 285 let listvar = [] 286 def ListFunc(arg: list<number>) 287 listvar = arg 288 enddef 289 [1, 2, 3]->ListFunc() 290 assert_equal([1, 2, 3], listvar) 291 292 let dictvar = {} 293 def DictFunc(arg: dict<number>) 294 dictvar = arg 295 enddef 296 {'a': 1, 'b': 2}->DictFunc() 297 assert_equal(#{a: 1, b: 2}, dictvar) 298 def CompiledDict() 299 {'a': 3, 'b': 4}->DictFunc() 300 enddef 301 CompiledDict() 302 assert_equal(#{a: 3, b: 4}, dictvar) 303 304 #{a: 3, b: 4}->DictFunc() 305 assert_equal(#{a: 3, b: 4}, dictvar) 306 307 ('text')->MyFunc() 308 assert_equal('text', var) 309 ("some")->MyFunc() 310 assert_equal('some', var) 311 END 312 writefile(lines, 'Xcall.vim') 313 source Xcall.vim 314 delete('Xcall.vim') 315enddef 316 317def Test_vim9script_call_fail_decl() 318 let lines =<< trim END 319 vim9script 320 let var = '' 321 def MyFunc(arg: string) 322 let var = 123 323 enddef 324 END 325 writefile(lines, 'Xcall_decl.vim') 326 assert_fails('source Xcall_decl.vim', 'E1054:') 327 delete('Xcall_decl.vim') 328enddef 329 330def Test_vim9script_call_fail_const() 331 let lines =<< trim END 332 vim9script 333 const var = '' 334 def MyFunc(arg: string) 335 var = 'asdf' 336 enddef 337 END 338 writefile(lines, 'Xcall_const.vim') 339 assert_fails('source Xcall_const.vim', 'E46:') 340 delete('Xcall_const.vim') 341enddef 342 343" Test that inside :function a Python function can be defined, :def is not 344" recognized. 345func Test_function_python() 346 CheckFeature python3 347 let py = 'python3' 348 execute py "<< EOF" 349def do_something(): 350 return 1 351EOF 352endfunc 353 354def Test_delfunc() 355 let lines =<< trim END 356 vim9script 357 def g:GoneSoon() 358 echo 'hello' 359 enddef 360 361 def CallGoneSoon() 362 GoneSoon() 363 enddef 364 365 delfunc g:GoneSoon 366 CallGoneSoon() 367 END 368 writefile(lines, 'XToDelFunc') 369 assert_fails('so XToDelFunc', 'E933') 370 assert_fails('so XToDelFunc', 'E933') 371 372 delete('XToDelFunc') 373enddef 374 375def Test_redef_failure() 376 call writefile(['def Func0(): string', 'return "Func0"', 'enddef'], 'Xdef') 377 so Xdef 378 call writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') 379 so Xdef 380 call writefile(['def! Func0(): string', 'enddef'], 'Xdef') 381 call assert_fails('so Xdef', 'E1027:') 382 call writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') 383 so Xdef 384 call delete('Xdef') 385 386 call assert_equal(0, g:Func0()) 387 call assert_equal('Func1', g:Func1()) 388 call assert_equal('Func2', g:Func2()) 389 390 delfunc! Func0 391 delfunc! Func1 392 delfunc! Func2 393enddef 394 395def Test_vim9script_func() 396 let lines =<< trim END 397 vim9script 398 func Func(arg) 399 echo a:arg 400 endfunc 401 Func('text') 402 END 403 writefile(lines, 'XVim9Func') 404 so XVim9Func 405 406 delete('XVim9Func') 407enddef 408 409" Test for internal functions returning different types 410func Test_InternalFuncRetType() 411 let lines =<< trim END 412 def RetFloat(): float 413 return ceil(1.456) 414 enddef 415 416 def RetListAny(): list<any> 417 return items({'k' : 'v'}) 418 enddef 419 420 def RetListString(): list<string> 421 return split('a:b:c', ':') 422 enddef 423 424 def RetListDictAny(): list<dict<any>> 425 return getbufinfo() 426 enddef 427 428 def RetDictNumber(): dict<number> 429 return wordcount() 430 enddef 431 432 def RetDictString(): dict<string> 433 return environ() 434 enddef 435 END 436 call writefile(lines, 'Xscript') 437 source Xscript 438 439 call assert_equal(2.0, RetFloat()) 440 call assert_equal([['k', 'v']], RetListAny()) 441 call assert_equal(['a', 'b', 'c'], RetListString()) 442 call assert_notequal([], RetListDictAny()) 443 call assert_notequal({}, RetDictNumber()) 444 call assert_notequal({}, RetDictString()) 445 call delete('Xscript') 446endfunc 447 448" Test for passing too many or too few arguments to internal functions 449func Test_internalfunc_arg_error() 450 let l =<< trim END 451 def! FArgErr(): float 452 return ceil(1.1, 2) 453 enddef 454 END 455 call writefile(l, 'Xinvalidarg') 456 call assert_fails('so Xinvalidarg', 'E118:') 457 let l =<< trim END 458 def! FArgErr(): float 459 return ceil() 460 enddef 461 END 462 call writefile(l, 'Xinvalidarg') 463 call assert_fails('so Xinvalidarg', 'E119:') 464 call delete('Xinvalidarg') 465endfunc 466 467let s:funcResult = 0 468 469def FuncNoArgNoRet() 470 funcResult = 11 471enddef 472 473def FuncNoArgRetNumber(): number 474 funcResult = 22 475 return 1234 476enddef 477 478def FuncNoArgRetString(): string 479 funcResult = 45 480 return 'text' 481enddef 482 483def FuncOneArgNoRet(arg: number) 484 funcResult = arg 485enddef 486 487def FuncOneArgRetNumber(arg: number): number 488 funcResult = arg 489 return arg 490enddef 491 492def FuncTwoArgNoRet(one: bool, two: number) 493 funcResult = two 494enddef 495 496def FuncOneArgRetString(arg: string): string 497 return arg 498enddef 499 500def FuncOneArgRetAny(arg: any): any 501 return arg 502enddef 503 504def Test_func_type() 505 let Ref1: func() 506 funcResult = 0 507 Ref1 = FuncNoArgNoRet 508 Ref1() 509 assert_equal(11, funcResult) 510 511 let Ref2: func 512 funcResult = 0 513 Ref2 = FuncNoArgNoRet 514 Ref2() 515 assert_equal(11, funcResult) 516 517 funcResult = 0 518 Ref2 = FuncOneArgNoRet 519 Ref2(12) 520 assert_equal(12, funcResult) 521 522 funcResult = 0 523 Ref2 = FuncNoArgRetNumber 524 assert_equal(1234, Ref2()) 525 assert_equal(22, funcResult) 526 527 funcResult = 0 528 Ref2 = FuncOneArgRetNumber 529 assert_equal(13, Ref2(13)) 530 assert_equal(13, funcResult) 531enddef 532 533def Test_func_type_part() 534 let RefVoid: func: void 535 RefVoid = FuncNoArgNoRet 536 RefVoid = FuncOneArgNoRet 537 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 538 CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string') 539 540 let RefAny: func(): any 541 RefAny = FuncNoArgRetNumber 542 RefAny = FuncNoArgRetString 543 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): any but got func()') 544 CheckDefFailure(['let RefAny: func(): any', 'RefAny = FuncOneArgNoRet'], 'E1013: type mismatch, expected func(): any but got func(number)') 545 546 let RefNr: func: number 547 RefNr = FuncNoArgRetNumber 548 RefNr = FuncOneArgRetNumber 549 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()') 550 CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string') 551 552 let RefStr: func: string 553 RefStr = FuncNoArgRetString 554 RefStr = FuncOneArgRetString 555 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): string but got func()') 556 CheckDefFailure(['let RefStr: func: string', 'RefStr = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func(): string but got func(): number') 557enddef 558 559def Test_func_type_fails() 560 CheckDefFailure(['let ref1: func()'], 'E704:') 561 562 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number') 563 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)') 564 CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number') 565 CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)') 566 CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)') 567 CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)') 568 569 call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:') 570 call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:') 571 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:') 572 call CheckDefFailure(['let RefWrong: func(bool):string'], 'E1069:') 573enddef 574 575def Test_func_return_type() 576 let nr: number 577 nr = FuncNoArgRetNumber() 578 assert_equal(1234, nr) 579 580 nr = FuncOneArgRetAny(122) 581 assert_equal(122, nr) 582 583 let str: string 584 str = FuncOneArgRetAny('yes') 585 assert_equal('yes', str) 586 587 CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1013: type mismatch, expected string but got number') 588enddef 589 590def MultiLine( 591 arg1: string, 592 arg2 = 1234, 593 ...rest: list<string> 594 ): string 595 return arg1 .. arg2 .. join(rest, '-') 596enddef 597 598def MultiLineComment( 599 arg1: string, # comment 600 arg2 = 1234, # comment 601 ...rest: list<string> # comment 602 ): string # comment 603 return arg1 .. arg2 .. join(rest, '-') 604enddef 605 606def Test_multiline() 607 assert_equal('text1234', MultiLine('text')) 608 assert_equal('text777', MultiLine('text', 777)) 609 assert_equal('text777one', MultiLine('text', 777, 'one')) 610 assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 611enddef 612 613func Test_multiline_not_vim9() 614 call assert_equal('text1234', MultiLine('text')) 615 call assert_equal('text777', MultiLine('text', 777)) 616 call assert_equal('text777one', MultiLine('text', 777, 'one')) 617 call assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) 618endfunc 619 620 621" When using CheckScriptFailure() for the below test, E1010 is generated instead 622" of E1056. 623func Test_E1056_1059() 624 let caught_1056 = 0 625 try 626 def F(): 627 return 1 628 enddef 629 catch /E1056:/ 630 let caught_1056 = 1 631 endtry 632 call assert_equal(1, caught_1056) 633 634 let caught_1059 = 0 635 try 636 def F5(items : list) 637 echo 'a' 638 enddef 639 catch /E1059:/ 640 let caught_1059 = 1 641 endtry 642 call assert_equal(1, caught_1059) 643endfunc 644 645func DelMe() 646 echo 'DelMe' 647endfunc 648 649def Test_deleted_function() 650 CheckDefExecFailure([ 651 'let RefMe: func = function("g:DelMe")', 652 'delfunc g:DelMe', 653 'echo RefMe()'], 'E117:') 654enddef 655 656def Test_unknown_function() 657 CheckDefExecFailure([ 658 'let Ref: func = function("NotExist")', 659 'delfunc g:NotExist'], 'E130:') 660enddef 661 662def RefFunc(Ref: func(string): string): string 663 return Ref('more') 664enddef 665 666def Test_closure_simple() 667 let local = 'some ' 668 assert_equal('some more', RefFunc({s -> local .. s})) 669enddef 670 671def MakeRef() 672 let local = 'some ' 673 g:Ref = {s -> local .. s} 674enddef 675 676def Test_closure_ref_after_return() 677 MakeRef() 678 assert_equal('some thing', g:Ref('thing')) 679 unlet g:Ref 680enddef 681 682def MakeTwoRefs() 683 let local = ['some'] 684 g:Extend = {s -> local->add(s)} 685 g:Read = {-> local} 686enddef 687 688def Test_closure_two_refs() 689 MakeTwoRefs() 690 assert_equal('some', join(g:Read(), ' ')) 691 g:Extend('more') 692 assert_equal('some more', join(g:Read(), ' ')) 693 g:Extend('even') 694 assert_equal('some more even', join(g:Read(), ' ')) 695 696 unlet g:Extend 697 unlet g:Read 698enddef 699 700def ReadRef(Ref: func(): list<string>): string 701 return join(Ref(), ' ') 702enddef 703 704def ExtendRef(Ref: func(string), add: string) 705 Ref(add) 706enddef 707 708def Test_closure_two_indirect_refs() 709 MakeTwoRefs() 710 assert_equal('some', ReadRef(g:Read)) 711 ExtendRef(g:Extend, 'more') 712 assert_equal('some more', ReadRef(g:Read)) 713 ExtendRef(g:Extend, 'even') 714 assert_equal('some more even', ReadRef(g:Read)) 715 716 unlet g:Extend 717 unlet g:Read 718enddef 719 720def MakeArgRefs(theArg: string) 721 let local = 'loc_val' 722 g:UseArg = {s -> theArg .. '/' .. local .. '/' .. s} 723enddef 724 725def MakeArgRefsVarargs(theArg: string, ...rest: list<string>) 726 let local = 'the_loc' 727 g:UseVararg = {s -> theArg .. '/' .. local .. '/' .. s .. '/' .. join(rest)} 728enddef 729 730def Test_closure_using_argument() 731 MakeArgRefs('arg_val') 732 assert_equal('arg_val/loc_val/call_val', g:UseArg('call_val')) 733 734 MakeArgRefsVarargs('arg_val', 'one', 'two') 735 assert_equal('arg_val/the_loc/call_val/one two', g:UseVararg('call_val')) 736 737 unlet g:UseArg 738 unlet g:UseVararg 739enddef 740 741def MakeGetAndAppendRefs() 742 let local = 'a' 743 744 def Append(arg: string) 745 local ..= arg 746 enddef 747 g:Append = Append 748 749 def Get(): string 750 return local 751 enddef 752 g:Get = Get 753enddef 754 755def Test_closure_append_get() 756 MakeGetAndAppendRefs() 757 assert_equal('a', g:Get()) 758 g:Append('-b') 759 assert_equal('a-b', g:Get()) 760 g:Append('-c') 761 assert_equal('a-b-c', g:Get()) 762 763 unlet g:Append 764 unlet g:Get 765enddef 766 767def Test_nested_closure() 768 let local = 'text' 769 def Closure(arg: string): string 770 return local .. arg 771 enddef 772 assert_equal('text!!!', Closure('!!!')) 773enddef 774 775 776" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 777