1" Test various aspects of the Vim script language. 2" Most of this was formerly in test49. 3 4source check.vim 5source shared.vim 6source script_util.vim 7 8"------------------------------------------------------------------------------- 9" Test environment {{{1 10"------------------------------------------------------------------------------- 11 12" Append a message to the "messages" file 13func Xout(text) 14 split messages 15 $put =a:text 16 wq 17endfunc 18 19com! -nargs=1 Xout call Xout(<args>) 20 21" Create a new instance of Vim and run the commands in 'test' and then 'verify' 22" The commands in 'test' are expected to store the test results in the Xtest.out 23" file. If the test passes successfully, then Xtest.out should be empty. 24func RunInNewVim(test, verify) 25 let init =<< trim END 26 source script_util.vim 27 XpathINIT 28 XloopINIT 29 END 30 let cleanup =<< trim END 31 call writefile(v:errors, 'Xtest.out') 32 qall 33 END 34 call writefile(init, 'Xtest.vim') 35 call writefile(a:test, 'Xtest.vim', 'a') 36 call writefile(a:verify, 'Xverify.vim') 37 call writefile(cleanup, 'Xverify.vim', 'a') 38 call RunVim([], [], "-S Xtest.vim -S Xverify.vim") 39 call assert_equal([], readfile('Xtest.out')) 40 call delete('Xtest.out') 41 call delete('Xtest.vim') 42 call delete('Xverify.vim') 43endfunc 44 45"------------------------------------------------------------------------------- 46" Test 1: :endwhile in function {{{1 47" 48" Detect if a broken loop is (incorrectly) reactivated by the 49" :endwhile. Use a :return to prevent an endless loop, and make 50" this test first to get a meaningful result on an error before other 51" tests will hang. 52"------------------------------------------------------------------------------- 53 54func T1_F() 55 Xpath 'a' 56 let first = 1 57 while 1 58 Xpath 'b' 59 if first 60 Xpath 'c' 61 let first = 0 62 break 63 else 64 Xpath 'd' 65 return 66 endif 67 endwhile 68endfunc 69 70func T1_G() 71 Xpath 'h' 72 let first = 1 73 while 1 74 Xpath 'i' 75 if first 76 Xpath 'j' 77 let first = 0 78 break 79 else 80 Xpath 'k' 81 return 82 endif 83 if 1 " unmatched :if 84 endwhile 85endfunc 86 87func Test_endwhile_function() 88 XpathINIT 89 call T1_F() 90 Xpath 'F' 91 92 try 93 call T1_G() 94 catch 95 " Catch missing :endif 96 call assert_true(v:exception =~ 'E171') 97 Xpath 'x' 98 endtry 99 Xpath 'G' 100 101 call assert_equal('abcFhijxG', g:Xpath) 102endfunc 103 104"------------------------------------------------------------------------------- 105" Test 2: :endwhile in script {{{1 106" 107" Detect if a broken loop is (incorrectly) reactivated by the 108" :endwhile. Use a :finish to prevent an endless loop, and place 109" this test before others that might hang to get a meaningful result 110" on an error. 111" 112" This test executes the bodies of the functions T1_F and T1_G from 113" the previous test as script files (:return replaced by :finish). 114"------------------------------------------------------------------------------- 115 116func Test_endwhile_script() 117 XpathINIT 118 ExecAsScript T1_F 119 Xpath 'F' 120 call DeleteTheScript() 121 122 try 123 ExecAsScript T1_G 124 catch 125 " Catch missing :endif 126 call assert_true(v:exception =~ 'E171') 127 Xpath 'x' 128 endtry 129 Xpath 'G' 130 call DeleteTheScript() 131 132 call assert_equal('abcFhijxG', g:Xpath) 133endfunc 134 135"------------------------------------------------------------------------------- 136" Test 3: :if, :elseif, :while, :continue, :break {{{1 137"------------------------------------------------------------------------------- 138 139func Test_if_while() 140 XpathINIT 141 if 1 142 Xpath 'a' 143 let loops = 3 144 while loops > -1 " main loop: loops == 3, 2, 1 (which breaks) 145 if loops <= 0 146 let break_err = 1 147 let loops = -1 148 else 149 Xpath 'b' . loops 150 endif 151 if (loops == 2) 152 while loops == 2 " dummy loop 153 Xpath 'c' . loops 154 let loops = loops - 1 155 continue " stop dummy loop 156 Xpath 'd' . loops 157 endwhile 158 continue " continue main loop 159 Xpath 'e' . loops 160 elseif (loops == 1) 161 let p = 1 162 while p " dummy loop 163 Xpath 'f' . loops 164 let p = 0 165 break " break dummy loop 166 Xpath 'g' . loops 167 endwhile 168 Xpath 'h' . loops 169 unlet p 170 break " break main loop 171 Xpath 'i' . loops 172 endif 173 if (loops > 0) 174 Xpath 'j' . loops 175 endif 176 while loops == 3 " dummy loop 177 let loops = loops - 1 178 endwhile " end dummy loop 179 endwhile " end main loop 180 Xpath 'k' 181 else 182 Xpath 'l' 183 endif 184 Xpath 'm' 185 if exists("break_err") 186 Xpath 'm' 187 unlet break_err 188 endif 189 190 unlet loops 191 192 call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath) 193endfunc 194 195"------------------------------------------------------------------------------- 196" Test 4: :return {{{1 197"------------------------------------------------------------------------------- 198 199func T4_F() 200 if 1 201 Xpath 'a' 202 let loops = 3 203 while loops > 0 " 3: 2: 1: 204 Xpath 'b' . loops 205 if (loops == 2) 206 Xpath 'c' . loops 207 return 208 Xpath 'd' . loops 209 endif 210 Xpath 'e' . loops 211 let loops = loops - 1 212 endwhile 213 Xpath 'f' 214 else 215 Xpath 'g' 216 endif 217endfunc 218 219func Test_return() 220 XpathINIT 221 call T4_F() 222 Xpath '4' 223 224 call assert_equal('ab3e3b2c24', g:Xpath) 225endfunc 226 227 228"------------------------------------------------------------------------------- 229" Test 5: :finish {{{1 230" 231" This test executes the body of the function T4_F from the previous 232" test as a script file (:return replaced by :finish). 233"------------------------------------------------------------------------------- 234 235func Test_finish() 236 XpathINIT 237 ExecAsScript T4_F 238 Xpath '5' 239 call DeleteTheScript() 240 241 call assert_equal('ab3e3b2c25', g:Xpath) 242endfunc 243 244 245 246"------------------------------------------------------------------------------- 247" Test 6: Defining functions in :while loops {{{1 248" 249" Functions can be defined inside other functions. An inner function 250" gets defined when the outer function is executed. Functions may 251" also be defined inside while loops. Expressions in braces for 252" defining the function name are allowed. 253" 254" The functions are defined when sourcing the script, only the 255" resulting path is checked in the test function. 256"------------------------------------------------------------------------------- 257 258XpathINIT 259 260" The command CALL collects the argument of all its invocations in "calls" 261" when used from a function (that is, when the global variable "calls" needs 262" the "g:" prefix). This is to check that the function code is skipped when 263" the function is defined. For inner functions, do so only if the outer 264" function is not being executed. 265" 266let calls = "" 267com! -nargs=1 CALL 268 \ if !exists("calls") && !exists("outer") | 269 \ let g:calls = g:calls . <args> | 270 \ endif 271 272let i = 0 273while i < 3 274 let i = i + 1 275 if i == 1 276 Xpath 'a' 277 function! F1(arg) 278 CALL a:arg 279 let outer = 1 280 281 let j = 0 282 while j < 1 283 Xpath 'b' 284 let j = j + 1 285 function! G1(arg) 286 CALL a:arg 287 endfunction 288 Xpath 'c' 289 endwhile 290 endfunction 291 Xpath 'd' 292 293 continue 294 endif 295 296 Xpath 'e' . i 297 function! F{i}(i, arg) 298 CALL a:arg 299 let outer = 1 300 301 if a:i == 3 302 Xpath 'f' 303 endif 304 let k = 0 305 while k < 3 306 Xpath 'g' . k 307 let k = k + 1 308 function! G{a:i}{k}(arg) 309 CALL a:arg 310 endfunction 311 Xpath 'h' . k 312 endwhile 313 endfunction 314 Xpath 'i' 315 316endwhile 317 318if exists("*G1") 319 Xpath 'j' 320endif 321if exists("*F1") 322 call F1("F1") 323 if exists("*G1") 324 call G1("G1") 325 endif 326endif 327 328if exists("G21") || exists("G22") || exists("G23") 329 Xpath 'k' 330endif 331if exists("*F2") 332 call F2(2, "F2") 333 if exists("*G21") 334 call G21("G21") 335 endif 336 if exists("*G22") 337 call G22("G22") 338 endif 339 if exists("*G23") 340 call G23("G23") 341 endif 342endif 343 344if exists("G31") || exists("G32") || exists("G33") 345 Xpath 'l' 346endif 347if exists("*F3") 348 call F3(3, "F3") 349 if exists("*G31") 350 call G31("G31") 351 endif 352 if exists("*G32") 353 call G32("G32") 354 endif 355 if exists("*G33") 356 call G33("G33") 357 endif 358endif 359 360Xpath 'm' 361 362let g:test6_result = g:Xpath 363let g:test6_calls = calls 364 365unlet calls 366delfunction F1 367delfunction G1 368delfunction F2 369delfunction G21 370delfunction G22 371delfunction G23 372delfunction G31 373delfunction G32 374delfunction G33 375 376func Test_defining_functions() 377 call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result) 378 call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls) 379endfunc 380 381"------------------------------------------------------------------------------- 382" Test 7: Continuing on errors outside functions {{{1 383" 384" On an error outside a function, the script processing continues 385" at the line following the outermost :endif or :endwhile. When not 386" inside an :if or :while, the script processing continues at the next 387" line. 388"------------------------------------------------------------------------------- 389 390XpathINIT 391 392if 1 393 Xpath 'a' 394 while 1 395 Xpath 'b' 396 asdf 397 Xpath 'c' 398 break 399 endwhile | Xpath 'd' 400 Xpath 'e' 401endif | Xpath 'f' 402Xpath 'g' 403 404while 1 405 Xpath 'h' 406 if 1 407 Xpath 'i' 408 asdf 409 Xpath 'j' 410 endif | Xpath 'k' 411 Xpath 'l' 412 break 413endwhile | Xpath 'm' 414Xpath 'n' 415 416asdf 417Xpath 'o' 418 419asdf | Xpath 'p' 420Xpath 'q' 421 422let g:test7_result = g:Xpath 423 424func Test_error_in_script() 425 call assert_equal('abghinoq', g:test7_result) 426endfunc 427 428"------------------------------------------------------------------------------- 429" Test 8: Aborting and continuing on errors inside functions {{{1 430" 431" On an error inside a function without the "abort" attribute, the 432" script processing continues at the next line (unless the error was 433" in a :return command). On an error inside a function with the 434" "abort" attribute, the function is aborted and the script processing 435" continues after the function call; the value -1 is returned then. 436"------------------------------------------------------------------------------- 437 438XpathINIT 439 440func T8_F() 441 if 1 442 Xpath 'a' 443 while 1 444 Xpath 'b' 445 asdf 446 Xpath 'c' 447 asdf | Xpath 'd' 448 Xpath 'e' 449 break 450 endwhile 451 Xpath 'f' 452 endif | Xpath 'g' 453 Xpath 'h' 454 455 while 1 456 Xpath 'i' 457 if 1 458 Xpath 'j' 459 asdf 460 Xpath 'k' 461 asdf | Xpath 'l' 462 Xpath 'm' 463 endif 464 Xpath 'n' 465 break 466 endwhile | Xpath 'o' 467 Xpath 'p' 468 469 return novar " returns (default return value 0) 470 Xpath 'q' 471 return 1 " not reached 472endfunc 473 474func T8_G() abort 475 if 1 476 Xpath 'r' 477 while 1 478 Xpath 's' 479 asdf " returns -1 480 Xpath 't' 481 break 482 endwhile 483 Xpath 'v' 484 endif | Xpath 'w' 485 Xpath 'x' 486 487 return -4 " not reached 488endfunc 489 490func T8_H() abort 491 while 1 492 Xpath 'A' 493 if 1 494 Xpath 'B' 495 asdf " returns -1 496 Xpath 'C' 497 endif 498 Xpath 'D' 499 break 500 endwhile | Xpath 'E' 501 Xpath 'F' 502 503 return -4 " not reached 504endfunc 505 506" Aborted functions (T8_G and T8_H) return -1. 507let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H() 508Xpath 'X' 509let g:test8_result = g:Xpath 510 511func Test_error_in_function() 512 call assert_equal(13, g:test8_sum) 513 call assert_equal('abcefghijkmnoprsABX', g:test8_result) 514 515 delfunction T8_F 516 delfunction T8_G 517 delfunction T8_H 518endfunc 519 520 521"------------------------------------------------------------------------------- 522" Test 9: Continuing after aborted functions {{{1 523" 524" When a function with the "abort" attribute is aborted due to an 525" error, the next function back in the call hierarchy without an 526" "abort" attribute continues; the value -1 is returned then. 527"------------------------------------------------------------------------------- 528 529XpathINIT 530 531func F() abort 532 Xpath 'a' 533 let result = G() " not aborted 534 Xpath 'b' 535 if result != 2 536 Xpath 'c' 537 endif 538 return 1 539endfunc 540 541func G() " no abort attribute 542 Xpath 'd' 543 if H() != -1 " aborted 544 Xpath 'e' 545 endif 546 Xpath 'f' 547 return 2 548endfunc 549 550func H() abort 551 Xpath 'g' 552 call I() " aborted 553 Xpath 'h' 554 return 4 555endfunc 556 557func I() abort 558 Xpath 'i' 559 asdf " error 560 Xpath 'j' 561 return 8 562endfunc 563 564if F() != 1 565 Xpath 'k' 566endif 567 568let g:test9_result = g:Xpath 569 570delfunction F 571delfunction G 572delfunction H 573delfunction I 574 575func Test_func_abort() 576 call assert_equal('adgifb', g:test9_result) 577endfunc 578 579 580"------------------------------------------------------------------------------- 581" Test 10: :if, :elseif, :while argument parsing {{{1 582" 583" A '"' or '|' in an argument expression must not be mixed up with 584" a comment or a next command after a bar. Parsing errors should 585" be recognized. 586"------------------------------------------------------------------------------- 587 588XpathINIT 589 590func MSG(enr, emsg) 591 let english = v:lang == "C" || v:lang =~ '^[Ee]n' 592 if a:enr == "" 593 Xout "TODO: Add message number for:" a:emsg 594 let v:errmsg = ":" . v:errmsg 595 endif 596 let match = 1 597 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) 598 let match = 0 599 if v:errmsg == "" 600 Xout "Message missing." 601 else 602 let v:errmsg = v:errmsg->escape('"') 603 Xout "Unexpected message:" v:errmsg 604 endif 605 endif 606 return match 607endfunc 608 609if 1 || strlen("\"") | Xpath 'a' 610 Xpath 'b' 611endif 612Xpath 'c' 613 614if 0 615elseif 1 || strlen("\"") | Xpath 'd' 616 Xpath 'e' 617endif 618Xpath 'f' 619 620while 1 || strlen("\"") | Xpath 'g' 621 Xpath 'h' 622 break 623endwhile 624Xpath 'i' 625 626let v:errmsg = "" 627if 1 ||| strlen("\"") | Xpath 'j' 628 Xpath 'k' 629endif 630Xpath 'l' 631if !MSG('E15', "Invalid expression") 632 Xpath 'm' 633endif 634 635let v:errmsg = "" 636if 0 637elseif 1 ||| strlen("\"") | Xpath 'n' 638 Xpath 'o' 639endif 640Xpath 'p' 641if !MSG('E15', "Invalid expression") 642 Xpath 'q' 643endif 644 645let v:errmsg = "" 646while 1 ||| strlen("\"") | Xpath 'r' 647 Xpath 's' 648 break 649endwhile 650Xpath 't' 651if !MSG('E15', "Invalid expression") 652 Xpath 'u' 653endif 654 655let g:test10_result = g:Xpath 656delfunction MSG 657 658func Test_expr_parsing() 659 call assert_equal('abcdefghilpt', g:test10_result) 660endfunc 661 662 663"------------------------------------------------------------------------------- 664" Test 11: :if, :elseif, :while argument evaluation after abort {{{1 665" 666" When code is skipped over due to an error, the boolean argument to 667" an :if, :elseif, or :while must not be evaluated. 668"------------------------------------------------------------------------------- 669 670XpathINIT 671 672let calls = 0 673 674func P(num) 675 let g:calls = g:calls + a:num " side effect on call 676 return 0 677endfunc 678 679if 1 680 Xpath 'a' 681 asdf " error 682 Xpath 'b' 683 if P(1) " should not be called 684 Xpath 'c' 685 elseif !P(2) " should not be called 686 Xpath 'd' 687 else 688 Xpath 'e' 689 endif 690 Xpath 'f' 691 while P(4) " should not be called 692 Xpath 'g' 693 endwhile 694 Xpath 'h' 695endif 696Xpath 'x' 697 698let g:test11_calls = calls 699let g:test11_result = g:Xpath 700 701unlet calls 702delfunction P 703 704func Test_arg_abort() 705 call assert_equal(0, g:test11_calls) 706 call assert_equal('ax', g:test11_result) 707endfunc 708 709 710"------------------------------------------------------------------------------- 711" Test 12: Expressions in braces in skipped code {{{1 712" 713" In code skipped over due to an error or inactive conditional, 714" an expression in braces as part of a variable or function name 715" should not be evaluated. 716"------------------------------------------------------------------------------- 717 718XpathINIT 719 720function! NULL() 721 Xpath 'a' 722 return 0 723endfunction 724 725function! ZERO() 726 Xpath 'b' 727 return 0 728endfunction 729 730function! F0() 731 Xpath 'c' 732endfunction 733 734function! F1(arg) 735 Xpath 'e' 736endfunction 737 738let V0 = 1 739 740Xpath 'f' 741echo 0 ? F{NULL() + V{ZERO()}}() : 1 742 743Xpath 'g' 744if 0 745 Xpath 'h' 746 call F{NULL() + V{ZERO()}}() 747endif 748 749Xpath 'i' 750if 1 751 asdf " error 752 Xpath 'j' 753 call F1(F{NULL() + V{ZERO()}}()) 754endif 755 756Xpath 'k' 757if 1 758 asdf " error 759 Xpath 'l' 760 call F{NULL() + V{ZERO()}}() 761endif 762 763let g:test12_result = g:Xpath 764 765func Test_braces_skipped() 766 call assert_equal('fgik', g:test12_result) 767endfunc 768 769 770"------------------------------------------------------------------------------- 771" Test 13: Failure in argument evaluation for :while {{{1 772" 773" A failure in the expression evaluation for the condition of a :while 774" causes the whole :while loop until the matching :endwhile being 775" ignored. Continuation is at the next following line. 776"------------------------------------------------------------------------------- 777 778XpathINIT 779 780Xpath 'a' 781while asdf 782 Xpath 'b' 783 while 1 784 Xpath 'c' 785 break 786 endwhile 787 Xpath 'd' 788 break 789endwhile 790Xpath 'e' 791 792while asdf | Xpath 'f' | endwhile | Xpath 'g' 793Xpath 'h' 794let g:test13_result = g:Xpath 795 796func Test_while_fail() 797 call assert_equal('aeh', g:test13_result) 798endfunc 799 800 801"------------------------------------------------------------------------------- 802" Test 14: Failure in argument evaluation for :if {{{1 803" 804" A failure in the expression evaluation for the condition of an :if 805" does not cause the corresponding :else or :endif being matched to 806" a previous :if/:elseif. Neither of both branches of the failed :if 807" are executed. 808"------------------------------------------------------------------------------- 809 810XpathINIT 811 812function! F() 813 Xpath 'a' 814 let x = 0 815 if x " false 816 Xpath 'b' 817 elseif !x " always true 818 Xpath 'c' 819 let x = 1 820 if g:boolvar " possibly undefined 821 Xpath 'd' 822 else 823 Xpath 'e' 824 endif 825 Xpath 'f' 826 elseif x " never executed 827 Xpath 'g' 828 endif 829 Xpath 'h' 830endfunction 831 832let boolvar = 1 833call F() 834Xpath '-' 835 836unlet boolvar 837call F() 838let g:test14_result = g:Xpath 839 840delfunction F 841 842func Test_if_fail() 843 call assert_equal('acdfh-acfh', g:test14_result) 844endfunc 845 846 847"------------------------------------------------------------------------------- 848" Test 15: Failure in argument evaluation for :if (bar) {{{1 849" 850" Like previous test, except that the failing :if ... | ... | :endif 851" is in a single line. 852"------------------------------------------------------------------------------- 853 854XpathINIT 855 856function! F() 857 Xpath 'a' 858 let x = 0 859 if x " false 860 Xpath 'b' 861 elseif !x " always true 862 Xpath 'c' 863 let x = 1 864 if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif 865 Xpath 'f' 866 elseif x " never executed 867 Xpath 'g' 868 endif 869 Xpath 'h' 870endfunction 871 872let boolvar = 1 873call F() 874Xpath '-' 875 876unlet boolvar 877call F() 878let g:test15_result = g:Xpath 879 880delfunction F 881 882func Test_if_bar_fail() 883 call assert_equal('acdfh-acfh', g:test15_result) 884endfunc 885 886"------------------------------------------------------------------------------- 887" Test 16: Double :else or :elseif after :else {{{1 888" 889" Multiple :elses or an :elseif after an :else are forbidden. 890"------------------------------------------------------------------------------- 891 892func T16_F() abort 893 if 0 894 Xpath 'a' 895 else 896 Xpath 'b' 897 else " aborts function 898 Xpath 'c' 899 endif 900 Xpath 'd' 901endfunc 902 903func T16_G() abort 904 if 0 905 Xpath 'a' 906 else 907 Xpath 'b' 908 elseif 1 " aborts function 909 Xpath 'c' 910 else 911 Xpath 'd' 912 endif 913 Xpath 'e' 914endfunc 915 916func T16_H() abort 917 if 0 918 Xpath 'a' 919 elseif 0 920 Xpath 'b' 921 else 922 Xpath 'c' 923 else " aborts function 924 Xpath 'd' 925 endif 926 Xpath 'e' 927endfunc 928 929func T16_I() abort 930 if 0 931 Xpath 'a' 932 elseif 0 933 Xpath 'b' 934 else 935 Xpath 'c' 936 elseif 1 " aborts function 937 Xpath 'd' 938 else 939 Xpath 'e' 940 endif 941 Xpath 'f' 942endfunc 943 944func Test_Multi_Else() 945 XpathINIT 946 try 947 call T16_F() 948 catch /E583:/ 949 Xpath 'e' 950 endtry 951 call assert_equal('be', g:Xpath) 952 953 XpathINIT 954 try 955 call T16_G() 956 catch /E584:/ 957 Xpath 'f' 958 endtry 959 call assert_equal('bf', g:Xpath) 960 961 XpathINIT 962 try 963 call T16_H() 964 catch /E583:/ 965 Xpath 'f' 966 endtry 967 call assert_equal('cf', g:Xpath) 968 969 XpathINIT 970 try 971 call T16_I() 972 catch /E584:/ 973 Xpath 'g' 974 endtry 975 call assert_equal('cg', g:Xpath) 976endfunc 977 978"------------------------------------------------------------------------------- 979" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1 980" 981" The :while/:endwhile takes precedence in nesting over an unclosed 982" :if or an unopened :endif. 983"------------------------------------------------------------------------------- 984 985" While loops inside a function are continued on error. 986func T17_F() 987 let loops = 3 988 while loops > 0 989 let loops -= 1 990 Xpath 'a' . loops 991 if (loops == 1) 992 Xpath 'b' . loops 993 continue 994 elseif (loops == 0) 995 Xpath 'c' . loops 996 break 997 elseif 1 998 Xpath 'd' . loops 999 " endif missing! 1000 endwhile " :endwhile after :if 1 1001 Xpath 'e' 1002endfunc 1003 1004func T17_G() 1005 let loops = 2 1006 while loops > 0 1007 let loops -= 1 1008 Xpath 'a' . loops 1009 if 0 1010 Xpath 'b' . loops 1011 " endif missing 1012 endwhile " :endwhile after :if 0 1013endfunc 1014 1015func T17_H() 1016 let loops = 2 1017 while loops > 0 1018 let loops -= 1 1019 Xpath 'a' . loops 1020 " if missing! 1021 endif " :endif without :if in while 1022 Xpath 'b' . loops 1023 endwhile 1024endfunc 1025 1026" Error continuation outside a function is at the outermost :endwhile or :endif. 1027XpathINIT 1028let v:errmsg = '' 1029let loops = 2 1030while loops > 0 1031 let loops -= 1 1032 Xpath 'a' . loops 1033 if 0 1034 Xpath 'b' . loops 1035 " endif missing! Following :endwhile fails. 1036endwhile | Xpath 'c' 1037Xpath 'd' 1038call assert_match('E171:', v:errmsg) 1039call assert_equal('a1d', g:Xpath) 1040 1041func Test_unmatched_if_in_while() 1042 XpathINIT 1043 call assert_fails('call T17_F()', 'E171:') 1044 call assert_equal('a2d2a1b1a0c0e', g:Xpath) 1045 1046 XpathINIT 1047 call assert_fails('call T17_G()', 'E171:') 1048 call assert_equal('a1a0', g:Xpath) 1049 1050 XpathINIT 1051 call assert_fails('call T17_H()', 'E580:') 1052 call assert_equal('a1b1a0b0', g:Xpath) 1053endfunc 1054 1055"------------------------------------------------------------------------------- 1056" Test 18: Interrupt (Ctrl-C pressed) {{{1 1057" 1058" On an interrupt, the script processing is terminated immediately. 1059"------------------------------------------------------------------------------- 1060 1061func Test_interrupt_while_if() 1062 let test =<< trim [CODE] 1063 try 1064 if 1 1065 Xpath 'a' 1066 while 1 1067 Xpath 'b' 1068 if 1 1069 Xpath 'c' 1070 call interrupt() 1071 call assert_report('should not get here') 1072 break 1073 finish 1074 endif | call assert_report('should not get here') 1075 call assert_report('should not get here') 1076 endwhile | call assert_report('should not get here') 1077 call assert_report('should not get here') 1078 endif | call assert_report('should not get here') 1079 call assert_report('should not get here') 1080 catch /^Vim:Interrupt$/ 1081 Xpath 'd' 1082 endtry | Xpath 'e' 1083 Xpath 'f' 1084 [CODE] 1085 let verify =<< trim [CODE] 1086 call assert_equal('abcdef', g:Xpath) 1087 [CODE] 1088 call RunInNewVim(test, verify) 1089endfunc 1090 1091func Test_interrupt_try() 1092 let test =<< trim [CODE] 1093 try 1094 try 1095 Xpath 'a' 1096 call interrupt() 1097 call assert_report('should not get here') 1098 endtry | call assert_report('should not get here') 1099 call assert_report('should not get here') 1100 catch /^Vim:Interrupt$/ 1101 Xpath 'b' 1102 endtry | Xpath 'c' 1103 Xpath 'd' 1104 [CODE] 1105 let verify =<< trim [CODE] 1106 call assert_equal('abcd', g:Xpath) 1107 [CODE] 1108 call RunInNewVim(test, verify) 1109endfunc 1110 1111func Test_interrupt_func_while_if() 1112 let test =<< trim [CODE] 1113 func F() 1114 if 1 1115 Xpath 'a' 1116 while 1 1117 Xpath 'b' 1118 if 1 1119 Xpath 'c' 1120 call interrupt() 1121 call assert_report('should not get here') 1122 break 1123 return 1124 endif | call assert_report('should not get here') 1125 call assert_report('should not get here') 1126 endwhile | call assert_report('should not get here') 1127 call assert_report('should not get here') 1128 endif | call assert_report('should not get here') 1129 call assert_report('should not get here') 1130 endfunc 1131 1132 Xpath 'd' 1133 try 1134 call F() | call assert_report('should not get here') 1135 catch /^Vim:Interrupt$/ 1136 Xpath 'e' 1137 endtry | Xpath 'f' 1138 Xpath 'g' 1139 [CODE] 1140 let verify =<< trim [CODE] 1141 call assert_equal('dabcefg', g:Xpath) 1142 [CODE] 1143 call RunInNewVim(test, verify) 1144endfunc 1145 1146func Test_interrupt_func_try() 1147 let test =<< trim [CODE] 1148 func G() 1149 try 1150 Xpath 'a' 1151 call interrupt() 1152 call assert_report('should not get here') 1153 endtry | call assert_report('should not get here') 1154 call assert_report('should not get here') 1155 endfunc 1156 1157 Xpath 'b' 1158 try 1159 call G() | call assert_report('should not get here') 1160 catch /^Vim:Interrupt$/ 1161 Xpath 'c' 1162 endtry | Xpath 'd' 1163 Xpath 'e' 1164 [CODE] 1165 let verify =<< trim [CODE] 1166 call assert_equal('bacde', g:Xpath) 1167 [CODE] 1168 call RunInNewVim(test, verify) 1169endfunc 1170 1171"------------------------------------------------------------------------------- 1172" Test 19: Aborting on errors inside :try/:endtry {{{1 1173" 1174" An error in a command dynamically enclosed in a :try/:endtry region 1175" aborts script processing immediately. It does not matter whether 1176" the failing command is outside or inside a function and whether a 1177" function has an "abort" attribute. 1178"------------------------------------------------------------------------------- 1179 1180func Test_try_error_abort_1() 1181 let test =<< trim [CODE] 1182 func F() abort 1183 Xpath 'a' 1184 asdf 1185 call assert_report('should not get here') 1186 endfunc 1187 1188 try 1189 Xpath 'b' 1190 call F() 1191 call assert_report('should not get here') 1192 endtry | call assert_report('should not get here') 1193 call assert_report('should not get here') 1194 [CODE] 1195 let verify =<< trim [CODE] 1196 call assert_equal('ba', g:Xpath) 1197 [CODE] 1198 call RunInNewVim(test, verify) 1199endfunc 1200 1201func Test_try_error_abort_2() 1202 let test =<< trim [CODE] 1203 func G() 1204 Xpath 'a' 1205 asdf 1206 call assert_report('should not get here') 1207 endfunc 1208 1209 try 1210 Xpath 'b' 1211 call G() 1212 call assert_report('should not get here') 1213 endtry | call assert_report('should not get here') 1214 call assert_report('should not get here') 1215 [CODE] 1216 let verify =<< trim [CODE] 1217 call assert_equal('ba', g:Xpath) 1218 [CODE] 1219 call RunInNewVim(test, verify) 1220endfunc 1221 1222func Test_try_error_abort_3() 1223 let test =<< trim [CODE] 1224 try 1225 Xpath 'a' 1226 asdf 1227 call assert_report('should not get here') 1228 endtry | call assert_report('should not get here') 1229 call assert_report('should not get here') 1230 [CODE] 1231 let verify =<< trim [CODE] 1232 call assert_equal('a', g:Xpath) 1233 [CODE] 1234 call RunInNewVim(test, verify) 1235endfunc 1236 1237func Test_try_error_abort_4() 1238 let test =<< trim [CODE] 1239 if 1 1240 try 1241 Xpath 'a' 1242 asdf 1243 call assert_report('should not get here') 1244 endtry | call assert_report('should not get here') 1245 endif | call assert_report('should not get here') 1246 call assert_report('should not get here') 1247 [CODE] 1248 let verify =<< trim [CODE] 1249 call assert_equal('a', g:Xpath) 1250 [CODE] 1251 call RunInNewVim(test, verify) 1252endfunc 1253 1254func Test_try_error_abort_5() 1255 let test =<< trim [CODE] 1256 let p = 1 1257 while p 1258 let p = 0 1259 try 1260 Xpath 'a' 1261 asdf 1262 call assert_report('should not get here') 1263 endtry | call assert_report('should not get here') 1264 endwhile | call assert_report('should not get here') 1265 call assert_report('should not get here') 1266 [CODE] 1267 let verify =<< trim [CODE] 1268 call assert_equal('a', g:Xpath) 1269 [CODE] 1270 call RunInNewVim(test, verify) 1271endfunc 1272 1273func Test_try_error_abort_6() 1274 let test =<< trim [CODE] 1275 let p = 1 1276 Xpath 'a' 1277 while p 1278 Xpath 'b' 1279 let p = 0 1280 try 1281 Xpath 'c' 1282 endwhile | call assert_report('should not get here') 1283 call assert_report('should not get here') 1284 [CODE] 1285 let verify =<< trim [CODE] 1286 call assert_equal('abc', g:Xpath) 1287 [CODE] 1288 call RunInNewVim(test, verify) 1289endfunc 1290 1291"------------------------------------------------------------------------------- 1292" Test 20: Aborting on errors after :try/:endtry {{{1 1293" 1294" When an error occurs after the last active :try/:endtry region has 1295" been left, termination behavior is as if no :try/:endtry has been 1296" seen. 1297"------------------------------------------------------------------------------- 1298 1299func Test_error_after_try_1() 1300 let test =<< trim [CODE] 1301 let p = 1 1302 while p 1303 let p = 0 1304 Xpath 'a' 1305 try 1306 Xpath 'b' 1307 endtry 1308 asdf 1309 call assert_report('should not get here') 1310 endwhile | call assert_report('should not get here') 1311 Xpath 'c' 1312 [CODE] 1313 let verify =<< trim [CODE] 1314 call assert_equal('abc', g:Xpath) 1315 [CODE] 1316 call RunInNewVim(test, verify) 1317endfunc 1318 1319func Test_error_after_try_2() 1320 let test =<< trim [CODE] 1321 while 1 1322 try 1323 Xpath 'a' 1324 break 1325 call assert_report('should not get here') 1326 endtry 1327 endwhile 1328 Xpath 'b' 1329 asdf 1330 Xpath 'c' 1331 [CODE] 1332 let verify =<< trim [CODE] 1333 call assert_equal('abc', g:Xpath) 1334 [CODE] 1335 call RunInNewVim(test, verify) 1336endfunc 1337 1338func Test_error_after_try_3() 1339 let test =<< trim [CODE] 1340 while 1 1341 try 1342 Xpath 'a' 1343 break 1344 call assert_report('should not get here') 1345 finally 1346 Xpath 'b' 1347 endtry 1348 endwhile 1349 Xpath 'c' 1350 asdf 1351 Xpath 'd' 1352 [CODE] 1353 let verify =<< trim [CODE] 1354 call assert_equal('abcd', g:Xpath) 1355 [CODE] 1356 call RunInNewVim(test, verify) 1357endfunc 1358 1359func Test_error_after_try_4() 1360 let test =<< trim [CODE] 1361 while 1 1362 try 1363 Xpath 'a' 1364 finally 1365 Xpath 'b' 1366 break 1367 call assert_report('should not get here') 1368 endtry 1369 endwhile 1370 Xpath 'c' 1371 asdf 1372 Xpath 'd' 1373 [CODE] 1374 let verify =<< trim [CODE] 1375 call assert_equal('abcd', g:Xpath) 1376 [CODE] 1377 call RunInNewVim(test, verify) 1378endfunc 1379 1380func Test_error_after_try_5() 1381 let test =<< trim [CODE] 1382 let p = 1 1383 while p 1384 let p = 0 1385 try 1386 Xpath 'a' 1387 continue 1388 call assert_report('should not get here') 1389 endtry 1390 endwhile 1391 Xpath 'b' 1392 asdf 1393 Xpath 'c' 1394 [CODE] 1395 let verify =<< trim [CODE] 1396 call assert_equal('abc', g:Xpath) 1397 [CODE] 1398 call RunInNewVim(test, verify) 1399endfunc 1400 1401func Test_error_after_try_6() 1402 let test =<< trim [CODE] 1403 let p = 1 1404 while p 1405 let p = 0 1406 try 1407 Xpath 'a' 1408 continue 1409 call assert_report('should not get here') 1410 finally 1411 Xpath 'b' 1412 endtry 1413 endwhile 1414 Xpath 'c' 1415 asdf 1416 Xpath 'd' 1417 [CODE] 1418 let verify =<< trim [CODE] 1419 call assert_equal('abcd', g:Xpath) 1420 [CODE] 1421 call RunInNewVim(test, verify) 1422endfunc 1423 1424func Test_error_after_try_7() 1425 let test =<< trim [CODE] 1426 let p = 1 1427 while p 1428 let p = 0 1429 try 1430 Xpath 'a' 1431 finally 1432 Xpath 'b' 1433 continue 1434 call assert_report('should not get here') 1435 endtry 1436 endwhile 1437 Xpath 'c' 1438 asdf 1439 Xpath 'd' 1440 [CODE] 1441 let verify =<< trim [CODE] 1442 call assert_equal('abcd', g:Xpath) 1443 [CODE] 1444 call RunInNewVim(test, verify) 1445endfunc 1446 1447"------------------------------------------------------------------------------- 1448" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1 1449" 1450" If a :try conditional stays inactive due to a preceding :continue, 1451" :break, :return, or :finish, its :finally clause should not be 1452" executed. 1453"------------------------------------------------------------------------------- 1454 1455func Test_finally_after_loop_ctrl_statement() 1456 let test =<< trim [CODE] 1457 func F() 1458 let loops = 2 1459 while loops > 0 1460 XloopNEXT 1461 let loops = loops - 1 1462 try 1463 if loops == 1 1464 Xloop 'a' 1465 continue 1466 call assert_report('should not get here') 1467 elseif loops == 0 1468 Xloop 'b' 1469 break 1470 call assert_report('should not get here') 1471 endif 1472 1473 try " inactive 1474 call assert_report('should not get here') 1475 finally 1476 call assert_report('should not get here') 1477 endtry 1478 finally 1479 Xloop 'c' 1480 endtry 1481 call assert_report('should not get here') 1482 endwhile 1483 1484 try 1485 Xpath 'd' 1486 return 1487 call assert_report('should not get here') 1488 try " inactive 1489 call assert_report('should not get here') 1490 finally 1491 call assert_report('should not get here') 1492 endtry 1493 finally 1494 Xpath 'e' 1495 endtry 1496 call assert_report('should not get here') 1497 endfunc 1498 1499 try 1500 Xpath 'f' 1501 call F() 1502 Xpath 'g' 1503 finish 1504 call assert_report('should not get here') 1505 try " inactive 1506 call assert_report('should not get here') 1507 finally 1508 call assert_report('should not get here') 1509 endtry 1510 finally 1511 Xpath 'h' 1512 endtry 1513 call assert_report('should not get here') 1514 [CODE] 1515 let verify =<< trim [CODE] 1516 call assert_equal('fa2c2b3c3degh', g:Xpath) 1517 [CODE] 1518 call RunInNewVim(test, verify) 1519endfunc 1520 1521"------------------------------------------------------------------------------- 1522" Test 22: :finally for a :try after an error/interrupt/:throw {{{1 1523" 1524" If a :try conditional stays inactive due to a preceding error or 1525" interrupt or :throw, its :finally clause should not be executed. 1526"------------------------------------------------------------------------------- 1527 1528func Test_finally_after_error_in_func() 1529 let test =<< trim [CODE] 1530 func Error() 1531 try 1532 Xpath 'b' 1533 asdf " aborting error, triggering error exception 1534 call assert_report('should not get here') 1535 endtry 1536 call assert_report('should not get here') 1537 endfunc 1538 1539 Xpath 'a' 1540 call Error() 1541 call assert_report('should not get here') 1542 1543 if 1 " not active due to error 1544 try " not active since :if inactive 1545 call assert_report('should not get here') 1546 finally 1547 call assert_report('should not get here') 1548 endtry 1549 endif 1550 1551 try " not active due to error 1552 call assert_report('should not get here') 1553 finally 1554 call assert_report('should not get here') 1555 endtry 1556 [CODE] 1557 let verify =<< trim [CODE] 1558 call assert_equal('ab', g:Xpath) 1559 [CODE] 1560 call RunInNewVim(test, verify) 1561endfunc 1562 1563func Test_finally_after_interrupt() 1564 let test =<< trim [CODE] 1565 func Interrupt() 1566 try 1567 Xpath 'a' 1568 call interrupt() " triggering interrupt exception 1569 call assert_report('should not get here') 1570 endtry 1571 endfunc 1572 1573 Xpath 'b' 1574 try 1575 call Interrupt() 1576 catch /^Vim:Interrupt$/ 1577 Xpath 'c' 1578 finish 1579 endtry 1580 call assert_report('should not get here') 1581 1582 if 1 " not active due to interrupt 1583 try " not active since :if inactive 1584 call assert_report('should not get here') 1585 finally 1586 call assert_report('should not get here') 1587 endtry 1588 endif 1589 1590 try " not active due to interrupt 1591 call assert_report('should not get here') 1592 finally 1593 call assert_report('should not get here') 1594 endtry 1595 [CODE] 1596 let verify =<< trim [CODE] 1597 call assert_equal('bac', g:Xpath) 1598 [CODE] 1599 call RunInNewVim(test, verify) 1600endfunc 1601 1602func Test_finally_after_throw() 1603 let test =<< trim [CODE] 1604 func Throw() 1605 Xpath 'a' 1606 throw 'xyz' 1607 endfunc 1608 1609 Xpath 'b' 1610 call Throw() 1611 call assert_report('should not get here') 1612 1613 if 1 " not active due to :throw 1614 try " not active since :if inactive 1615 call assert_report('should not get here') 1616 finally 1617 call assert_report('should not get here') 1618 endtry 1619 endif 1620 1621 try " not active due to :throw 1622 call assert_report('should not get here') 1623 finally 1624 call assert_report('should not get here') 1625 endtry 1626 [CODE] 1627 let verify =<< trim [CODE] 1628 call assert_equal('ba', g:Xpath) 1629 [CODE] 1630 call RunInNewVim(test, verify) 1631endfunc 1632 1633"------------------------------------------------------------------------------- 1634" Test 23: :catch clauses for a :try after a :throw {{{1 1635" 1636" If a :try conditional stays inactive due to a preceding :throw, 1637" none of its :catch clauses should be executed. 1638"------------------------------------------------------------------------------- 1639 1640func Test_catch_after_throw() 1641 let test =<< trim [CODE] 1642 try 1643 Xpath 'a' 1644 throw "xyz" 1645 call assert_report('should not get here') 1646 1647 if 1 " not active due to :throw 1648 try " not active since :if inactive 1649 call assert_report('should not get here') 1650 catch /xyz/ 1651 call assert_report('should not get here') 1652 endtry 1653 endif 1654 catch /xyz/ 1655 Xpath 'b' 1656 endtry 1657 1658 Xpath 'c' 1659 throw "abc" 1660 call assert_report('should not get here') 1661 1662 try " not active due to :throw 1663 call assert_report('should not get here') 1664 catch /abc/ 1665 call assert_report('should not get here') 1666 endtry 1667 [CODE] 1668 let verify =<< trim [CODE] 1669 call assert_equal('abc', g:Xpath) 1670 [CODE] 1671 call RunInNewVim(test, verify) 1672endfunc 1673 1674"------------------------------------------------------------------------------- 1675" Test 24: :endtry for a :try after a :throw {{{1 1676" 1677" If a :try conditional stays inactive due to a preceding :throw, 1678" its :endtry should not rethrow the exception to the next surrounding 1679" active :try conditional. 1680"------------------------------------------------------------------------------- 1681 1682func Test_endtry_after_throw() 1683 let test =<< trim [CODE] 1684 try " try 1 1685 try " try 2 1686 Xpath 'a' 1687 throw "xyz" " makes try 2 inactive 1688 call assert_report('should not get here') 1689 1690 try " try 3 1691 call assert_report('should not get here') 1692 endtry " no rethrow to try 1 1693 catch /xyz/ " should catch although try 2 inactive 1694 Xpath 'b' 1695 endtry 1696 catch /xyz/ " try 1 active, but exception already caught 1697 call assert_report('should not get here') 1698 endtry 1699 Xpath 'c' 1700 [CODE] 1701 let verify =<< trim [CODE] 1702 call assert_equal('abc', g:Xpath) 1703 [CODE] 1704 call RunInNewVim(test, verify) 1705endfunc 1706 1707"------------------------------------------------------------------------------- 1708" Test 27: Executing :finally clauses after :return {{{1 1709" 1710" For a :return command dynamically enclosed in a :try/:endtry region, 1711" :finally clauses are executed and the called function is ended. 1712"------------------------------------------------------------------------------- 1713 1714func T27_F() 1715 try 1716 Xpath 'a' 1717 try 1718 Xpath 'b' 1719 return 1720 call assert_report('should not get here') 1721 finally 1722 Xpath 'c' 1723 endtry 1724 Xpath 'd' 1725 finally 1726 Xpath 'e' 1727 endtry 1728 call assert_report('should not get here') 1729endfunc 1730 1731func T27_G() 1732 try 1733 Xpath 'f' 1734 return 1735 call assert_report('should not get here') 1736 finally 1737 Xpath 'g' 1738 call T27_F() 1739 Xpath 'h' 1740 endtry 1741 call assert_report('should not get here') 1742endfunc 1743 1744func T27_H() 1745 try 1746 Xpath 'i' 1747 call T27_G() 1748 Xpath 'j' 1749 finally 1750 Xpath 'k' 1751 return 1752 call assert_report('should not get here') 1753 endtry 1754 call assert_report('should not get here') 1755endfunction 1756 1757func Test_finally_after_return() 1758 XpathINIT 1759 try 1760 Xpath 'l' 1761 call T27_H() 1762 Xpath 'm' 1763 finally 1764 Xpath 'n' 1765 endtry 1766 call assert_equal('lifgabcehjkmn', g:Xpath) 1767endfunc 1768 1769"------------------------------------------------------------------------------- 1770" Test 28: Executing :finally clauses after :finish {{{1 1771" 1772" For a :finish command dynamically enclosed in a :try/:endtry region, 1773" :finally clauses are executed and the sourced file is finished. 1774" 1775" This test executes the bodies of the functions F, G, and H from the 1776" previous test as script files (:return replaced by :finish). 1777"------------------------------------------------------------------------------- 1778 1779func Test_finally_after_finish() 1780 XpathINIT 1781 1782 let scriptF = MakeScript("T27_F") 1783 let scriptG = MakeScript("T27_G", scriptF) 1784 let scriptH = MakeScript("T27_H", scriptG) 1785 1786 try 1787 Xpath 'A' 1788 exec "source" scriptH 1789 Xpath 'B' 1790 finally 1791 Xpath 'C' 1792 endtry 1793 Xpath 'D' 1794 call assert_equal('AifgabcehjkBCD', g:Xpath) 1795 call delete(scriptF) 1796 call delete(scriptG) 1797 call delete(scriptH) 1798endfunc 1799 1800"------------------------------------------------------------------------------- 1801" Test 29: Executing :finally clauses on errors {{{1 1802" 1803" After an error in a command dynamically enclosed in a :try/:endtry 1804" region, :finally clauses are executed and the script processing is 1805" terminated. 1806"------------------------------------------------------------------------------- 1807 1808func Test_finally_after_error_1() 1809 let test =<< trim [CODE] 1810 func F() 1811 while 1 1812 try 1813 Xpath 'a' 1814 while 1 1815 try 1816 Xpath 'b' 1817 asdf " error 1818 call assert_report('should not get here') 1819 finally 1820 Xpath 'c' 1821 endtry | call assert_report('should not get here') 1822 call assert_report('should not get here') 1823 break 1824 endwhile 1825 call assert_report('should not get here') 1826 finally 1827 Xpath 'd' 1828 endtry | call assert_report('should not get here') 1829 call assert_report('should not get here') 1830 break 1831 endwhile 1832 call assert_report('should not get here') 1833 endfunc 1834 1835 while 1 1836 try 1837 Xpath 'e' 1838 while 1 1839 call F() 1840 call assert_report('should not get here') 1841 break 1842 endwhile | call assert_report('should not get here') 1843 call assert_report('should not get here') 1844 finally 1845 Xpath 'f' 1846 endtry | call assert_report('should not get here') 1847 endwhile | call assert_report('should not get here') 1848 call assert_report('should not get here') 1849 [CODE] 1850 let verify =<< trim [CODE] 1851 call assert_equal('eabcdf', g:Xpath) 1852 [CODE] 1853 call RunInNewVim(test, verify) 1854endfunc 1855 1856func Test_finally_after_error_2() 1857 let test =<< trim [CODE] 1858 func G() abort 1859 if 1 1860 try 1861 Xpath 'a' 1862 asdf " error 1863 call assert_report('should not get here') 1864 finally 1865 Xpath 'b' 1866 endtry | Xpath 'c' 1867 endif | Xpath 'd' 1868 call assert_report('should not get here') 1869 endfunc 1870 1871 if 1 1872 try 1873 Xpath 'e' 1874 call G() 1875 call assert_report('should not get here') 1876 finally 1877 Xpath 'f' 1878 endtry | call assert_report('should not get here') 1879 endif | call assert_report('should not get here') 1880 call assert_report('should not get here') 1881 [CODE] 1882 let verify =<< trim [CODE] 1883 call assert_equal('eabf', g:Xpath) 1884 [CODE] 1885 call RunInNewVim(test, verify) 1886endfunc 1887 1888"------------------------------------------------------------------------------- 1889" Test 30: Executing :finally clauses on interrupt {{{1 1890" 1891" After an interrupt in a command dynamically enclosed in 1892" a :try/:endtry region, :finally clauses are executed and the 1893" script processing is terminated. 1894"------------------------------------------------------------------------------- 1895 1896func Test_finally_on_interrupt() 1897 let test =<< trim [CODE] 1898 func F() 1899 try 1900 Xloop 'a' 1901 call interrupt() 1902 call assert_report('should not get here') 1903 finally 1904 Xloop 'b' 1905 endtry 1906 call assert_report('should not get here') 1907 endfunc 1908 1909 try 1910 try 1911 Xpath 'c' 1912 try 1913 Xpath 'd' 1914 call interrupt() 1915 call assert_report('should not get here') 1916 finally 1917 Xpath 'e' 1918 try 1919 Xpath 'f' 1920 try 1921 Xpath 'g' 1922 finally 1923 Xpath 'h' 1924 try 1925 Xpath 'i' 1926 call interrupt() 1927 call assert_report('should not get here') 1928 endtry 1929 call assert_report('should not get here') 1930 endtry 1931 call assert_report('should not get here') 1932 endtry 1933 call assert_report('should not get here') 1934 endtry 1935 call assert_report('should not get here') 1936 finally 1937 Xpath 'j' 1938 try 1939 Xpath 'k' 1940 call F() 1941 call assert_report('should not get here') 1942 finally 1943 Xpath 'l' 1944 try 1945 Xpath 'm' 1946 XloopNEXT 1947 ExecAsScript F 1948 call assert_report('should not get here') 1949 finally 1950 Xpath 'n' 1951 endtry 1952 call assert_report('should not get here') 1953 endtry 1954 call assert_report('should not get here') 1955 endtry 1956 call assert_report('should not get here') 1957 catch /^Vim:Interrupt$/ 1958 Xpath 'o' 1959 endtry 1960 [CODE] 1961 let verify =<< trim [CODE] 1962 call assert_equal('cdefghijka1b1lma2b2no', g:Xpath) 1963 [CODE] 1964 call RunInNewVim(test, verify) 1965endfunc 1966 1967"------------------------------------------------------------------------------- 1968" Test 31: Executing :finally clauses after :throw {{{1 1969" 1970" After a :throw dynamically enclosed in a :try/:endtry region, 1971" :finally clauses are executed and the script processing is 1972" terminated. 1973"------------------------------------------------------------------------------- 1974 1975func Test_finally_after_throw_2() 1976 let test =<< trim [CODE] 1977 func F() 1978 try 1979 Xloop 'a' 1980 throw "exception" 1981 call assert_report('should not get here') 1982 finally 1983 Xloop 'b' 1984 endtry 1985 call assert_report('should not get here') 1986 endfunc 1987 1988 try 1989 Xpath 'c' 1990 try 1991 Xpath 'd' 1992 throw "exception" 1993 call assert_report('should not get here') 1994 finally 1995 Xpath 'e' 1996 try 1997 Xpath 'f' 1998 try 1999 Xpath 'g' 2000 finally 2001 Xpath 'h' 2002 try 2003 Xpath 'i' 2004 throw "exception" 2005 call assert_report('should not get here') 2006 endtry 2007 call assert_report('should not get here') 2008 endtry 2009 call assert_report('should not get here') 2010 endtry 2011 call assert_report('should not get here') 2012 endtry 2013 call assert_report('should not get here') 2014 finally 2015 Xpath 'j' 2016 try 2017 Xpath 'k' 2018 call F() 2019 call assert_report('should not get here') 2020 finally 2021 Xpath 'l' 2022 try 2023 Xpath 'm' 2024 XloopNEXT 2025 ExecAsScript F 2026 call assert_report('should not get here') 2027 finally 2028 Xpath 'n' 2029 endtry 2030 call assert_report('should not get here') 2031 endtry 2032 call assert_report('should not get here') 2033 endtry 2034 call assert_report('should not get here') 2035 [CODE] 2036 let verify =<< trim [CODE] 2037 call assert_equal('cdefghijka1b1lma2b2n', g:Xpath) 2038 [CODE] 2039 call RunInNewVim(test, verify) 2040endfunc 2041 2042"------------------------------------------------------------------------------- 2043" Test 34: :finally reason discarded by :continue {{{1 2044" 2045" When a :finally clause is executed due to a :continue, :break, 2046" :return, :finish, error, interrupt or :throw, the jump reason is 2047" discarded by a :continue in the finally clause. 2048"------------------------------------------------------------------------------- 2049 2050func Test_finally_after_continue() 2051 let test =<< trim [CODE] 2052 func C(jump) 2053 XloopNEXT 2054 let loop = 0 2055 while loop < 2 2056 let loop = loop + 1 2057 if loop == 1 2058 try 2059 if a:jump == "continue" 2060 continue 2061 elseif a:jump == "break" 2062 break 2063 elseif a:jump == "return" || a:jump == "finish" 2064 return 2065 elseif a:jump == "error" 2066 asdf 2067 elseif a:jump == "interrupt" 2068 call interrupt() 2069 let dummy = 0 2070 elseif a:jump == "throw" 2071 throw "abc" 2072 endif 2073 finally 2074 continue " discards jump that caused the :finally 2075 call assert_report('should not get here') 2076 endtry 2077 call assert_report('should not get here') 2078 elseif loop == 2 2079 Xloop 'a' 2080 endif 2081 endwhile 2082 endfunc 2083 2084 call C("continue") 2085 Xpath 'b' 2086 call C("break") 2087 Xpath 'c' 2088 call C("return") 2089 Xpath 'd' 2090 let g:jump = "finish" 2091 ExecAsScript C 2092 unlet g:jump 2093 Xpath 'e' 2094 try 2095 call C("error") 2096 Xpath 'f' 2097 finally 2098 Xpath 'g' 2099 try 2100 call C("interrupt") 2101 Xpath 'h' 2102 finally 2103 Xpath 'i' 2104 call C("throw") 2105 Xpath 'j' 2106 endtry 2107 endtry 2108 Xpath 'k' 2109 [CODE] 2110 let verify =<< trim [CODE] 2111 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) 2112 [CODE] 2113 call RunInNewVim(test, verify) 2114endfunc 2115 2116"------------------------------------------------------------------------------- 2117" Test 35: :finally reason discarded by :break {{{1 2118" 2119" When a :finally clause is executed due to a :continue, :break, 2120" :return, :finish, error, interrupt or :throw, the jump reason is 2121" discarded by a :break in the finally clause. 2122"------------------------------------------------------------------------------- 2123 2124func Test_finally_discard_by_break() 2125 let test =<< trim [CODE] 2126 func B(jump) 2127 XloopNEXT 2128 let loop = 0 2129 while loop < 2 2130 let loop = loop + 1 2131 if loop == 1 2132 try 2133 if a:jump == "continue" 2134 continue 2135 elseif a:jump == "break" 2136 break 2137 elseif a:jump == "return" || a:jump == "finish" 2138 return 2139 elseif a:jump == "error" 2140 asdf 2141 elseif a:jump == "interrupt" 2142 call interrupt() 2143 let dummy = 0 2144 elseif a:jump == "throw" 2145 throw "abc" 2146 endif 2147 finally 2148 break " discards jump that caused the :finally 2149 call assert_report('should not get here') 2150 endtry 2151 elseif loop == 2 2152 call assert_report('should not get here') 2153 endif 2154 endwhile 2155 Xloop 'a' 2156 endfunc 2157 2158 call B("continue") 2159 Xpath 'b' 2160 call B("break") 2161 Xpath 'c' 2162 call B("return") 2163 Xpath 'd' 2164 let g:jump = "finish" 2165 ExecAsScript B 2166 unlet g:jump 2167 Xpath 'e' 2168 try 2169 call B("error") 2170 Xpath 'f' 2171 finally 2172 Xpath 'g' 2173 try 2174 call B("interrupt") 2175 Xpath 'h' 2176 finally 2177 Xpath 'i' 2178 call B("throw") 2179 Xpath 'j' 2180 endtry 2181 endtry 2182 Xpath 'k' 2183 [CODE] 2184 let verify =<< trim [CODE] 2185 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) 2186 [CODE] 2187 call RunInNewVim(test, verify) 2188endfunc 2189 2190"------------------------------------------------------------------------------- 2191" Test 36: :finally reason discarded by :return {{{1 2192" 2193" When a :finally clause is executed due to a :continue, :break, 2194" :return, :finish, error, interrupt or :throw, the jump reason is 2195" discarded by a :return in the finally clause. 2196"------------------------------------------------------------------------------- 2197 2198func Test_finally_discard_by_return() 2199 let test =<< trim [CODE] 2200 func R(jump, retval) abort 2201 let loop = 0 2202 while loop < 2 2203 let loop = loop + 1 2204 if loop == 1 2205 try 2206 if a:jump == "continue" 2207 continue 2208 elseif a:jump == "break" 2209 break 2210 elseif a:jump == "return" 2211 return 2212 elseif a:jump == "error" 2213 asdf 2214 elseif a:jump == "interrupt" 2215 call interrupt() 2216 let dummy = 0 2217 elseif a:jump == "throw" 2218 throw "abc" 2219 endif 2220 finally 2221 return a:retval " discards jump that caused the :finally 2222 call assert_report('should not get here') 2223 endtry 2224 elseif loop == 2 2225 call assert_report('should not get here') 2226 endif 2227 endwhile 2228 call assert_report('should not get here') 2229 endfunc 2230 2231 let sum = -R("continue", -8) 2232 Xpath 'a' 2233 let sum = sum - R("break", -16) 2234 Xpath 'b' 2235 let sum = sum - R("return", -32) 2236 Xpath 'c' 2237 try 2238 let sum = sum - R("error", -64) 2239 Xpath 'd' 2240 finally 2241 Xpath 'e' 2242 try 2243 let sum = sum - R("interrupt", -128) 2244 Xpath 'f' 2245 finally 2246 Xpath 'g' 2247 let sum = sum - R("throw", -256) 2248 Xpath 'h' 2249 endtry 2250 endtry 2251 Xpath 'i' 2252 2253 let expected = 8 + 16 + 32 + 64 + 128 + 256 2254 call assert_equal(sum, expected) 2255 [CODE] 2256 let verify =<< trim [CODE] 2257 call assert_equal('abcdefghi', g:Xpath) 2258 [CODE] 2259 call RunInNewVim(test, verify) 2260endfunc 2261 2262"------------------------------------------------------------------------------- 2263" Test 37: :finally reason discarded by :finish {{{1 2264" 2265" When a :finally clause is executed due to a :continue, :break, 2266" :return, :finish, error, interrupt or :throw, the jump reason is 2267" discarded by a :finish in the finally clause. 2268"------------------------------------------------------------------------------- 2269 2270func Test_finally_discard_by_finish() 2271 let test =<< trim [CODE] 2272 func F(jump) " not executed as function, transformed to a script 2273 let loop = 0 2274 while loop < 2 2275 let loop = loop + 1 2276 if loop == 1 2277 try 2278 if a:jump == "continue" 2279 continue 2280 elseif a:jump == "break" 2281 break 2282 elseif a:jump == "finish" 2283 finish 2284 elseif a:jump == "error" 2285 asdf 2286 elseif a:jump == "interrupt" 2287 call interrupt() 2288 let dummy = 0 2289 elseif a:jump == "throw" 2290 throw "abc" 2291 endif 2292 finally 2293 finish " discards jump that caused the :finally 2294 call assert_report('should not get here') 2295 endtry 2296 elseif loop == 2 2297 call assert_report('should not get here') 2298 endif 2299 endwhile 2300 call assert_report('should not get here') 2301 endfunc 2302 2303 let scriptF = MakeScript("F") 2304 delfunction F 2305 2306 let g:jump = "continue" 2307 exec "source" scriptF 2308 Xpath 'a' 2309 let g:jump = "break" 2310 exec "source" scriptF 2311 Xpath 'b' 2312 let g:jump = "finish" 2313 exec "source" scriptF 2314 Xpath 'c' 2315 try 2316 let g:jump = "error" 2317 exec "source" scriptF 2318 Xpath 'd' 2319 finally 2320 Xpath 'e' 2321 try 2322 let g:jump = "interrupt" 2323 exec "source" scriptF 2324 Xpath 'f' 2325 finally 2326 Xpath 'g' 2327 try 2328 let g:jump = "throw" 2329 exec "source" scriptF 2330 Xpath 'h' 2331 finally 2332 Xpath 'i' 2333 endtry 2334 endtry 2335 endtry 2336 unlet g:jump 2337 call delete(scriptF) 2338 [CODE] 2339 let verify =<< trim [CODE] 2340 call assert_equal('abcdefghi', g:Xpath) 2341 [CODE] 2342 call RunInNewVim(test, verify) 2343endfunc 2344 2345"------------------------------------------------------------------------------- 2346" Test 38: :finally reason discarded by an error {{{1 2347" 2348" When a :finally clause is executed due to a :continue, :break, 2349" :return, :finish, error, interrupt or :throw, the jump reason is 2350" discarded by an error in the finally clause. 2351"------------------------------------------------------------------------------- 2352 2353func Test_finally_discard_by_error() 2354 let test =<< trim [CODE] 2355 func E(jump) 2356 let loop = 0 2357 while loop < 2 2358 let loop = loop + 1 2359 if loop == 1 2360 try 2361 if a:jump == "continue" 2362 continue 2363 elseif a:jump == "break" 2364 break 2365 elseif a:jump == "return" || a:jump == "finish" 2366 return 2367 elseif a:jump == "error" 2368 asdf 2369 elseif a:jump == "interrupt" 2370 call interrupt() 2371 let dummy = 0 2372 elseif a:jump == "throw" 2373 throw "abc" 2374 endif 2375 finally 2376 asdf " error; discards jump that caused the :finally 2377 endtry 2378 elseif loop == 2 2379 call assert_report('should not get here') 2380 endif 2381 endwhile 2382 call assert_report('should not get here') 2383 endfunc 2384 2385 try 2386 Xpath 'a' 2387 call E("continue") 2388 call assert_report('should not get here') 2389 finally 2390 try 2391 Xpath 'b' 2392 call E("break") 2393 call assert_report('should not get here') 2394 finally 2395 try 2396 Xpath 'c' 2397 call E("return") 2398 call assert_report('should not get here') 2399 finally 2400 try 2401 Xpath 'd' 2402 let g:jump = "finish" 2403 ExecAsScript E 2404 call assert_report('should not get here') 2405 finally 2406 unlet g:jump 2407 try 2408 Xpath 'e' 2409 call E("error") 2410 call assert_report('should not get here') 2411 finally 2412 try 2413 Xpath 'f' 2414 call E("interrupt") 2415 call assert_report('should not get here') 2416 finally 2417 try 2418 Xpath 'g' 2419 call E("throw") 2420 call assert_report('should not get here') 2421 finally 2422 Xpath 'h' 2423 delfunction E 2424 endtry 2425 endtry 2426 endtry 2427 endtry 2428 endtry 2429 endtry 2430 endtry 2431 call assert_report('should not get here') 2432 [CODE] 2433 let verify =<< trim [CODE] 2434 call assert_equal('abcdefgh', g:Xpath) 2435 [CODE] 2436 call RunInNewVim(test, verify) 2437endfunc 2438 2439"------------------------------------------------------------------------------- 2440" Test 39: :finally reason discarded by an interrupt {{{1 2441" 2442" When a :finally clause is executed due to a :continue, :break, 2443" :return, :finish, error, interrupt or :throw, the jump reason is 2444" discarded by an interrupt in the finally clause. 2445"------------------------------------------------------------------------------- 2446 2447func Test_finally_discarded_by_interrupt() 2448 let test =<< trim [CODE] 2449 func I(jump) 2450 let loop = 0 2451 while loop < 2 2452 let loop = loop + 1 2453 if loop == 1 2454 try 2455 if a:jump == "continue" 2456 continue 2457 elseif a:jump == "break" 2458 break 2459 elseif a:jump == "return" || a:jump == "finish" 2460 return 2461 elseif a:jump == "error" 2462 asdf 2463 elseif a:jump == "interrupt" 2464 call interrupt() 2465 let dummy = 0 2466 elseif a:jump == "throw" 2467 throw "abc" 2468 endif 2469 finally 2470 call interrupt() 2471 let dummy = 0 2472 endtry 2473 elseif loop == 2 2474 call assert_report('should not get here') 2475 endif 2476 endwhile 2477 call assert_report('should not get here') 2478 endfunc 2479 2480 try 2481 try 2482 Xpath 'a' 2483 call I("continue") 2484 call assert_report('should not get here') 2485 finally 2486 try 2487 Xpath 'b' 2488 call I("break") 2489 call assert_report('should not get here') 2490 finally 2491 try 2492 Xpath 'c' 2493 call I("return") 2494 call assert_report('should not get here') 2495 finally 2496 try 2497 Xpath 'd' 2498 let g:jump = "finish" 2499 ExecAsScript I 2500 call assert_report('should not get here') 2501 finally 2502 unlet g:jump 2503 try 2504 Xpath 'e' 2505 call I("error") 2506 call assert_report('should not get here') 2507 finally 2508 try 2509 Xpath 'f' 2510 call I("interrupt") 2511 call assert_report('should not get here') 2512 finally 2513 try 2514 Xpath 'g' 2515 call I("throw") 2516 call assert_report('should not get here') 2517 finally 2518 Xpath 'h' 2519 delfunction I 2520 endtry 2521 endtry 2522 endtry 2523 endtry 2524 endtry 2525 endtry 2526 endtry 2527 call assert_report('should not get here') 2528 catch /^Vim:Interrupt$/ 2529 Xpath 'A' 2530 endtry 2531 [CODE] 2532 let verify =<< trim [CODE] 2533 call assert_equal('abcdefghA', g:Xpath) 2534 [CODE] 2535 call RunInNewVim(test, verify) 2536endfunc 2537 2538"------------------------------------------------------------------------------- 2539" Test 40: :finally reason discarded by :throw {{{1 2540" 2541" When a :finally clause is executed due to a :continue, :break, 2542" :return, :finish, error, interrupt or :throw, the jump reason is 2543" discarded by a :throw in the finally clause. 2544"------------------------------------------------------------------------------- 2545 2546func Test_finally_discard_by_throw() 2547 let test =<< trim [CODE] 2548 func T(jump) 2549 let loop = 0 2550 while loop < 2 2551 let loop = loop + 1 2552 if loop == 1 2553 try 2554 if a:jump == "continue" 2555 continue 2556 elseif a:jump == "break" 2557 break 2558 elseif a:jump == "return" || a:jump == "finish" 2559 return 2560 elseif a:jump == "error" 2561 asdf 2562 elseif a:jump == "interrupt" 2563 call interrupt() 2564 let dummy = 0 2565 elseif a:jump == "throw" 2566 throw "abc" 2567 endif 2568 finally 2569 throw "xyz" " discards jump that caused the :finally 2570 endtry 2571 elseif loop == 2 2572 call assert_report('should not get here') 2573 endif 2574 endwhile 2575 call assert_report('should not get here') 2576 endfunc 2577 2578 try 2579 Xpath 'a' 2580 call T("continue") 2581 call assert_report('should not get here') 2582 finally 2583 try 2584 Xpath 'b' 2585 call T("break") 2586 call assert_report('should not get here') 2587 finally 2588 try 2589 Xpath 'c' 2590 call T("return") 2591 call assert_report('should not get here') 2592 finally 2593 try 2594 Xpath 'd' 2595 let g:jump = "finish" 2596 ExecAsScript T 2597 call assert_report('should not get here') 2598 finally 2599 unlet g:jump 2600 try 2601 Xpath 'e' 2602 call T("error") 2603 call assert_report('should not get here') 2604 finally 2605 try 2606 Xpath 'f' 2607 call T("interrupt") 2608 call assert_report('should not get here') 2609 finally 2610 try 2611 Xpath 'g' 2612 call T("throw") 2613 call assert_report('should not get here') 2614 finally 2615 Xpath 'h' 2616 delfunction T 2617 endtry 2618 endtry 2619 endtry 2620 endtry 2621 endtry 2622 endtry 2623 endtry 2624 call assert_report('should not get here') 2625 [CODE] 2626 let verify =<< trim [CODE] 2627 call assert_equal('abcdefgh', g:Xpath) 2628 [CODE] 2629 call RunInNewVim(test, verify) 2630endfunc 2631 2632"------------------------------------------------------------------------------- 2633" Test 49: Throwing exceptions across functions {{{1 2634" 2635" When an exception is thrown but not caught inside a function, the 2636" caller is checked for a matching :catch clause. 2637"------------------------------------------------------------------------------- 2638 2639func T49_C() 2640 try 2641 Xpath 'a' 2642 throw "arrgh" 2643 call assert_report('should not get here') 2644 catch /arrgh/ 2645 Xpath 'b' 2646 endtry 2647 Xpath 'c' 2648endfunc 2649 2650func T49_T1() 2651 XloopNEXT 2652 try 2653 Xloop 'd' 2654 throw "arrgh" 2655 call assert_report('should not get here') 2656 finally 2657 Xloop 'e' 2658 endtry 2659 Xloop 'f' 2660endfunc 2661 2662func T49_T2() 2663 try 2664 Xpath 'g' 2665 call T49_T1() 2666 call assert_report('should not get here') 2667 finally 2668 Xpath 'h' 2669 endtry 2670 call assert_report('should not get here') 2671endfunc 2672 2673func Test_throw_exception_across_funcs() 2674 XpathINIT 2675 XloopINIT 2676 try 2677 Xpath 'i' 2678 call T49_C() " throw and catch 2679 Xpath 'j' 2680 catch /.*/ 2681 call assert_report('should not get here') 2682 endtry 2683 2684 try 2685 Xpath 'k' 2686 call T49_T1() " throw, one level 2687 call assert_report('should not get here') 2688 catch /arrgh/ 2689 Xpath 'l' 2690 catch /.*/ 2691 call assert_report('should not get here') 2692 endtry 2693 2694 try 2695 Xpath 'm' 2696 call T49_T2() " throw, two levels 2697 call assert_report('should not get here') 2698 catch /arrgh/ 2699 Xpath 'n' 2700 catch /.*/ 2701 call assert_report('should not get here') 2702 endtry 2703 Xpath 'o' 2704 2705 call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath) 2706endfunc 2707 2708"------------------------------------------------------------------------------- 2709" Test 50: Throwing exceptions across script files {{{1 2710" 2711" When an exception is thrown but not caught inside a script file, 2712" the sourcing script or function is checked for a matching :catch 2713" clause. 2714" 2715" This test executes the bodies of the functions C, T1, and T2 from 2716" the previous test as script files (:return replaced by :finish). 2717"------------------------------------------------------------------------------- 2718 2719func T50_F() 2720 try 2721 Xpath 'A' 2722 exec "source" g:scriptC 2723 Xpath 'B' 2724 catch /.*/ 2725 call assert_report('should not get here') 2726 endtry 2727 2728 try 2729 Xpath 'C' 2730 exec "source" g:scriptT1 2731 call assert_report('should not get here') 2732 catch /arrgh/ 2733 Xpath 'D' 2734 catch /.*/ 2735 call assert_report('should not get here') 2736 endtry 2737endfunc 2738 2739func Test_throw_across_script() 2740 XpathINIT 2741 XloopINIT 2742 let g:scriptC = MakeScript("T49_C") 2743 let g:scriptT1 = MakeScript("T49_T1") 2744 let scriptT2 = MakeScript("T49_T2", g:scriptT1) 2745 2746 try 2747 Xpath 'E' 2748 call T50_F() 2749 Xpath 'F' 2750 exec "source" scriptT2 2751 call assert_report('should not get here') 2752 catch /arrgh/ 2753 Xpath 'G' 2754 catch /.*/ 2755 call assert_report('should not get here') 2756 endtry 2757 Xpath 'H' 2758 call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath) 2759 2760 call delete(g:scriptC) 2761 call delete(g:scriptT1) 2762 call delete(scriptT2) 2763 unlet g:scriptC g:scriptT1 scriptT2 2764endfunc 2765 2766"------------------------------------------------------------------------------- 2767" Test 87 using (expr) ? funcref : funcref {{{1 2768" 2769" Vim needs to correctly parse the funcref and even when it does 2770" not execute the funcref, it needs to consume the trailing () 2771"------------------------------------------------------------------------------- 2772 2773func Add2(x1, x2) 2774 return a:x1 + a:x2 2775endfu 2776 2777func GetStr() 2778 return "abcdefghijklmnopqrstuvwxyp" 2779endfu 2780 2781func Test_funcref_with_condexpr() 2782 call assert_equal(5, function('Add2')(2,3)) 2783 2784 call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3)) 2785 call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3)) 2786 " Make sure, GetStr() still works. 2787 call assert_equal('abcdefghijk', GetStr()[0:10]) 2788endfunc 2789 2790" Test 90: Recognizing {} in variable name. {{{1 2791"------------------------------------------------------------------------------- 2792 2793func Test_curlies() 2794 let s:var = 66 2795 let ns = 's' 2796 call assert_equal(66, {ns}:var) 2797 2798 let g:a = {} 2799 let g:b = 't' 2800 let g:a[g:b] = 77 2801 call assert_equal(77, g:a['t']) 2802endfunc 2803 2804"------------------------------------------------------------------------------- 2805" Test 91: using type(). {{{1 2806"------------------------------------------------------------------------------- 2807 2808func Test_type() 2809 call assert_equal(0, type(0)) 2810 call assert_equal(1, type("")) 2811 call assert_equal(2, type(function("tr"))) 2812 call assert_equal(2, type(function("tr", [8]))) 2813 call assert_equal(3, type([])) 2814 call assert_equal(4, type({})) 2815 if has('float') 2816 call assert_equal(5, type(0.0)) 2817 endif 2818 call assert_equal(6, type(v:false)) 2819 call assert_equal(6, type(v:true)) 2820 call assert_equal(7, type(v:none)) 2821 call assert_equal(7, type(v:null)) 2822 call assert_equal(8, v:t_job) 2823 call assert_equal(9, v:t_channel) 2824 call assert_equal(v:t_number, type(0)) 2825 call assert_equal(v:t_string, type("")) 2826 call assert_equal(v:t_func, type(function("tr"))) 2827 call assert_equal(v:t_func, type(function("tr", [8]))) 2828 call assert_equal(v:t_list, type([])) 2829 call assert_equal(v:t_dict, type({})) 2830 if has('float') 2831 call assert_equal(v:t_float, type(0.0)) 2832 endif 2833 call assert_equal(v:t_bool, type(v:false)) 2834 call assert_equal(v:t_bool, type(v:true)) 2835 call assert_equal(v:t_none, type(v:none)) 2836 call assert_equal(v:t_none, type(v:null)) 2837 call assert_equal(v:t_string, type(test_null_string())) 2838 call assert_equal(v:t_func, type(test_null_function())) 2839 call assert_equal(v:t_func, type(test_null_partial())) 2840 call assert_equal(v:t_list, type(test_null_list())) 2841 call assert_equal(v:t_dict, type(test_null_dict())) 2842 if has('job') 2843 call assert_equal(v:t_job, type(test_null_job())) 2844 endif 2845 if has('channel') 2846 call assert_equal(v:t_channel, type(test_null_channel())) 2847 endif 2848 call assert_equal(v:t_blob, type(test_null_blob())) 2849 2850 call assert_fails("call type(test_void())", 'E685:') 2851 call assert_fails("call type(test_unknown())", 'E685:') 2852 2853 call assert_equal(0, 0 + v:false) 2854 call assert_equal(1, 0 + v:true) 2855 call assert_equal(0, 0 + v:none) 2856 call assert_equal(0, 0 + v:null) 2857 2858 call assert_equal('v:false', '' . v:false) 2859 call assert_equal('v:true', '' . v:true) 2860 call assert_equal('v:none', '' . v:none) 2861 call assert_equal('v:null', '' . v:null) 2862 2863 call assert_true(v:false == 0) 2864 call assert_false(v:false != 0) 2865 call assert_true(v:true == 1) 2866 call assert_false(v:true != 1) 2867 call assert_false(v:true == v:false) 2868 call assert_true(v:true != v:false) 2869 2870 call assert_true(v:null == 0) 2871 call assert_false(v:null != 0) 2872 call assert_true(v:none == 0) 2873 call assert_false(v:none != 0) 2874 2875 call assert_true(v:false is v:false) 2876 call assert_true(v:true is v:true) 2877 call assert_true(v:none is v:none) 2878 call assert_true(v:null is v:null) 2879 2880 call assert_false(v:false isnot v:false) 2881 call assert_false(v:true isnot v:true) 2882 call assert_false(v:none isnot v:none) 2883 call assert_false(v:null isnot v:null) 2884 2885 call assert_false(v:false is 0) 2886 call assert_false(v:true is 1) 2887 call assert_false(v:true is v:false) 2888 call assert_false(v:none is 0) 2889 call assert_false(v:null is 0) 2890 call assert_false(v:null is v:none) 2891 2892 call assert_true(v:false isnot 0) 2893 call assert_true(v:true isnot 1) 2894 call assert_true(v:true isnot v:false) 2895 call assert_true(v:none isnot 0) 2896 call assert_true(v:null isnot 0) 2897 call assert_true(v:null isnot v:none) 2898 2899 call assert_equal(v:false, eval(string(v:false))) 2900 call assert_equal(v:true, eval(string(v:true))) 2901 call assert_equal(v:none, eval(string(v:none))) 2902 call assert_equal(v:null, eval(string(v:null))) 2903 2904 call assert_equal(v:false, copy(v:false)) 2905 call assert_equal(v:true, copy(v:true)) 2906 call assert_equal(v:none, copy(v:none)) 2907 call assert_equal(v:null, copy(v:null)) 2908 2909 call assert_equal([v:false], deepcopy([v:false])) 2910 call assert_equal([v:true], deepcopy([v:true])) 2911 call assert_equal([v:none], deepcopy([v:none])) 2912 call assert_equal([v:null], deepcopy([v:null])) 2913 2914 call assert_true(empty(v:false)) 2915 call assert_false(empty(v:true)) 2916 call assert_true(empty(v:null)) 2917 call assert_true(empty(v:none)) 2918 2919 func ChangeYourMind() 2920 try 2921 return v:true 2922 finally 2923 return 'something else' 2924 endtry 2925 endfunc 2926 2927 call ChangeYourMind() 2928endfunc 2929 2930"------------------------------------------------------------------------------- 2931" Test 92: skipping code {{{1 2932"------------------------------------------------------------------------------- 2933 2934func Test_skip() 2935 let Fn = function('Test_type') 2936 call assert_false(0 && Fn[1]) 2937 call assert_false(0 && string(Fn)) 2938 call assert_false(0 && len(Fn)) 2939 let l = [] 2940 call assert_false(0 && l[1]) 2941 call assert_false(0 && string(l)) 2942 call assert_false(0 && len(l)) 2943 let f = 1.0 2944 call assert_false(0 && f[1]) 2945 call assert_false(0 && string(f)) 2946 call assert_false(0 && len(f)) 2947 let sp = v:null 2948 call assert_false(0 && sp[1]) 2949 call assert_false(0 && string(sp)) 2950 call assert_false(0 && len(sp)) 2951 2952endfunc 2953 2954"------------------------------------------------------------------------------- 2955" Test 93: :echo and string() {{{1 2956"------------------------------------------------------------------------------- 2957 2958func Test_echo_and_string() 2959 " String 2960 let a = 'foo bar' 2961 redir => result 2962 echo a 2963 echo string(a) 2964 redir END 2965 let l = split(result, "\n") 2966 call assert_equal(["foo bar", 2967 \ "'foo bar'"], l) 2968 2969 " Float 2970 if has('float') 2971 let a = -1.2e0 2972 redir => result 2973 echo a 2974 echo string(a) 2975 redir END 2976 let l = split(result, "\n") 2977 call assert_equal(["-1.2", 2978 \ "-1.2"], l) 2979 endif 2980 2981 " Funcref 2982 redir => result 2983 echo function('string') 2984 echo string(function('string')) 2985 redir END 2986 let l = split(result, "\n") 2987 call assert_equal(["string", 2988 \ "function('string')"], l) 2989 2990 " Recursive dictionary 2991 let a = {} 2992 let a["a"] = a 2993 redir => result 2994 echo a 2995 echo string(a) 2996 redir END 2997 let l = split(result, "\n") 2998 call assert_equal(["{'a': {...}}", 2999 \ "{'a': {...}}"], l) 3000 3001 " Recursive list 3002 let a = [0] 3003 let a[0] = a 3004 redir => result 3005 echo a 3006 echo string(a) 3007 redir END 3008 let l = split(result, "\n") 3009 call assert_equal(["[[...]]", 3010 \ "[[...]]"], l) 3011 3012 " Empty dictionaries in a list 3013 let a = {} 3014 redir => result 3015 echo [a, a, a] 3016 echo string([a, a, a]) 3017 redir END 3018 let l = split(result, "\n") 3019 call assert_equal(["[{}, {}, {}]", 3020 \ "[{}, {}, {}]"], l) 3021 3022 " Empty dictionaries in a dictionary 3023 let a = {} 3024 let b = {"a": a, "b": a} 3025 redir => result 3026 echo b 3027 echo string(b) 3028 redir END 3029 let l = split(result, "\n") 3030 call assert_equal(["{'a': {}, 'b': {}}", 3031 \ "{'a': {}, 'b': {}}"], l) 3032 3033 " Empty lists in a list 3034 let a = [] 3035 redir => result 3036 echo [a, a, a] 3037 echo string([a, a, a]) 3038 redir END 3039 let l = split(result, "\n") 3040 call assert_equal(["[[], [], []]", 3041 \ "[[], [], []]"], l) 3042 3043 " Empty lists in a dictionary 3044 let a = [] 3045 let b = {"a": a, "b": a} 3046 redir => result 3047 echo b 3048 echo string(b) 3049 redir END 3050 let l = split(result, "\n") 3051 call assert_equal(["{'a': [], 'b': []}", 3052 \ "{'a': [], 'b': []}"], l) 3053 3054 " Dictionaries in a list 3055 let a = {"one": "yes", "two": "yes", "three": "yes"} 3056 redir => result 3057 echo [a, a, a] 3058 echo string([a, a, a]) 3059 redir END 3060 let l = split(result, "\n") 3061 call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]", 3062 \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l) 3063 3064 " Dictionaries in a dictionary 3065 let a = {"one": "yes", "two": "yes", "three": "yes"} 3066 let b = {"a": a, "b": a} 3067 redir => result 3068 echo b 3069 echo string(b) 3070 redir END 3071 let l = split(result, "\n") 3072 call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}", 3073 \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l) 3074 3075 " Lists in a list 3076 let a = [1, 2, 3] 3077 redir => result 3078 echo [a, a, a] 3079 echo string([a, a, a]) 3080 redir END 3081 let l = split(result, "\n") 3082 call assert_equal(["[[1, 2, 3], [...], [...]]", 3083 \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l) 3084 3085 " Lists in a dictionary 3086 let a = [1, 2, 3] 3087 let b = {"a": a, "b": a} 3088 redir => result 3089 echo b 3090 echo string(b) 3091 redir END 3092 let l = split(result, "\n") 3093 call assert_equal(["{'a': [1, 2, 3], 'b': [...]}", 3094 \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l) 3095 3096 call assert_fails('echo &:', 'E112:') 3097 call assert_fails('echo &g:', 'E112:') 3098 call assert_fails('echo &l:', 'E112:') 3099 3100endfunc 3101 3102"------------------------------------------------------------------------------- 3103" Test 94: 64-bit Numbers {{{1 3104"------------------------------------------------------------------------------- 3105 3106func Test_num64() 3107 call assert_notequal( 4294967296, 0) 3108 call assert_notequal(-4294967296, 0) 3109 call assert_equal( 4294967296, 0xFFFFffff + 1) 3110 call assert_equal(-4294967296, -0xFFFFffff - 1) 3111 3112 call assert_equal( 9223372036854775807, 1 / 0) 3113 call assert_equal(-9223372036854775807, -1 / 0) 3114 call assert_equal(-9223372036854775807 - 1, 0 / 0) 3115 3116 if has('float') 3117 call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150)) 3118 call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150)) 3119 endif 3120 3121 let rng = range(0xFFFFffff, 0x100000001) 3122 call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng) 3123 call assert_equal(0x100000001, max(rng)) 3124 call assert_equal(0xFFFFffff, min(rng)) 3125 call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N')) 3126endfunc 3127 3128"------------------------------------------------------------------------------- 3129" Test 95: lines of :append, :change, :insert {{{1 3130"------------------------------------------------------------------------------- 3131 3132function! DefineFunction(name, body) 3133 let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n") 3134 exec func 3135endfunction 3136 3137func Test_script_lines() 3138 " :append 3139 try 3140 call DefineFunction('T_Append', [ 3141 \ 'append', 3142 \ 'py <<EOS', 3143 \ '.', 3144 \ ]) 3145 catch 3146 call assert_report("Can't define function") 3147 endtry 3148 try 3149 call DefineFunction('T_Append', [ 3150 \ 'append', 3151 \ 'abc', 3152 \ ]) 3153 call assert_report("Shouldn't be able to define function") 3154 catch 3155 call assert_exception('Vim(function):E126: Missing :endfunction') 3156 endtry 3157 3158 " :change 3159 try 3160 call DefineFunction('T_Change', [ 3161 \ 'change', 3162 \ 'py <<EOS', 3163 \ '.', 3164 \ ]) 3165 catch 3166 call assert_report("Can't define function") 3167 endtry 3168 try 3169 call DefineFunction('T_Change', [ 3170 \ 'change', 3171 \ 'abc', 3172 \ ]) 3173 call assert_report("Shouldn't be able to define function") 3174 catch 3175 call assert_exception('Vim(function):E126: Missing :endfunction') 3176 endtry 3177 3178 " :insert 3179 try 3180 call DefineFunction('T_Insert', [ 3181 \ 'insert', 3182 \ 'py <<EOS', 3183 \ '.', 3184 \ ]) 3185 catch 3186 call assert_report("Can't define function") 3187 endtry 3188 try 3189 call DefineFunction('T_Insert', [ 3190 \ 'insert', 3191 \ 'abc', 3192 \ ]) 3193 call assert_report("Shouldn't be able to define function") 3194 catch 3195 call assert_exception('Vim(function):E126: Missing :endfunction') 3196 endtry 3197endfunc 3198 3199"------------------------------------------------------------------------------- 3200" Test 96: line continuation {{{1 3201" 3202" Undefined behavior was detected by ubsan with line continuation 3203" after an empty line. 3204"------------------------------------------------------------------------------- 3205func Test_script_emty_line_continuation() 3206 3207 \ 3208endfunc 3209 3210"------------------------------------------------------------------------------- 3211" Test 97: bitwise functions {{{1 3212"------------------------------------------------------------------------------- 3213func Test_bitwise_functions() 3214 " and 3215 call assert_equal(127, and(127, 127)) 3216 call assert_equal(16, and(127, 16)) 3217 eval 127->and(16)->assert_equal(16) 3218 call assert_equal(0, and(127, 128)) 3219 call assert_fails("call and([], 1)", 'E745:') 3220 call assert_fails("call and({}, 1)", 'E728:') 3221 if has('float') 3222 call assert_fails("call and(1.0, 1)", 'E805:') 3223 call assert_fails("call and(1, 1.0)", 'E805:') 3224 endif 3225 call assert_fails("call and(1, [])", 'E745:') 3226 call assert_fails("call and(1, {})", 'E728:') 3227 " or 3228 call assert_equal(23, or(16, 7)) 3229 call assert_equal(15, or(8, 7)) 3230 eval 8->or(7)->assert_equal(15) 3231 call assert_equal(123, or(0, 123)) 3232 call assert_fails("call or([], 1)", 'E745:') 3233 call assert_fails("call or({}, 1)", 'E728:') 3234 if has('float') 3235 call assert_fails("call or(1.0, 1)", 'E805:') 3236 call assert_fails("call or(1, 1.0)", 'E805:') 3237 endif 3238 call assert_fails("call or(1, [])", 'E745:') 3239 call assert_fails("call or(1, {})", 'E728:') 3240 " xor 3241 call assert_equal(0, xor(127, 127)) 3242 call assert_equal(111, xor(127, 16)) 3243 eval 127->xor(16)->assert_equal(111) 3244 call assert_equal(255, xor(127, 128)) 3245 if has('float') 3246 call assert_fails("call xor(1.0, 1)", 'E805:') 3247 call assert_fails("call xor(1, 1.0)", 'E805:') 3248 endif 3249 call assert_fails("call xor([], 1)", 'E745:') 3250 call assert_fails("call xor({}, 1)", 'E728:') 3251 call assert_fails("call xor(1, [])", 'E745:') 3252 call assert_fails("call xor(1, {})", 'E728:') 3253 " invert 3254 call assert_equal(65408, and(invert(127), 65535)) 3255 eval 127->invert()->and(65535)->assert_equal(65408) 3256 call assert_equal(65519, and(invert(16), 65535)) 3257 call assert_equal(65407, and(invert(128), 65535)) 3258 if has('float') 3259 call assert_fails("call invert(1.0)", 'E805:') 3260 endif 3261 call assert_fails("call invert([])", 'E745:') 3262 call assert_fails("call invert({})", 'E728:') 3263endfunc 3264 3265" Test using bang after user command {{{1 3266func Test_user_command_with_bang() 3267 command -bang Nieuw let nieuw = 1 3268 Ni! 3269 call assert_equal(1, nieuw) 3270 unlet nieuw 3271 delcommand Nieuw 3272endfunc 3273 3274func Test_script_expand_sfile() 3275 let lines =<< trim END 3276 func s:snr() 3277 return expand('<sfile>') 3278 endfunc 3279 let g:result = s:snr() 3280 END 3281 call writefile(lines, 'Xexpand') 3282 source Xexpand 3283 call assert_match('<SNR>\d\+_snr', g:result) 3284 source Xexpand 3285 call assert_match('<SNR>\d\+_snr', g:result) 3286 3287 call delete('Xexpand') 3288 unlet g:result 3289endfunc 3290 3291func Test_compound_assignment_operators() 3292 " Test for number 3293 let x = 1 3294 let x += 10 3295 call assert_equal(11, x) 3296 let x -= 5 3297 call assert_equal(6, x) 3298 let x *= 4 3299 call assert_equal(24, x) 3300 let x /= 3 3301 call assert_equal(8, x) 3302 let x %= 3 3303 call assert_equal(2, x) 3304 let x .= 'n' 3305 call assert_equal('2n', x) 3306 3307 " Test special cases: division or modulus with 0. 3308 let x = 1 3309 let x /= 0 3310 call assert_equal(0x7FFFFFFFFFFFFFFF, x) 3311 3312 let x = -1 3313 let x /= 0 3314 call assert_equal(-0x7FFFFFFFFFFFFFFF, x) 3315 3316 let x = 0 3317 let x /= 0 3318 call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x) 3319 3320 let x = 1 3321 let x %= 0 3322 call assert_equal(0, x) 3323 3324 let x = -1 3325 let x %= 0 3326 call assert_equal(0, x) 3327 3328 let x = 0 3329 let x %= 0 3330 call assert_equal(0, x) 3331 3332 " Test for string 3333 let x = 'str' 3334 let x .= 'ing' 3335 call assert_equal('string', x) 3336 let x += 1 3337 call assert_equal(1, x) 3338 3339 if has('float') 3340 " Test for float 3341 let x -= 1.5 3342 call assert_equal(-0.5, x) 3343 let x = 0.5 3344 let x += 4.5 3345 call assert_equal(5.0, x) 3346 let x -= 1.5 3347 call assert_equal(3.5, x) 3348 let x *= 3.0 3349 call assert_equal(10.5, x) 3350 let x /= 2.5 3351 call assert_equal(4.2, x) 3352 call assert_fails('let x %= 0.5', 'E734') 3353 call assert_fails('let x .= "f"', 'E734') 3354 let x = !3.14 3355 call assert_equal(0.0, x) 3356 3357 " integer and float operations 3358 let x = 1 3359 let x *= 2.1 3360 call assert_equal(2.1, x) 3361 let x = 1 3362 let x /= 0.25 3363 call assert_equal(4.0, x) 3364 let x = 1 3365 call assert_fails('let x %= 0.25', 'E734:') 3366 let x = 1 3367 call assert_fails('let x .= 0.25', 'E734:') 3368 let x = 1.0 3369 call assert_fails('let x += [1.1]', 'E734:') 3370 endif 3371 3372 " Test for environment variable 3373 let $FOO = 1 3374 call assert_fails('let $FOO += 1', 'E734') 3375 call assert_fails('let $FOO -= 1', 'E734') 3376 call assert_fails('let $FOO *= 1', 'E734') 3377 call assert_fails('let $FOO /= 1', 'E734') 3378 call assert_fails('let $FOO %= 1', 'E734') 3379 let $FOO .= 's' 3380 call assert_equal('1s', $FOO) 3381 unlet $FOO 3382 3383 " Test for option variable (type: number) 3384 let &scrolljump = 1 3385 let &scrolljump += 5 3386 call assert_equal(6, &scrolljump) 3387 let &scrolljump -= 2 3388 call assert_equal(4, &scrolljump) 3389 let &scrolljump *= 3 3390 call assert_equal(12, &scrolljump) 3391 let &scrolljump /= 2 3392 call assert_equal(6, &scrolljump) 3393 let &scrolljump %= 5 3394 call assert_equal(1, &scrolljump) 3395 call assert_fails('let &scrolljump .= "j"', 'E734') 3396 set scrolljump&vim 3397 3398 " Test for register 3399 let @/ = 1 3400 call assert_fails('let @/ += 1', 'E734') 3401 call assert_fails('let @/ -= 1', 'E734') 3402 call assert_fails('let @/ *= 1', 'E734') 3403 call assert_fails('let @/ /= 1', 'E734') 3404 call assert_fails('let @/ %= 1', 'E734') 3405 let @/ .= 's' 3406 call assert_equal('1s', @/) 3407 let @/ = '' 3408endfunc 3409 3410func Test_unlet_env() 3411 let $TESTVAR = 'yes' 3412 call assert_equal('yes', $TESTVAR) 3413 call assert_fails('lockvar $TESTVAR', 'E940') 3414 call assert_fails('unlockvar $TESTVAR', 'E940') 3415 call assert_equal('yes', $TESTVAR) 3416 if 0 3417 unlet $TESTVAR 3418 endif 3419 call assert_equal('yes', $TESTVAR) 3420 unlet $TESTVAR 3421 call assert_equal('', $TESTVAR) 3422endfunc 3423 3424func Test_refcount() 3425 " Immediate values 3426 call assert_equal(-1, test_refcount(1)) 3427 call assert_equal(-1, test_refcount('s')) 3428 call assert_equal(-1, test_refcount(v:true)) 3429 call assert_equal(0, test_refcount([])) 3430 call assert_equal(0, test_refcount({})) 3431 call assert_equal(0, test_refcount(0zff)) 3432 call assert_equal(0, test_refcount({-> line('.')})) 3433 if has('float') 3434 call assert_equal(-1, test_refcount(0.1)) 3435 endif 3436 if has('job') 3437 call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .']))) 3438 endif 3439 3440 " No refcount types 3441 let x = 1 3442 call assert_equal(-1, test_refcount(x)) 3443 let x = 's' 3444 call assert_equal(-1, test_refcount(x)) 3445 let x = v:true 3446 call assert_equal(-1, test_refcount(x)) 3447 if has('float') 3448 let x = 0.1 3449 call assert_equal(-1, test_refcount(x)) 3450 endif 3451 3452 " Check refcount 3453 let x = [] 3454 call assert_equal(1, test_refcount(x)) 3455 3456 let x = {} 3457 call assert_equal(1, x->test_refcount()) 3458 3459 let x = 0zff 3460 call assert_equal(1, test_refcount(x)) 3461 3462 let X = {-> line('.')} 3463 call assert_equal(1, test_refcount(X)) 3464 let Y = X 3465 call assert_equal(2, test_refcount(X)) 3466 3467 if has('job') 3468 let job = job_start([&shell, &shellcmdflag, 'echo .']) 3469 call assert_equal(1, test_refcount(job)) 3470 call assert_equal(1, test_refcount(job_getchannel(job))) 3471 call assert_equal(1, test_refcount(job)) 3472 endif 3473 3474 " Function arguments, copying and unassigning 3475 func ExprCheck(x, i) 3476 let i = a:i + 1 3477 call assert_equal(i, test_refcount(a:x)) 3478 let Y = a:x 3479 call assert_equal(i + 1, test_refcount(a:x)) 3480 call assert_equal(test_refcount(a:x), test_refcount(Y)) 3481 let Y = 0 3482 call assert_equal(i, test_refcount(a:x)) 3483 endfunc 3484 call ExprCheck([], 0) 3485 call ExprCheck({}, 0) 3486 call ExprCheck(0zff, 0) 3487 call ExprCheck({-> line('.')}, 0) 3488 if has('job') 3489 call ExprCheck(job, 1) 3490 call ExprCheck(job_getchannel(job), 1) 3491 call job_stop(job) 3492 endif 3493 delfunc ExprCheck 3494 3495 " Regarding function 3496 func Func(x) abort 3497 call assert_equal(2, test_refcount(function('Func'))) 3498 call assert_equal(0, test_refcount(funcref('Func'))) 3499 endfunc 3500 call assert_equal(1, test_refcount(function('Func'))) 3501 call assert_equal(0, test_refcount(function('Func', [1]))) 3502 call assert_equal(0, test_refcount(funcref('Func'))) 3503 call assert_equal(0, test_refcount(funcref('Func', [1]))) 3504 let X = function('Func') 3505 let Y = X 3506 call assert_equal(1, test_refcount(X)) 3507 let X = function('Func', [1]) 3508 let Y = X 3509 call assert_equal(2, test_refcount(X)) 3510 let X = funcref('Func') 3511 let Y = X 3512 call assert_equal(2, test_refcount(X)) 3513 let X = funcref('Func', [1]) 3514 let Y = X 3515 call assert_equal(2, test_refcount(X)) 3516 unlet X 3517 unlet Y 3518 call Func(1) 3519 delfunc Func 3520 3521 " Function with dict 3522 func DictFunc() dict 3523 call assert_equal(3, test_refcount(self)) 3524 endfunc 3525 let d = {'Func': function('DictFunc')} 3526 call assert_equal(1, test_refcount(d)) 3527 call assert_equal(0, test_refcount(d.Func)) 3528 call d.Func() 3529 unlet d 3530 delfunc DictFunc 3531endfunc 3532 3533" Test for missing :endif, :endfor, :endwhile and :endtry {{{1 3534func Test_missing_end() 3535 call writefile(['if 2 > 1', 'echo ">"'], 'Xscript') 3536 call assert_fails('source Xscript', 'E171:') 3537 call writefile(['for i in range(5)', 'echo i'], 'Xscript') 3538 call assert_fails('source Xscript', 'E170:') 3539 call writefile(['while v:true', 'echo "."'], 'Xscript') 3540 call assert_fails('source Xscript', 'E170:') 3541 call writefile(['try', 'echo "."'], 'Xscript') 3542 call assert_fails('source Xscript', 'E600:') 3543 call delete('Xscript') 3544 3545 " Using endfor with :while 3546 let caught_e732 = 0 3547 try 3548 while v:true 3549 endfor 3550 catch /E732:/ 3551 let caught_e732 = 1 3552 endtry 3553 call assert_equal(1, caught_e732) 3554 3555 " Using endwhile with :for 3556 let caught_e733 = 0 3557 try 3558 for i in range(1) 3559 endwhile 3560 catch /E733:/ 3561 let caught_e733 = 1 3562 endtry 3563 call assert_equal(1, caught_e733) 3564 3565 " Using endfunc with :if 3566 call assert_fails('exe "if 1 | endfunc | endif"', 'E193:') 3567 3568 " Missing 'in' in a :for statement 3569 call assert_fails('for i range(1) | endfor', 'E690:') 3570 3571 " Incorrect number of variables in for 3572 call assert_fails('for [i,] in range(3) | endfor', 'E475:') 3573endfunc 3574 3575" Test for deep nesting of if/for/while/try statements {{{1 3576func Test_deep_nest() 3577 CheckRunVimInTerminal 3578 3579 let lines =<< trim [SCRIPT] 3580 " Deep nesting of if ... endif 3581 func Test1() 3582 let @a = join(repeat(['if v:true'], 51), "\n") 3583 let @a ..= "\n" 3584 let @a ..= join(repeat(['endif'], 51), "\n") 3585 @a 3586 let @a = '' 3587 endfunc 3588 3589 " Deep nesting of for ... endfor 3590 func Test2() 3591 let @a = join(repeat(['for i in [1]'], 51), "\n") 3592 let @a ..= "\n" 3593 let @a ..= join(repeat(['endfor'], 51), "\n") 3594 @a 3595 let @a = '' 3596 endfunc 3597 3598 " Deep nesting of while ... endwhile 3599 func Test3() 3600 let @a = join(repeat(['while v:true'], 51), "\n") 3601 let @a ..= "\n" 3602 let @a ..= join(repeat(['endwhile'], 51), "\n") 3603 @a 3604 let @a = '' 3605 endfunc 3606 3607 " Deep nesting of try ... endtry 3608 func Test4() 3609 let @a = join(repeat(['try'], 51), "\n") 3610 let @a ..= "\necho v:true\n" 3611 let @a ..= join(repeat(['endtry'], 51), "\n") 3612 @a 3613 let @a = '' 3614 endfunc 3615 3616 " Deep nesting of function ... endfunction 3617 func Test5() 3618 let @a = join(repeat(['function X()'], 51), "\n") 3619 let @a ..= "\necho v:true\n" 3620 let @a ..= join(repeat(['endfunction'], 51), "\n") 3621 @a 3622 let @a = '' 3623 endfunc 3624 [SCRIPT] 3625 call writefile(lines, 'Xscript') 3626 3627 let buf = RunVimInTerminal('-S Xscript', {'rows': 6}) 3628 3629 " Deep nesting of if ... endif 3630 call term_sendkeys(buf, ":call Test1()\n") 3631 call TermWait(buf) 3632 call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))}) 3633 3634 " Deep nesting of for ... endfor 3635 call term_sendkeys(buf, ":call Test2()\n") 3636 call TermWait(buf) 3637 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))}) 3638 3639 " Deep nesting of while ... endwhile 3640 call term_sendkeys(buf, ":call Test3()\n") 3641 call TermWait(buf) 3642 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))}) 3643 3644 " Deep nesting of try ... endtry 3645 call term_sendkeys(buf, ":call Test4()\n") 3646 call TermWait(buf) 3647 call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))}) 3648 3649 " Deep nesting of function ... endfunction 3650 call term_sendkeys(buf, ":call Test5()\n") 3651 call TermWait(buf) 3652 call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))}) 3653 call term_sendkeys(buf, "\<C-C>\n") 3654 call TermWait(buf) 3655 3656 "let l = '' 3657 "for i in range(1, 6) 3658 " let l ..= term_getline(buf, i) . "\n" 3659 "endfor 3660 "call assert_report(l) 3661 3662 call StopVimInTerminal(buf) 3663 call delete('Xscript') 3664endfunc 3665 3666" Test for errors in converting to float from various types {{{1 3667func Test_float_conversion_errors() 3668 if has('float') 3669 call assert_fails('let x = 4.0 % 2.0', 'E804') 3670 call assert_fails('echo 1.1[0]', 'E806') 3671 call assert_fails('echo sort([function("min"), 1], "f")', 'E891:') 3672 call assert_fails('echo 3.2 == "vim"', 'E892:') 3673 call assert_fails('echo sort([[], 1], "f")', 'E893:') 3674 call assert_fails('echo sort([{}, 1], "f")', 'E894:') 3675 call assert_fails('echo 3.2 == v:true', 'E362:') 3676 call assert_fails('echo 3.2 == v:none', 'E907:') 3677 endif 3678endfunc 3679 3680" invalid function names {{{1 3681func Test_invalid_function_names() 3682 " function name not starting with capital 3683 let caught_e128 = 0 3684 try 3685 func! g:test() 3686 echo "test" 3687 endfunc 3688 catch /E128:/ 3689 let caught_e128 = 1 3690 endtry 3691 call assert_equal(1, caught_e128) 3692 3693 " function name includes a colon 3694 let caught_e884 = 0 3695 try 3696 func! b:test() 3697 echo "test" 3698 endfunc 3699 catch /E884:/ 3700 let caught_e884 = 1 3701 endtry 3702 call assert_equal(1, caught_e884) 3703 3704 " function name folowed by # 3705 let caught_e128 = 0 3706 try 3707 func! test2() "# 3708 echo "test2" 3709 endfunc 3710 catch /E128:/ 3711 let caught_e128 = 1 3712 endtry 3713 call assert_equal(1, caught_e128) 3714 3715 " function name starting with/without "g:", buffer-local funcref. 3716 function! g:Foo(n) 3717 return 'called Foo(' . a:n . ')' 3718 endfunction 3719 let b:my_func = function('Foo') 3720 call assert_equal('called Foo(1)', b:my_func(1)) 3721 call assert_equal('called Foo(2)', g:Foo(2)) 3722 call assert_equal('called Foo(3)', Foo(3)) 3723 delfunc g:Foo 3724 3725 " script-local function used in Funcref must exist. 3726 let lines =<< trim END 3727 func s:Testje() 3728 return "foo" 3729 endfunc 3730 let Bar = function('s:Testje') 3731 call assert_equal(0, exists('s:Testje')) 3732 call assert_equal(1, exists('*s:Testje')) 3733 call assert_equal(1, exists('Bar')) 3734 call assert_equal(1, exists('*Bar')) 3735 END 3736 call writefile(lines, 'Xscript') 3737 source Xscript 3738 call delete('Xscript') 3739endfunc 3740 3741" substring and variable name {{{1 3742func Test_substring_var() 3743 let str = 'abcdef' 3744 let n = 3 3745 call assert_equal('def', str[n:]) 3746 call assert_equal('abcd', str[:n]) 3747 call assert_equal('d', str[n:n]) 3748 unlet n 3749 let nn = 3 3750 call assert_equal('def', str[nn:]) 3751 call assert_equal('abcd', str[:nn]) 3752 call assert_equal('d', str[nn:nn]) 3753 unlet nn 3754 let b:nn = 4 3755 call assert_equal('ef', str[b:nn:]) 3756 call assert_equal('abcde', str[:b:nn]) 3757 call assert_equal('e', str[b:nn:b:nn]) 3758 unlet b:nn 3759endfunc 3760 3761" Test using s: with a typed command {{{1 3762func Test_typed_script_var() 3763 CheckRunVimInTerminal 3764 3765 let buf = RunVimInTerminal('', {'rows': 6}) 3766 3767 " Deep nesting of if ... endif 3768 call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n") 3769 call TermWait(buf) 3770 call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))}) 3771 3772 call StopVimInTerminal(buf) 3773endfunc 3774 3775"------------------------------------------------------------------------------- 3776" Modelines {{{1 3777" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 3778"------------------------------------------------------------------------------- 3779