1" Test various aspects of the Vim script language. 2" Most of this was formerly in test49. 3 4source check.vim 5source shared.vim 6 7"------------------------------------------------------------------------------- 8" Test environment {{{1 9"------------------------------------------------------------------------------- 10 11com! XpathINIT let g:Xpath = '' 12com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args> 13 14" Append a message to the "messages" file 15func Xout(text) 16 split messages 17 $put =a:text 18 wq 19endfunc 20 21com! -nargs=1 Xout call Xout(<args>) 22 23" MakeScript() - Make a script file from a function. {{{2 24" 25" Create a script that consists of the body of the function a:funcname. 26" Replace any ":return" by a ":finish", any argument variable by a global 27" variable, and every ":call" by a ":source" for the next following argument 28" in the variable argument list. This function is useful if similar tests are 29" to be made for a ":return" from a function call or a ":finish" in a script 30" file. 31func MakeScript(funcname, ...) 32 let script = tempname() 33 execute "redir! >" . script 34 execute "function" a:funcname 35 redir END 36 execute "edit" script 37 " Delete the "function" and the "endfunction" lines. Do not include the 38 " word "function" in the pattern since it might be translated if LANG is 39 " set. When MakeScript() is being debugged, this deletes also the debugging 40 " output of its line 3 and 4. 41 exec '1,/.*' . a:funcname . '(.*)/d' 42 /^\d*\s*endfunction\>/,$d 43 %s/^\d*//e 44 %s/return/finish/e 45 %s/\<a:\(\h\w*\)/g:\1/ge 46 normal gg0 47 let cnt = 0 48 while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0 49 let cnt = cnt + 1 50 s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/ 51 endwhile 52 g/^\s*$/d 53 write 54 bwipeout 55 return script 56endfunc 57 58" ExecAsScript - Source a temporary script made from a function. {{{2 59" 60" Make a temporary script file from the function a:funcname, ":source" it, and 61" delete it afterwards. However, if an exception is thrown the file may remain, 62" the caller should call DeleteTheScript() afterwards. 63let s:script_name = '' 64function! ExecAsScript(funcname) 65 " Make a script from the function passed as argument. 66 let s:script_name = MakeScript(a:funcname) 67 68 " Source and delete the script. 69 exec "source" s:script_name 70 call delete(s:script_name) 71 let s:script_name = '' 72endfunction 73 74function! DeleteTheScript() 75 if s:script_name 76 call delete(s:script_name) 77 let s:script_name = '' 78 endif 79endfunc 80 81com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>) 82 83 84"------------------------------------------------------------------------------- 85" Test 1: :endwhile in function {{{1 86" 87" Detect if a broken loop is (incorrectly) reactivated by the 88" :endwhile. Use a :return to prevent an endless loop, and make 89" this test first to get a meaningful result on an error before other 90" tests will hang. 91"------------------------------------------------------------------------------- 92 93function! T1_F() 94 Xpath 'a' 95 let first = 1 96 while 1 97 Xpath 'b' 98 if first 99 Xpath 'c' 100 let first = 0 101 break 102 else 103 Xpath 'd' 104 return 105 endif 106 endwhile 107endfunction 108 109function! T1_G() 110 Xpath 'h' 111 let first = 1 112 while 1 113 Xpath 'i' 114 if first 115 Xpath 'j' 116 let first = 0 117 break 118 else 119 Xpath 'k' 120 return 121 endif 122 if 1 " unmatched :if 123 endwhile 124endfunction 125 126func Test_endwhile_function() 127 XpathINIT 128 call T1_F() 129 Xpath 'F' 130 131 try 132 call T1_G() 133 catch 134 " Catch missing :endif 135 call assert_true(v:exception =~ 'E171') 136 Xpath 'x' 137 endtry 138 Xpath 'G' 139 140 call assert_equal('abcFhijxG', g:Xpath) 141endfunc 142 143"------------------------------------------------------------------------------- 144" Test 2: :endwhile in script {{{1 145" 146" Detect if a broken loop is (incorrectly) reactivated by the 147" :endwhile. Use a :finish to prevent an endless loop, and place 148" this test before others that might hang to get a meaningful result 149" on an error. 150" 151" This test executes the bodies of the functions T1_F and T1_G from 152" the previous test as script files (:return replaced by :finish). 153"------------------------------------------------------------------------------- 154 155func Test_endwhile_script() 156 XpathINIT 157 ExecAsScript T1_F 158 Xpath 'F' 159 call DeleteTheScript() 160 161 try 162 ExecAsScript T1_G 163 catch 164 " Catch missing :endif 165 call assert_true(v:exception =~ 'E171') 166 Xpath 'x' 167 endtry 168 Xpath 'G' 169 call DeleteTheScript() 170 171 call assert_equal('abcFhijxG', g:Xpath) 172endfunc 173 174"------------------------------------------------------------------------------- 175" Test 3: :if, :elseif, :while, :continue, :break {{{1 176"------------------------------------------------------------------------------- 177 178function Test_if_while() 179 XpathINIT 180 if 1 181 Xpath 'a' 182 let loops = 3 183 while loops > -1 " main loop: loops == 3, 2, 1 (which breaks) 184 if loops <= 0 185 let break_err = 1 186 let loops = -1 187 else 188 Xpath 'b' . loops 189 endif 190 if (loops == 2) 191 while loops == 2 " dummy loop 192 Xpath 'c' . loops 193 let loops = loops - 1 194 continue " stop dummy loop 195 Xpath 'd' . loops 196 endwhile 197 continue " continue main loop 198 Xpath 'e' . loops 199 elseif (loops == 1) 200 let p = 1 201 while p " dummy loop 202 Xpath 'f' . loops 203 let p = 0 204 break " break dummy loop 205 Xpath 'g' . loops 206 endwhile 207 Xpath 'h' . loops 208 unlet p 209 break " break main loop 210 Xpath 'i' . loops 211 endif 212 if (loops > 0) 213 Xpath 'j' . loops 214 endif 215 while loops == 3 " dummy loop 216 let loops = loops - 1 217 endwhile " end dummy loop 218 endwhile " end main loop 219 Xpath 'k' 220 else 221 Xpath 'l' 222 endif 223 Xpath 'm' 224 if exists("break_err") 225 Xpath 'm' 226 unlet break_err 227 endif 228 229 unlet loops 230 231 call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath) 232endfunc 233 234"------------------------------------------------------------------------------- 235" Test 4: :return {{{1 236"------------------------------------------------------------------------------- 237 238function! T4_F() 239 if 1 240 Xpath 'a' 241 let loops = 3 242 while loops > 0 " 3: 2: 1: 243 Xpath 'b' . loops 244 if (loops == 2) 245 Xpath 'c' . loops 246 return 247 Xpath 'd' . loops 248 endif 249 Xpath 'e' . loops 250 let loops = loops - 1 251 endwhile 252 Xpath 'f' 253 else 254 Xpath 'g' 255 endif 256endfunction 257 258function Test_return() 259 XpathINIT 260 call T4_F() 261 Xpath '4' 262 263 call assert_equal('ab3e3b2c24', g:Xpath) 264endfunction 265 266 267"------------------------------------------------------------------------------- 268" Test 5: :finish {{{1 269" 270" This test executes the body of the function T4_F from the previous 271" test as a script file (:return replaced by :finish). 272"------------------------------------------------------------------------------- 273 274function Test_finish() 275 XpathINIT 276 ExecAsScript T4_F 277 Xpath '5' 278 call DeleteTheScript() 279 280 call assert_equal('ab3e3b2c25', g:Xpath) 281endfunction 282 283 284 285"------------------------------------------------------------------------------- 286" Test 6: Defining functions in :while loops {{{1 287" 288" Functions can be defined inside other functions. An inner function 289" gets defined when the outer function is executed. Functions may 290" also be defined inside while loops. Expressions in braces for 291" defining the function name are allowed. 292" 293" The functions are defined when sourcing the script, only the 294" resulting path is checked in the test function. 295"------------------------------------------------------------------------------- 296 297XpathINIT 298 299" The command CALL collects the argument of all its invocations in "calls" 300" when used from a function (that is, when the global variable "calls" needs 301" the "g:" prefix). This is to check that the function code is skipped when 302" the function is defined. For inner functions, do so only if the outer 303" function is not being executed. 304" 305let calls = "" 306com! -nargs=1 CALL 307 \ if !exists("calls") && !exists("outer") | 308 \ let g:calls = g:calls . <args> | 309 \ endif 310 311let i = 0 312while i < 3 313 let i = i + 1 314 if i == 1 315 Xpath 'a' 316 function! F1(arg) 317 CALL a:arg 318 let outer = 1 319 320 let j = 0 321 while j < 1 322 Xpath 'b' 323 let j = j + 1 324 function! G1(arg) 325 CALL a:arg 326 endfunction 327 Xpath 'c' 328 endwhile 329 endfunction 330 Xpath 'd' 331 332 continue 333 endif 334 335 Xpath 'e' . i 336 function! F{i}(i, arg) 337 CALL a:arg 338 let outer = 1 339 340 if a:i == 3 341 Xpath 'f' 342 endif 343 let k = 0 344 while k < 3 345 Xpath 'g' . k 346 let k = k + 1 347 function! G{a:i}{k}(arg) 348 CALL a:arg 349 endfunction 350 Xpath 'h' . k 351 endwhile 352 endfunction 353 Xpath 'i' 354 355endwhile 356 357if exists("*G1") 358 Xpath 'j' 359endif 360if exists("*F1") 361 call F1("F1") 362 if exists("*G1") 363 call G1("G1") 364 endif 365endif 366 367if exists("G21") || exists("G22") || exists("G23") 368 Xpath 'k' 369endif 370if exists("*F2") 371 call F2(2, "F2") 372 if exists("*G21") 373 call G21("G21") 374 endif 375 if exists("*G22") 376 call G22("G22") 377 endif 378 if exists("*G23") 379 call G23("G23") 380 endif 381endif 382 383if exists("G31") || exists("G32") || exists("G33") 384 Xpath 'l' 385endif 386if exists("*F3") 387 call F3(3, "F3") 388 if exists("*G31") 389 call G31("G31") 390 endif 391 if exists("*G32") 392 call G32("G32") 393 endif 394 if exists("*G33") 395 call G33("G33") 396 endif 397endif 398 399Xpath 'm' 400 401let g:test6_result = g:Xpath 402let g:test6_calls = calls 403 404unlet calls 405delfunction F1 406delfunction G1 407delfunction F2 408delfunction G21 409delfunction G22 410delfunction G23 411delfunction G31 412delfunction G32 413delfunction G33 414 415function Test_defining_functions() 416 call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result) 417 call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls) 418endfunc 419 420"------------------------------------------------------------------------------- 421" Test 7: Continuing on errors outside functions {{{1 422" 423" On an error outside a function, the script processing continues 424" at the line following the outermost :endif or :endwhile. When not 425" inside an :if or :while, the script processing continues at the next 426" line. 427"------------------------------------------------------------------------------- 428 429XpathINIT 430 431if 1 432 Xpath 'a' 433 while 1 434 Xpath 'b' 435 asdf 436 Xpath 'c' 437 break 438 endwhile | Xpath 'd' 439 Xpath 'e' 440endif | Xpath 'f' 441Xpath 'g' 442 443while 1 444 Xpath 'h' 445 if 1 446 Xpath 'i' 447 asdf 448 Xpath 'j' 449 endif | Xpath 'k' 450 Xpath 'l' 451 break 452endwhile | Xpath 'm' 453Xpath 'n' 454 455asdf 456Xpath 'o' 457 458asdf | Xpath 'p' 459Xpath 'q' 460 461let g:test7_result = g:Xpath 462 463func Test_error_in_script() 464 call assert_equal('abghinoq', g:test7_result) 465endfunc 466 467"------------------------------------------------------------------------------- 468" Test 8: Aborting and continuing on errors inside functions {{{1 469" 470" On an error inside a function without the "abort" attribute, the 471" script processing continues at the next line (unless the error was 472" in a :return command). On an error inside a function with the 473" "abort" attribute, the function is aborted and the script processing 474" continues after the function call; the value -1 is returned then. 475"------------------------------------------------------------------------------- 476 477XpathINIT 478 479function! T8_F() 480 if 1 481 Xpath 'a' 482 while 1 483 Xpath 'b' 484 asdf 485 Xpath 'c' 486 asdf | Xpath 'd' 487 Xpath 'e' 488 break 489 endwhile 490 Xpath 'f' 491 endif | Xpath 'g' 492 Xpath 'h' 493 494 while 1 495 Xpath 'i' 496 if 1 497 Xpath 'j' 498 asdf 499 Xpath 'k' 500 asdf | Xpath 'l' 501 Xpath 'm' 502 endif 503 Xpath 'n' 504 break 505 endwhile | Xpath 'o' 506 Xpath 'p' 507 508 return novar " returns (default return value 0) 509 Xpath 'q' 510 return 1 " not reached 511endfunction 512 513function! T8_G() abort 514 if 1 515 Xpath 'r' 516 while 1 517 Xpath 's' 518 asdf " returns -1 519 Xpath 't' 520 break 521 endwhile 522 Xpath 'v' 523 endif | Xpath 'w' 524 Xpath 'x' 525 526 return -4 " not reached 527endfunction 528 529function! T8_H() abort 530 while 1 531 Xpath 'A' 532 if 1 533 Xpath 'B' 534 asdf " returns -1 535 Xpath 'C' 536 endif 537 Xpath 'D' 538 break 539 endwhile | Xpath 'E' 540 Xpath 'F' 541 542 return -4 " not reached 543endfunction 544 545" Aborted functions (T8_G and T8_H) return -1. 546let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H() 547Xpath 'X' 548let g:test8_result = g:Xpath 549 550func Test_error_in_function() 551 call assert_equal(13, g:test8_sum) 552 call assert_equal('abcefghijkmnoprsABX', g:test8_result) 553 554 delfunction T8_F 555 delfunction T8_G 556 delfunction T8_H 557endfunc 558 559 560"------------------------------------------------------------------------------- 561" Test 9: Continuing after aborted functions {{{1 562" 563" When a function with the "abort" attribute is aborted due to an 564" error, the next function back in the call hierarchy without an 565" "abort" attribute continues; the value -1 is returned then. 566"------------------------------------------------------------------------------- 567 568XpathINIT 569 570function! F() abort 571 Xpath 'a' 572 let result = G() " not aborted 573 Xpath 'b' 574 if result != 2 575 Xpath 'c' 576 endif 577 return 1 578endfunction 579 580function! G() " no abort attribute 581 Xpath 'd' 582 if H() != -1 " aborted 583 Xpath 'e' 584 endif 585 Xpath 'f' 586 return 2 587endfunction 588 589function! H() abort 590 Xpath 'g' 591 call I() " aborted 592 Xpath 'h' 593 return 4 594endfunction 595 596function! I() abort 597 Xpath 'i' 598 asdf " error 599 Xpath 'j' 600 return 8 601endfunction 602 603if F() != 1 604 Xpath 'k' 605endif 606 607let g:test9_result = g:Xpath 608 609delfunction F 610delfunction G 611delfunction H 612delfunction I 613 614func Test_func_abort() 615 call assert_equal('adgifb', g:test9_result) 616endfunc 617 618 619"------------------------------------------------------------------------------- 620" Test 10: :if, :elseif, :while argument parsing {{{1 621" 622" A '"' or '|' in an argument expression must not be mixed up with 623" a comment or a next command after a bar. Parsing errors should 624" be recognized. 625"------------------------------------------------------------------------------- 626 627XpathINIT 628 629function! MSG(enr, emsg) 630 let english = v:lang == "C" || v:lang =~ '^[Ee]n' 631 if a:enr == "" 632 Xout "TODO: Add message number for:" a:emsg 633 let v:errmsg = ":" . v:errmsg 634 endif 635 let match = 1 636 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) 637 let match = 0 638 if v:errmsg == "" 639 Xout "Message missing." 640 else 641 let v:errmsg = v:errmsg->escape('"') 642 Xout "Unexpected message:" v:errmsg 643 endif 644 endif 645 return match 646endfunc 647 648if 1 || strlen("\"") | Xpath 'a' 649 Xpath 'b' 650endif 651Xpath 'c' 652 653if 0 654elseif 1 || strlen("\"") | Xpath 'd' 655 Xpath 'e' 656endif 657Xpath 'f' 658 659while 1 || strlen("\"") | Xpath 'g' 660 Xpath 'h' 661 break 662endwhile 663Xpath 'i' 664 665let v:errmsg = "" 666if 1 ||| strlen("\"") | Xpath 'j' 667 Xpath 'k' 668endif 669Xpath 'l' 670if !MSG('E15', "Invalid expression") 671 Xpath 'm' 672endif 673 674let v:errmsg = "" 675if 0 676elseif 1 ||| strlen("\"") | Xpath 'n' 677 Xpath 'o' 678endif 679Xpath 'p' 680if !MSG('E15', "Invalid expression") 681 Xpath 'q' 682endif 683 684let v:errmsg = "" 685while 1 ||| strlen("\"") | Xpath 'r' 686 Xpath 's' 687 break 688endwhile 689Xpath 't' 690if !MSG('E15', "Invalid expression") 691 Xpath 'u' 692endif 693 694let g:test10_result = g:Xpath 695delfunction MSG 696 697func Test_expr_parsing() 698 call assert_equal('abcdefghilpt', g:test10_result) 699endfunc 700 701 702"------------------------------------------------------------------------------- 703" Test 11: :if, :elseif, :while argument evaluation after abort {{{1 704" 705" When code is skipped over due to an error, the boolean argument to 706" an :if, :elseif, or :while must not be evaluated. 707"------------------------------------------------------------------------------- 708 709XpathINIT 710 711let calls = 0 712 713function! P(num) 714 let g:calls = g:calls + a:num " side effect on call 715 return 0 716endfunction 717 718if 1 719 Xpath 'a' 720 asdf " error 721 Xpath 'b' 722 if P(1) " should not be called 723 Xpath 'c' 724 elseif !P(2) " should not be called 725 Xpath 'd' 726 else 727 Xpath 'e' 728 endif 729 Xpath 'f' 730 while P(4) " should not be called 731 Xpath 'g' 732 endwhile 733 Xpath 'h' 734endif 735Xpath 'x' 736 737let g:test11_calls = calls 738let g:test11_result = g:Xpath 739 740unlet calls 741delfunction P 742 743func Test_arg_abort() 744 call assert_equal(0, g:test11_calls) 745 call assert_equal('ax', g:test11_result) 746endfunc 747 748 749"------------------------------------------------------------------------------- 750" Test 12: Expressions in braces in skipped code {{{1 751" 752" In code skipped over due to an error or inactive conditional, 753" an expression in braces as part of a variable or function name 754" should not be evaluated. 755"------------------------------------------------------------------------------- 756 757XpathINIT 758 759function! NULL() 760 Xpath 'a' 761 return 0 762endfunction 763 764function! ZERO() 765 Xpath 'b' 766 return 0 767endfunction 768 769function! F0() 770 Xpath 'c' 771endfunction 772 773function! F1(arg) 774 Xpath 'e' 775endfunction 776 777let V0 = 1 778 779Xpath 'f' 780echo 0 ? F{NULL() + V{ZERO()}}() : 1 781 782Xpath 'g' 783if 0 784 Xpath 'h' 785 call F{NULL() + V{ZERO()}}() 786endif 787 788Xpath 'i' 789if 1 790 asdf " error 791 Xpath 'j' 792 call F1(F{NULL() + V{ZERO()}}()) 793endif 794 795Xpath 'k' 796if 1 797 asdf " error 798 Xpath 'l' 799 call F{NULL() + V{ZERO()}}() 800endif 801 802let g:test12_result = g:Xpath 803 804func Test_braces_skipped() 805 call assert_equal('fgik', g:test12_result) 806endfunc 807 808 809"------------------------------------------------------------------------------- 810" Test 13: Failure in argument evaluation for :while {{{1 811" 812" A failure in the expression evaluation for the condition of a :while 813" causes the whole :while loop until the matching :endwhile being 814" ignored. Continuation is at the next following line. 815"------------------------------------------------------------------------------- 816 817XpathINIT 818 819Xpath 'a' 820while asdf 821 Xpath 'b' 822 while 1 823 Xpath 'c' 824 break 825 endwhile 826 Xpath 'd' 827 break 828endwhile 829Xpath 'e' 830 831while asdf | Xpath 'f' | endwhile | Xpath 'g' 832Xpath 'h' 833let g:test13_result = g:Xpath 834 835func Test_while_fail() 836 call assert_equal('aeh', g:test13_result) 837endfunc 838 839 840"------------------------------------------------------------------------------- 841" Test 14: Failure in argument evaluation for :if {{{1 842" 843" A failure in the expression evaluation for the condition of an :if 844" does not cause the corresponding :else or :endif being matched to 845" a previous :if/:elseif. Neither of both branches of the failed :if 846" are executed. 847"------------------------------------------------------------------------------- 848 849XpathINIT 850 851function! F() 852 Xpath 'a' 853 let x = 0 854 if x " false 855 Xpath 'b' 856 elseif !x " always true 857 Xpath 'c' 858 let x = 1 859 if g:boolvar " possibly undefined 860 Xpath 'd' 861 else 862 Xpath 'e' 863 endif 864 Xpath 'f' 865 elseif x " never executed 866 Xpath 'g' 867 endif 868 Xpath 'h' 869endfunction 870 871let boolvar = 1 872call F() 873Xpath '-' 874 875unlet boolvar 876call F() 877let g:test14_result = g:Xpath 878 879delfunction F 880 881func Test_if_fail() 882 call assert_equal('acdfh-acfh', g:test14_result) 883endfunc 884 885 886"------------------------------------------------------------------------------- 887" Test 15: Failure in argument evaluation for :if (bar) {{{1 888" 889" Like previous test, except that the failing :if ... | ... | :endif 890" is in a single line. 891"------------------------------------------------------------------------------- 892 893XpathINIT 894 895function! F() 896 Xpath 'a' 897 let x = 0 898 if x " false 899 Xpath 'b' 900 elseif !x " always true 901 Xpath 'c' 902 let x = 1 903 if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif 904 Xpath 'f' 905 elseif x " never executed 906 Xpath 'g' 907 endif 908 Xpath 'h' 909endfunction 910 911let boolvar = 1 912call F() 913Xpath '-' 914 915unlet boolvar 916call F() 917let g:test15_result = g:Xpath 918 919delfunction F 920 921func Test_if_bar_fail() 922 call assert_equal('acdfh-acfh', g:test15_result) 923endfunc 924 925"------------------------------------------------------------------------------- 926" Test 90: Recognizing {} in variable name. {{{1 927"------------------------------------------------------------------------------- 928 929func Test_curlies() 930 let s:var = 66 931 let ns = 's' 932 call assert_equal(66, {ns}:var) 933 934 let g:a = {} 935 let g:b = 't' 936 let g:a[g:b] = 77 937 call assert_equal(77, g:a['t']) 938endfunc 939 940"------------------------------------------------------------------------------- 941" Test 91: using type(). {{{1 942"------------------------------------------------------------------------------- 943 944func Test_type() 945 call assert_equal(0, type(0)) 946 call assert_equal(1, type("")) 947 call assert_equal(2, type(function("tr"))) 948 call assert_equal(2, type(function("tr", [8]))) 949 call assert_equal(3, type([])) 950 call assert_equal(4, type({})) 951 call assert_equal(5, type(0.0)) 952 call assert_equal(6, type(v:false)) 953 call assert_equal(6, type(v:true)) 954 call assert_equal(7, type(v:none)) 955 call assert_equal(7, type(v:null)) 956 call assert_equal(8, v:t_job) 957 call assert_equal(9, v:t_channel) 958 call assert_equal(v:t_number, type(0)) 959 call assert_equal(v:t_string, type("")) 960 call assert_equal(v:t_func, type(function("tr"))) 961 call assert_equal(v:t_func, type(function("tr", [8]))) 962 call assert_equal(v:t_list, type([])) 963 call assert_equal(v:t_dict, type({})) 964 call assert_equal(v:t_float, type(0.0)) 965 call assert_equal(v:t_bool, type(v:false)) 966 call assert_equal(v:t_bool, type(v:true)) 967 call assert_equal(v:t_none, type(v:none)) 968 call assert_equal(v:t_none, type(v:null)) 969 970 971 call assert_equal(0, 0 + v:false) 972 call assert_equal(1, 0 + v:true) 973 call assert_equal(0, 0 + v:none) 974 call assert_equal(0, 0 + v:null) 975 976 call assert_equal('v:false', '' . v:false) 977 call assert_equal('v:true', '' . v:true) 978 call assert_equal('v:none', '' . v:none) 979 call assert_equal('v:null', '' . v:null) 980 981 call assert_true(v:false == 0) 982 call assert_false(v:false != 0) 983 call assert_true(v:true == 1) 984 call assert_false(v:true != 1) 985 call assert_false(v:true == v:false) 986 call assert_true(v:true != v:false) 987 988 call assert_true(v:null == 0) 989 call assert_false(v:null != 0) 990 call assert_true(v:none == 0) 991 call assert_false(v:none != 0) 992 993 call assert_true(v:false is v:false) 994 call assert_true(v:true is v:true) 995 call assert_true(v:none is v:none) 996 call assert_true(v:null is v:null) 997 998 call assert_false(v:false isnot v:false) 999 call assert_false(v:true isnot v:true) 1000 call assert_false(v:none isnot v:none) 1001 call assert_false(v:null isnot v:null) 1002 1003 call assert_false(v:false is 0) 1004 call assert_false(v:true is 1) 1005 call assert_false(v:true is v:false) 1006 call assert_false(v:none is 0) 1007 call assert_false(v:null is 0) 1008 call assert_false(v:null is v:none) 1009 1010 call assert_true(v:false isnot 0) 1011 call assert_true(v:true isnot 1) 1012 call assert_true(v:true isnot v:false) 1013 call assert_true(v:none isnot 0) 1014 call assert_true(v:null isnot 0) 1015 call assert_true(v:null isnot v:none) 1016 1017 call assert_equal(v:false, eval(string(v:false))) 1018 call assert_equal(v:true, eval(string(v:true))) 1019 call assert_equal(v:none, eval(string(v:none))) 1020 call assert_equal(v:null, eval(string(v:null))) 1021 1022 call assert_equal(v:false, copy(v:false)) 1023 call assert_equal(v:true, copy(v:true)) 1024 call assert_equal(v:none, copy(v:none)) 1025 call assert_equal(v:null, copy(v:null)) 1026 1027 call assert_equal([v:false], deepcopy([v:false])) 1028 call assert_equal([v:true], deepcopy([v:true])) 1029 call assert_equal([v:none], deepcopy([v:none])) 1030 call assert_equal([v:null], deepcopy([v:null])) 1031 1032 call assert_true(empty(v:false)) 1033 call assert_false(empty(v:true)) 1034 call assert_true(empty(v:null)) 1035 call assert_true(empty(v:none)) 1036 1037 func ChangeYourMind() 1038 try 1039 return v:true 1040 finally 1041 return 'something else' 1042 endtry 1043 endfunc 1044 1045 call ChangeYourMind() 1046endfunc 1047 1048"------------------------------------------------------------------------------- 1049" Test 92: skipping code {{{1 1050"------------------------------------------------------------------------------- 1051 1052func Test_skip() 1053 let Fn = function('Test_type') 1054 call assert_false(0 && Fn[1]) 1055 call assert_false(0 && string(Fn)) 1056 call assert_false(0 && len(Fn)) 1057 let l = [] 1058 call assert_false(0 && l[1]) 1059 call assert_false(0 && string(l)) 1060 call assert_false(0 && len(l)) 1061 let f = 1.0 1062 call assert_false(0 && f[1]) 1063 call assert_false(0 && string(f)) 1064 call assert_false(0 && len(f)) 1065 let sp = v:null 1066 call assert_false(0 && sp[1]) 1067 call assert_false(0 && string(sp)) 1068 call assert_false(0 && len(sp)) 1069 1070endfunc 1071 1072"------------------------------------------------------------------------------- 1073" Test 93: :echo and string() {{{1 1074"------------------------------------------------------------------------------- 1075 1076func Test_echo_and_string() 1077 " String 1078 let a = 'foo bar' 1079 redir => result 1080 echo a 1081 echo string(a) 1082 redir END 1083 let l = split(result, "\n") 1084 call assert_equal(["foo bar", 1085 \ "'foo bar'"], l) 1086 1087 " Float 1088 if has('float') 1089 let a = -1.2e0 1090 redir => result 1091 echo a 1092 echo string(a) 1093 redir END 1094 let l = split(result, "\n") 1095 call assert_equal(["-1.2", 1096 \ "-1.2"], l) 1097 endif 1098 1099 " Funcref 1100 redir => result 1101 echo function('string') 1102 echo string(function('string')) 1103 redir END 1104 let l = split(result, "\n") 1105 call assert_equal(["string", 1106 \ "function('string')"], l) 1107 1108 " Recursive dictionary 1109 let a = {} 1110 let a["a"] = a 1111 redir => result 1112 echo a 1113 echo string(a) 1114 redir END 1115 let l = split(result, "\n") 1116 call assert_equal(["{'a': {...}}", 1117 \ "{'a': {...}}"], l) 1118 1119 " Recursive list 1120 let a = [0] 1121 let a[0] = a 1122 redir => result 1123 echo a 1124 echo string(a) 1125 redir END 1126 let l = split(result, "\n") 1127 call assert_equal(["[[...]]", 1128 \ "[[...]]"], l) 1129 1130 " Empty dictionaries in a list 1131 let a = {} 1132 redir => result 1133 echo [a, a, a] 1134 echo string([a, a, a]) 1135 redir END 1136 let l = split(result, "\n") 1137 call assert_equal(["[{}, {}, {}]", 1138 \ "[{}, {}, {}]"], l) 1139 1140 " Empty dictionaries in a dictionary 1141 let a = {} 1142 let b = {"a": a, "b": a} 1143 redir => result 1144 echo b 1145 echo string(b) 1146 redir END 1147 let l = split(result, "\n") 1148 call assert_equal(["{'a': {}, 'b': {}}", 1149 \ "{'a': {}, 'b': {}}"], l) 1150 1151 " Empty lists in a list 1152 let a = [] 1153 redir => result 1154 echo [a, a, a] 1155 echo string([a, a, a]) 1156 redir END 1157 let l = split(result, "\n") 1158 call assert_equal(["[[], [], []]", 1159 \ "[[], [], []]"], l) 1160 1161 " Empty lists in a dictionary 1162 let a = [] 1163 let b = {"a": a, "b": a} 1164 redir => result 1165 echo b 1166 echo string(b) 1167 redir END 1168 let l = split(result, "\n") 1169 call assert_equal(["{'a': [], 'b': []}", 1170 \ "{'a': [], 'b': []}"], l) 1171 1172 " Dictionaries in a list 1173 let a = {"one": "yes", "two": "yes", "three": "yes"} 1174 redir => result 1175 echo [a, a, a] 1176 echo string([a, a, a]) 1177 redir END 1178 let l = split(result, "\n") 1179 call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]", 1180 \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l) 1181 1182 " Dictionaries in a dictionary 1183 let a = {"one": "yes", "two": "yes", "three": "yes"} 1184 let b = {"a": a, "b": a} 1185 redir => result 1186 echo b 1187 echo string(b) 1188 redir END 1189 let l = split(result, "\n") 1190 call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}", 1191 \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l) 1192 1193 " Lists in a list 1194 let a = [1, 2, 3] 1195 redir => result 1196 echo [a, a, a] 1197 echo string([a, a, a]) 1198 redir END 1199 let l = split(result, "\n") 1200 call assert_equal(["[[1, 2, 3], [...], [...]]", 1201 \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l) 1202 1203 " Lists in a dictionary 1204 let a = [1, 2, 3] 1205 let b = {"a": a, "b": a} 1206 redir => result 1207 echo b 1208 echo string(b) 1209 redir END 1210 let l = split(result, "\n") 1211 call assert_equal(["{'a': [1, 2, 3], 'b': [...]}", 1212 \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l) 1213 1214endfunc 1215 1216"------------------------------------------------------------------------------- 1217" Test 94: 64-bit Numbers {{{1 1218"------------------------------------------------------------------------------- 1219 1220func Test_num64() 1221 if !has('num64') 1222 return 1223 endif 1224 1225 call assert_notequal( 4294967296, 0) 1226 call assert_notequal(-4294967296, 0) 1227 call assert_equal( 4294967296, 0xFFFFffff + 1) 1228 call assert_equal(-4294967296, -0xFFFFffff - 1) 1229 1230 call assert_equal( 9223372036854775807, 1 / 0) 1231 call assert_equal(-9223372036854775807, -1 / 0) 1232 call assert_equal(-9223372036854775807 - 1, 0 / 0) 1233 1234 call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150)) 1235 call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150)) 1236 1237 let rng = range(0xFFFFffff, 0x100000001) 1238 call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng) 1239 call assert_equal(0x100000001, max(rng)) 1240 call assert_equal(0xFFFFffff, min(rng)) 1241 call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N')) 1242endfunc 1243 1244"------------------------------------------------------------------------------- 1245" Test 95: lines of :append, :change, :insert {{{1 1246"------------------------------------------------------------------------------- 1247 1248function! DefineFunction(name, body) 1249 let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n") 1250 exec func 1251endfunction 1252 1253func Test_script_lines() 1254 " :append 1255 try 1256 call DefineFunction('T_Append', [ 1257 \ 'append', 1258 \ 'py <<EOS', 1259 \ '.', 1260 \ ]) 1261 catch 1262 call assert_report("Can't define function") 1263 endtry 1264 try 1265 call DefineFunction('T_Append', [ 1266 \ 'append', 1267 \ 'abc', 1268 \ ]) 1269 call assert_report("Shouldn't be able to define function") 1270 catch 1271 call assert_exception('Vim(function):E126: Missing :endfunction') 1272 endtry 1273 1274 " :change 1275 try 1276 call DefineFunction('T_Change', [ 1277 \ 'change', 1278 \ 'py <<EOS', 1279 \ '.', 1280 \ ]) 1281 catch 1282 call assert_report("Can't define function") 1283 endtry 1284 try 1285 call DefineFunction('T_Change', [ 1286 \ 'change', 1287 \ 'abc', 1288 \ ]) 1289 call assert_report("Shouldn't be able to define function") 1290 catch 1291 call assert_exception('Vim(function):E126: Missing :endfunction') 1292 endtry 1293 1294 " :insert 1295 try 1296 call DefineFunction('T_Insert', [ 1297 \ 'insert', 1298 \ 'py <<EOS', 1299 \ '.', 1300 \ ]) 1301 catch 1302 call assert_report("Can't define function") 1303 endtry 1304 try 1305 call DefineFunction('T_Insert', [ 1306 \ 'insert', 1307 \ 'abc', 1308 \ ]) 1309 call assert_report("Shouldn't be able to define function") 1310 catch 1311 call assert_exception('Vim(function):E126: Missing :endfunction') 1312 endtry 1313endfunc 1314 1315"------------------------------------------------------------------------------- 1316" Test 96: line continuation {{{1 1317" 1318" Undefined behavior was detected by ubsan with line continuation 1319" after an empty line. 1320"------------------------------------------------------------------------------- 1321func Test_script_emty_line_continuation() 1322 1323 \ 1324endfunc 1325 1326"------------------------------------------------------------------------------- 1327" Test 97: bitwise functions {{{1 1328"------------------------------------------------------------------------------- 1329func Test_bitwise_functions() 1330 " and 1331 call assert_equal(127, and(127, 127)) 1332 call assert_equal(16, and(127, 16)) 1333 eval 127->and(16)->assert_equal(16) 1334 call assert_equal(0, and(127, 128)) 1335 call assert_fails("call and(1.0, 1)", 'E805:') 1336 call assert_fails("call and([], 1)", 'E745:') 1337 call assert_fails("call and({}, 1)", 'E728:') 1338 call assert_fails("call and(1, 1.0)", 'E805:') 1339 call assert_fails("call and(1, [])", 'E745:') 1340 call assert_fails("call and(1, {})", 'E728:') 1341 " or 1342 call assert_equal(23, or(16, 7)) 1343 call assert_equal(15, or(8, 7)) 1344 eval 8->or(7)->assert_equal(15) 1345 call assert_equal(123, or(0, 123)) 1346 call assert_fails("call or(1.0, 1)", 'E805:') 1347 call assert_fails("call or([], 1)", 'E745:') 1348 call assert_fails("call or({}, 1)", 'E728:') 1349 call assert_fails("call or(1, 1.0)", 'E805:') 1350 call assert_fails("call or(1, [])", 'E745:') 1351 call assert_fails("call or(1, {})", 'E728:') 1352 " xor 1353 call assert_equal(0, xor(127, 127)) 1354 call assert_equal(111, xor(127, 16)) 1355 eval 127->xor(16)->assert_equal(111) 1356 call assert_equal(255, xor(127, 128)) 1357 call assert_fails("call xor(1.0, 1)", 'E805:') 1358 call assert_fails("call xor([], 1)", 'E745:') 1359 call assert_fails("call xor({}, 1)", 'E728:') 1360 call assert_fails("call xor(1, 1.0)", 'E805:') 1361 call assert_fails("call xor(1, [])", 'E745:') 1362 call assert_fails("call xor(1, {})", 'E728:') 1363 " invert 1364 call assert_equal(65408, and(invert(127), 65535)) 1365 eval 127->invert()->and(65535)->assert_equal(65408) 1366 call assert_equal(65519, and(invert(16), 65535)) 1367 call assert_equal(65407, and(invert(128), 65535)) 1368 call assert_fails("call invert(1.0)", 'E805:') 1369 call assert_fails("call invert([])", 'E745:') 1370 call assert_fails("call invert({})", 'E728:') 1371endfunc 1372 1373" Test trailing text after :endfunction {{{1 1374func Test_endfunction_trailing() 1375 call assert_false(exists('*Xtest')) 1376 1377 exe "func Xtest()\necho 'hello'\nendfunc\nlet done = 'yes'" 1378 call assert_true(exists('*Xtest')) 1379 call assert_equal('yes', done) 1380 delfunc Xtest 1381 unlet done 1382 1383 exe "func Xtest()\necho 'hello'\nendfunc|let done = 'yes'" 1384 call assert_true(exists('*Xtest')) 1385 call assert_equal('yes', done) 1386 delfunc Xtest 1387 unlet done 1388 1389 " trailing line break 1390 exe "func Xtest()\necho 'hello'\nendfunc\n" 1391 call assert_true(exists('*Xtest')) 1392 delfunc Xtest 1393 1394 set verbose=1 1395 exe "func Xtest()\necho 'hello'\nendfunc \" garbage" 1396 call assert_notmatch('W22:', split(execute('1messages'), "\n")[0]) 1397 call assert_true(exists('*Xtest')) 1398 delfunc Xtest 1399 1400 exe "func Xtest()\necho 'hello'\nendfunc garbage" 1401 call assert_match('W22:', split(execute('1messages'), "\n")[0]) 1402 call assert_true(exists('*Xtest')) 1403 delfunc Xtest 1404 set verbose=0 1405 1406 function Foo() 1407 echo 'hello' 1408 endfunction | echo 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 1409 delfunc Foo 1410endfunc 1411 1412func Test_delfunction_force() 1413 delfunc! Xtest 1414 delfunc! Xtest 1415 func Xtest() 1416 echo 'nothing' 1417 endfunc 1418 delfunc! Xtest 1419 delfunc! Xtest 1420endfunc 1421 1422" Test using bang after user command {{{1 1423func Test_user_command_with_bang() 1424 command -bang Nieuw let nieuw = 1 1425 Ni! 1426 call assert_equal(1, nieuw) 1427 unlet nieuw 1428 delcommand Nieuw 1429endfunc 1430 1431" Test for script-local function 1432func <SID>DoLast() 1433 call append(line('$'), "last line") 1434endfunc 1435 1436func s:DoNothing() 1437 call append(line('$'), "nothing line") 1438endfunc 1439 1440func Test_script_local_func() 1441 set nocp viminfo+=nviminfo 1442 new 1443 nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr> 1444 1445 normal _x 1446 call assert_equal('nothing line', getline(2)) 1447 call assert_equal('last line', getline(3)) 1448 enew! | close 1449endfunc 1450 1451func Test_compound_assignment_operators() 1452 " Test for number 1453 let x = 1 1454 let x += 10 1455 call assert_equal(11, x) 1456 let x -= 5 1457 call assert_equal(6, x) 1458 let x *= 4 1459 call assert_equal(24, x) 1460 let x /= 3 1461 call assert_equal(8, x) 1462 let x %= 3 1463 call assert_equal(2, x) 1464 let x .= 'n' 1465 call assert_equal('2n', x) 1466 1467 " Test special cases: division or modulus with 0. 1468 let x = 1 1469 let x /= 0 1470 if has('num64') 1471 call assert_equal(0x7FFFFFFFFFFFFFFF, x) 1472 else 1473 call assert_equal(0x7fffffff, x) 1474 endif 1475 1476 let x = -1 1477 let x /= 0 1478 if has('num64') 1479 call assert_equal(-0x7FFFFFFFFFFFFFFF, x) 1480 else 1481 call assert_equal(-0x7fffffff, x) 1482 endif 1483 1484 let x = 0 1485 let x /= 0 1486 if has('num64') 1487 call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x) 1488 else 1489 call assert_equal(-0x7FFFFFFF - 1, x) 1490 endif 1491 1492 let x = 1 1493 let x %= 0 1494 call assert_equal(0, x) 1495 1496 let x = -1 1497 let x %= 0 1498 call assert_equal(0, x) 1499 1500 let x = 0 1501 let x %= 0 1502 call assert_equal(0, x) 1503 1504 " Test for string 1505 let x = 'str' 1506 let x .= 'ing' 1507 call assert_equal('string', x) 1508 let x += 1 1509 call assert_equal(1, x) 1510 let x -= 1.5 1511 call assert_equal(-0.5, x) 1512 1513 if has('float') 1514 " Test for float 1515 let x = 0.5 1516 let x += 4.5 1517 call assert_equal(5.0, x) 1518 let x -= 1.5 1519 call assert_equal(3.5, x) 1520 let x *= 3.0 1521 call assert_equal(10.5, x) 1522 let x /= 2.5 1523 call assert_equal(4.2, x) 1524 call assert_fails('let x %= 0.5', 'E734') 1525 call assert_fails('let x .= "f"', 'E734') 1526 endif 1527 1528 " Test for environment variable 1529 let $FOO = 1 1530 call assert_fails('let $FOO += 1', 'E734') 1531 call assert_fails('let $FOO -= 1', 'E734') 1532 call assert_fails('let $FOO *= 1', 'E734') 1533 call assert_fails('let $FOO /= 1', 'E734') 1534 call assert_fails('let $FOO %= 1', 'E734') 1535 let $FOO .= 's' 1536 call assert_equal('1s', $FOO) 1537 unlet $FOO 1538 1539 " Test for option variable (type: number) 1540 let &scrolljump = 1 1541 let &scrolljump += 5 1542 call assert_equal(6, &scrolljump) 1543 let &scrolljump -= 2 1544 call assert_equal(4, &scrolljump) 1545 let &scrolljump *= 3 1546 call assert_equal(12, &scrolljump) 1547 let &scrolljump /= 2 1548 call assert_equal(6, &scrolljump) 1549 let &scrolljump %= 5 1550 call assert_equal(1, &scrolljump) 1551 call assert_fails('let &scrolljump .= "j"', 'E734') 1552 set scrolljump&vim 1553 1554 " Test for register 1555 let @/ = 1 1556 call assert_fails('let @/ += 1', 'E734') 1557 call assert_fails('let @/ -= 1', 'E734') 1558 call assert_fails('let @/ *= 1', 'E734') 1559 call assert_fails('let @/ /= 1', 'E734') 1560 call assert_fails('let @/ %= 1', 'E734') 1561 let @/ .= 's' 1562 call assert_equal('1s', @/) 1563 let @/ = '' 1564endfunc 1565 1566func Test_refcount() 1567 " Immediate values 1568 call assert_equal(-1, test_refcount(1)) 1569 call assert_equal(-1, test_refcount('s')) 1570 call assert_equal(-1, test_refcount(v:true)) 1571 call assert_equal(0, test_refcount([])) 1572 call assert_equal(0, test_refcount({})) 1573 call assert_equal(0, test_refcount(0zff)) 1574 call assert_equal(0, test_refcount({-> line('.')})) 1575 if has('float') 1576 call assert_equal(-1, test_refcount(0.1)) 1577 endif 1578 if has('job') 1579 call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .']))) 1580 endif 1581 1582 " No refcount types 1583 let x = 1 1584 call assert_equal(-1, test_refcount(x)) 1585 let x = 's' 1586 call assert_equal(-1, test_refcount(x)) 1587 let x = v:true 1588 call assert_equal(-1, test_refcount(x)) 1589 if has('float') 1590 let x = 0.1 1591 call assert_equal(-1, test_refcount(x)) 1592 endif 1593 1594 " Check refcount 1595 let x = [] 1596 call assert_equal(1, test_refcount(x)) 1597 1598 let x = {} 1599 call assert_equal(1, test_refcount(x)) 1600 1601 let x = 0zff 1602 call assert_equal(1, test_refcount(x)) 1603 1604 let X = {-> line('.')} 1605 call assert_equal(1, test_refcount(X)) 1606 let Y = X 1607 call assert_equal(2, test_refcount(X)) 1608 1609 if has('job') 1610 let job = job_start([&shell, &shellcmdflag, 'echo .']) 1611 call assert_equal(1, test_refcount(job)) 1612 call assert_equal(1, test_refcount(job_getchannel(job))) 1613 call assert_equal(1, test_refcount(job)) 1614 endif 1615 1616 " Function arguments, copying and unassigning 1617 func ExprCheck(x, i) 1618 let i = a:i + 1 1619 call assert_equal(i, test_refcount(a:x)) 1620 let Y = a:x 1621 call assert_equal(i + 1, test_refcount(a:x)) 1622 call assert_equal(test_refcount(a:x), test_refcount(Y)) 1623 let Y = 0 1624 call assert_equal(i, test_refcount(a:x)) 1625 endfunc 1626 call ExprCheck([], 0) 1627 call ExprCheck({}, 0) 1628 call ExprCheck(0zff, 0) 1629 call ExprCheck({-> line('.')}, 0) 1630 if has('job') 1631 call ExprCheck(job, 1) 1632 call ExprCheck(job_getchannel(job), 1) 1633 call job_stop(job) 1634 endif 1635 delfunc ExprCheck 1636 1637 " Regarding function 1638 func Func(x) abort 1639 call assert_equal(2, test_refcount(function('Func'))) 1640 call assert_equal(0, test_refcount(funcref('Func'))) 1641 endfunc 1642 call assert_equal(1, test_refcount(function('Func'))) 1643 call assert_equal(0, test_refcount(function('Func', [1]))) 1644 call assert_equal(0, test_refcount(funcref('Func'))) 1645 call assert_equal(0, test_refcount(funcref('Func', [1]))) 1646 let X = function('Func') 1647 let Y = X 1648 call assert_equal(1, test_refcount(X)) 1649 let X = function('Func', [1]) 1650 let Y = X 1651 call assert_equal(2, test_refcount(X)) 1652 let X = funcref('Func') 1653 let Y = X 1654 call assert_equal(2, test_refcount(X)) 1655 let X = funcref('Func', [1]) 1656 let Y = X 1657 call assert_equal(2, test_refcount(X)) 1658 unlet X 1659 unlet Y 1660 call Func(1) 1661 delfunc Func 1662 1663 " Function with dict 1664 func DictFunc() dict 1665 call assert_equal(3, test_refcount(self)) 1666 endfunc 1667 let d = {'Func': function('DictFunc')} 1668 call assert_equal(1, test_refcount(d)) 1669 call assert_equal(0, test_refcount(d.Func)) 1670 call d.Func() 1671 unlet d 1672 delfunc DictFunc 1673endfunc 1674 1675func Test_funccall_garbage_collect() 1676 func Func(x, ...) 1677 call add(a:x, a:000) 1678 endfunc 1679 call Func([], []) 1680 " Must not crash cause by invalid freeing 1681 call test_garbagecollect_now() 1682 call assert_true(v:true) 1683 delfunc Func 1684endfunc 1685 1686func Test_function_defined_line() 1687 CheckNotGui 1688 1689 let lines =<< trim [CODE] 1690 " F1 1691 func F1() 1692 " F2 1693 func F2() 1694 " 1695 " 1696 " 1697 return 1698 endfunc 1699 " F3 1700 execute "func F3()\n\n\n\nreturn\nendfunc" 1701 " F4 1702 execute "func F4()\n 1703 \\n 1704 \\n 1705 \\n 1706 \return\n 1707 \endfunc" 1708 endfunc 1709 " F5 1710 execute "func F5()\n\n\n\nreturn\nendfunc" 1711 " F6 1712 execute "func F6()\n 1713 \\n 1714 \\n 1715 \\n 1716 \return\n 1717 \endfunc" 1718 call F1() 1719 verbose func F1 1720 verbose func F2 1721 verbose func F3 1722 verbose func F4 1723 verbose func F5 1724 verbose func F6 1725 qall! 1726 [CODE] 1727 1728 call writefile(lines, 'Xtest.vim') 1729 let res = system(GetVimCommandClean() .. ' -es -X -S Xtest.vim') 1730 call assert_equal(0, v:shell_error) 1731 1732 let m = matchstr(res, 'function F1()[^[:print:]]*[[:print:]]*') 1733 call assert_match(' line 2$', m) 1734 1735 let m = matchstr(res, 'function F2()[^[:print:]]*[[:print:]]*') 1736 call assert_match(' line 4$', m) 1737 1738 let m = matchstr(res, 'function F3()[^[:print:]]*[[:print:]]*') 1739 call assert_match(' line 11$', m) 1740 1741 let m = matchstr(res, 'function F4()[^[:print:]]*[[:print:]]*') 1742 call assert_match(' line 13$', m) 1743 1744 let m = matchstr(res, 'function F5()[^[:print:]]*[[:print:]]*') 1745 call assert_match(' line 21$', m) 1746 1747 let m = matchstr(res, 'function F6()[^[:print:]]*[[:print:]]*') 1748 call assert_match(' line 23$', m) 1749 1750 call delete('Xtest.vim') 1751endfunc 1752 1753"------------------------------------------------------------------------------- 1754" Modelines {{{1 1755" vim: ts=8 sw=4 tw=80 fdm=marker 1756"------------------------------------------------------------------------------- 1757