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 set cpo-=C " support line-continuation in sourced script 27 source script_util.vim 28 XpathINIT 29 XloopINIT 30 END 31 let cleanup =<< trim END 32 call writefile(v:errors, 'Xtest.out') 33 qall 34 END 35 call writefile(init, 'Xtest.vim') 36 call writefile(a:test, 'Xtest.vim', 'a') 37 call writefile(a:verify, 'Xverify.vim') 38 call writefile(cleanup, 'Xverify.vim', 'a') 39 call RunVim([], [], "-S Xtest.vim -S Xverify.vim") 40 call assert_equal([], readfile('Xtest.out')) 41 call delete('Xtest.out') 42 call delete('Xtest.vim') 43 call delete('Xverify.vim') 44endfunc 45 46"------------------------------------------------------------------------------- 47" Test 1: :endwhile in function {{{1 48" 49" Detect if a broken loop is (incorrectly) reactivated by the 50" :endwhile. Use a :return to prevent an endless loop, and make 51" this test first to get a meaningful result on an error before other 52" tests will hang. 53"------------------------------------------------------------------------------- 54 55func T1_F() 56 Xpath 'a' 57 let first = 1 58 while 1 59 Xpath 'b' 60 if first 61 Xpath 'c' 62 let first = 0 63 break 64 else 65 Xpath 'd' 66 return 67 endif 68 endwhile 69endfunc 70 71func T1_G() 72 Xpath 'h' 73 let first = 1 74 while 1 75 Xpath 'i' 76 if first 77 Xpath 'j' 78 let first = 0 79 break 80 else 81 Xpath 'k' 82 return 83 endif 84 if 1 " unmatched :if 85 endwhile 86endfunc 87 88func Test_endwhile_function() 89 XpathINIT 90 call T1_F() 91 Xpath 'F' 92 93 try 94 call T1_G() 95 catch 96 " Catch missing :endif 97 call assert_true(v:exception =~ 'E171') 98 Xpath 'x' 99 endtry 100 Xpath 'G' 101 102 call assert_equal('abcFhijxG', g:Xpath) 103endfunc 104 105"------------------------------------------------------------------------------- 106" Test 2: :endwhile in script {{{1 107" 108" Detect if a broken loop is (incorrectly) reactivated by the 109" :endwhile. Use a :finish to prevent an endless loop, and place 110" this test before others that might hang to get a meaningful result 111" on an error. 112" 113" This test executes the bodies of the functions T1_F and T1_G from 114" the previous test as script files (:return replaced by :finish). 115"------------------------------------------------------------------------------- 116 117func Test_endwhile_script() 118 XpathINIT 119 ExecAsScript T1_F 120 Xpath 'F' 121 call DeleteTheScript() 122 123 try 124 ExecAsScript T1_G 125 catch 126 " Catch missing :endif 127 call assert_true(v:exception =~ 'E171') 128 Xpath 'x' 129 endtry 130 Xpath 'G' 131 call DeleteTheScript() 132 133 call assert_equal('abcFhijxG', g:Xpath) 134endfunc 135 136"------------------------------------------------------------------------------- 137" Test 3: :if, :elseif, :while, :continue, :break {{{1 138"------------------------------------------------------------------------------- 139 140func Test_if_while() 141 XpathINIT 142 if 1 143 Xpath 'a' 144 let loops = 3 145 while loops > -1 " main loop: loops == 3, 2, 1 (which breaks) 146 if loops <= 0 147 let break_err = 1 148 let loops = -1 149 else 150 Xpath 'b' . loops 151 endif 152 if (loops == 2) 153 while loops == 2 " dummy loop 154 Xpath 'c' . loops 155 let loops = loops - 1 156 continue " stop dummy loop 157 Xpath 'd' . loops 158 endwhile 159 continue " continue main loop 160 Xpath 'e' . loops 161 elseif (loops == 1) 162 let p = 1 163 while p " dummy loop 164 Xpath 'f' . loops 165 let p = 0 166 break " break dummy loop 167 Xpath 'g' . loops 168 endwhile 169 Xpath 'h' . loops 170 unlet p 171 break " break main loop 172 Xpath 'i' . loops 173 endif 174 if (loops > 0) 175 Xpath 'j' . loops 176 endif 177 while loops == 3 " dummy loop 178 let loops = loops - 1 179 endwhile " end dummy loop 180 endwhile " end main loop 181 Xpath 'k' 182 else 183 Xpath 'l' 184 endif 185 Xpath 'm' 186 if exists("break_err") 187 Xpath 'm' 188 unlet break_err 189 endif 190 191 unlet loops 192 193 call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath) 194endfunc 195 196"------------------------------------------------------------------------------- 197" Test 4: :return {{{1 198"------------------------------------------------------------------------------- 199 200func T4_F() 201 if 1 202 Xpath 'a' 203 let loops = 3 204 while loops > 0 " 3: 2: 1: 205 Xpath 'b' . loops 206 if (loops == 2) 207 Xpath 'c' . loops 208 return 209 Xpath 'd' . loops 210 endif 211 Xpath 'e' . loops 212 let loops = loops - 1 213 endwhile 214 Xpath 'f' 215 else 216 Xpath 'g' 217 endif 218endfunc 219 220func Test_return() 221 XpathINIT 222 call T4_F() 223 Xpath '4' 224 225 call assert_equal('ab3e3b2c24', g:Xpath) 226endfunc 227 228 229"------------------------------------------------------------------------------- 230" Test 5: :finish {{{1 231" 232" This test executes the body of the function T4_F from the previous 233" test as a script file (:return replaced by :finish). 234"------------------------------------------------------------------------------- 235 236func Test_finish() 237 XpathINIT 238 ExecAsScript T4_F 239 Xpath '5' 240 call DeleteTheScript() 241 242 call assert_equal('ab3e3b2c25', g:Xpath) 243endfunc 244 245 246 247"------------------------------------------------------------------------------- 248" Test 6: Defining functions in :while loops {{{1 249" 250" Functions can be defined inside other functions. An inner function 251" gets defined when the outer function is executed. Functions may 252" also be defined inside while loops. Expressions in braces for 253" defining the function name are allowed. 254" 255" The functions are defined when sourcing the script, only the 256" resulting path is checked in the test function. 257"------------------------------------------------------------------------------- 258 259XpathINIT 260 261" The command CALL collects the argument of all its invocations in "calls" 262" when used from a function (that is, when the global variable "calls" needs 263" the "g:" prefix). This is to check that the function code is skipped when 264" the function is defined. For inner functions, do so only if the outer 265" function is not being executed. 266" 267let calls = "" 268com! -nargs=1 CALL 269 \ if !exists("calls") && !exists("outer") | 270 \ let g:calls = g:calls . <args> | 271 \ endif 272 273let i = 0 274while i < 3 275 let i = i + 1 276 if i == 1 277 Xpath 'a' 278 function! F1(arg) 279 CALL a:arg 280 let outer = 1 281 282 let j = 0 283 while j < 1 284 Xpath 'b' 285 let j = j + 1 286 function! G1(arg) 287 CALL a:arg 288 endfunction 289 Xpath 'c' 290 endwhile 291 endfunction 292 Xpath 'd' 293 294 continue 295 endif 296 297 Xpath 'e' . i 298 function! F{i}(i, arg) 299 CALL a:arg 300 let outer = 1 301 302 if a:i == 3 303 Xpath 'f' 304 endif 305 let k = 0 306 while k < 3 307 Xpath 'g' . k 308 let k = k + 1 309 function! G{a:i}{k}(arg) 310 CALL a:arg 311 endfunction 312 Xpath 'h' . k 313 endwhile 314 endfunction 315 Xpath 'i' 316 317endwhile 318 319if exists("*G1") 320 Xpath 'j' 321endif 322if exists("*F1") 323 call F1("F1") 324 if exists("*G1") 325 call G1("G1") 326 endif 327endif 328 329if exists("G21") || exists("G22") || exists("G23") 330 Xpath 'k' 331endif 332if exists("*F2") 333 call F2(2, "F2") 334 if exists("*G21") 335 call G21("G21") 336 endif 337 if exists("*G22") 338 call G22("G22") 339 endif 340 if exists("*G23") 341 call G23("G23") 342 endif 343endif 344 345if exists("G31") || exists("G32") || exists("G33") 346 Xpath 'l' 347endif 348if exists("*F3") 349 call F3(3, "F3") 350 if exists("*G31") 351 call G31("G31") 352 endif 353 if exists("*G32") 354 call G32("G32") 355 endif 356 if exists("*G33") 357 call G33("G33") 358 endif 359endif 360 361Xpath 'm' 362 363let g:test6_result = g:Xpath 364let g:test6_calls = calls 365 366unlet calls 367delfunction F1 368delfunction G1 369delfunction F2 370delfunction G21 371delfunction G22 372delfunction G23 373delfunction G31 374delfunction G32 375delfunction G33 376 377func Test_defining_functions() 378 call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result) 379 call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls) 380endfunc 381 382"------------------------------------------------------------------------------- 383" Test 7: Continuing on errors outside functions {{{1 384" 385" On an error outside a function, the script processing continues 386" at the line following the outermost :endif or :endwhile. When not 387" inside an :if or :while, the script processing continues at the next 388" line. 389"------------------------------------------------------------------------------- 390 391XpathINIT 392 393if 1 394 Xpath 'a' 395 while 1 396 Xpath 'b' 397 asdf 398 Xpath 'c' 399 break 400 endwhile | Xpath 'd' 401 Xpath 'e' 402endif | Xpath 'f' 403Xpath 'g' 404 405while 1 406 Xpath 'h' 407 if 1 408 Xpath 'i' 409 asdf 410 Xpath 'j' 411 endif | Xpath 'k' 412 Xpath 'l' 413 break 414endwhile | Xpath 'm' 415Xpath 'n' 416 417asdf 418Xpath 'o' 419 420asdf | Xpath 'p' 421Xpath 'q' 422 423let g:test7_result = g:Xpath 424 425func Test_error_in_script() 426 call assert_equal('abghinoq', g:test7_result) 427endfunc 428 429"------------------------------------------------------------------------------- 430" Test 8: Aborting and continuing on errors inside functions {{{1 431" 432" On an error inside a function without the "abort" attribute, the 433" script processing continues at the next line (unless the error was 434" in a :return command). On an error inside a function with the 435" "abort" attribute, the function is aborted and the script processing 436" continues after the function call; the value -1 is returned then. 437"------------------------------------------------------------------------------- 438 439XpathINIT 440 441func T8_F() 442 if 1 443 Xpath 'a' 444 while 1 445 Xpath 'b' 446 asdf 447 Xpath 'c' 448 asdf | Xpath 'd' 449 Xpath 'e' 450 break 451 endwhile 452 Xpath 'f' 453 endif | Xpath 'g' 454 Xpath 'h' 455 456 while 1 457 Xpath 'i' 458 if 1 459 Xpath 'j' 460 asdf 461 Xpath 'k' 462 asdf | Xpath 'l' 463 Xpath 'm' 464 endif 465 Xpath 'n' 466 break 467 endwhile | Xpath 'o' 468 Xpath 'p' 469 470 return novar " returns (default return value 0) 471 Xpath 'q' 472 return 1 " not reached 473endfunc 474 475func T8_G() abort 476 if 1 477 Xpath 'r' 478 while 1 479 Xpath 's' 480 asdf " returns -1 481 Xpath 't' 482 break 483 endwhile 484 Xpath 'v' 485 endif | Xpath 'w' 486 Xpath 'x' 487 488 return -4 " not reached 489endfunc 490 491func T8_H() abort 492 while 1 493 Xpath 'A' 494 if 1 495 Xpath 'B' 496 asdf " returns -1 497 Xpath 'C' 498 endif 499 Xpath 'D' 500 break 501 endwhile | Xpath 'E' 502 Xpath 'F' 503 504 return -4 " not reached 505endfunc 506 507" Aborted functions (T8_G and T8_H) return -1. 508let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H() 509Xpath 'X' 510let g:test8_result = g:Xpath 511 512func Test_error_in_function() 513 call assert_equal(13, g:test8_sum) 514 call assert_equal('abcefghijkmnoprsABX', g:test8_result) 515 516 delfunction T8_F 517 delfunction T8_G 518 delfunction T8_H 519endfunc 520 521 522"------------------------------------------------------------------------------- 523" Test 9: Continuing after aborted functions {{{1 524" 525" When a function with the "abort" attribute is aborted due to an 526" error, the next function back in the call hierarchy without an 527" "abort" attribute continues; the value -1 is returned then. 528"------------------------------------------------------------------------------- 529 530XpathINIT 531 532func F() abort 533 Xpath 'a' 534 let result = G() " not aborted 535 Xpath 'b' 536 if result != 2 537 Xpath 'c' 538 endif 539 return 1 540endfunc 541 542func G() " no abort attribute 543 Xpath 'd' 544 if H() != -1 " aborted 545 Xpath 'e' 546 endif 547 Xpath 'f' 548 return 2 549endfunc 550 551func H() abort 552 Xpath 'g' 553 call I() " aborted 554 Xpath 'h' 555 return 4 556endfunc 557 558func I() abort 559 Xpath 'i' 560 asdf " error 561 Xpath 'j' 562 return 8 563endfunc 564 565if F() != 1 566 Xpath 'k' 567endif 568 569let g:test9_result = g:Xpath 570 571delfunction F 572delfunction G 573delfunction H 574delfunction I 575 576func Test_func_abort() 577 call assert_equal('adgifb', g:test9_result) 578endfunc 579 580 581"------------------------------------------------------------------------------- 582" Test 10: :if, :elseif, :while argument parsing {{{1 583" 584" A '"' or '|' in an argument expression must not be mixed up with 585" a comment or a next command after a bar. Parsing errors should 586" be recognized. 587"------------------------------------------------------------------------------- 588 589XpathINIT 590 591func MSG(enr, emsg) 592 let english = v:lang == "C" || v:lang =~ '^[Ee]n' 593 if a:enr == "" 594 Xout "TODO: Add message number for:" a:emsg 595 let v:errmsg = ":" . v:errmsg 596 endif 597 let match = 1 598 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) 599 let match = 0 600 if v:errmsg == "" 601 Xout "Message missing." 602 else 603 let v:errmsg = v:errmsg->escape('"') 604 Xout "Unexpected message:" v:errmsg 605 endif 606 endif 607 return match 608endfunc 609 610if 1 || strlen("\"") | Xpath 'a' 611 Xpath 'b' 612endif 613Xpath 'c' 614 615if 0 616elseif 1 || strlen("\"") | Xpath 'd' 617 Xpath 'e' 618endif 619Xpath 'f' 620 621while 1 || strlen("\"") | Xpath 'g' 622 Xpath 'h' 623 break 624endwhile 625Xpath 'i' 626 627let v:errmsg = "" 628if 1 ||| strlen("\"") | Xpath 'j' 629 Xpath 'k' 630endif 631Xpath 'l' 632if !MSG('E15', "Invalid expression") 633 Xpath 'm' 634endif 635 636let v:errmsg = "" 637if 0 638elseif 1 ||| strlen("\"") | Xpath 'n' 639 Xpath 'o' 640endif 641Xpath 'p' 642if !MSG('E15', "Invalid expression") 643 Xpath 'q' 644endif 645 646let v:errmsg = "" 647while 1 ||| strlen("\"") | Xpath 'r' 648 Xpath 's' 649 break 650endwhile 651Xpath 't' 652if !MSG('E15', "Invalid expression") 653 Xpath 'u' 654endif 655 656let g:test10_result = g:Xpath 657delfunction MSG 658 659func Test_expr_parsing() 660 call assert_equal('abcdefghilpt', g:test10_result) 661endfunc 662 663 664"------------------------------------------------------------------------------- 665" Test 11: :if, :elseif, :while argument evaluation after abort {{{1 666" 667" When code is skipped over due to an error, the boolean argument to 668" an :if, :elseif, or :while must not be evaluated. 669"------------------------------------------------------------------------------- 670 671XpathINIT 672 673let calls = 0 674 675func P(num) 676 let g:calls = g:calls + a:num " side effect on call 677 return 0 678endfunc 679 680if 1 681 Xpath 'a' 682 asdf " error 683 Xpath 'b' 684 if P(1) " should not be called 685 Xpath 'c' 686 elseif !P(2) " should not be called 687 Xpath 'd' 688 else 689 Xpath 'e' 690 endif 691 Xpath 'f' 692 while P(4) " should not be called 693 Xpath 'g' 694 endwhile 695 Xpath 'h' 696endif 697Xpath 'x' 698 699let g:test11_calls = calls 700let g:test11_result = g:Xpath 701 702unlet calls 703delfunction P 704 705func Test_arg_abort() 706 call assert_equal(0, g:test11_calls) 707 call assert_equal('ax', g:test11_result) 708endfunc 709 710 711"------------------------------------------------------------------------------- 712" Test 12: Expressions in braces in skipped code {{{1 713" 714" In code skipped over due to an error or inactive conditional, 715" an expression in braces as part of a variable or function name 716" should not be evaluated. 717"------------------------------------------------------------------------------- 718 719XpathINIT 720 721function! NULL() 722 Xpath 'a' 723 return 0 724endfunction 725 726function! ZERO() 727 Xpath 'b' 728 return 0 729endfunction 730 731function! F0() 732 Xpath 'c' 733endfunction 734 735function! F1(arg) 736 Xpath 'e' 737endfunction 738 739let V0 = 1 740 741Xpath 'f' 742echo 0 ? F{NULL() + V{ZERO()}}() : 1 743 744Xpath 'g' 745if 0 746 Xpath 'h' 747 call F{NULL() + V{ZERO()}}() 748endif 749 750Xpath 'i' 751if 1 752 asdf " error 753 Xpath 'j' 754 call F1(F{NULL() + V{ZERO()}}()) 755endif 756 757Xpath 'k' 758if 1 759 asdf " error 760 Xpath 'l' 761 call F{NULL() + V{ZERO()}}() 762endif 763 764let g:test12_result = g:Xpath 765 766func Test_braces_skipped() 767 call assert_equal('fgik', g:test12_result) 768endfunc 769 770 771"------------------------------------------------------------------------------- 772" Test 13: Failure in argument evaluation for :while {{{1 773" 774" A failure in the expression evaluation for the condition of a :while 775" causes the whole :while loop until the matching :endwhile being 776" ignored. Continuation is at the next following line. 777"------------------------------------------------------------------------------- 778 779XpathINIT 780 781Xpath 'a' 782while asdf 783 Xpath 'b' 784 while 1 785 Xpath 'c' 786 break 787 endwhile 788 Xpath 'd' 789 break 790endwhile 791Xpath 'e' 792 793while asdf | Xpath 'f' | endwhile | Xpath 'g' 794Xpath 'h' 795let g:test13_result = g:Xpath 796 797func Test_while_fail() 798 call assert_equal('aeh', g:test13_result) 799endfunc 800 801 802"------------------------------------------------------------------------------- 803" Test 14: Failure in argument evaluation for :if {{{1 804" 805" A failure in the expression evaluation for the condition of an :if 806" does not cause the corresponding :else or :endif being matched to 807" a previous :if/:elseif. Neither of both branches of the failed :if 808" are executed. 809"------------------------------------------------------------------------------- 810 811XpathINIT 812 813function! F() 814 Xpath 'a' 815 let x = 0 816 if x " false 817 Xpath 'b' 818 elseif !x " always true 819 Xpath 'c' 820 let x = 1 821 if g:boolvar " possibly undefined 822 Xpath 'd' 823 else 824 Xpath 'e' 825 endif 826 Xpath 'f' 827 elseif x " never executed 828 Xpath 'g' 829 endif 830 Xpath 'h' 831endfunction 832 833let boolvar = 1 834call F() 835Xpath '-' 836 837unlet boolvar 838call F() 839let g:test14_result = g:Xpath 840 841delfunction F 842 843func Test_if_fail() 844 call assert_equal('acdfh-acfh', g:test14_result) 845endfunc 846 847 848"------------------------------------------------------------------------------- 849" Test 15: Failure in argument evaluation for :if (bar) {{{1 850" 851" Like previous test, except that the failing :if ... | ... | :endif 852" is in a single line. 853"------------------------------------------------------------------------------- 854 855XpathINIT 856 857function! F() 858 Xpath 'a' 859 let x = 0 860 if x " false 861 Xpath 'b' 862 elseif !x " always true 863 Xpath 'c' 864 let x = 1 865 if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif 866 Xpath 'f' 867 elseif x " never executed 868 Xpath 'g' 869 endif 870 Xpath 'h' 871endfunction 872 873let boolvar = 1 874call F() 875Xpath '-' 876 877unlet boolvar 878call F() 879let g:test15_result = g:Xpath 880 881delfunction F 882 883func Test_if_bar_fail() 884 call assert_equal('acdfh-acfh', g:test15_result) 885endfunc 886 887"------------------------------------------------------------------------------- 888" Test 16: Double :else or :elseif after :else {{{1 889" 890" Multiple :elses or an :elseif after an :else are forbidden. 891"------------------------------------------------------------------------------- 892 893func T16_F() abort 894 if 0 895 Xpath 'a' 896 else 897 Xpath 'b' 898 else " aborts function 899 Xpath 'c' 900 endif 901 Xpath 'd' 902endfunc 903 904func T16_G() abort 905 if 0 906 Xpath 'a' 907 else 908 Xpath 'b' 909 elseif 1 " aborts function 910 Xpath 'c' 911 else 912 Xpath 'd' 913 endif 914 Xpath 'e' 915endfunc 916 917func T16_H() abort 918 if 0 919 Xpath 'a' 920 elseif 0 921 Xpath 'b' 922 else 923 Xpath 'c' 924 else " aborts function 925 Xpath 'd' 926 endif 927 Xpath 'e' 928endfunc 929 930func T16_I() abort 931 if 0 932 Xpath 'a' 933 elseif 0 934 Xpath 'b' 935 else 936 Xpath 'c' 937 elseif 1 " aborts function 938 Xpath 'd' 939 else 940 Xpath 'e' 941 endif 942 Xpath 'f' 943endfunc 944 945func Test_Multi_Else() 946 XpathINIT 947 try 948 call T16_F() 949 catch /E583:/ 950 Xpath 'e' 951 endtry 952 call assert_equal('be', g:Xpath) 953 954 XpathINIT 955 try 956 call T16_G() 957 catch /E584:/ 958 Xpath 'f' 959 endtry 960 call assert_equal('bf', g:Xpath) 961 962 XpathINIT 963 try 964 call T16_H() 965 catch /E583:/ 966 Xpath 'f' 967 endtry 968 call assert_equal('cf', g:Xpath) 969 970 XpathINIT 971 try 972 call T16_I() 973 catch /E584:/ 974 Xpath 'g' 975 endtry 976 call assert_equal('cg', g:Xpath) 977endfunc 978 979"------------------------------------------------------------------------------- 980" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1 981" 982" The :while/:endwhile takes precedence in nesting over an unclosed 983" :if or an unopened :endif. 984"------------------------------------------------------------------------------- 985 986" While loops inside a function are continued on error. 987func T17_F() 988 let loops = 3 989 while loops > 0 990 let loops -= 1 991 Xpath 'a' . loops 992 if (loops == 1) 993 Xpath 'b' . loops 994 continue 995 elseif (loops == 0) 996 Xpath 'c' . loops 997 break 998 elseif 1 999 Xpath 'd' . loops 1000 " endif missing! 1001 endwhile " :endwhile after :if 1 1002 Xpath 'e' 1003endfunc 1004 1005func T17_G() 1006 let loops = 2 1007 while loops > 0 1008 let loops -= 1 1009 Xpath 'a' . loops 1010 if 0 1011 Xpath 'b' . loops 1012 " endif missing 1013 endwhile " :endwhile after :if 0 1014endfunc 1015 1016func T17_H() 1017 let loops = 2 1018 while loops > 0 1019 let loops -= 1 1020 Xpath 'a' . loops 1021 " if missing! 1022 endif " :endif without :if in while 1023 Xpath 'b' . loops 1024 endwhile 1025endfunc 1026 1027" Error continuation outside a function is at the outermost :endwhile or :endif. 1028XpathINIT 1029let v:errmsg = '' 1030let loops = 2 1031while loops > 0 1032 let loops -= 1 1033 Xpath 'a' . loops 1034 if 0 1035 Xpath 'b' . loops 1036 " endif missing! Following :endwhile fails. 1037endwhile | Xpath 'c' 1038Xpath 'd' 1039call assert_match('E171:', v:errmsg) 1040call assert_equal('a1d', g:Xpath) 1041 1042func Test_unmatched_if_in_while() 1043 XpathINIT 1044 call assert_fails('call T17_F()', 'E171:') 1045 call assert_equal('a2d2a1b1a0c0e', g:Xpath) 1046 1047 XpathINIT 1048 call assert_fails('call T17_G()', 'E171:') 1049 call assert_equal('a1a0', g:Xpath) 1050 1051 XpathINIT 1052 call assert_fails('call T17_H()', 'E580:') 1053 call assert_equal('a1b1a0b0', g:Xpath) 1054endfunc 1055 1056"------------------------------------------------------------------------------- 1057" Test 18: Interrupt (Ctrl-C pressed) {{{1 1058" 1059" On an interrupt, the script processing is terminated immediately. 1060"------------------------------------------------------------------------------- 1061 1062func Test_interrupt_while_if() 1063 let test =<< trim [CODE] 1064 try 1065 if 1 1066 Xpath 'a' 1067 while 1 1068 Xpath 'b' 1069 if 1 1070 Xpath 'c' 1071 call interrupt() 1072 call assert_report('should not get here') 1073 break 1074 finish 1075 endif | call assert_report('should not get here') 1076 call assert_report('should not get here') 1077 endwhile | call assert_report('should not get here') 1078 call assert_report('should not get here') 1079 endif | call assert_report('should not get here') 1080 call assert_report('should not get here') 1081 catch /^Vim:Interrupt$/ 1082 Xpath 'd' 1083 endtry | Xpath 'e' 1084 Xpath 'f' 1085 [CODE] 1086 let verify =<< trim [CODE] 1087 call assert_equal('abcdef', g:Xpath) 1088 [CODE] 1089 call RunInNewVim(test, verify) 1090endfunc 1091 1092func Test_interrupt_try() 1093 let test =<< trim [CODE] 1094 try 1095 try 1096 Xpath 'a' 1097 call interrupt() 1098 call assert_report('should not get here') 1099 endtry | call assert_report('should not get here') 1100 call assert_report('should not get here') 1101 catch /^Vim:Interrupt$/ 1102 Xpath 'b' 1103 endtry | Xpath 'c' 1104 Xpath 'd' 1105 [CODE] 1106 let verify =<< trim [CODE] 1107 call assert_equal('abcd', g:Xpath) 1108 [CODE] 1109 call RunInNewVim(test, verify) 1110endfunc 1111 1112func Test_interrupt_func_while_if() 1113 let test =<< trim [CODE] 1114 func F() 1115 if 1 1116 Xpath 'a' 1117 while 1 1118 Xpath 'b' 1119 if 1 1120 Xpath 'c' 1121 call interrupt() 1122 call assert_report('should not get here') 1123 break 1124 return 1125 endif | call assert_report('should not get here') 1126 call assert_report('should not get here') 1127 endwhile | call assert_report('should not get here') 1128 call assert_report('should not get here') 1129 endif | call assert_report('should not get here') 1130 call assert_report('should not get here') 1131 endfunc 1132 1133 Xpath 'd' 1134 try 1135 call F() | call assert_report('should not get here') 1136 catch /^Vim:Interrupt$/ 1137 Xpath 'e' 1138 endtry | Xpath 'f' 1139 Xpath 'g' 1140 [CODE] 1141 let verify =<< trim [CODE] 1142 call assert_equal('dabcefg', g:Xpath) 1143 [CODE] 1144 call RunInNewVim(test, verify) 1145endfunc 1146 1147func Test_interrupt_func_try() 1148 let test =<< trim [CODE] 1149 func G() 1150 try 1151 Xpath 'a' 1152 call interrupt() 1153 call assert_report('should not get here') 1154 endtry | call assert_report('should not get here') 1155 call assert_report('should not get here') 1156 endfunc 1157 1158 Xpath 'b' 1159 try 1160 call G() | call assert_report('should not get here') 1161 catch /^Vim:Interrupt$/ 1162 Xpath 'c' 1163 endtry | Xpath 'd' 1164 Xpath 'e' 1165 [CODE] 1166 let verify =<< trim [CODE] 1167 call assert_equal('bacde', g:Xpath) 1168 [CODE] 1169 call RunInNewVim(test, verify) 1170endfunc 1171 1172"------------------------------------------------------------------------------- 1173" Test 19: Aborting on errors inside :try/:endtry {{{1 1174" 1175" An error in a command dynamically enclosed in a :try/:endtry region 1176" aborts script processing immediately. It does not matter whether 1177" the failing command is outside or inside a function and whether a 1178" function has an "abort" attribute. 1179"------------------------------------------------------------------------------- 1180 1181func Test_try_error_abort_1() 1182 let test =<< trim [CODE] 1183 func F() abort 1184 Xpath 'a' 1185 asdf 1186 call assert_report('should not get here') 1187 endfunc 1188 1189 try 1190 Xpath 'b' 1191 call F() 1192 call assert_report('should not get here') 1193 endtry | call assert_report('should not get here') 1194 call assert_report('should not get here') 1195 [CODE] 1196 let verify =<< trim [CODE] 1197 call assert_equal('ba', g:Xpath) 1198 [CODE] 1199 call RunInNewVim(test, verify) 1200endfunc 1201 1202func Test_try_error_abort_2() 1203 let test =<< trim [CODE] 1204 func G() 1205 Xpath 'a' 1206 asdf 1207 call assert_report('should not get here') 1208 endfunc 1209 1210 try 1211 Xpath 'b' 1212 call G() 1213 call assert_report('should not get here') 1214 endtry | call assert_report('should not get here') 1215 call assert_report('should not get here') 1216 [CODE] 1217 let verify =<< trim [CODE] 1218 call assert_equal('ba', g:Xpath) 1219 [CODE] 1220 call RunInNewVim(test, verify) 1221endfunc 1222 1223func Test_try_error_abort_3() 1224 let test =<< trim [CODE] 1225 try 1226 Xpath 'a' 1227 asdf 1228 call assert_report('should not get here') 1229 endtry | call assert_report('should not get here') 1230 call assert_report('should not get here') 1231 [CODE] 1232 let verify =<< trim [CODE] 1233 call assert_equal('a', g:Xpath) 1234 [CODE] 1235 call RunInNewVim(test, verify) 1236endfunc 1237 1238func Test_try_error_abort_4() 1239 let test =<< trim [CODE] 1240 if 1 1241 try 1242 Xpath 'a' 1243 asdf 1244 call assert_report('should not get here') 1245 endtry | call assert_report('should not get here') 1246 endif | call assert_report('should not get here') 1247 call assert_report('should not get here') 1248 [CODE] 1249 let verify =<< trim [CODE] 1250 call assert_equal('a', g:Xpath) 1251 [CODE] 1252 call RunInNewVim(test, verify) 1253endfunc 1254 1255func Test_try_error_abort_5() 1256 let test =<< trim [CODE] 1257 let p = 1 1258 while p 1259 let p = 0 1260 try 1261 Xpath 'a' 1262 asdf 1263 call assert_report('should not get here') 1264 endtry | call assert_report('should not get here') 1265 endwhile | call assert_report('should not get here') 1266 call assert_report('should not get here') 1267 [CODE] 1268 let verify =<< trim [CODE] 1269 call assert_equal('a', g:Xpath) 1270 [CODE] 1271 call RunInNewVim(test, verify) 1272endfunc 1273 1274func Test_try_error_abort_6() 1275 let test =<< trim [CODE] 1276 let p = 1 1277 Xpath 'a' 1278 while p 1279 Xpath 'b' 1280 let p = 0 1281 try 1282 Xpath 'c' 1283 endwhile | call assert_report('should not get here') 1284 call assert_report('should not get here') 1285 [CODE] 1286 let verify =<< trim [CODE] 1287 call assert_equal('abc', g:Xpath) 1288 [CODE] 1289 call RunInNewVim(test, verify) 1290endfunc 1291 1292"------------------------------------------------------------------------------- 1293" Test 20: Aborting on errors after :try/:endtry {{{1 1294" 1295" When an error occurs after the last active :try/:endtry region has 1296" been left, termination behavior is as if no :try/:endtry has been 1297" seen. 1298"------------------------------------------------------------------------------- 1299 1300func Test_error_after_try_1() 1301 let test =<< trim [CODE] 1302 let p = 1 1303 while p 1304 let p = 0 1305 Xpath 'a' 1306 try 1307 Xpath 'b' 1308 endtry 1309 asdf 1310 call assert_report('should not get here') 1311 endwhile | call assert_report('should not get here') 1312 Xpath 'c' 1313 [CODE] 1314 let verify =<< trim [CODE] 1315 call assert_equal('abc', g:Xpath) 1316 [CODE] 1317 call RunInNewVim(test, verify) 1318endfunc 1319 1320func Test_error_after_try_2() 1321 let test =<< trim [CODE] 1322 while 1 1323 try 1324 Xpath 'a' 1325 break 1326 call assert_report('should not get here') 1327 endtry 1328 endwhile 1329 Xpath 'b' 1330 asdf 1331 Xpath 'c' 1332 [CODE] 1333 let verify =<< trim [CODE] 1334 call assert_equal('abc', g:Xpath) 1335 [CODE] 1336 call RunInNewVim(test, verify) 1337endfunc 1338 1339func Test_error_after_try_3() 1340 let test =<< trim [CODE] 1341 while 1 1342 try 1343 Xpath 'a' 1344 break 1345 call assert_report('should not get here') 1346 finally 1347 Xpath 'b' 1348 endtry 1349 endwhile 1350 Xpath 'c' 1351 asdf 1352 Xpath 'd' 1353 [CODE] 1354 let verify =<< trim [CODE] 1355 call assert_equal('abcd', g:Xpath) 1356 [CODE] 1357 call RunInNewVim(test, verify) 1358endfunc 1359 1360func Test_error_after_try_4() 1361 let test =<< trim [CODE] 1362 while 1 1363 try 1364 Xpath 'a' 1365 finally 1366 Xpath 'b' 1367 break 1368 call assert_report('should not get here') 1369 endtry 1370 endwhile 1371 Xpath 'c' 1372 asdf 1373 Xpath 'd' 1374 [CODE] 1375 let verify =<< trim [CODE] 1376 call assert_equal('abcd', g:Xpath) 1377 [CODE] 1378 call RunInNewVim(test, verify) 1379endfunc 1380 1381func Test_error_after_try_5() 1382 let test =<< trim [CODE] 1383 let p = 1 1384 while p 1385 let p = 0 1386 try 1387 Xpath 'a' 1388 continue 1389 call assert_report('should not get here') 1390 endtry 1391 endwhile 1392 Xpath 'b' 1393 asdf 1394 Xpath 'c' 1395 [CODE] 1396 let verify =<< trim [CODE] 1397 call assert_equal('abc', g:Xpath) 1398 [CODE] 1399 call RunInNewVim(test, verify) 1400endfunc 1401 1402func Test_error_after_try_6() 1403 let test =<< trim [CODE] 1404 let p = 1 1405 while p 1406 let p = 0 1407 try 1408 Xpath 'a' 1409 continue 1410 call assert_report('should not get here') 1411 finally 1412 Xpath 'b' 1413 endtry 1414 endwhile 1415 Xpath 'c' 1416 asdf 1417 Xpath 'd' 1418 [CODE] 1419 let verify =<< trim [CODE] 1420 call assert_equal('abcd', g:Xpath) 1421 [CODE] 1422 call RunInNewVim(test, verify) 1423endfunc 1424 1425func Test_error_after_try_7() 1426 let test =<< trim [CODE] 1427 let p = 1 1428 while p 1429 let p = 0 1430 try 1431 Xpath 'a' 1432 finally 1433 Xpath 'b' 1434 continue 1435 call assert_report('should not get here') 1436 endtry 1437 endwhile 1438 Xpath 'c' 1439 asdf 1440 Xpath 'd' 1441 [CODE] 1442 let verify =<< trim [CODE] 1443 call assert_equal('abcd', g:Xpath) 1444 [CODE] 1445 call RunInNewVim(test, verify) 1446endfunc 1447 1448"------------------------------------------------------------------------------- 1449" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1 1450" 1451" If a :try conditional stays inactive due to a preceding :continue, 1452" :break, :return, or :finish, its :finally clause should not be 1453" executed. 1454"------------------------------------------------------------------------------- 1455 1456func Test_finally_after_loop_ctrl_statement() 1457 let test =<< trim [CODE] 1458 func F() 1459 let loops = 2 1460 while loops > 0 1461 XloopNEXT 1462 let loops = loops - 1 1463 try 1464 if loops == 1 1465 Xloop 'a' 1466 continue 1467 call assert_report('should not get here') 1468 elseif loops == 0 1469 Xloop 'b' 1470 break 1471 call assert_report('should not get here') 1472 endif 1473 1474 try " inactive 1475 call assert_report('should not get here') 1476 finally 1477 call assert_report('should not get here') 1478 endtry 1479 finally 1480 Xloop 'c' 1481 endtry 1482 call assert_report('should not get here') 1483 endwhile 1484 1485 try 1486 Xpath 'd' 1487 return 1488 call assert_report('should not get here') 1489 try " inactive 1490 call assert_report('should not get here') 1491 finally 1492 call assert_report('should not get here') 1493 endtry 1494 finally 1495 Xpath 'e' 1496 endtry 1497 call assert_report('should not get here') 1498 endfunc 1499 1500 try 1501 Xpath 'f' 1502 call F() 1503 Xpath 'g' 1504 finish 1505 call assert_report('should not get here') 1506 try " inactive 1507 call assert_report('should not get here') 1508 finally 1509 call assert_report('should not get here') 1510 endtry 1511 finally 1512 Xpath 'h' 1513 endtry 1514 call assert_report('should not get here') 1515 [CODE] 1516 let verify =<< trim [CODE] 1517 call assert_equal('fa2c2b3c3degh', g:Xpath) 1518 [CODE] 1519 call RunInNewVim(test, verify) 1520endfunc 1521 1522"------------------------------------------------------------------------------- 1523" Test 22: :finally for a :try after an error/interrupt/:throw {{{1 1524" 1525" If a :try conditional stays inactive due to a preceding error or 1526" interrupt or :throw, its :finally clause should not be executed. 1527"------------------------------------------------------------------------------- 1528 1529func Test_finally_after_error_in_func() 1530 let test =<< trim [CODE] 1531 func Error() 1532 try 1533 Xpath 'b' 1534 asdf " aborting error, triggering error exception 1535 call assert_report('should not get here') 1536 endtry 1537 call assert_report('should not get here') 1538 endfunc 1539 1540 Xpath 'a' 1541 call Error() 1542 call assert_report('should not get here') 1543 1544 if 1 " not active due to error 1545 try " not active since :if inactive 1546 call assert_report('should not get here') 1547 finally 1548 call assert_report('should not get here') 1549 endtry 1550 endif 1551 1552 try " not active due to error 1553 call assert_report('should not get here') 1554 finally 1555 call assert_report('should not get here') 1556 endtry 1557 [CODE] 1558 let verify =<< trim [CODE] 1559 call assert_equal('ab', g:Xpath) 1560 [CODE] 1561 call RunInNewVim(test, verify) 1562endfunc 1563 1564func Test_finally_after_interrupt() 1565 let test =<< trim [CODE] 1566 func Interrupt() 1567 try 1568 Xpath 'a' 1569 call interrupt() " triggering interrupt exception 1570 call assert_report('should not get here') 1571 endtry 1572 endfunc 1573 1574 Xpath 'b' 1575 try 1576 call Interrupt() 1577 catch /^Vim:Interrupt$/ 1578 Xpath 'c' 1579 finish 1580 endtry 1581 call assert_report('should not get here') 1582 1583 if 1 " not active due to interrupt 1584 try " not active since :if inactive 1585 call assert_report('should not get here') 1586 finally 1587 call assert_report('should not get here') 1588 endtry 1589 endif 1590 1591 try " not active due to interrupt 1592 call assert_report('should not get here') 1593 finally 1594 call assert_report('should not get here') 1595 endtry 1596 [CODE] 1597 let verify =<< trim [CODE] 1598 call assert_equal('bac', g:Xpath) 1599 [CODE] 1600 call RunInNewVim(test, verify) 1601endfunc 1602 1603func Test_finally_after_throw() 1604 let test =<< trim [CODE] 1605 func Throw() 1606 Xpath 'a' 1607 throw 'xyz' 1608 endfunc 1609 1610 Xpath 'b' 1611 call Throw() 1612 call assert_report('should not get here') 1613 1614 if 1 " not active due to :throw 1615 try " not active since :if inactive 1616 call assert_report('should not get here') 1617 finally 1618 call assert_report('should not get here') 1619 endtry 1620 endif 1621 1622 try " not active due to :throw 1623 call assert_report('should not get here') 1624 finally 1625 call assert_report('should not get here') 1626 endtry 1627 [CODE] 1628 let verify =<< trim [CODE] 1629 call assert_equal('ba', g:Xpath) 1630 [CODE] 1631 call RunInNewVim(test, verify) 1632endfunc 1633 1634"------------------------------------------------------------------------------- 1635" Test 23: :catch clauses for a :try after a :throw {{{1 1636" 1637" If a :try conditional stays inactive due to a preceding :throw, 1638" none of its :catch clauses should be executed. 1639"------------------------------------------------------------------------------- 1640 1641func Test_catch_after_throw() 1642 let test =<< trim [CODE] 1643 try 1644 Xpath 'a' 1645 throw "xyz" 1646 call assert_report('should not get here') 1647 1648 if 1 " not active due to :throw 1649 try " not active since :if inactive 1650 call assert_report('should not get here') 1651 catch /xyz/ 1652 call assert_report('should not get here') 1653 endtry 1654 endif 1655 catch /xyz/ 1656 Xpath 'b' 1657 endtry 1658 1659 Xpath 'c' 1660 throw "abc" 1661 call assert_report('should not get here') 1662 1663 try " not active due to :throw 1664 call assert_report('should not get here') 1665 catch /abc/ 1666 call assert_report('should not get here') 1667 endtry 1668 [CODE] 1669 let verify =<< trim [CODE] 1670 call assert_equal('abc', g:Xpath) 1671 [CODE] 1672 call RunInNewVim(test, verify) 1673endfunc 1674 1675"------------------------------------------------------------------------------- 1676" Test 24: :endtry for a :try after a :throw {{{1 1677" 1678" If a :try conditional stays inactive due to a preceding :throw, 1679" its :endtry should not rethrow the exception to the next surrounding 1680" active :try conditional. 1681"------------------------------------------------------------------------------- 1682 1683func Test_endtry_after_throw() 1684 let test =<< trim [CODE] 1685 try " try 1 1686 try " try 2 1687 Xpath 'a' 1688 throw "xyz" " makes try 2 inactive 1689 call assert_report('should not get here') 1690 1691 try " try 3 1692 call assert_report('should not get here') 1693 endtry " no rethrow to try 1 1694 catch /xyz/ " should catch although try 2 inactive 1695 Xpath 'b' 1696 endtry 1697 catch /xyz/ " try 1 active, but exception already caught 1698 call assert_report('should not get here') 1699 endtry 1700 Xpath 'c' 1701 [CODE] 1702 let verify =<< trim [CODE] 1703 call assert_equal('abc', g:Xpath) 1704 [CODE] 1705 call RunInNewVim(test, verify) 1706endfunc 1707 1708"------------------------------------------------------------------------------- 1709" Test 27: Executing :finally clauses after :return {{{1 1710" 1711" For a :return command dynamically enclosed in a :try/:endtry region, 1712" :finally clauses are executed and the called function is ended. 1713"------------------------------------------------------------------------------- 1714 1715func T27_F() 1716 try 1717 Xpath 'a' 1718 try 1719 Xpath 'b' 1720 return 1721 call assert_report('should not get here') 1722 finally 1723 Xpath 'c' 1724 endtry 1725 Xpath 'd' 1726 finally 1727 Xpath 'e' 1728 endtry 1729 call assert_report('should not get here') 1730endfunc 1731 1732func T27_G() 1733 try 1734 Xpath 'f' 1735 return 1736 call assert_report('should not get here') 1737 finally 1738 Xpath 'g' 1739 call T27_F() 1740 Xpath 'h' 1741 endtry 1742 call assert_report('should not get here') 1743endfunc 1744 1745func T27_H() 1746 try 1747 Xpath 'i' 1748 call T27_G() 1749 Xpath 'j' 1750 finally 1751 Xpath 'k' 1752 return 1753 call assert_report('should not get here') 1754 endtry 1755 call assert_report('should not get here') 1756endfunction 1757 1758func Test_finally_after_return() 1759 XpathINIT 1760 try 1761 Xpath 'l' 1762 call T27_H() 1763 Xpath 'm' 1764 finally 1765 Xpath 'n' 1766 endtry 1767 call assert_equal('lifgabcehjkmn', g:Xpath) 1768endfunc 1769 1770"------------------------------------------------------------------------------- 1771" Test 28: Executing :finally clauses after :finish {{{1 1772" 1773" For a :finish command dynamically enclosed in a :try/:endtry region, 1774" :finally clauses are executed and the sourced file is finished. 1775" 1776" This test executes the bodies of the functions F, G, and H from the 1777" previous test as script files (:return replaced by :finish). 1778"------------------------------------------------------------------------------- 1779 1780func Test_finally_after_finish() 1781 XpathINIT 1782 1783 let scriptF = MakeScript("T27_F") 1784 let scriptG = MakeScript("T27_G", scriptF) 1785 let scriptH = MakeScript("T27_H", scriptG) 1786 1787 try 1788 Xpath 'A' 1789 exec "source" scriptH 1790 Xpath 'B' 1791 finally 1792 Xpath 'C' 1793 endtry 1794 Xpath 'D' 1795 call assert_equal('AifgabcehjkBCD', g:Xpath) 1796 call delete(scriptF) 1797 call delete(scriptG) 1798 call delete(scriptH) 1799endfunc 1800 1801"------------------------------------------------------------------------------- 1802" Test 29: Executing :finally clauses on errors {{{1 1803" 1804" After an error in a command dynamically enclosed in a :try/:endtry 1805" region, :finally clauses are executed and the script processing is 1806" terminated. 1807"------------------------------------------------------------------------------- 1808 1809func Test_finally_after_error_1() 1810 let test =<< trim [CODE] 1811 func F() 1812 while 1 1813 try 1814 Xpath 'a' 1815 while 1 1816 try 1817 Xpath 'b' 1818 asdf " error 1819 call assert_report('should not get here') 1820 finally 1821 Xpath 'c' 1822 endtry | call assert_report('should not get here') 1823 call assert_report('should not get here') 1824 break 1825 endwhile 1826 call assert_report('should not get here') 1827 finally 1828 Xpath 'd' 1829 endtry | call assert_report('should not get here') 1830 call assert_report('should not get here') 1831 break 1832 endwhile 1833 call assert_report('should not get here') 1834 endfunc 1835 1836 while 1 1837 try 1838 Xpath 'e' 1839 while 1 1840 call F() 1841 call assert_report('should not get here') 1842 break 1843 endwhile | call assert_report('should not get here') 1844 call assert_report('should not get here') 1845 finally 1846 Xpath 'f' 1847 endtry | call assert_report('should not get here') 1848 endwhile | call assert_report('should not get here') 1849 call assert_report('should not get here') 1850 [CODE] 1851 let verify =<< trim [CODE] 1852 call assert_equal('eabcdf', g:Xpath) 1853 [CODE] 1854 call RunInNewVim(test, verify) 1855endfunc 1856 1857func Test_finally_after_error_2() 1858 let test =<< trim [CODE] 1859 func G() abort 1860 if 1 1861 try 1862 Xpath 'a' 1863 asdf " error 1864 call assert_report('should not get here') 1865 finally 1866 Xpath 'b' 1867 endtry | Xpath 'c' 1868 endif | Xpath 'd' 1869 call assert_report('should not get here') 1870 endfunc 1871 1872 if 1 1873 try 1874 Xpath 'e' 1875 call G() 1876 call assert_report('should not get here') 1877 finally 1878 Xpath 'f' 1879 endtry | call assert_report('should not get here') 1880 endif | call assert_report('should not get here') 1881 call assert_report('should not get here') 1882 [CODE] 1883 let verify =<< trim [CODE] 1884 call assert_equal('eabf', g:Xpath) 1885 [CODE] 1886 call RunInNewVim(test, verify) 1887endfunc 1888 1889"------------------------------------------------------------------------------- 1890" Test 30: Executing :finally clauses on interrupt {{{1 1891" 1892" After an interrupt in a command dynamically enclosed in 1893" a :try/:endtry region, :finally clauses are executed and the 1894" script processing is terminated. 1895"------------------------------------------------------------------------------- 1896 1897func Test_finally_on_interrupt() 1898 let test =<< trim [CODE] 1899 func F() 1900 try 1901 Xloop 'a' 1902 call interrupt() 1903 call assert_report('should not get here') 1904 finally 1905 Xloop 'b' 1906 endtry 1907 call assert_report('should not get here') 1908 endfunc 1909 1910 try 1911 try 1912 Xpath 'c' 1913 try 1914 Xpath 'd' 1915 call interrupt() 1916 call assert_report('should not get here') 1917 finally 1918 Xpath 'e' 1919 try 1920 Xpath 'f' 1921 try 1922 Xpath 'g' 1923 finally 1924 Xpath 'h' 1925 try 1926 Xpath 'i' 1927 call interrupt() 1928 call assert_report('should not get here') 1929 endtry 1930 call assert_report('should not get here') 1931 endtry 1932 call assert_report('should not get here') 1933 endtry 1934 call assert_report('should not get here') 1935 endtry 1936 call assert_report('should not get here') 1937 finally 1938 Xpath 'j' 1939 try 1940 Xpath 'k' 1941 call F() 1942 call assert_report('should not get here') 1943 finally 1944 Xpath 'l' 1945 try 1946 Xpath 'm' 1947 XloopNEXT 1948 ExecAsScript F 1949 call assert_report('should not get here') 1950 finally 1951 Xpath 'n' 1952 endtry 1953 call assert_report('should not get here') 1954 endtry 1955 call assert_report('should not get here') 1956 endtry 1957 call assert_report('should not get here') 1958 catch /^Vim:Interrupt$/ 1959 Xpath 'o' 1960 endtry 1961 [CODE] 1962 let verify =<< trim [CODE] 1963 call assert_equal('cdefghijka1b1lma2b2no', g:Xpath) 1964 [CODE] 1965 call RunInNewVim(test, verify) 1966endfunc 1967 1968"------------------------------------------------------------------------------- 1969" Test 31: Executing :finally clauses after :throw {{{1 1970" 1971" After a :throw dynamically enclosed in a :try/:endtry region, 1972" :finally clauses are executed and the script processing is 1973" terminated. 1974"------------------------------------------------------------------------------- 1975 1976func Test_finally_after_throw_2() 1977 let test =<< trim [CODE] 1978 func F() 1979 try 1980 Xloop 'a' 1981 throw "exception" 1982 call assert_report('should not get here') 1983 finally 1984 Xloop 'b' 1985 endtry 1986 call assert_report('should not get here') 1987 endfunc 1988 1989 try 1990 Xpath 'c' 1991 try 1992 Xpath 'd' 1993 throw "exception" 1994 call assert_report('should not get here') 1995 finally 1996 Xpath 'e' 1997 try 1998 Xpath 'f' 1999 try 2000 Xpath 'g' 2001 finally 2002 Xpath 'h' 2003 try 2004 Xpath 'i' 2005 throw "exception" 2006 call assert_report('should not get here') 2007 endtry 2008 call assert_report('should not get here') 2009 endtry 2010 call assert_report('should not get here') 2011 endtry 2012 call assert_report('should not get here') 2013 endtry 2014 call assert_report('should not get here') 2015 finally 2016 Xpath 'j' 2017 try 2018 Xpath 'k' 2019 call F() 2020 call assert_report('should not get here') 2021 finally 2022 Xpath 'l' 2023 try 2024 Xpath 'm' 2025 XloopNEXT 2026 ExecAsScript F 2027 call assert_report('should not get here') 2028 finally 2029 Xpath 'n' 2030 endtry 2031 call assert_report('should not get here') 2032 endtry 2033 call assert_report('should not get here') 2034 endtry 2035 call assert_report('should not get here') 2036 [CODE] 2037 let verify =<< trim [CODE] 2038 call assert_equal('cdefghijka1b1lma2b2n', g:Xpath) 2039 [CODE] 2040 call RunInNewVim(test, verify) 2041endfunc 2042 2043"------------------------------------------------------------------------------- 2044" Test 34: :finally reason discarded by :continue {{{1 2045" 2046" When a :finally clause is executed due to a :continue, :break, 2047" :return, :finish, error, interrupt or :throw, the jump reason is 2048" discarded by a :continue in the finally clause. 2049"------------------------------------------------------------------------------- 2050 2051func Test_finally_after_continue() 2052 let test =<< trim [CODE] 2053 func C(jump) 2054 XloopNEXT 2055 let loop = 0 2056 while loop < 2 2057 let loop = loop + 1 2058 if loop == 1 2059 try 2060 if a:jump == "continue" 2061 continue 2062 elseif a:jump == "break" 2063 break 2064 elseif a:jump == "return" || a:jump == "finish" 2065 return 2066 elseif a:jump == "error" 2067 asdf 2068 elseif a:jump == "interrupt" 2069 call interrupt() 2070 let dummy = 0 2071 elseif a:jump == "throw" 2072 throw "abc" 2073 endif 2074 finally 2075 continue " discards jump that caused the :finally 2076 call assert_report('should not get here') 2077 endtry 2078 call assert_report('should not get here') 2079 elseif loop == 2 2080 Xloop 'a' 2081 endif 2082 endwhile 2083 endfunc 2084 2085 call C("continue") 2086 Xpath 'b' 2087 call C("break") 2088 Xpath 'c' 2089 call C("return") 2090 Xpath 'd' 2091 let g:jump = "finish" 2092 ExecAsScript C 2093 unlet g:jump 2094 Xpath 'e' 2095 try 2096 call C("error") 2097 Xpath 'f' 2098 finally 2099 Xpath 'g' 2100 try 2101 call C("interrupt") 2102 Xpath 'h' 2103 finally 2104 Xpath 'i' 2105 call C("throw") 2106 Xpath 'j' 2107 endtry 2108 endtry 2109 Xpath 'k' 2110 [CODE] 2111 let verify =<< trim [CODE] 2112 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) 2113 [CODE] 2114 call RunInNewVim(test, verify) 2115endfunc 2116 2117"------------------------------------------------------------------------------- 2118" Test 35: :finally reason discarded by :break {{{1 2119" 2120" When a :finally clause is executed due to a :continue, :break, 2121" :return, :finish, error, interrupt or :throw, the jump reason is 2122" discarded by a :break in the finally clause. 2123"------------------------------------------------------------------------------- 2124 2125func Test_finally_discard_by_break() 2126 let test =<< trim [CODE] 2127 func B(jump) 2128 XloopNEXT 2129 let loop = 0 2130 while loop < 2 2131 let loop = loop + 1 2132 if loop == 1 2133 try 2134 if a:jump == "continue" 2135 continue 2136 elseif a:jump == "break" 2137 break 2138 elseif a:jump == "return" || a:jump == "finish" 2139 return 2140 elseif a:jump == "error" 2141 asdf 2142 elseif a:jump == "interrupt" 2143 call interrupt() 2144 let dummy = 0 2145 elseif a:jump == "throw" 2146 throw "abc" 2147 endif 2148 finally 2149 break " discards jump that caused the :finally 2150 call assert_report('should not get here') 2151 endtry 2152 elseif loop == 2 2153 call assert_report('should not get here') 2154 endif 2155 endwhile 2156 Xloop 'a' 2157 endfunc 2158 2159 call B("continue") 2160 Xpath 'b' 2161 call B("break") 2162 Xpath 'c' 2163 call B("return") 2164 Xpath 'd' 2165 let g:jump = "finish" 2166 ExecAsScript B 2167 unlet g:jump 2168 Xpath 'e' 2169 try 2170 call B("error") 2171 Xpath 'f' 2172 finally 2173 Xpath 'g' 2174 try 2175 call B("interrupt") 2176 Xpath 'h' 2177 finally 2178 Xpath 'i' 2179 call B("throw") 2180 Xpath 'j' 2181 endtry 2182 endtry 2183 Xpath 'k' 2184 [CODE] 2185 let verify =<< trim [CODE] 2186 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) 2187 [CODE] 2188 call RunInNewVim(test, verify) 2189endfunc 2190 2191"------------------------------------------------------------------------------- 2192" Test 36: :finally reason discarded by :return {{{1 2193" 2194" When a :finally clause is executed due to a :continue, :break, 2195" :return, :finish, error, interrupt or :throw, the jump reason is 2196" discarded by a :return in the finally clause. 2197"------------------------------------------------------------------------------- 2198 2199func Test_finally_discard_by_return() 2200 let test =<< trim [CODE] 2201 func R(jump, retval) abort 2202 let loop = 0 2203 while loop < 2 2204 let loop = loop + 1 2205 if loop == 1 2206 try 2207 if a:jump == "continue" 2208 continue 2209 elseif a:jump == "break" 2210 break 2211 elseif a:jump == "return" 2212 return 2213 elseif a:jump == "error" 2214 asdf 2215 elseif a:jump == "interrupt" 2216 call interrupt() 2217 let dummy = 0 2218 elseif a:jump == "throw" 2219 throw "abc" 2220 endif 2221 finally 2222 return a:retval " discards jump that caused the :finally 2223 call assert_report('should not get here') 2224 endtry 2225 elseif loop == 2 2226 call assert_report('should not get here') 2227 endif 2228 endwhile 2229 call assert_report('should not get here') 2230 endfunc 2231 2232 let sum = -R("continue", -8) 2233 Xpath 'a' 2234 let sum = sum - R("break", -16) 2235 Xpath 'b' 2236 let sum = sum - R("return", -32) 2237 Xpath 'c' 2238 try 2239 let sum = sum - R("error", -64) 2240 Xpath 'd' 2241 finally 2242 Xpath 'e' 2243 try 2244 let sum = sum - R("interrupt", -128) 2245 Xpath 'f' 2246 finally 2247 Xpath 'g' 2248 let sum = sum - R("throw", -256) 2249 Xpath 'h' 2250 endtry 2251 endtry 2252 Xpath 'i' 2253 2254 let expected = 8 + 16 + 32 + 64 + 128 + 256 2255 call assert_equal(sum, expected) 2256 [CODE] 2257 let verify =<< trim [CODE] 2258 call assert_equal('abcdefghi', g:Xpath) 2259 [CODE] 2260 call RunInNewVim(test, verify) 2261endfunc 2262 2263"------------------------------------------------------------------------------- 2264" Test 37: :finally reason discarded by :finish {{{1 2265" 2266" When a :finally clause is executed due to a :continue, :break, 2267" :return, :finish, error, interrupt or :throw, the jump reason is 2268" discarded by a :finish in the finally clause. 2269"------------------------------------------------------------------------------- 2270 2271func Test_finally_discard_by_finish() 2272 let test =<< trim [CODE] 2273 func F(jump) " not executed as function, transformed to a script 2274 let loop = 0 2275 while loop < 2 2276 let loop = loop + 1 2277 if loop == 1 2278 try 2279 if a:jump == "continue" 2280 continue 2281 elseif a:jump == "break" 2282 break 2283 elseif a:jump == "finish" 2284 finish 2285 elseif a:jump == "error" 2286 asdf 2287 elseif a:jump == "interrupt" 2288 call interrupt() 2289 let dummy = 0 2290 elseif a:jump == "throw" 2291 throw "abc" 2292 endif 2293 finally 2294 finish " discards jump that caused the :finally 2295 call assert_report('should not get here') 2296 endtry 2297 elseif loop == 2 2298 call assert_report('should not get here') 2299 endif 2300 endwhile 2301 call assert_report('should not get here') 2302 endfunc 2303 2304 let scriptF = MakeScript("F") 2305 delfunction F 2306 2307 let g:jump = "continue" 2308 exec "source" scriptF 2309 Xpath 'a' 2310 let g:jump = "break" 2311 exec "source" scriptF 2312 Xpath 'b' 2313 let g:jump = "finish" 2314 exec "source" scriptF 2315 Xpath 'c' 2316 try 2317 let g:jump = "error" 2318 exec "source" scriptF 2319 Xpath 'd' 2320 finally 2321 Xpath 'e' 2322 try 2323 let g:jump = "interrupt" 2324 exec "source" scriptF 2325 Xpath 'f' 2326 finally 2327 Xpath 'g' 2328 try 2329 let g:jump = "throw" 2330 exec "source" scriptF 2331 Xpath 'h' 2332 finally 2333 Xpath 'i' 2334 endtry 2335 endtry 2336 endtry 2337 unlet g:jump 2338 call delete(scriptF) 2339 [CODE] 2340 let verify =<< trim [CODE] 2341 call assert_equal('abcdefghi', g:Xpath) 2342 [CODE] 2343 call RunInNewVim(test, verify) 2344endfunc 2345 2346"------------------------------------------------------------------------------- 2347" Test 38: :finally reason discarded by an error {{{1 2348" 2349" When a :finally clause is executed due to a :continue, :break, 2350" :return, :finish, error, interrupt or :throw, the jump reason is 2351" discarded by an error in the finally clause. 2352"------------------------------------------------------------------------------- 2353 2354func Test_finally_discard_by_error() 2355 let test =<< trim [CODE] 2356 func E(jump) 2357 let loop = 0 2358 while loop < 2 2359 let loop = loop + 1 2360 if loop == 1 2361 try 2362 if a:jump == "continue" 2363 continue 2364 elseif a:jump == "break" 2365 break 2366 elseif a:jump == "return" || a:jump == "finish" 2367 return 2368 elseif a:jump == "error" 2369 asdf 2370 elseif a:jump == "interrupt" 2371 call interrupt() 2372 let dummy = 0 2373 elseif a:jump == "throw" 2374 throw "abc" 2375 endif 2376 finally 2377 asdf " error; discards jump that caused the :finally 2378 endtry 2379 elseif loop == 2 2380 call assert_report('should not get here') 2381 endif 2382 endwhile 2383 call assert_report('should not get here') 2384 endfunc 2385 2386 try 2387 Xpath 'a' 2388 call E("continue") 2389 call assert_report('should not get here') 2390 finally 2391 try 2392 Xpath 'b' 2393 call E("break") 2394 call assert_report('should not get here') 2395 finally 2396 try 2397 Xpath 'c' 2398 call E("return") 2399 call assert_report('should not get here') 2400 finally 2401 try 2402 Xpath 'd' 2403 let g:jump = "finish" 2404 ExecAsScript E 2405 call assert_report('should not get here') 2406 finally 2407 unlet g:jump 2408 try 2409 Xpath 'e' 2410 call E("error") 2411 call assert_report('should not get here') 2412 finally 2413 try 2414 Xpath 'f' 2415 call E("interrupt") 2416 call assert_report('should not get here') 2417 finally 2418 try 2419 Xpath 'g' 2420 call E("throw") 2421 call assert_report('should not get here') 2422 finally 2423 Xpath 'h' 2424 delfunction E 2425 endtry 2426 endtry 2427 endtry 2428 endtry 2429 endtry 2430 endtry 2431 endtry 2432 call assert_report('should not get here') 2433 [CODE] 2434 let verify =<< trim [CODE] 2435 call assert_equal('abcdefgh', g:Xpath) 2436 [CODE] 2437 call RunInNewVim(test, verify) 2438endfunc 2439 2440"------------------------------------------------------------------------------- 2441" Test 39: :finally reason discarded by an interrupt {{{1 2442" 2443" When a :finally clause is executed due to a :continue, :break, 2444" :return, :finish, error, interrupt or :throw, the jump reason is 2445" discarded by an interrupt in the finally clause. 2446"------------------------------------------------------------------------------- 2447 2448func Test_finally_discarded_by_interrupt() 2449 let test =<< trim [CODE] 2450 func I(jump) 2451 let loop = 0 2452 while loop < 2 2453 let loop = loop + 1 2454 if loop == 1 2455 try 2456 if a:jump == "continue" 2457 continue 2458 elseif a:jump == "break" 2459 break 2460 elseif a:jump == "return" || a:jump == "finish" 2461 return 2462 elseif a:jump == "error" 2463 asdf 2464 elseif a:jump == "interrupt" 2465 call interrupt() 2466 let dummy = 0 2467 elseif a:jump == "throw" 2468 throw "abc" 2469 endif 2470 finally 2471 call interrupt() 2472 let dummy = 0 2473 endtry 2474 elseif loop == 2 2475 call assert_report('should not get here') 2476 endif 2477 endwhile 2478 call assert_report('should not get here') 2479 endfunc 2480 2481 try 2482 try 2483 Xpath 'a' 2484 call I("continue") 2485 call assert_report('should not get here') 2486 finally 2487 try 2488 Xpath 'b' 2489 call I("break") 2490 call assert_report('should not get here') 2491 finally 2492 try 2493 Xpath 'c' 2494 call I("return") 2495 call assert_report('should not get here') 2496 finally 2497 try 2498 Xpath 'd' 2499 let g:jump = "finish" 2500 ExecAsScript I 2501 call assert_report('should not get here') 2502 finally 2503 unlet g:jump 2504 try 2505 Xpath 'e' 2506 call I("error") 2507 call assert_report('should not get here') 2508 finally 2509 try 2510 Xpath 'f' 2511 call I("interrupt") 2512 call assert_report('should not get here') 2513 finally 2514 try 2515 Xpath 'g' 2516 call I("throw") 2517 call assert_report('should not get here') 2518 finally 2519 Xpath 'h' 2520 delfunction I 2521 endtry 2522 endtry 2523 endtry 2524 endtry 2525 endtry 2526 endtry 2527 endtry 2528 call assert_report('should not get here') 2529 catch /^Vim:Interrupt$/ 2530 Xpath 'A' 2531 endtry 2532 [CODE] 2533 let verify =<< trim [CODE] 2534 call assert_equal('abcdefghA', g:Xpath) 2535 [CODE] 2536 call RunInNewVim(test, verify) 2537endfunc 2538 2539"------------------------------------------------------------------------------- 2540" Test 40: :finally reason discarded by :throw {{{1 2541" 2542" When a :finally clause is executed due to a :continue, :break, 2543" :return, :finish, error, interrupt or :throw, the jump reason is 2544" discarded by a :throw in the finally clause. 2545"------------------------------------------------------------------------------- 2546 2547func Test_finally_discard_by_throw() 2548 let test =<< trim [CODE] 2549 func T(jump) 2550 let loop = 0 2551 while loop < 2 2552 let loop = loop + 1 2553 if loop == 1 2554 try 2555 if a:jump == "continue" 2556 continue 2557 elseif a:jump == "break" 2558 break 2559 elseif a:jump == "return" || a:jump == "finish" 2560 return 2561 elseif a:jump == "error" 2562 asdf 2563 elseif a:jump == "interrupt" 2564 call interrupt() 2565 let dummy = 0 2566 elseif a:jump == "throw" 2567 throw "abc" 2568 endif 2569 finally 2570 throw "xyz" " discards jump that caused the :finally 2571 endtry 2572 elseif loop == 2 2573 call assert_report('should not get here') 2574 endif 2575 endwhile 2576 call assert_report('should not get here') 2577 endfunc 2578 2579 try 2580 Xpath 'a' 2581 call T("continue") 2582 call assert_report('should not get here') 2583 finally 2584 try 2585 Xpath 'b' 2586 call T("break") 2587 call assert_report('should not get here') 2588 finally 2589 try 2590 Xpath 'c' 2591 call T("return") 2592 call assert_report('should not get here') 2593 finally 2594 try 2595 Xpath 'd' 2596 let g:jump = "finish" 2597 ExecAsScript T 2598 call assert_report('should not get here') 2599 finally 2600 unlet g:jump 2601 try 2602 Xpath 'e' 2603 call T("error") 2604 call assert_report('should not get here') 2605 finally 2606 try 2607 Xpath 'f' 2608 call T("interrupt") 2609 call assert_report('should not get here') 2610 finally 2611 try 2612 Xpath 'g' 2613 call T("throw") 2614 call assert_report('should not get here') 2615 finally 2616 Xpath 'h' 2617 delfunction T 2618 endtry 2619 endtry 2620 endtry 2621 endtry 2622 endtry 2623 endtry 2624 endtry 2625 call assert_report('should not get here') 2626 [CODE] 2627 let verify =<< trim [CODE] 2628 call assert_equal('abcdefgh', g:Xpath) 2629 [CODE] 2630 call RunInNewVim(test, verify) 2631endfunc 2632 2633"------------------------------------------------------------------------------- 2634" Test 49: Throwing exceptions across functions {{{1 2635" 2636" When an exception is thrown but not caught inside a function, the 2637" caller is checked for a matching :catch clause. 2638"------------------------------------------------------------------------------- 2639 2640func T49_C() 2641 try 2642 Xpath 'a' 2643 throw "arrgh" 2644 call assert_report('should not get here') 2645 catch /arrgh/ 2646 Xpath 'b' 2647 endtry 2648 Xpath 'c' 2649endfunc 2650 2651func T49_T1() 2652 XloopNEXT 2653 try 2654 Xloop 'd' 2655 throw "arrgh" 2656 call assert_report('should not get here') 2657 finally 2658 Xloop 'e' 2659 endtry 2660 Xloop 'f' 2661endfunc 2662 2663func T49_T2() 2664 try 2665 Xpath 'g' 2666 call T49_T1() 2667 call assert_report('should not get here') 2668 finally 2669 Xpath 'h' 2670 endtry 2671 call assert_report('should not get here') 2672endfunc 2673 2674func Test_throw_exception_across_funcs() 2675 XpathINIT 2676 XloopINIT 2677 try 2678 Xpath 'i' 2679 call T49_C() " throw and catch 2680 Xpath 'j' 2681 catch /.*/ 2682 call assert_report('should not get here') 2683 endtry 2684 2685 try 2686 Xpath 'k' 2687 call T49_T1() " throw, one level 2688 call assert_report('should not get here') 2689 catch /arrgh/ 2690 Xpath 'l' 2691 catch /.*/ 2692 call assert_report('should not get here') 2693 endtry 2694 2695 try 2696 Xpath 'm' 2697 call T49_T2() " throw, two levels 2698 call assert_report('should not get here') 2699 catch /arrgh/ 2700 Xpath 'n' 2701 catch /.*/ 2702 call assert_report('should not get here') 2703 endtry 2704 Xpath 'o' 2705 2706 call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath) 2707endfunc 2708 2709"------------------------------------------------------------------------------- 2710" Test 50: Throwing exceptions across script files {{{1 2711" 2712" When an exception is thrown but not caught inside a script file, 2713" the sourcing script or function is checked for a matching :catch 2714" clause. 2715" 2716" This test executes the bodies of the functions C, T1, and T2 from 2717" the previous test as script files (:return replaced by :finish). 2718"------------------------------------------------------------------------------- 2719 2720func T50_F() 2721 try 2722 Xpath 'A' 2723 exec "source" g:scriptC 2724 Xpath 'B' 2725 catch /.*/ 2726 call assert_report('should not get here') 2727 endtry 2728 2729 try 2730 Xpath 'C' 2731 exec "source" g:scriptT1 2732 call assert_report('should not get here') 2733 catch /arrgh/ 2734 Xpath 'D' 2735 catch /.*/ 2736 call assert_report('should not get here') 2737 endtry 2738endfunc 2739 2740func Test_throw_across_script() 2741 XpathINIT 2742 XloopINIT 2743 let g:scriptC = MakeScript("T49_C") 2744 let g:scriptT1 = MakeScript("T49_T1") 2745 let scriptT2 = MakeScript("T49_T2", g:scriptT1) 2746 2747 try 2748 Xpath 'E' 2749 call T50_F() 2750 Xpath 'F' 2751 exec "source" scriptT2 2752 call assert_report('should not get here') 2753 catch /arrgh/ 2754 Xpath 'G' 2755 catch /.*/ 2756 call assert_report('should not get here') 2757 endtry 2758 Xpath 'H' 2759 call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath) 2760 2761 call delete(g:scriptC) 2762 call delete(g:scriptT1) 2763 call delete(scriptT2) 2764 unlet g:scriptC g:scriptT1 scriptT2 2765endfunc 2766 2767"------------------------------------------------------------------------------- 2768" Test 52: Uncaught exceptions {{{1 2769" 2770" When an exception is thrown but not caught, an error message is 2771" displayed when the script is terminated. In case of an interrupt 2772" or error exception, the normal interrupt or error message(s) are 2773" displayed. 2774"------------------------------------------------------------------------------- 2775 2776func Test_uncaught_exception_1() 2777 CheckEnglish 2778 2779 let test =<< trim [CODE] 2780 Xpath 'a' 2781 throw "arrgh" 2782 call assert_report('should not get here')` 2783 [CODE] 2784 let verify =<< trim [CODE] 2785 call assert_equal('E605: Exception not caught: arrgh', v:errmsg) 2786 call assert_equal('a', g:Xpath) 2787 [CODE] 2788 call RunInNewVim(test, verify) 2789endfunc 2790 2791func Test_uncaught_exception_2() 2792 CheckEnglish 2793 2794 let test =<< trim [CODE] 2795 try 2796 Xpath 'a' 2797 throw "oops" 2798 call assert_report('should not get here')` 2799 catch /arrgh/ 2800 call assert_report('should not get here')` 2801 endtry 2802 call assert_report('should not get here')` 2803 [CODE] 2804 let verify =<< trim [CODE] 2805 call assert_equal('E605: Exception not caught: oops', v:errmsg) 2806 call assert_equal('a', g:Xpath) 2807 [CODE] 2808 call RunInNewVim(test, verify) 2809endfunc 2810 2811func Test_uncaught_exception_3() 2812 CheckEnglish 2813 2814 let test =<< trim [CODE] 2815 func T() 2816 Xpath 'c' 2817 throw "brrr" 2818 call assert_report('should not get here')` 2819 endfunc 2820 2821 try 2822 Xpath 'a' 2823 throw "arrgh" 2824 call assert_report('should not get here')` 2825 catch /.*/ 2826 Xpath 'b' 2827 call T() 2828 call assert_report('should not get here')` 2829 endtry 2830 call assert_report('should not get here')` 2831 [CODE] 2832 let verify =<< trim [CODE] 2833 call assert_equal('E605: Exception not caught: brrr', v:errmsg) 2834 call assert_equal('abc', g:Xpath) 2835 [CODE] 2836 call RunInNewVim(test, verify) 2837endfunc 2838 2839func Test_uncaught_exception_4() 2840 CheckEnglish 2841 2842 let test =<< trim [CODE] 2843 try 2844 Xpath 'a' 2845 throw "arrgh" 2846 call assert_report('should not get here')` 2847 finally 2848 Xpath 'b' 2849 throw "brrr" 2850 call assert_report('should not get here')` 2851 endtry 2852 call assert_report('should not get here')` 2853 [CODE] 2854 let verify =<< trim [CODE] 2855 call assert_equal('E605: Exception not caught: brrr', v:errmsg) 2856 call assert_equal('ab', g:Xpath) 2857 [CODE] 2858 call RunInNewVim(test, verify) 2859endfunc 2860 2861func Test_uncaught_exception_5() 2862 CheckEnglish 2863 2864 " Need to catch and handle interrupt, otherwise the test will wait for the 2865 " user to press <Enter> to continue 2866 let test =<< trim [CODE] 2867 try 2868 try 2869 Xpath 'a' 2870 call interrupt() 2871 call assert_report('should not get here') 2872 endtry 2873 call assert_report('should not get here') 2874 catch /^Vim:Interrupt$/ 2875 Xpath 'b' 2876 endtry 2877 [CODE] 2878 let verify =<< trim [CODE] 2879 call assert_equal('ab', g:Xpath) 2880 [CODE] 2881 call RunInNewVim(test, verify) 2882endfunc 2883 2884func Test_uncaught_exception_6() 2885 CheckEnglish 2886 2887 let test =<< trim [CODE] 2888 try 2889 Xpath 'a' 2890 let x = novar " error E121; exception: E121 2891 catch /E15:/ " should not catch 2892 call assert_report('should not get here') 2893 endtry 2894 call assert_report('should not get here') 2895 [CODE] 2896 let verify =<< trim [CODE] 2897 call assert_equal('a', g:Xpath) 2898 call assert_equal('E121: Undefined variable: novar', v:errmsg) 2899 [CODE] 2900 call RunInNewVim(test, verify) 2901endfunc 2902 2903func Test_uncaught_exception_7() 2904 CheckEnglish 2905 2906 let test =<< trim [CODE] 2907 try 2908 Xpath 'a' 2909 " error E108/E488; exception: E488 2910 unlet novar # 2911 catch /E108:/ " should not catch 2912 call assert_report('should not get here') 2913 endtry 2914 call assert_report('should not get here') 2915 [CODE] 2916 let verify =<< trim [CODE] 2917 call assert_equal('a', g:Xpath) 2918 call assert_equal('E488: Trailing characters: #', v:errmsg) 2919 [CODE] 2920 call RunInNewVim(test, verify) 2921endfunc 2922 2923"------------------------------------------------------------------------------- 2924" Test 53: Nesting errors: :endif/:else/:elseif {{{1 2925" 2926" For nesting errors of :if conditionals the correct error messages 2927" should be given. 2928"------------------------------------------------------------------------------- 2929 2930func Test_nested_if_else_errors() 2931 CheckEnglish 2932 2933 " :endif without :if 2934 let code =<< trim END 2935 endif 2936 END 2937 call writefile(code, 'Xtest') 2938 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2939 2940 " :endif without :if 2941 let code =<< trim END 2942 while 1 2943 endif 2944 endwhile 2945 END 2946 call writefile(code, 'Xtest') 2947 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2948 2949 " :endif without :if 2950 let code =<< trim END 2951 try 2952 finally 2953 endif 2954 endtry 2955 END 2956 call writefile(code, 'Xtest') 2957 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2958 2959 " :endif without :if 2960 let code =<< trim END 2961 try 2962 endif 2963 endtry 2964 END 2965 call writefile(code, 'Xtest') 2966 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2967 2968 " :endif without :if 2969 let code =<< trim END 2970 try 2971 throw "a" 2972 catch /a/ 2973 endif 2974 endtry 2975 END 2976 call writefile(code, 'Xtest') 2977 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2978 2979 " :else without :if 2980 let code =<< trim END 2981 else 2982 END 2983 call writefile(code, 'Xtest') 2984 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 2985 2986 " :else without :if 2987 let code =<< trim END 2988 while 1 2989 else 2990 endwhile 2991 END 2992 call writefile(code, 'Xtest') 2993 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 2994 2995 " :else without :if 2996 let code =<< trim END 2997 try 2998 finally 2999 else 3000 endtry 3001 END 3002 call writefile(code, 'Xtest') 3003 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 3004 3005 " :else without :if 3006 let code =<< trim END 3007 try 3008 else 3009 endtry 3010 END 3011 call writefile(code, 'Xtest') 3012 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 3013 3014 " :else without :if 3015 let code =<< trim END 3016 try 3017 throw "a" 3018 catch /a/ 3019 else 3020 endtry 3021 END 3022 call writefile(code, 'Xtest') 3023 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 3024 3025 " :elseif without :if 3026 let code =<< trim END 3027 elseif 3028 END 3029 call writefile(code, 'Xtest') 3030 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3031 3032 " :elseif without :if 3033 let code =<< trim END 3034 while 1 3035 elseif 3036 endwhile 3037 END 3038 call writefile(code, 'Xtest') 3039 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3040 3041 " :elseif without :if 3042 let code =<< trim END 3043 try 3044 finally 3045 elseif 3046 endtry 3047 END 3048 call writefile(code, 'Xtest') 3049 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3050 3051 " :elseif without :if 3052 let code =<< trim END 3053 try 3054 elseif 3055 endtry 3056 END 3057 call writefile(code, 'Xtest') 3058 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3059 3060 " :elseif without :if 3061 let code =<< trim END 3062 try 3063 throw "a" 3064 catch /a/ 3065 elseif 3066 endtry 3067 END 3068 call writefile(code, 'Xtest') 3069 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3070 3071 " multiple :else 3072 let code =<< trim END 3073 if 1 3074 else 3075 else 3076 endif 3077 END 3078 call writefile(code, 'Xtest') 3079 call AssertException(['source Xtest'], 'Vim(else):E583: multiple :else') 3080 3081 " :elseif after :else 3082 let code =<< trim END 3083 if 1 3084 else 3085 elseif 1 3086 endif 3087 END 3088 call writefile(code, 'Xtest') 3089 call AssertException(['source Xtest'], 'Vim(elseif):E584: :elseif after :else') 3090 3091 call delete('Xtest') 3092endfunc 3093 3094"------------------------------------------------------------------------------- 3095" Test 54: Nesting errors: :while/:endwhile {{{1 3096" 3097" For nesting errors of :while conditionals the correct error messages 3098" should be given. 3099" 3100" This test reuses the function MESSAGES() from the previous test. 3101" This functions checks the messages in g:msgfile. 3102"------------------------------------------------------------------------------- 3103 3104func Test_nested_while_error() 3105 CheckEnglish 3106 3107 " :endwhile without :while 3108 let code =<< trim END 3109 endwhile 3110 END 3111 call writefile(code, 'Xtest') 3112 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3113 3114 " :endwhile without :while 3115 let code =<< trim END 3116 if 1 3117 endwhile 3118 endif 3119 END 3120 call writefile(code, 'Xtest') 3121 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3122 3123 " Missing :endif 3124 let code =<< trim END 3125 while 1 3126 if 1 3127 endwhile 3128 END 3129 call writefile(code, 'Xtest') 3130 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif') 3131 3132 " :endwhile without :while 3133 let code =<< trim END 3134 try 3135 finally 3136 endwhile 3137 endtry 3138 END 3139 call writefile(code, 'Xtest') 3140 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3141 3142 " Missing :endtry 3143 let code =<< trim END 3144 while 1 3145 try 3146 finally 3147 endwhile 3148 END 3149 call writefile(code, 'Xtest') 3150 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry') 3151 3152 " Missing :endtry 3153 let code =<< trim END 3154 while 1 3155 if 1 3156 try 3157 finally 3158 endwhile 3159 END 3160 call writefile(code, 'Xtest') 3161 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry') 3162 3163 " Missing :endif 3164 let code =<< trim END 3165 while 1 3166 try 3167 finally 3168 if 1 3169 endwhile 3170 END 3171 call writefile(code, 'Xtest') 3172 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif') 3173 3174 " :endwhile without :while 3175 let code =<< trim END 3176 try 3177 endwhile 3178 endtry 3179 END 3180 call writefile(code, 'Xtest') 3181 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3182 3183 " :endwhile without :while 3184 let code =<< trim END 3185 while 1 3186 try 3187 endwhile 3188 endtry 3189 endwhile 3190 END 3191 call writefile(code, 'Xtest') 3192 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3193 3194 " :endwhile without :while 3195 let code =<< trim END 3196 try 3197 throw "a" 3198 catch /a/ 3199 endwhile 3200 endtry 3201 END 3202 call writefile(code, 'Xtest') 3203 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3204 3205 " :endwhile without :while 3206 let code =<< trim END 3207 while 1 3208 try 3209 throw "a" 3210 catch /a/ 3211 endwhile 3212 endtry 3213 endwhile 3214 END 3215 call writefile(code, 'Xtest') 3216 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3217 3218 call delete('Xtest') 3219endfunc 3220 3221"------------------------------------------------------------------------------- 3222" Test 55: Nesting errors: :continue/:break {{{1 3223" 3224" For nesting errors of :continue and :break commands the correct 3225" error messages should be given. 3226" 3227" This test reuses the function MESSAGES() from the previous test. 3228" This functions checks the messages in g:msgfile. 3229"------------------------------------------------------------------------------- 3230 3231func Test_nested_cont_break_error() 3232 CheckEnglish 3233 3234 " :continue without :while 3235 let code =<< trim END 3236 continue 3237 END 3238 call writefile(code, 'Xtest') 3239 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3240 3241 " :continue without :while 3242 let code =<< trim END 3243 if 1 3244 continue 3245 endif 3246 END 3247 call writefile(code, 'Xtest') 3248 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3249 3250 " :continue without :while 3251 let code =<< trim END 3252 try 3253 finally 3254 continue 3255 endtry 3256 END 3257 call writefile(code, 'Xtest') 3258 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3259 3260 " :continue without :while 3261 let code =<< trim END 3262 try 3263 continue 3264 endtry 3265 END 3266 call writefile(code, 'Xtest') 3267 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3268 3269 " :continue without :while 3270 let code =<< trim END 3271 try 3272 throw "a" 3273 catch /a/ 3274 continue 3275 endtry 3276 END 3277 call writefile(code, 'Xtest') 3278 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3279 3280 " :break without :while 3281 let code =<< trim END 3282 break 3283 END 3284 call writefile(code, 'Xtest') 3285 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3286 3287 " :break without :while 3288 let code =<< trim END 3289 if 1 3290 break 3291 endif 3292 END 3293 call writefile(code, 'Xtest') 3294 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3295 3296 " :break without :while 3297 let code =<< trim END 3298 try 3299 finally 3300 break 3301 endtry 3302 END 3303 call writefile(code, 'Xtest') 3304 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3305 3306 " :break without :while 3307 let code =<< trim END 3308 try 3309 break 3310 endtry 3311 END 3312 call writefile(code, 'Xtest') 3313 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3314 3315 " :break without :while 3316 let code =<< trim END 3317 try 3318 throw "a" 3319 catch /a/ 3320 break 3321 endtry 3322 END 3323 call writefile(code, 'Xtest') 3324 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3325 3326 call delete('Xtest') 3327endfunc 3328 3329"------------------------------------------------------------------------------- 3330" Test 56: Nesting errors: :endtry {{{1 3331" 3332" For nesting errors of :try conditionals the correct error messages 3333" should be given. 3334" 3335" This test reuses the function MESSAGES() from the previous test. 3336" This functions checks the messages in g:msgfile. 3337"------------------------------------------------------------------------------- 3338 3339func Test_nested_endtry_error() 3340 CheckEnglish 3341 3342 " :endtry without :try 3343 let code =<< trim END 3344 endtry 3345 END 3346 call writefile(code, 'Xtest') 3347 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try') 3348 3349 " :endtry without :try 3350 let code =<< trim END 3351 if 1 3352 endtry 3353 endif 3354 END 3355 call writefile(code, 'Xtest') 3356 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try') 3357 3358 " :endtry without :try 3359 let code =<< trim END 3360 while 1 3361 endtry 3362 endwhile 3363 END 3364 call writefile(code, 'Xtest') 3365 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try') 3366 3367 " Missing :endif 3368 let code =<< trim END 3369 try 3370 if 1 3371 endtry 3372 END 3373 call writefile(code, 'Xtest') 3374 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif') 3375 3376 " Missing :endwhile 3377 let code =<< trim END 3378 try 3379 while 1 3380 endtry 3381 END 3382 call writefile(code, 'Xtest') 3383 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile') 3384 3385 " Missing :endif 3386 let code =<< trim END 3387 try 3388 finally 3389 if 1 3390 endtry 3391 END 3392 call writefile(code, 'Xtest') 3393 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif') 3394 3395 " Missing :endwhile 3396 let code =<< trim END 3397 try 3398 finally 3399 while 1 3400 endtry 3401 END 3402 call writefile(code, 'Xtest') 3403 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile') 3404 3405 " Missing :endif 3406 let code =<< trim END 3407 try 3408 throw "a" 3409 catch /a/ 3410 if 1 3411 endtry 3412 END 3413 call writefile(code, 'Xtest') 3414 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif') 3415 3416 " Missing :endwhile 3417 let code =<< trim END 3418 try 3419 throw "a" 3420 catch /a/ 3421 while 1 3422 endtry 3423 END 3424 call writefile(code, 'Xtest') 3425 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile') 3426 3427 call delete('Xtest') 3428endfunc 3429 3430"------------------------------------------------------------------------------- 3431" Test 57: v:exception and v:throwpoint for user exceptions {{{1 3432" 3433" v:exception evaluates to the value of the exception that was caught 3434" most recently and is not finished. (A caught exception is finished 3435" when the next ":catch", ":finally", or ":endtry" is reached.) 3436" v:throwpoint evaluates to the script/function name and line number 3437" where that exception has been thrown. 3438"------------------------------------------------------------------------------- 3439 3440func Test_user_exception_info() 3441 CheckEnglish 3442 3443 XpathINIT 3444 XloopINIT 3445 3446 func FuncException() 3447 let g:exception = v:exception 3448 endfunc 3449 3450 func FuncThrowpoint() 3451 let g:throwpoint = v:throwpoint 3452 endfunc 3453 3454 let scriptException = MakeScript("FuncException") 3455 let scriptThrowPoint = MakeScript("FuncThrowpoint") 3456 3457 command! CmdException let g:exception = v:exception 3458 command! CmdThrowpoint let g:throwpoint = v:throwpoint 3459 3460 func T(arg, line) 3461 if a:line == 2 3462 throw a:arg " in line 2 3463 elseif a:line == 4 3464 throw a:arg " in line 4 3465 elseif a:line == 6 3466 throw a:arg " in line 6 3467 elseif a:line == 8 3468 throw a:arg " in line 8 3469 endif 3470 endfunc 3471 3472 func G(arg, line) 3473 call T(a:arg, a:line) 3474 endfunc 3475 3476 func F(arg, line) 3477 call G(a:arg, a:line) 3478 endfunc 3479 3480 let scriptT = MakeScript("T") 3481 let scriptG = MakeScript("G", scriptT) 3482 let scriptF = MakeScript("F", scriptG) 3483 3484 try 3485 Xpath 'a' 3486 call F("oops", 2) 3487 catch /.*/ 3488 Xpath 'b' 3489 let exception = v:exception 3490 let throwpoint = v:throwpoint 3491 call assert_equal("oops", v:exception) 3492 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3493 call assert_match('\<2\>', v:throwpoint) 3494 3495 exec "let exception = v:exception" 3496 exec "let throwpoint = v:throwpoint" 3497 call assert_equal("oops", v:exception) 3498 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3499 call assert_match('\<2\>', v:throwpoint) 3500 3501 CmdException 3502 CmdThrowpoint 3503 call assert_equal("oops", v:exception) 3504 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3505 call assert_match('\<2\>', v:throwpoint) 3506 3507 call FuncException() 3508 call FuncThrowpoint() 3509 call assert_equal("oops", v:exception) 3510 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3511 call assert_match('\<2\>', v:throwpoint) 3512 3513 exec "source" scriptException 3514 exec "source" scriptThrowPoint 3515 call assert_equal("oops", v:exception) 3516 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3517 call assert_match('\<2\>', v:throwpoint) 3518 3519 try 3520 Xpath 'c' 3521 call G("arrgh", 4) 3522 catch /.*/ 3523 Xpath 'd' 3524 let exception = v:exception 3525 let throwpoint = v:throwpoint 3526 call assert_equal("arrgh", v:exception) 3527 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3528 call assert_match('\<4\>', v:throwpoint) 3529 3530 try 3531 Xpath 'e' 3532 let g:arg = "autsch" 3533 let g:line = 6 3534 exec "source" scriptF 3535 catch /.*/ 3536 Xpath 'f' 3537 let exception = v:exception 3538 let throwpoint = v:throwpoint 3539 call assert_equal("autsch", v:exception) 3540 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint) 3541 call assert_match('\<6\>', v:throwpoint) 3542 finally 3543 Xpath 'g' 3544 let exception = v:exception 3545 let throwpoint = v:throwpoint 3546 call assert_equal("arrgh", v:exception) 3547 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3548 call assert_match('\<4\>', v:throwpoint) 3549 try 3550 Xpath 'h' 3551 let g:arg = "brrrr" 3552 let g:line = 8 3553 exec "source" scriptG 3554 catch /.*/ 3555 Xpath 'i' 3556 let exception = v:exception 3557 let throwpoint = v:throwpoint 3558 " Resolve scriptT for matching it against v:throwpoint. 3559 call assert_equal("brrrr", v:exception) 3560 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint) 3561 call assert_match('\<8\>', v:throwpoint) 3562 finally 3563 Xpath 'j' 3564 let exception = v:exception 3565 let throwpoint = v:throwpoint 3566 call assert_equal("arrgh", v:exception) 3567 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3568 call assert_match('\<4\>', v:throwpoint) 3569 endtry 3570 Xpath 'k' 3571 let exception = v:exception 3572 let throwpoint = v:throwpoint 3573 call assert_equal("arrgh", v:exception) 3574 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3575 call assert_match('\<4\>', v:throwpoint) 3576 endtry 3577 Xpath 'l' 3578 let exception = v:exception 3579 let throwpoint = v:throwpoint 3580 call assert_equal("arrgh", v:exception) 3581 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3582 call assert_match('\<4\>', v:throwpoint) 3583 finally 3584 Xpath 'm' 3585 let exception = v:exception 3586 let throwpoint = v:throwpoint 3587 call assert_equal("oops", v:exception) 3588 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3589 call assert_match('\<2\>', v:throwpoint) 3590 endtry 3591 Xpath 'n' 3592 let exception = v:exception 3593 let throwpoint = v:throwpoint 3594 call assert_equal("oops", v:exception) 3595 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3596 call assert_match('\<2\>', v:throwpoint) 3597 finally 3598 Xpath 'o' 3599 let exception = v:exception 3600 let throwpoint = v:throwpoint 3601 call assert_equal("", v:exception) 3602 call assert_match('^$', v:throwpoint) 3603 call assert_match('^$', v:throwpoint) 3604 endtry 3605 3606 call assert_equal('abcdefghijklmno', g:Xpath) 3607 3608 unlet exception throwpoint 3609 delfunction FuncException 3610 delfunction FuncThrowpoint 3611 call delete(scriptException) 3612 call delete(scriptThrowPoint) 3613 unlet scriptException scriptThrowPoint 3614 delcommand CmdException 3615 delcommand CmdThrowpoint 3616 delfunction T 3617 delfunction G 3618 delfunction F 3619 call delete(scriptT) 3620 call delete(scriptG) 3621 call delete(scriptF) 3622 unlet scriptT scriptG scriptF 3623endfunc 3624 3625"------------------------------------------------------------------------------- 3626" 3627" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1 3628" 3629" v:exception and v:throwpoint work also for error and interrupt 3630" exceptions. 3631"------------------------------------------------------------------------------- 3632 3633func Test_execption_info_for_error() 3634 CheckEnglish 3635 3636 let test =<< trim [CODE] 3637 func T(line) 3638 if a:line == 2 3639 delfunction T " error (function in use) in line 2 3640 elseif a:line == 4 3641 call interrupt() 3642 endif 3643 endfunc 3644 3645 while 1 3646 try 3647 Xpath 'a' 3648 call T(2) 3649 call assert_report('should not get here') 3650 catch /.*/ 3651 Xpath 'b' 3652 if v:exception !~ 'Vim(delfunction):' 3653 call assert_report('should not get here') 3654 endif 3655 if v:throwpoint !~ '\<T\>' 3656 call assert_report('should not get here') 3657 endif 3658 if v:throwpoint !~ '\<2\>' 3659 call assert_report('should not get here') 3660 endif 3661 finally 3662 Xpath 'c' 3663 if v:exception != "" 3664 call assert_report('should not get here') 3665 endif 3666 if v:throwpoint != "" 3667 call assert_report('should not get here') 3668 endif 3669 break 3670 endtry 3671 endwhile 3672 3673 Xpath 'd' 3674 if v:exception != "" 3675 call assert_report('should not get here') 3676 endif 3677 if v:throwpoint != "" 3678 call assert_report('should not get here') 3679 endif 3680 3681 while 1 3682 try 3683 Xpath 'e' 3684 call T(4) 3685 call assert_report('should not get here') 3686 catch /.*/ 3687 Xpath 'f' 3688 if v:exception != 'Vim:Interrupt' 3689 call assert_report('should not get here') 3690 endif 3691 if v:throwpoint !~ 'function T' 3692 call assert_report('should not get here') 3693 endif 3694 if v:throwpoint !~ '\<4\>' 3695 call assert_report('should not get here') 3696 endif 3697 finally 3698 Xpath 'g' 3699 if v:exception != "" 3700 call assert_report('should not get here') 3701 endif 3702 if v:throwpoint != "" 3703 call assert_report('should not get here') 3704 endif 3705 break 3706 endtry 3707 endwhile 3708 3709 Xpath 'h' 3710 if v:exception != "" 3711 call assert_report('should not get here') 3712 endif 3713 if v:throwpoint != "" 3714 call assert_report('should not get here') 3715 endif 3716 [CODE] 3717 let verify =<< trim [CODE] 3718 call assert_equal('abcdefgh', g:Xpath) 3719 [CODE] 3720 call RunInNewVim(test, verify) 3721endfunc 3722 3723"------------------------------------------------------------------------------- 3724" 3725" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1 3726" 3727" When a :catch clause is left by a ":break" etc or an error or 3728" interrupt exception, v:exception and v:throwpoint are reset. They 3729" are not affected by an exception that is discarded before being 3730" caught. 3731"------------------------------------------------------------------------------- 3732func Test_exception_info_on_discard() 3733 CheckEnglish 3734 3735 let test =<< trim [CODE] 3736 let sfile = expand("<sfile>") 3737 3738 while 1 3739 try 3740 throw "x1" 3741 catch /.*/ 3742 break 3743 endtry 3744 endwhile 3745 call assert_equal('', v:exception) 3746 call assert_equal('', v:throwpoint) 3747 3748 while 1 3749 try 3750 throw "x2" 3751 catch /.*/ 3752 break 3753 finally 3754 call assert_equal('', v:exception) 3755 call assert_equal('', v:throwpoint) 3756 endtry 3757 break 3758 endwhile 3759 call assert_equal('', v:exception) 3760 call assert_equal('', v:throwpoint) 3761 3762 while 1 3763 try 3764 let errcaught = 0 3765 try 3766 try 3767 throw "x3" 3768 catch /.*/ 3769 let lnum = expand("<sflnum>") 3770 asdf 3771 endtry 3772 catch /.*/ 3773 let errcaught = 1 3774 call assert_match('Vim:E492: Not an editor command:', v:exception) 3775 call assert_match('line ' .. (lnum + 1), v:throwpoint) 3776 endtry 3777 finally 3778 call assert_equal(1, errcaught) 3779 break 3780 endtry 3781 endwhile 3782 call assert_equal('', v:exception) 3783 call assert_equal('', v:throwpoint) 3784 3785 Xpath 'a' 3786 3787 while 1 3788 try 3789 let intcaught = 0 3790 try 3791 try 3792 throw "x4" 3793 catch /.*/ 3794 let lnum = expand("<sflnum>") 3795 call interrupt() 3796 endtry 3797 catch /.*/ 3798 let intcaught = 1 3799 call assert_match('Vim:Interrupt', v:exception) 3800 call assert_match('line ' .. (lnum + 1), v:throwpoint) 3801 endtry 3802 finally 3803 call assert_equal(1, intcaught) 3804 break 3805 endtry 3806 endwhile 3807 call assert_equal('', v:exception) 3808 call assert_equal('', v:throwpoint) 3809 3810 Xpath 'b' 3811 3812 while 1 3813 try 3814 let errcaught = 0 3815 try 3816 try 3817 if 1 3818 let lnum = expand("<sflnum>") 3819 throw "x5" 3820 " missing endif 3821 catch /.*/ 3822 call assert_report('should not get here') 3823 endtry 3824 catch /.*/ 3825 let errcaught = 1 3826 call assert_match('Vim(catch):E171: Missing :endif:', v:exception) 3827 call assert_match('line ' .. (lnum + 3), v:throwpoint) 3828 endtry 3829 finally 3830 call assert_equal(1, errcaught) 3831 break 3832 endtry 3833 endwhile 3834 call assert_equal('', v:exception) 3835 call assert_equal('', v:throwpoint) 3836 3837 Xpath 'c' 3838 3839 try 3840 while 1 3841 try 3842 throw "x6" 3843 finally 3844 break 3845 endtry 3846 break 3847 endwhile 3848 catch /.*/ 3849 call assert_report('should not get here') 3850 endtry 3851 call assert_equal('', v:exception) 3852 call assert_equal('', v:throwpoint) 3853 3854 try 3855 while 1 3856 try 3857 throw "x7" 3858 finally 3859 break 3860 endtry 3861 break 3862 endwhile 3863 catch /.*/ 3864 call assert_report('should not get here') 3865 finally 3866 call assert_equal('', v:exception) 3867 call assert_equal('', v:throwpoint) 3868 endtry 3869 call assert_equal('', v:exception) 3870 call assert_equal('', v:throwpoint) 3871 3872 while 1 3873 try 3874 let errcaught = 0 3875 try 3876 try 3877 throw "x8" 3878 finally 3879 let lnum = expand("<sflnum>") 3880 asdf 3881 endtry 3882 catch /.*/ 3883 let errcaught = 1 3884 call assert_match('Vim:E492: Not an editor command:', v:exception) 3885 call assert_match('line ' .. (lnum + 1), v:throwpoint) 3886 endtry 3887 finally 3888 call assert_equal(1, errcaught) 3889 break 3890 endtry 3891 endwhile 3892 call assert_equal('', v:exception) 3893 call assert_equal('', v:throwpoint) 3894 3895 Xpath 'd' 3896 3897 while 1 3898 try 3899 let intcaught = 0 3900 try 3901 try 3902 throw "x9" 3903 finally 3904 let lnum = expand("<sflnum>") 3905 call interrupt() 3906 endtry 3907 catch /.*/ 3908 let intcaught = 1 3909 call assert_match('Vim:Interrupt', v:exception) 3910 call assert_match('line ' .. (lnum + 1), v:throwpoint) 3911 endtry 3912 finally 3913 call assert_equal(1, intcaught) 3914 break 3915 endtry 3916 endwhile 3917 call assert_equal('', v:exception) 3918 call assert_equal('', v:throwpoint) 3919 3920 Xpath 'e' 3921 3922 while 1 3923 try 3924 let errcaught = 0 3925 try 3926 try 3927 if 1 3928 let lnum = expand("<sflnum>") 3929 throw "x10" 3930 " missing endif 3931 finally 3932 call assert_equal('', v:exception) 3933 call assert_equal('', v:throwpoint) 3934 endtry 3935 catch /.*/ 3936 let errcaught = 1 3937 call assert_match('Vim(finally):E171: Missing :endif:', v:exception) 3938 call assert_match('line ' .. (lnum + 3), v:throwpoint) 3939 endtry 3940 finally 3941 call assert_equal(1, errcaught) 3942 break 3943 endtry 3944 endwhile 3945 call assert_equal('', v:exception) 3946 call assert_equal('', v:throwpoint) 3947 3948 Xpath 'f' 3949 3950 while 1 3951 try 3952 let errcaught = 0 3953 try 3954 try 3955 if 1 3956 let lnum = expand("<sflnum>") 3957 throw "x11" 3958 " missing endif 3959 endtry 3960 catch /.*/ 3961 let errcaught = 1 3962 call assert_match('Vim(endtry):E171: Missing :endif:', v:exception) 3963 call assert_match('line ' .. (lnum + 3), v:throwpoint) 3964 endtry 3965 finally 3966 call assert_equal(1, errcaught) 3967 break 3968 endtry 3969 endwhile 3970 call assert_equal('', v:exception) 3971 call assert_equal('', v:throwpoint) 3972 3973 Xpath 'g' 3974 [CODE] 3975 let verify =<< trim [CODE] 3976 call assert_equal('abcdefg', g:Xpath) 3977 [CODE] 3978 call RunInNewVim(test, verify) 3979endfunc 3980 3981"------------------------------------------------------------------------------- 3982" 3983" Test 60: (Re)throwing v:exception; :echoerr. {{{1 3984" 3985" A user exception can be rethrown after catching by throwing 3986" v:exception. An error or interrupt exception cannot be rethrown 3987" because Vim exceptions cannot be faked. A Vim exception using the 3988" value of v:exception can, however, be triggered by the :echoerr 3989" command. 3990"------------------------------------------------------------------------------- 3991 3992func Test_rethrow_exception_1() 3993 XpathINIT 3994 try 3995 try 3996 Xpath 'a' 3997 throw "oops" 3998 catch /oops/ 3999 Xpath 'b' 4000 throw v:exception " rethrow user exception 4001 catch /.*/ 4002 call assert_report('should not get here') 4003 endtry 4004 catch /^oops$/ " catches rethrown user exception 4005 Xpath 'c' 4006 catch /.*/ 4007 call assert_report('should not get here') 4008 endtry 4009 call assert_equal('abc', g:Xpath) 4010endfunc 4011 4012func Test_rethrow_exception_2() 4013 XpathINIT 4014 try 4015 let caught = 0 4016 try 4017 Xpath 'a' 4018 write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e 4019 call assert_report('should not get here') 4020 catch /^Vim(write):/ 4021 let caught = 1 4022 throw v:exception " throw error: cannot fake Vim exception 4023 catch /.*/ 4024 call assert_report('should not get here') 4025 finally 4026 Xpath 'b' 4027 call assert_equal(1, caught) 4028 endtry 4029 catch /^Vim(throw):/ " catches throw error 4030 let caught = caught + 1 4031 catch /.*/ 4032 call assert_report('should not get here') 4033 finally 4034 Xpath 'c' 4035 call assert_equal(2, caught) 4036 endtry 4037 call assert_equal('abc', g:Xpath) 4038endfunc 4039 4040func Test_rethrow_exception_3() 4041 XpathINIT 4042 try 4043 let caught = 0 4044 try 4045 Xpath 'a' 4046 asdf 4047 catch /^Vim/ " catch error exception 4048 let caught = 1 4049 " Trigger Vim error exception with value specified after :echoerr 4050 let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "") 4051 echoerr value 4052 catch /.*/ 4053 call assert_report('should not get here') 4054 finally 4055 Xpath 'b' 4056 call assert_equal(1, caught) 4057 endtry 4058 catch /^Vim(echoerr):/ 4059 let caught = caught + 1 4060 call assert_match(value, v:exception) 4061 catch /.*/ 4062 call assert_report('should not get here') 4063 finally 4064 Xpath 'c' 4065 call assert_equal(2, caught) 4066 endtry 4067 call assert_equal('abc', g:Xpath) 4068endfunc 4069 4070func Test_rethrow_exception_3() 4071 XpathINIT 4072 try 4073 let errcaught = 0 4074 try 4075 Xpath 'a' 4076 let intcaught = 0 4077 call interrupt() 4078 catch /^Vim:/ " catch interrupt exception 4079 let intcaught = 1 4080 " Trigger Vim error exception with value specified after :echoerr 4081 echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "") 4082 catch /.*/ 4083 call assert_report('should not get here') 4084 finally 4085 Xpath 'b' 4086 call assert_equal(1, intcaught) 4087 endtry 4088 catch /^Vim(echoerr):/ 4089 let errcaught = 1 4090 call assert_match('Interrupt', v:exception) 4091 finally 4092 Xpath 'c' 4093 call assert_equal(1, errcaught) 4094 endtry 4095 call assert_equal('abc', g:Xpath) 4096endfunc 4097 4098"------------------------------------------------------------------------------- 4099" Test 61: Catching interrupt exceptions {{{1 4100" 4101" When an interrupt occurs inside a :try/:endtry region, an 4102" interrupt exception is thrown and can be caught. Its value is 4103" "Vim:Interrupt". If the interrupt occurs after an error or a :throw 4104" but before a matching :catch is reached, all following :catches of 4105" that try block are ignored, but the interrupt exception can be 4106" caught by the next surrounding try conditional. An interrupt is 4107" ignored when there is a previous interrupt that has not been caught 4108" or causes a :finally clause to be executed. 4109"------------------------------------------------------------------------------- 4110 4111func Test_catch_intr_exception() 4112 let test =<< trim [CODE] 4113 while 1 4114 try 4115 try 4116 Xpath 'a' 4117 call interrupt() 4118 call assert_report('should not get here') 4119 catch /^Vim:Interrupt$/ 4120 Xpath 'b' 4121 finally 4122 Xpath 'c' 4123 endtry 4124 catch /.*/ 4125 call assert_report('should not get here') 4126 finally 4127 Xpath 'd' 4128 break 4129 endtry 4130 endwhile 4131 4132 while 1 4133 try 4134 try 4135 try 4136 Xpath 'e' 4137 asdf 4138 call assert_report('should not get here') 4139 catch /do_not_catch/ 4140 call assert_report('should not get here') 4141 catch /.*/ 4142 Xpath 'f' 4143 call interrupt() 4144 call assert_report('should not get here') 4145 catch /.*/ 4146 call assert_report('should not get here') 4147 finally 4148 Xpath 'g' 4149 call interrupt() 4150 call assert_report('should not get here') 4151 endtry 4152 catch /^Vim:Interrupt$/ 4153 Xpath 'h' 4154 finally 4155 Xpath 'i' 4156 endtry 4157 catch /.*/ 4158 call assert_report('should not get here') 4159 finally 4160 Xpath 'j' 4161 break 4162 endtry 4163 endwhile 4164 4165 while 1 4166 try 4167 try 4168 try 4169 Xpath 'k' 4170 throw "x" 4171 call assert_report('should not get here') 4172 catch /do_not_catch/ 4173 call assert_report('should not get here') 4174 catch /x/ 4175 Xpath 'l' 4176 call interrupt() 4177 call assert_report('should not get here') 4178 catch /.*/ 4179 call assert_report('should not get here') 4180 endtry 4181 catch /^Vim:Interrupt$/ 4182 Xpath 'm' 4183 finally 4184 Xpath 'n' 4185 endtry 4186 catch /.*/ 4187 call assert_report('should not get here') 4188 finally 4189 Xpath 'o' 4190 break 4191 endtry 4192 endwhile 4193 4194 while 1 4195 try 4196 try 4197 Xpath 'p' 4198 call interrupt() 4199 call assert_report('should not get here') 4200 catch /do_not_catch/ 4201 call interrupt() 4202 call assert_report('should not get here') 4203 catch /^Vim:Interrupt$/ 4204 Xpath 'q' 4205 finally 4206 Xpath 'r' 4207 endtry 4208 catch /.*/ 4209 call assert_report('should not get here') 4210 finally 4211 Xpath 's' 4212 break 4213 endtry 4214 endwhile 4215 4216 Xpath 't' 4217 [CODE] 4218 let verify =<< trim [CODE] 4219 call assert_equal('abcdefghijklmnopqrst', g:Xpath) 4220 [CODE] 4221 call RunInNewVim(test, verify) 4222endfunc 4223 4224"------------------------------------------------------------------------------- 4225" Test 62: Catching error exceptions {{{1 4226" 4227" An error inside a :try/:endtry region is converted to an exception 4228" and can be caught. The error exception has a "Vim(cmdname):" prefix 4229" where cmdname is the name of the failing command, or a "Vim:" prefix 4230" if no command name is known. The "Vim" prefixes cannot be faked. 4231"------------------------------------------------------------------------------- 4232 4233func Test_catch_err_exception_1() 4234 XpathINIT 4235 while 1 4236 try 4237 try 4238 let caught = 0 4239 unlet novar 4240 catch /^Vim(unlet):/ 4241 Xpath 'a' 4242 let caught = 1 4243 let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "") 4244 finally 4245 Xpath 'b' 4246 call assert_equal(1, caught) 4247 call assert_match('E108: No such variable: "novar"', v:errmsg) 4248 endtry 4249 catch /.*/ 4250 call assert_report('should not get here') 4251 finally 4252 Xpath 'c' 4253 break 4254 endtry 4255 call assert_report('should not get here') 4256 endwhile 4257 call assert_equal('abc', g:Xpath) 4258endfunc 4259 4260func Test_catch_err_exception_2() 4261 XpathINIT 4262 while 1 4263 try 4264 try 4265 let caught = 0 4266 throw novar " error in :throw 4267 catch /^Vim(throw):/ 4268 Xpath 'a' 4269 let caught = 1 4270 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "") 4271 finally 4272 Xpath 'b' 4273 call assert_equal(1, caught) 4274 call assert_match('E121: Undefined variable: novar', v:errmsg) 4275 endtry 4276 catch /.*/ 4277 call assert_report('should not get here') 4278 finally 4279 Xpath 'c' 4280 break 4281 endtry 4282 call assert_report('should not get here') 4283 endwhile 4284 call assert_equal('abc', g:Xpath) 4285endfunc 4286 4287func Test_catch_err_exception_3() 4288 XpathINIT 4289 while 1 4290 try 4291 try 4292 let caught = 0 4293 throw "Vim:faked" " error: cannot fake Vim exception 4294 catch /^Vim(throw):/ 4295 Xpath 'a' 4296 let caught = 1 4297 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "") 4298 finally 4299 Xpath 'b' 4300 call assert_equal(1, caught) 4301 call assert_match("E608: Cannot :throw exceptions with 'Vim' prefix", 4302 \ v:errmsg) 4303 endtry 4304 catch /.*/ 4305 call assert_report('should not get here') 4306 finally 4307 Xpath 'c' 4308 break 4309 endtry 4310 call assert_report('should not get here') 4311 endwhile 4312 call assert_equal('abc', g:Xpath) 4313endfunc 4314 4315func Test_catch_err_exception_4() 4316 XpathINIT 4317 func F() 4318 while 1 4319 " Missing :endwhile 4320 endfunc 4321 4322 while 1 4323 try 4324 try 4325 let caught = 0 4326 call F() 4327 catch /^Vim(endfunction):/ 4328 Xpath 'a' 4329 let caught = 1 4330 let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "") 4331 finally 4332 Xpath 'b' 4333 call assert_equal(1, caught) 4334 call assert_match("E170: Missing :endwhile", v:errmsg) 4335 endtry 4336 catch /.*/ 4337 call assert_report('should not get here') 4338 finally 4339 Xpath 'c' 4340 break 4341 endtry 4342 call assert_report('should not get here') 4343 endwhile 4344 call assert_equal('abc', g:Xpath) 4345 delfunc F 4346endfunc 4347 4348func Test_catch_err_exception_5() 4349 XpathINIT 4350 func F() 4351 while 1 4352 " Missing :endwhile 4353 endfunc 4354 4355 while 1 4356 try 4357 try 4358 let caught = 0 4359 ExecAsScript F 4360 catch /^Vim:/ 4361 Xpath 'a' 4362 let caught = 1 4363 let v:errmsg = substitute(v:exception, '^Vim:', '', "") 4364 finally 4365 Xpath 'b' 4366 call assert_equal(1, caught) 4367 call assert_match("E170: Missing :endwhile", v:errmsg) 4368 endtry 4369 catch /.*/ 4370 call assert_report('should not get here') 4371 finally 4372 Xpath 'c' 4373 break 4374 endtry 4375 call assert_report('should not get here') 4376 endwhile 4377 call assert_equal('abc', g:Xpath) 4378 delfunc F 4379endfunc 4380 4381func Test_catch_err_exception_6() 4382 XpathINIT 4383 func G() 4384 call G() 4385 endfunc 4386 4387 while 1 4388 try 4389 let mfd_save = &mfd 4390 set mfd=3 4391 try 4392 let caught = 0 4393 call G() 4394 catch /^Vim(call):/ 4395 Xpath 'a' 4396 let caught = 1 4397 let v:errmsg = substitute(v:exception, '^Vim(call):', '', "") 4398 finally 4399 Xpath 'b' 4400 call assert_equal(1, caught) 4401 call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg) 4402 endtry 4403 catch /.*/ 4404 call assert_report('should not get here') 4405 finally 4406 Xpath 'c' 4407 let &mfd = mfd_save 4408 break 4409 endtry 4410 call assert_report('should not get here') 4411 endwhile 4412 call assert_equal('abc', g:Xpath) 4413 delfunc G 4414endfunc 4415 4416func Test_catch_err_exception_7() 4417 XpathINIT 4418 func H() 4419 return H() 4420 endfunc 4421 4422 while 1 4423 try 4424 let mfd_save = &mfd 4425 set mfd=3 4426 try 4427 let caught = 0 4428 call H() 4429 catch /^Vim(return):/ 4430 Xpath 'a' 4431 let caught = 1 4432 let v:errmsg = substitute(v:exception, '^Vim(return):', '', "") 4433 finally 4434 Xpath 'b' 4435 call assert_equal(1, caught) 4436 call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg) 4437 endtry 4438 catch /.*/ 4439 call assert_report('should not get here') 4440 finally 4441 Xpath 'c' 4442 let &mfd = mfd_save 4443 break " discard error for $VIMNOERRTHROW 4444 endtry 4445 call assert_report('should not get here') 4446 endwhile 4447 4448 call assert_equal('abc', g:Xpath) 4449 delfunc H 4450endfunc 4451 4452"------------------------------------------------------------------------------- 4453" Test 63: Suppressing error exceptions by :silent!. {{{1 4454" 4455" A :silent! command inside a :try/:endtry region suppresses the 4456" conversion of errors to an exception and the immediate abortion on 4457" error. When the commands executed by the :silent! themselves open 4458" a new :try/:endtry region, conversion of errors to exception and 4459" immediate abortion is switched on again - until the next :silent! 4460" etc. The :silent! has the effect of setting v:errmsg to the error 4461" message text (without displaying it) and continuing with the next 4462" script line. 4463" 4464" When a command triggering autocommands is executed by :silent! 4465" inside a :try/:endtry, the autocommand execution is not suppressed 4466" on error. 4467" 4468" This test reuses the function MSG() from the previous test. 4469"------------------------------------------------------------------------------- 4470 4471func Test_silent_exception() 4472 XpathINIT 4473 XloopINIT 4474 let g:taken = "" 4475 4476 func S(n) abort 4477 XloopNEXT 4478 let g:taken = g:taken . "E" . a:n 4479 let v:errmsg = "" 4480 exec "asdf" . a:n 4481 4482 " Check that ":silent!" continues: 4483 Xloop 'a' 4484 4485 " Check that ":silent!" sets "v:errmsg": 4486 call assert_match("E492: Not an editor command", v:errmsg) 4487 endfunc 4488 4489 func Foo() 4490 while 1 4491 try 4492 try 4493 let caught = 0 4494 " This is not silent: 4495 call S(3) 4496 catch /^Vim:/ 4497 Xpath 'b' 4498 let caught = 1 4499 let errmsg3 = substitute(v:exception, '^Vim:', '', "") 4500 silent! call S(4) 4501 finally 4502 call assert_equal(1, caught) 4503 Xpath 'c' 4504 call assert_match("E492: Not an editor command", errmsg3) 4505 silent! call S(5) 4506 " Break out of try conditionals that cover ":silent!". This also 4507 " discards the aborting error when $VIMNOERRTHROW is non-zero. 4508 break 4509 endtry 4510 catch /.*/ 4511 call assert_report('should not get here') 4512 endtry 4513 endwhile 4514 " This is a double ":silent!" (see caller). 4515 silent! call S(6) 4516 endfunc 4517 4518 func Bar() 4519 try 4520 silent! call S(2) 4521 silent! execute "call Foo() | call S(7)" 4522 silent! call S(8) 4523 endtry " normal end of try cond that covers ":silent!" 4524 " This has a ":silent!" from the caller: 4525 call S(9) 4526 endfunc 4527 4528 silent! call S(1) 4529 silent! call Bar() 4530 silent! call S(10) 4531 4532 call assert_equal("E1E2E3E4E5E6E7E8E9E10", g:taken) 4533 4534 augroup TMP 4535 au! 4536 autocmd BufWritePost * Xpath 'd' 4537 augroup END 4538 4539 Xpath 'e' 4540 silent! write /i/m/p/o/s/s/i/b/l/e 4541 Xpath 'f' 4542 4543 call assert_equal('a2a3ba5ca6a7a8a9a10a11edf', g:Xpath) 4544 4545 augroup TMP 4546 au! 4547 augroup END 4548 augroup! TMP 4549 delfunction S 4550 delfunction Foo 4551 delfunction Bar 4552endfunc 4553 4554"------------------------------------------------------------------------------- 4555" Test 64: Error exceptions after error, interrupt or :throw {{{1 4556" 4557" When an error occurs after an interrupt or a :throw but before 4558" a matching :catch is reached, all following :catches of that try 4559" block are ignored, but the error exception can be caught by the next 4560" surrounding try conditional. Any previous error exception is 4561" discarded. An error is ignored when there is a previous error that 4562" has not been caught. 4563"------------------------------------------------------------------------------- 4564 4565func Test_exception_after_error_1() 4566 XpathINIT 4567 while 1 4568 try 4569 try 4570 Xpath 'a' 4571 let caught = 0 4572 while 1 4573 if 1 4574 " Missing :endif 4575 endwhile " throw error exception 4576 catch /^Vim(/ 4577 Xpath 'b' 4578 let caught = 1 4579 finally 4580 Xpath 'c' 4581 call assert_equal(1, caught) 4582 endtry 4583 catch /.*/ 4584 call assert_report('should not get here') 4585 finally 4586 Xpath 'd' 4587 break 4588 endtry 4589 call assert_report('should not get here') 4590 endwhile 4591 call assert_equal('abcd', g:Xpath) 4592endfunc 4593 4594func Test_exception_after_error_2() 4595 XpathINIT 4596 while 1 4597 try 4598 try 4599 Xpath 'a' 4600 let caught = 0 4601 try 4602 if 1 4603 " Missing :endif 4604 catch /.*/ " throw error exception 4605 call assert_report('should not get here') 4606 catch /.*/ 4607 call assert_report('should not get here') 4608 endtry 4609 catch /^Vim(/ 4610 Xpath 'b' 4611 let caught = 1 4612 finally 4613 Xpath 'c' 4614 call assert_equal(1, caught) 4615 endtry 4616 catch /.*/ 4617 call assert_report('should not get here') 4618 finally 4619 Xpath 'd' 4620 break 4621 endtry 4622 call assert_report('should not get here') 4623 endwhile 4624 call assert_equal('abcd', g:Xpath) 4625endfunc 4626 4627func Test_exception_after_error_3() 4628 XpathINIT 4629 while 1 4630 try 4631 try 4632 let caught = 0 4633 try 4634 Xpath 'a' 4635 call interrupt() 4636 catch /do_not_catch/ 4637 call assert_report('should not get here') 4638 if 1 4639 " Missing :endif 4640 catch /.*/ " throw error exception 4641 call assert_report('should not get here') 4642 catch /.*/ 4643 call assert_report('should not get here') 4644 endtry 4645 catch /^Vim(/ 4646 Xpath 'b' 4647 let caught = 1 4648 finally 4649 Xpath 'c' 4650 call assert_equal(1, caught) 4651 endtry 4652 catch /.*/ 4653 call assert_report('should not get here') 4654 finally 4655 Xpath 'd' 4656 break 4657 endtry 4658 call assert_report('should not get here') 4659 endwhile 4660 call assert_equal('abcd', g:Xpath) 4661endfunc 4662 4663func Test_exception_after_error_4() 4664 XpathINIT 4665 while 1 4666 try 4667 try 4668 let caught = 0 4669 try 4670 Xpath 'a' 4671 throw "x" 4672 catch /do_not_catch/ 4673 call assert_report('should not get here') 4674 if 1 4675 " Missing :endif 4676 catch /x/ " throw error exception 4677 call assert_report('should not get here') 4678 catch /.*/ 4679 call assert_report('should not get here') 4680 endtry 4681 catch /^Vim(/ 4682 Xpath 'b' 4683 let caught = 1 4684 finally 4685 Xpath 'c' 4686 call assert_equal(1, caught) 4687 endtry 4688 catch /.*/ 4689 call assert_report('should not get here') 4690 finally 4691 Xpath 'd' 4692 break 4693 endtry 4694 call assert_report('should not get here') 4695 endwhile 4696 call assert_equal('abcd', g:Xpath) 4697endfunc 4698 4699func Test_exception_after_error_5() 4700 XpathINIT 4701 while 1 4702 try 4703 try 4704 let caught = 0 4705 Xpath 'a' 4706 endif " :endif without :if; throw error exception 4707 if 1 4708 " Missing :endif 4709 catch /do_not_catch/ " ignore new error 4710 call assert_report('should not get here') 4711 catch /^Vim(endif):/ 4712 Xpath 'b' 4713 let caught = 1 4714 catch /^Vim(/ 4715 call assert_report('should not get here') 4716 finally 4717 Xpath 'c' 4718 call assert_equal(1, caught) 4719 endtry 4720 catch /.*/ 4721 call assert_report('should not get here') 4722 finally 4723 Xpath 'd' 4724 break 4725 endtry 4726 call assert_report('should not get here') 4727 endwhile 4728 call assert_equal('abcd', g:Xpath) 4729endfunc 4730 4731"------------------------------------------------------------------------------- 4732" Test 65: Errors in the /pattern/ argument of a :catch {{{1 4733" 4734" On an error in the /pattern/ argument of a :catch, the :catch does 4735" not match. Any following :catches of the same :try/:endtry don't 4736" match either. Finally clauses are executed. 4737"------------------------------------------------------------------------------- 4738 4739func Test_catch_pattern_error() 4740 CheckEnglish 4741 XpathINIT 4742 4743 try 4744 try 4745 Xpath 'a' 4746 throw "oops" 4747 catch /^oops$/ 4748 Xpath 'b' 4749 catch /\)/ " not checked; exception has already been caught 4750 call assert_report('should not get here') 4751 endtry 4752 Xpath 'c' 4753 catch /.*/ 4754 call assert_report('should not get here') 4755 endtry 4756 call assert_equal('abc', g:Xpath) 4757 4758 XpathINIT 4759 func F() 4760 try 4761 try 4762 try 4763 Xpath 'a' 4764 throw "ab" 4765 catch /abc/ " does not catch 4766 call assert_report('should not get here') 4767 catch /\)/ " error; discards exception 4768 call assert_report('should not get here') 4769 catch /.*/ " not checked 4770 call assert_report('should not get here') 4771 finally 4772 Xpath 'b' 4773 endtry 4774 call assert_report('should not get here') 4775 catch /^ab$/ " checked, but original exception is discarded 4776 call assert_report('should not get here') 4777 catch /^Vim(catch):/ 4778 Xpath 'c' 4779 call assert_match('Vim(catch):E475: Invalid argument:', v:exception) 4780 finally 4781 Xpath 'd' 4782 endtry 4783 Xpath 'e' 4784 catch /.*/ 4785 call assert_report('should not get here') 4786 endtry 4787 Xpath 'f' 4788 endfunc 4789 4790 call F() 4791 call assert_equal('abcdef', g:Xpath) 4792 4793 delfunc F 4794endfunc 4795 4796"------------------------------------------------------------------------------- 4797" Test 66: Stop range :call on error, interrupt, or :throw {{{1 4798" 4799" When a function which is multiply called for a range since it 4800" doesn't handle the range itself has an error in a command 4801" dynamically enclosed by :try/:endtry or gets an interrupt or 4802" executes a :throw, no more calls for the remaining lines in the 4803" range are made. On an error in a command not dynamically enclosed 4804" by :try/:endtry, the function is executed again for the remaining 4805" lines in the range. 4806"------------------------------------------------------------------------------- 4807 4808func Test_stop_range_on_error() 4809 let test =<< trim [CODE] 4810 let file = tempname() 4811 exec "edit" file 4812 call setline(1, ['line 1', 'line 2', 'line 3']) 4813 let taken = "" 4814 let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)" 4815 4816 func F(reason, n) abort 4817 let g:taken = g:taken .. "F" .. a:n .. 4818 \ substitute(a:reason, '\(\l\).*', '\u\1', "") .. 4819 \ "(" .. line(".") .. ")" 4820 4821 if a:reason == "error" 4822 asdf 4823 elseif a:reason == "interrupt" 4824 call interrupt() 4825 elseif a:reason == "throw" 4826 throw "xyz" 4827 elseif a:reason == "aborting error" 4828 XloopNEXT 4829 call assert_equal(g:taken, g:expected) 4830 try 4831 bwipeout! 4832 call delete(g:file) 4833 asdf 4834 endtry 4835 endif 4836 endfunc 4837 4838 func G(reason, n) 4839 let g:taken = g:taken .. "G" .. a:n .. 4840 \ substitute(a:reason, '\(\l\).*', '\u\1', "") 4841 1,3call F(a:reason, a:n) 4842 endfunc 4843 4844 Xpath 'a' 4845 call G("error", 1) 4846 try 4847 Xpath 'b' 4848 try 4849 call G("error", 2) 4850 call assert_report('should not get here') 4851 finally 4852 Xpath 'c' 4853 try 4854 call G("interrupt", 3) 4855 call assert_report('should not get here') 4856 finally 4857 Xpath 'd' 4858 try 4859 call G("throw", 4) 4860 call assert_report('should not get here') 4861 endtry 4862 endtry 4863 endtry 4864 catch /xyz/ 4865 Xpath 'e' 4866 catch /.*/ 4867 call assert_report('should not get here') 4868 endtry 4869 Xpath 'f' 4870 call G("aborting error", 5) 4871 call assert_report('should not get here') 4872 [CODE] 4873 let verify =<< trim [CODE] 4874 call assert_equal('abcdef', g:Xpath) 4875 [CODE] 4876 call RunInNewVim(test, verify) 4877endfunc 4878 4879"------------------------------------------------------------------------------- 4880" Test 67: :throw across :call command {{{1 4881" 4882" On a call command, an exception might be thrown when evaluating the 4883" function name, during evaluation of the arguments, or when the 4884" function is being executed. The exception can be caught by the 4885" caller. 4886"------------------------------------------------------------------------------- 4887 4888func THROW(x, n) 4889 if a:n == 1 4890 Xpath 'A' 4891 elseif a:n == 2 4892 Xpath 'B' 4893 elseif a:n == 3 4894 Xpath 'C' 4895 endif 4896 throw a:x 4897endfunc 4898 4899func NAME(x, n) 4900 if a:n == 1 4901 call assert_report('should not get here') 4902 elseif a:n == 2 4903 Xpath 'D' 4904 elseif a:n == 3 4905 Xpath 'E' 4906 elseif a:n == 4 4907 Xpath 'F' 4908 endif 4909 return a:x 4910endfunc 4911 4912func ARG(x, n) 4913 if a:n == 1 4914 call assert_report('should not get here') 4915 elseif a:n == 2 4916 call assert_report('should not get here') 4917 elseif a:n == 3 4918 Xpath 'G' 4919 elseif a:n == 4 4920 Xpath 'I' 4921 endif 4922 return a:x 4923endfunc 4924 4925func Test_throw_across_call_cmd() 4926 XpathINIT 4927 4928 func F(x, n) 4929 if a:n == 2 4930 call assert_report('should not get here') 4931 elseif a:n == 4 4932 Xpath 'a' 4933 endif 4934 endfunc 4935 4936 while 1 4937 try 4938 let v:errmsg = "" 4939 4940 while 1 4941 try 4942 Xpath 'b' 4943 call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1) 4944 call assert_report('should not get here') 4945 catch /^name$/ 4946 Xpath 'c' 4947 catch /.*/ 4948 call assert_report('should not get here') 4949 finally 4950 call assert_equal("", v:errmsg) 4951 let v:errmsg = "" 4952 break 4953 endtry 4954 endwhile 4955 4956 while 1 4957 try 4958 Xpath 'd' 4959 call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2) 4960 call assert_report('should not get here') 4961 catch /^arg$/ 4962 Xpath 'e' 4963 catch /.*/ 4964 call assert_report('should not get here') 4965 finally 4966 call assert_equal("", v:errmsg) 4967 let v:errmsg = "" 4968 break 4969 endtry 4970 endwhile 4971 4972 while 1 4973 try 4974 Xpath 'f' 4975 call {NAME("THROW", 3)}(ARG("call", 3), 3) 4976 call assert_report('should not get here') 4977 catch /^call$/ 4978 Xpath 'g' 4979 catch /^0$/ " default return value 4980 call assert_report('should not get here') 4981 catch /.*/ 4982 call assert_report('should not get here') 4983 finally 4984 call assert_equal("", v:errmsg) 4985 let v:errmsg = "" 4986 break 4987 endtry 4988 endwhile 4989 4990 while 1 4991 try 4992 Xpath 'h' 4993 call {NAME("F", 4)}(ARG(4711, 4), 4) 4994 Xpath 'i' 4995 catch /.*/ 4996 call assert_report('should not get here') 4997 finally 4998 call assert_equal("", v:errmsg) 4999 let v:errmsg = "" 5000 break 5001 endtry 5002 endwhile 5003 5004 catch /^0$/ " default return value 5005 call assert_report('should not get here') 5006 catch /.*/ 5007 call assert_report('should not get here') 5008 finally 5009 call assert_equal("", v:errmsg) 5010 let v:errmsg = "" 5011 break 5012 endtry 5013 endwhile 5014 5015 call assert_equal('bAcdDBefEGCghFIai', g:Xpath) 5016 delfunction F 5017endfunc 5018 5019"------------------------------------------------------------------------------- 5020" Test 68: :throw across function calls in expressions {{{1 5021" 5022" On a function call within an expression, an exception might be 5023" thrown when evaluating the function name, during evaluation of the 5024" arguments, or when the function is being executed. The exception 5025" can be caught by the caller. 5026" 5027" This test reuses the functions THROW(), NAME(), and ARG() from the 5028" previous test. 5029"------------------------------------------------------------------------------- 5030 5031func Test_throw_across_call_expr() 5032 XpathINIT 5033 5034 func F(x, n) 5035 if a:n == 2 5036 call assert_report('should not get here') 5037 elseif a:n == 4 5038 Xpath 'a' 5039 endif 5040 return a:x 5041 endfunction 5042 5043 while 1 5044 try 5045 let error = 0 5046 let v:errmsg = "" 5047 5048 while 1 5049 try 5050 Xpath 'b' 5051 let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1) 5052 call assert_report('should not get here') 5053 catch /^name$/ 5054 Xpath 'c' 5055 catch /.*/ 5056 call assert_report('should not get here') 5057 finally 5058 call assert_equal("", v:errmsg) 5059 let v:errmsg = "" 5060 break 5061 endtry 5062 endwhile 5063 call assert_true(!exists('var1')) 5064 5065 while 1 5066 try 5067 Xpath 'd' 5068 let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2) 5069 call assert_report('should not get here') 5070 catch /^arg$/ 5071 Xpath 'e' 5072 catch /.*/ 5073 call assert_report('should not get here') 5074 finally 5075 call assert_equal("", v:errmsg) 5076 let v:errmsg = "" 5077 break 5078 endtry 5079 endwhile 5080 call assert_true(!exists('var2')) 5081 5082 while 1 5083 try 5084 Xpath 'f' 5085 let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3) 5086 call assert_report('should not get here') 5087 catch /^call$/ 5088 Xpath 'g' 5089 catch /^0$/ " default return value 5090 call assert_report('should not get here') 5091 catch /.*/ 5092 call assert_report('should not get here') 5093 finally 5094 call assert_equal("", v:errmsg) 5095 let v:errmsg = "" 5096 break 5097 endtry 5098 endwhile 5099 call assert_true(!exists('var3')) 5100 5101 while 1 5102 try 5103 Xpath 'h' 5104 let var4 = {NAME("F", 4)}(ARG(4711, 4), 4) 5105 Xpath 'i' 5106 catch /.*/ 5107 call assert_report('should not get here') 5108 finally 5109 call assert_equal("", v:errmsg) 5110 let v:errmsg = "" 5111 break 5112 endtry 5113 endwhile 5114 call assert_true(exists('var4') && var4 == 4711) 5115 5116 catch /^0$/ " default return value 5117 call assert_report('should not get here') 5118 catch /.*/ 5119 call assert_report('should not get here') 5120 finally 5121 call assert_equal("", v:errmsg) 5122 break 5123 endtry 5124 endwhile 5125 5126 call assert_equal('bAcdDBefEGCghFIai', g:Xpath) 5127 delfunc F 5128endfunc 5129 5130"------------------------------------------------------------------------------- 5131" Test 76: Errors, interrupts, :throw during expression evaluation {{{1 5132" 5133" When a function call made during expression evaluation is aborted 5134" due to an error inside a :try/:endtry region or due to an interrupt 5135" or a :throw, the expression evaluation is aborted as well. No 5136" message is displayed for the cancelled expression evaluation. On an 5137" error not inside :try/:endtry, the expression evaluation continues. 5138"------------------------------------------------------------------------------- 5139 5140func Test_expr_eval_error() 5141 let test =<< trim [CODE] 5142 let taken = "" 5143 5144 func ERR(n) 5145 let g:taken = g:taken .. "E" .. a:n 5146 asdf 5147 endfunc 5148 5149 func ERRabort(n) abort 5150 let g:taken = g:taken .. "A" .. a:n 5151 asdf 5152 endfunc " returns -1; may cause follow-up msg for illegal var/func name 5153 5154 func WRAP(n, arg) 5155 let g:taken = g:taken .. "W" .. a:n 5156 let g:saved_errmsg = v:errmsg 5157 return arg 5158 endfunc 5159 5160 func INT(n) 5161 let g:taken = g:taken .. "I" .. a:n 5162 call interrupt() 5163 endfunc 5164 5165 func THR(n) 5166 let g:taken = g:taken .. "T" .. a:n 5167 throw "should not be caught" 5168 endfunc 5169 5170 func CONT(n) 5171 let g:taken = g:taken .. "C" .. a:n 5172 endfunc 5173 5174 func MSG(n) 5175 let g:taken = g:taken .. "M" .. a:n 5176 let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg 5177 let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf" 5178 call assert_match(msgptn, errmsg) 5179 let v:errmsg = "" 5180 let g:saved_errmsg = "" 5181 endfunc 5182 5183 let v:errmsg = "" 5184 5185 try 5186 let t = 1 5187 while t <= 9 5188 Xloop 'a' 5189 try 5190 if t == 1 5191 let v{ERR(t) + CONT(t)} = 0 5192 elseif t == 2 5193 let v{ERR(t) + CONT(t)} 5194 elseif t == 3 5195 let var = exists('v{ERR(t) + CONT(t)}') 5196 elseif t == 4 5197 unlet v{ERR(t) + CONT(t)} 5198 elseif t == 5 5199 function F{ERR(t) + CONT(t)}() 5200 endfunction 5201 elseif t == 6 5202 function F{ERR(t) + CONT(t)} 5203 elseif t == 7 5204 let var = exists('*F{ERR(t) + CONT(t)}') 5205 elseif t == 8 5206 delfunction F{ERR(t) + CONT(t)} 5207 elseif t == 9 5208 let var = ERR(t) + CONT(t) 5209 endif 5210 catch /asdf/ 5211 " v:errmsg is not set when the error message is converted to an 5212 " exception. Set it to the original error message. 5213 let v:errmsg = substitute(v:exception, '^Vim:', '', "") 5214 catch /^Vim\((\a\+)\)\=:/ 5215 " An error exception has been thrown after the original error. 5216 let v:errmsg = "" 5217 finally 5218 call MSG(t) 5219 let t = t + 1 5220 XloopNEXT 5221 continue " discard an aborting error 5222 endtry 5223 endwhile 5224 catch /.*/ 5225 call assert_report('should not get here') 5226 endtry 5227 5228 try 5229 let t = 10 5230 while t <= 18 5231 Xloop 'b' 5232 try 5233 if t == 10 5234 let v{INT(t) + CONT(t)} = 0 5235 elseif t == 11 5236 let v{INT(t) + CONT(t)} 5237 elseif t == 12 5238 let var = exists('v{INT(t) + CONT(t)}') 5239 elseif t == 13 5240 unlet v{INT(t) + CONT(t)} 5241 elseif t == 14 5242 function F{INT(t) + CONT(t)}() 5243 endfunction 5244 elseif t == 15 5245 function F{INT(t) + CONT(t)} 5246 elseif t == 16 5247 let var = exists('*F{INT(t) + CONT(t)}') 5248 elseif t == 17 5249 delfunction F{INT(t) + CONT(t)} 5250 elseif t == 18 5251 let var = INT(t) + CONT(t) 5252 endif 5253 catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/ 5254 " An error exception has been triggered after the interrupt. 5255 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") 5256 finally 5257 call MSG(t) 5258 let t = t + 1 5259 XloopNEXT 5260 continue " discard interrupt 5261 endtry 5262 endwhile 5263 catch /.*/ 5264 call assert_report('should not get here') 5265 endtry 5266 5267 try 5268 let t = 19 5269 while t <= 27 5270 Xloop 'c' 5271 try 5272 if t == 19 5273 let v{THR(t) + CONT(t)} = 0 5274 elseif t == 20 5275 let v{THR(t) + CONT(t)} 5276 elseif t == 21 5277 let var = exists('v{THR(t) + CONT(t)}') 5278 elseif t == 22 5279 unlet v{THR(t) + CONT(t)} 5280 elseif t == 23 5281 function F{THR(t) + CONT(t)}() 5282 endfunction 5283 elseif t == 24 5284 function F{THR(t) + CONT(t)} 5285 elseif t == 25 5286 let var = exists('*F{THR(t) + CONT(t)}') 5287 elseif t == 26 5288 delfunction F{THR(t) + CONT(t)} 5289 elseif t == 27 5290 let var = THR(t) + CONT(t) 5291 endif 5292 catch /^Vim\((\a\+)\)\=:/ 5293 " An error exception has been triggered after the :throw. 5294 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") 5295 finally 5296 call MSG(t) 5297 let t = t + 1 5298 XloopNEXT 5299 continue " discard exception 5300 endtry 5301 endwhile 5302 catch /.*/ 5303 call assert_report('should not get here') 5304 endtry 5305 5306 let v{ERR(28) + CONT(28)} = 0 5307 call MSG(28) 5308 let v{ERR(29) + CONT(29)} 5309 call MSG(29) 5310 let var = exists('v{ERR(30) + CONT(30)}') 5311 call MSG(30) 5312 unlet v{ERR(31) + CONT(31)} 5313 call MSG(31) 5314 function F{ERR(32) + CONT(32)}() 5315 endfunction 5316 call MSG(32) 5317 function F{ERR(33) + CONT(33)} 5318 call MSG(33) 5319 let var = exists('*F{ERR(34) + CONT(34)}') 5320 call MSG(34) 5321 delfunction F{ERR(35) + CONT(35)} 5322 call MSG(35) 5323 let var = ERR(36) + CONT(36) 5324 call MSG(36) 5325 5326 let saved_errmsg = "" 5327 5328 let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0 5329 call MSG(37) 5330 let v{WRAP(38, ERRabort(38)) + CONT(38)} 5331 call MSG(38) 5332 let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}') 5333 call MSG(39) 5334 unlet v{WRAP(40, ERRabort(40)) + CONT(40)} 5335 call MSG(40) 5336 function F{WRAP(41, ERRabort(41)) + CONT(41)}() 5337 endfunction 5338 call MSG(41) 5339 function F{WRAP(42, ERRabort(42)) + CONT(42)} 5340 call MSG(42) 5341 let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}') 5342 call MSG(43) 5343 delfunction F{WRAP(44, ERRabort(44)) + CONT(44)} 5344 call MSG(44) 5345 let var = ERRabort(45) + CONT(45) 5346 call MSG(45) 5347 Xpath 'd' 5348 5349 let expected = "" 5350 \ .. "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9" 5351 \ .. "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18" 5352 \ .. "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27" 5353 \ .. "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33" 5354 \ .. "E34C34M34E35C35M35E36C36M36" 5355 \ .. "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41" 5356 \ .. "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45" 5357 call assert_equal(expected, taken) 5358 [CODE] 5359 let verify =<< trim [CODE] 5360 let expected = "a1a2a3a4a5a6a7a8a9" 5361 \ .. "b10b11b12b13b14b15b16b17b18" 5362 \ .. "c19c20c21c22c23c24c25c26c27d" 5363 call assert_equal(expected, g:Xpath) 5364 [CODE] 5365 call RunInNewVim(test, verify) 5366endfunc 5367 5368"------------------------------------------------------------------------------- 5369" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1 5370" 5371" When a function call made during evaluation of an expression in 5372" braces as part of a function name after ":function" is aborted due 5373" to an error inside a :try/:endtry region or due to an interrupt or 5374" a :throw, the expression evaluation is aborted as well, and the 5375" function definition is ignored, skipping all commands to the 5376" ":endfunction". On an error not inside :try/:endtry, the expression 5377" evaluation continues and the function gets defined, and can be 5378" called and deleted. 5379"------------------------------------------------------------------------------- 5380func Test_brace_expr_error() 5381 let test =<< trim [CODE] 5382 func ERR() abort 5383 Xloop 'a' 5384 asdf 5385 endfunc " returns -1 5386 5387 func OK() 5388 Xloop 'b' 5389 let v:errmsg = "" 5390 return 0 5391 endfunc 5392 5393 let v:errmsg = "" 5394 5395 Xpath 'c' 5396 func F{1 + ERR() + OK()}(arg) 5397 " F0 should be defined. 5398 if exists("a:arg") && a:arg == "calling" 5399 Xpath 'd' 5400 else 5401 call assert_report('should not get here') 5402 endif 5403 endfunction 5404 call assert_equal("", v:errmsg) 5405 XloopNEXT 5406 5407 Xpath 'e' 5408 call F{1 + ERR() + OK()}("calling") 5409 call assert_equal("", v:errmsg) 5410 XloopNEXT 5411 5412 Xpath 'f' 5413 delfunction F{1 + ERR() + OK()} 5414 call assert_equal("", v:errmsg) 5415 XloopNEXT 5416 5417 try 5418 while 1 5419 try 5420 Xpath 'g' 5421 func G{1 + ERR() + OK()}(arg) 5422 " G0 should not be defined, and the function body should be 5423 " skipped. 5424 call assert_report('should not get here') 5425 " Use an unmatched ":finally" to check whether the body is 5426 " skipped when an error occurs in ERR(). This works whether or 5427 " not the exception is converted to an exception. 5428 finally 5429 call assert_report('should not get here') 5430 endtry 5431 try 5432 call assert_report('should not get here') 5433 endfunction 5434 5435 call assert_report('should not get here') 5436 catch /asdf/ 5437 " Jumped to when the function is not defined and the body is 5438 " skipped. 5439 Xpath 'h' 5440 catch /.*/ 5441 call assert_report('should not get here') 5442 finally 5443 Xpath 'i' 5444 break 5445 endtry " jumped to when the body is not skipped 5446 endwhile 5447 catch /.*/ 5448 call assert_report('should not get here') 5449 endtry 5450 [CODE] 5451 let verify =<< trim [CODE] 5452 call assert_equal('ca1b1ea2b2dfa3b3ga4hi', g:Xpath) 5453 [CODE] 5454 call RunInNewVim(test, verify) 5455endfunc 5456 5457"------------------------------------------------------------------------------- 5458" Test 78: Messages on parsing errors in expression evaluation {{{1 5459" 5460" When an expression evaluation detects a parsing error, an error 5461" message is given and converted to an exception, and the expression 5462" evaluation is aborted. 5463"------------------------------------------------------------------------------- 5464func Test_expr_eval_error_msg() 5465 CheckEnglish 5466 5467 let test =<< trim [CODE] 5468 let taken = "" 5469 5470 func F(n) 5471 let g:taken = g:taken . "F" . a:n 5472 endfunc 5473 5474 func MSG(n, enr, emsg) 5475 let g:taken = g:taken . "M" . a:n 5476 call assert_match('^' .. a:enr .. ':', v:errmsg) 5477 call assert_match(a:emsg, v:errmsg) 5478 endfunc 5479 5480 func CONT(n) 5481 let g:taken = g:taken . "C" . a:n 5482 endfunc 5483 5484 let v:errmsg = "" 5485 try 5486 let t = 1 5487 while t <= 14 5488 let g:taken = g:taken . "T" . t 5489 let v:errmsg = "" 5490 try 5491 if t == 1 5492 let v{novar + CONT(t)} = 0 5493 elseif t == 2 5494 let v{novar + CONT(t)} 5495 elseif t == 3 5496 let var = exists('v{novar + CONT(t)}') 5497 elseif t == 4 5498 unlet v{novar + CONT(t)} 5499 elseif t == 5 5500 function F{novar + CONT(t)}() 5501 endfunction 5502 elseif t == 6 5503 function F{novar + CONT(t)} 5504 elseif t == 7 5505 let var = exists('*F{novar + CONT(t)}') 5506 elseif t == 8 5507 delfunction F{novar + CONT(t)} 5508 elseif t == 9 5509 echo novar + CONT(t) 5510 elseif t == 10 5511 echo v{novar + CONT(t)} 5512 elseif t == 11 5513 echo F{novar + CONT(t)} 5514 elseif t == 12 5515 let var = novar + CONT(t) 5516 elseif t == 13 5517 let var = v{novar + CONT(t)} 5518 elseif t == 14 5519 let var = F{novar + CONT(t)}() 5520 endif 5521 catch /^Vim\((\a\+)\)\=:/ 5522 Xloop 'a' 5523 " v:errmsg is not set when the error message is converted to an 5524 " exception. Set it to the original error message. 5525 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") 5526 finally 5527 Xloop 'b' 5528 if t <= 8 && t != 3 && t != 7 5529 call MSG(t, 'E475', 'Invalid argument\>') 5530 else 5531 call MSG(t, 'E121', "Undefined variable") 5532 endif 5533 let t = t + 1 5534 XloopNEXT 5535 continue " discard an aborting error 5536 endtry 5537 endwhile 5538 catch /.*/ 5539 call assert_report('should not get here') 5540 endtry 5541 5542 func T(n, expr, enr, emsg) 5543 try 5544 let g:taken = g:taken . "T" . a:n 5545 let v:errmsg = "" 5546 try 5547 execute "let var = " . a:expr 5548 catch /^Vim\((\a\+)\)\=:/ 5549 Xloop 'c' 5550 " v:errmsg is not set when the error message is converted to an 5551 " exception. Set it to the original error message. 5552 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") 5553 finally 5554 Xloop 'd' 5555 call MSG(a:n, a:enr, a:emsg) 5556 XloopNEXT 5557 " Discard an aborting error: 5558 return 5559 endtry 5560 catch /.*/ 5561 call assert_report('should not get here') 5562 endtry 5563 endfunc 5564 5565 call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function") 5566 call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments") 5567 call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments") 5568 call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments") 5569 call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'") 5570 call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'") 5571 call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression") 5572 call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression") 5573 call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'") 5574 call T(24, '("abc) + CONT(24)', 'E114', "Missing quote") 5575 call T(25, "('abc) + CONT(25)", 'E115', "Missing quote") 5576 call T(26, '& + CONT(26)', 'E112', "Option name missing") 5577 call T(27, '&asdf + CONT(27)', 'E113', "Unknown option") 5578 5579 let expected = "" 5580 \ .. "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14" 5581 \ .. "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25" 5582 \ .. "T26M26T27M27" 5583 5584 call assert_equal(expected, taken) 5585 [CODE] 5586 let verify =<< trim [CODE] 5587 let expected = "a1b1a2b2a3b3a4b4a5b5a6b6a7b7a8b8a9b9a10b10a11b11a12b12" 5588 \ .. "a13b13a14b14c15d15c16d16c17d17c18d18c19d19c20d20" 5589 \ .. "c21d21c22d22c23d23c24d24c25d25c26d26c27d27" 5590 call assert_equal(expected, g:Xpath) 5591 [CODE] 5592 call RunInNewVim(test, verify) 5593endfunc 5594 5595"------------------------------------------------------------------------------- 5596" Test 79: Throwing one of several errors for the same command {{{1 5597" 5598" When several errors appear in a row (for instance during expression 5599" evaluation), the first as the most specific one is used when 5600" throwing an error exception. If, however, a syntax error is 5601" detected afterwards, this one is used for the error exception. 5602" On a syntax error, the next command is not executed, on a normal 5603" error, however, it is (relevant only in a function without the 5604" "abort" flag). v:errmsg is not set. 5605" 5606" If throwing error exceptions is configured off, v:errmsg is always 5607" set to the latest error message, that is, to the more general 5608" message or the syntax error, respectively. 5609"------------------------------------------------------------------------------- 5610func Test_throw_multi_error() 5611 CheckEnglish 5612 5613 let test =<< trim [CODE] 5614 func NEXT(cmd) 5615 exec a:cmd . " | Xloop 'a'" 5616 endfun 5617 5618 call NEXT('echo novar') " (checks nextcmd) 5619 XloopNEXT 5620 call NEXT('let novar #') " (skips nextcmd) 5621 XloopNEXT 5622 call NEXT('unlet novar #') " (skips nextcmd) 5623 XloopNEXT 5624 call NEXT('let {novar}') " (skips nextcmd) 5625 XloopNEXT 5626 call NEXT('unlet{ novar}') " (skips nextcmd) 5627 5628 call assert_equal('a1', g:Xpath) 5629 XpathINIT 5630 XloopINIT 5631 5632 func EXEC(cmd) 5633 exec a:cmd 5634 endfunc 5635 5636 try 5637 while 1 " dummy loop 5638 try 5639 let v:errmsg = "" 5640 call EXEC('echo novar') " normal error 5641 catch /^Vim\((\a\+)\)\=:/ 5642 Xpath 'b' 5643 call assert_match('E121: Undefined variable: novar', v:exception) 5644 finally 5645 Xpath 'c' 5646 call assert_equal("", v:errmsg) 5647 break 5648 endtry 5649 endwhile 5650 5651 Xpath 'd' 5652 let cmd = "let" 5653 while cmd != "" 5654 try 5655 let v:errmsg = "" 5656 call EXEC(cmd . ' novar #') " normal plus syntax error 5657 catch /^Vim\((\a\+)\)\=:/ 5658 Xloop 'e' 5659 call assert_match('E488: Trailing characters', v:exception) 5660 finally 5661 Xloop 'f' 5662 call assert_equal("", v:errmsg) 5663 if cmd == "let" 5664 let cmd = "unlet" 5665 else 5666 let cmd = "" 5667 endif 5668 XloopNEXT 5669 continue 5670 endtry 5671 endwhile 5672 5673 Xpath 'g' 5674 let cmd = "let" 5675 while cmd != "" 5676 try 5677 let v:errmsg = "" 5678 call EXEC(cmd . ' {novar}') " normal plus syntax error 5679 catch /^Vim\((\a\+)\)\=:/ 5680 Xloop 'h' 5681 call assert_match('E475: Invalid argument: {novar}', v:exception) 5682 finally 5683 Xloop 'i' 5684 call assert_equal("", v:errmsg) 5685 if cmd == "let" 5686 let cmd = "unlet" 5687 else 5688 let cmd = "" 5689 endif 5690 XloopNEXT 5691 continue 5692 endtry 5693 endwhile 5694 catch /.*/ 5695 call assert_report('should not get here') 5696 endtry 5697 Xpath 'j' 5698 [CODE] 5699 let verify =<< trim [CODE] 5700 call assert_equal('bcde1f1e2f2gh3i3h4i4j', g:Xpath) 5701 [CODE] 5702 call RunInNewVim(test, verify) 5703endfunc 5704 5705"------------------------------------------------------------------------------- 5706" Test 80: Syntax error in expression for illegal :elseif {{{1 5707" 5708" If there is a syntax error in the expression after an illegal 5709" :elseif, an error message is given (or an error exception thrown) 5710" for the illegal :elseif rather than the expression error. 5711"------------------------------------------------------------------------------- 5712func Test_if_syntax_error() 5713 CheckEnglish 5714 5715 let test =<< trim [CODE] 5716 let v:errmsg = "" 5717 if 0 5718 else 5719 elseif 1 ||| 2 5720 endif 5721 Xpath 'a' 5722 call assert_match('E584: :elseif after :else', v:errmsg) 5723 5724 let v:errmsg = "" 5725 if 1 5726 else 5727 elseif 1 ||| 2 5728 endif 5729 Xpath 'b' 5730 call assert_match('E584: :elseif after :else', v:errmsg) 5731 5732 let v:errmsg = "" 5733 elseif 1 ||| 2 5734 Xpath 'c' 5735 call assert_match('E582: :elseif without :if', v:errmsg) 5736 5737 let v:errmsg = "" 5738 while 1 5739 elseif 1 ||| 2 5740 endwhile 5741 Xpath 'd' 5742 call assert_match('E582: :elseif without :if', v:errmsg) 5743 5744 while 1 5745 try 5746 try 5747 let v:errmsg = "" 5748 if 0 5749 else 5750 elseif 1 ||| 2 5751 endif 5752 catch /^Vim\((\a\+)\)\=:/ 5753 Xpath 'e' 5754 call assert_match('E584: :elseif after :else', v:exception) 5755 finally 5756 Xpath 'f' 5757 call assert_equal("", v:errmsg) 5758 endtry 5759 catch /.*/ 5760 call assert_report('should not get here') 5761 finally 5762 Xpath 'g' 5763 break 5764 endtry 5765 endwhile 5766 5767 while 1 5768 try 5769 try 5770 let v:errmsg = "" 5771 if 1 5772 else 5773 elseif 1 ||| 2 5774 endif 5775 catch /^Vim\((\a\+)\)\=:/ 5776 Xpath 'h' 5777 call assert_match('E584: :elseif after :else', v:exception) 5778 finally 5779 Xpath 'i' 5780 call assert_equal("", v:errmsg) 5781 endtry 5782 catch /.*/ 5783 call assert_report('should not get here') 5784 finally 5785 Xpath 'j' 5786 break 5787 endtry 5788 endwhile 5789 5790 while 1 5791 try 5792 try 5793 let v:errmsg = "" 5794 elseif 1 ||| 2 5795 catch /^Vim\((\a\+)\)\=:/ 5796 Xpath 'k' 5797 call assert_match('E582: :elseif without :if', v:exception) 5798 finally 5799 Xpath 'l' 5800 call assert_equal("", v:errmsg) 5801 endtry 5802 catch /.*/ 5803 call assert_report('should not get here') 5804 finally 5805 Xpath 'm' 5806 break 5807 endtry 5808 endwhile 5809 5810 while 1 5811 try 5812 try 5813 let v:errmsg = "" 5814 while 1 5815 elseif 1 ||| 2 5816 endwhile 5817 catch /^Vim\((\a\+)\)\=:/ 5818 Xpath 'n' 5819 call assert_match('E582: :elseif without :if', v:exception) 5820 finally 5821 Xpath 'o' 5822 call assert_equal("", v:errmsg) 5823 endtry 5824 catch /.*/ 5825 call assert_report('should not get here') 5826 finally 5827 Xpath 'p' 5828 break 5829 endtry 5830 endwhile 5831 Xpath 'q' 5832 [CODE] 5833 let verify =<< trim [CODE] 5834 call assert_equal('abcdefghijklmnopq', g:Xpath) 5835 [CODE] 5836 call RunInNewVim(test, verify) 5837endfunc 5838 5839"------------------------------------------------------------------------------- 5840" Test 81: Discarding exceptions after an error or interrupt {{{1 5841" 5842" When an exception is thrown from inside a :try conditional without 5843" :catch and :finally clauses and an error or interrupt occurs before 5844" the :endtry is reached, the exception is discarded. 5845"------------------------------------------------------------------------------- 5846 5847func Test_discard_exception_after_error_1() 5848 let test =<< trim [CODE] 5849 try 5850 Xpath 'a' 5851 try 5852 Xpath 'b' 5853 throw "arrgh" 5854 call assert_report('should not get here') 5855 if 1 5856 call assert_report('should not get here') 5857 " error after :throw: missing :endif 5858 endtry 5859 call assert_report('should not get here') 5860 catch /arrgh/ 5861 call assert_report('should not get here') 5862 endtry 5863 call assert_report('should not get here') 5864 [CODE] 5865 let verify =<< trim [CODE] 5866 call assert_equal('ab', g:Xpath) 5867 [CODE] 5868 call RunInNewVim(test, verify) 5869endfunc 5870 5871" TODO: Not able inject an interrupt after throwing an exception 5872func Disable_Test_discard_exception_after_error_2() 5873 let test =<< trim [CODE] 5874 try 5875 Xpath 'a' 5876 try 5877 Xpath 'b' 5878 throw "arrgh" 5879 call interrupt() " FIXME: throw is not interrupted here 5880 call assert_report('should not get here') 5881 endtry 5882 call assert_report('should not get here') 5883 catch /arrgh/ 5884 call assert_report('should not get here') 5885 endtry 5886 call assert_report('should not get here') 5887 [CODE] 5888 let verify =<< trim [CODE] 5889 call assert_equal('ab', g:Xpath) 5890 [CODE] 5891 call RunInNewVim(test, verify) 5892endfunc 5893 5894"------------------------------------------------------------------------------- 5895" Test 87 using (expr) ? funcref : funcref {{{1 5896" 5897" Vim needs to correctly parse the funcref and even when it does 5898" not execute the funcref, it needs to consume the trailing () 5899"------------------------------------------------------------------------------- 5900 5901func Add2(x1, x2) 5902 return a:x1 + a:x2 5903endfu 5904 5905func GetStr() 5906 return "abcdefghijklmnopqrstuvwxyp" 5907endfu 5908 5909func Test_funcref_with_condexpr() 5910 call assert_equal(5, function('Add2')(2,3)) 5911 5912 call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3)) 5913 call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3)) 5914 " Make sure, GetStr() still works. 5915 call assert_equal('abcdefghijk', GetStr()[0:10]) 5916endfunc 5917 5918" Test 90: Recognizing {} in variable name. {{{1 5919"------------------------------------------------------------------------------- 5920 5921func Test_curlies() 5922 let s:var = 66 5923 let ns = 's' 5924 call assert_equal(66, {ns}:var) 5925 5926 let g:a = {} 5927 let g:b = 't' 5928 let g:a[g:b] = 77 5929 call assert_equal(77, g:a['t']) 5930endfunc 5931 5932"------------------------------------------------------------------------------- 5933" Test 91: using type(). {{{1 5934"------------------------------------------------------------------------------- 5935 5936func Test_type() 5937 call assert_equal(0, type(0)) 5938 call assert_equal(1, type("")) 5939 call assert_equal(2, type(function("tr"))) 5940 call assert_equal(2, type(function("tr", [8]))) 5941 call assert_equal(3, type([])) 5942 call assert_equal(4, type({})) 5943 if has('float') 5944 call assert_equal(5, type(0.0)) 5945 endif 5946 call assert_equal(6, type(v:false)) 5947 call assert_equal(6, type(v:true)) 5948 call assert_equal(7, type(v:none)) 5949 call assert_equal(7, type(v:null)) 5950 call assert_equal(8, v:t_job) 5951 call assert_equal(9, v:t_channel) 5952 call assert_equal(v:t_number, type(0)) 5953 call assert_equal(v:t_string, type("")) 5954 call assert_equal(v:t_func, type(function("tr"))) 5955 call assert_equal(v:t_func, type(function("tr", [8]))) 5956 call assert_equal(v:t_list, type([])) 5957 call assert_equal(v:t_dict, type({})) 5958 if has('float') 5959 call assert_equal(v:t_float, type(0.0)) 5960 endif 5961 call assert_equal(v:t_bool, type(v:false)) 5962 call assert_equal(v:t_bool, type(v:true)) 5963 call assert_equal(v:t_none, type(v:none)) 5964 call assert_equal(v:t_none, type(v:null)) 5965 call assert_equal(v:t_string, type(test_null_string())) 5966 call assert_equal(v:t_func, type(test_null_function())) 5967 call assert_equal(v:t_func, type(test_null_partial())) 5968 call assert_equal(v:t_list, type(test_null_list())) 5969 call assert_equal(v:t_dict, type(test_null_dict())) 5970 if has('job') 5971 call assert_equal(v:t_job, type(test_null_job())) 5972 endif 5973 if has('channel') 5974 call assert_equal(v:t_channel, type(test_null_channel())) 5975 endif 5976 call assert_equal(v:t_blob, type(test_null_blob())) 5977 5978 call assert_fails("call type(test_void())", 'E685:') 5979 call assert_fails("call type(test_unknown())", 'E685:') 5980 5981 call assert_equal(0, 0 + v:false) 5982 call assert_equal(1, 0 + v:true) 5983 call assert_equal(0, 0 + v:none) 5984 call assert_equal(0, 0 + v:null) 5985 5986 call assert_equal('v:false', '' . v:false) 5987 call assert_equal('v:true', '' . v:true) 5988 call assert_equal('v:none', '' . v:none) 5989 call assert_equal('v:null', '' . v:null) 5990 5991 call assert_true(v:false == 0) 5992 call assert_false(v:false != 0) 5993 call assert_true(v:true == 1) 5994 call assert_false(v:true != 1) 5995 call assert_false(v:true == v:false) 5996 call assert_true(v:true != v:false) 5997 5998 call assert_true(v:null == 0) 5999 call assert_false(v:null != 0) 6000 call assert_true(v:none == 0) 6001 call assert_false(v:none != 0) 6002 6003 call assert_true(v:false is v:false) 6004 call assert_true(v:true is v:true) 6005 call assert_true(v:none is v:none) 6006 call assert_true(v:null is v:null) 6007 6008 call assert_false(v:false isnot v:false) 6009 call assert_false(v:true isnot v:true) 6010 call assert_false(v:none isnot v:none) 6011 call assert_false(v:null isnot v:null) 6012 6013 call assert_false(v:false is 0) 6014 call assert_false(v:true is 1) 6015 call assert_false(v:true is v:false) 6016 call assert_false(v:none is 0) 6017 call assert_false(v:null is 0) 6018 call assert_false(v:null is v:none) 6019 6020 call assert_true(v:false isnot 0) 6021 call assert_true(v:true isnot 1) 6022 call assert_true(v:true isnot v:false) 6023 call assert_true(v:none isnot 0) 6024 call assert_true(v:null isnot 0) 6025 call assert_true(v:null isnot v:none) 6026 6027 call assert_equal(v:false, eval(string(v:false))) 6028 call assert_equal(v:true, eval(string(v:true))) 6029 call assert_equal(v:none, eval(string(v:none))) 6030 call assert_equal(v:null, eval(string(v:null))) 6031 6032 call assert_equal(v:false, copy(v:false)) 6033 call assert_equal(v:true, copy(v:true)) 6034 call assert_equal(v:none, copy(v:none)) 6035 call assert_equal(v:null, copy(v:null)) 6036 6037 call assert_equal([v:false], deepcopy([v:false])) 6038 call assert_equal([v:true], deepcopy([v:true])) 6039 call assert_equal([v:none], deepcopy([v:none])) 6040 call assert_equal([v:null], deepcopy([v:null])) 6041 6042 call assert_true(empty(v:false)) 6043 call assert_false(empty(v:true)) 6044 call assert_true(empty(v:null)) 6045 call assert_true(empty(v:none)) 6046 6047 func ChangeYourMind() 6048 try 6049 return v:true 6050 finally 6051 return 'something else' 6052 endtry 6053 endfunc 6054 6055 call ChangeYourMind() 6056endfunc 6057 6058"------------------------------------------------------------------------------- 6059" Test 92: skipping code {{{1 6060"------------------------------------------------------------------------------- 6061 6062func Test_skip() 6063 let Fn = function('Test_type') 6064 call assert_false(0 && Fn[1]) 6065 call assert_false(0 && string(Fn)) 6066 call assert_false(0 && len(Fn)) 6067 let l = [] 6068 call assert_false(0 && l[1]) 6069 call assert_false(0 && string(l)) 6070 call assert_false(0 && len(l)) 6071 let f = 1.0 6072 call assert_false(0 && f[1]) 6073 call assert_false(0 && string(f)) 6074 call assert_false(0 && len(f)) 6075 let sp = v:null 6076 call assert_false(0 && sp[1]) 6077 call assert_false(0 && string(sp)) 6078 call assert_false(0 && len(sp)) 6079 6080endfunc 6081 6082"------------------------------------------------------------------------------- 6083" Test 93: :echo and string() {{{1 6084"------------------------------------------------------------------------------- 6085 6086func Test_echo_and_string() 6087 " String 6088 let a = 'foo bar' 6089 redir => result 6090 echo a 6091 echo string(a) 6092 redir END 6093 let l = split(result, "\n") 6094 call assert_equal(["foo bar", 6095 \ "'foo bar'"], l) 6096 6097 " Float 6098 if has('float') 6099 let a = -1.2e0 6100 redir => result 6101 echo a 6102 echo string(a) 6103 redir END 6104 let l = split(result, "\n") 6105 call assert_equal(["-1.2", 6106 \ "-1.2"], l) 6107 endif 6108 6109 " Funcref 6110 redir => result 6111 echo function('string') 6112 echo string(function('string')) 6113 redir END 6114 let l = split(result, "\n") 6115 call assert_equal(["string", 6116 \ "function('string')"], l) 6117 6118 " Recursive dictionary 6119 let a = {} 6120 let a["a"] = a 6121 redir => result 6122 echo a 6123 echo string(a) 6124 redir END 6125 let l = split(result, "\n") 6126 call assert_equal(["{'a': {...}}", 6127 \ "{'a': {...}}"], l) 6128 6129 " Recursive list 6130 let a = [0] 6131 let a[0] = a 6132 redir => result 6133 echo a 6134 echo string(a) 6135 redir END 6136 let l = split(result, "\n") 6137 call assert_equal(["[[...]]", 6138 \ "[[...]]"], l) 6139 6140 " Empty dictionaries in a list 6141 let a = {} 6142 redir => result 6143 echo [a, a, a] 6144 echo string([a, a, a]) 6145 redir END 6146 let l = split(result, "\n") 6147 call assert_equal(["[{}, {}, {}]", 6148 \ "[{}, {}, {}]"], l) 6149 6150 " Empty dictionaries in a dictionary 6151 let a = {} 6152 let b = {"a": a, "b": a} 6153 redir => result 6154 echo b 6155 echo string(b) 6156 redir END 6157 let l = split(result, "\n") 6158 call assert_equal(["{'a': {}, 'b': {}}", 6159 \ "{'a': {}, 'b': {}}"], l) 6160 6161 " Empty lists in a list 6162 let a = [] 6163 redir => result 6164 echo [a, a, a] 6165 echo string([a, a, a]) 6166 redir END 6167 let l = split(result, "\n") 6168 call assert_equal(["[[], [], []]", 6169 \ "[[], [], []]"], l) 6170 6171 " Empty lists in a dictionary 6172 let a = [] 6173 let b = {"a": a, "b": a} 6174 redir => result 6175 echo b 6176 echo string(b) 6177 redir END 6178 let l = split(result, "\n") 6179 call assert_equal(["{'a': [], 'b': []}", 6180 \ "{'a': [], 'b': []}"], l) 6181 6182 " Dictionaries in a list 6183 let a = {"one": "yes", "two": "yes", "three": "yes"} 6184 redir => result 6185 echo [a, a, a] 6186 echo string([a, a, a]) 6187 redir END 6188 let l = split(result, "\n") 6189 call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]", 6190 \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l) 6191 6192 " Dictionaries in a dictionary 6193 let a = {"one": "yes", "two": "yes", "three": "yes"} 6194 let b = {"a": a, "b": a} 6195 redir => result 6196 echo b 6197 echo string(b) 6198 redir END 6199 let l = split(result, "\n") 6200 call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}", 6201 \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l) 6202 6203 " Lists in a list 6204 let a = [1, 2, 3] 6205 redir => result 6206 echo [a, a, a] 6207 echo string([a, a, a]) 6208 redir END 6209 let l = split(result, "\n") 6210 call assert_equal(["[[1, 2, 3], [...], [...]]", 6211 \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l) 6212 6213 " Lists in a dictionary 6214 let a = [1, 2, 3] 6215 let b = {"a": a, "b": a} 6216 redir => result 6217 echo b 6218 echo string(b) 6219 redir END 6220 let l = split(result, "\n") 6221 call assert_equal(["{'a': [1, 2, 3], 'b': [...]}", 6222 \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l) 6223 6224 call assert_fails('echo &:', 'E112:') 6225 call assert_fails('echo &g:', 'E112:') 6226 call assert_fails('echo &l:', 'E112:') 6227 6228endfunc 6229 6230"------------------------------------------------------------------------------- 6231" Test 94: 64-bit Numbers {{{1 6232"------------------------------------------------------------------------------- 6233 6234func Test_num64() 6235 call assert_notequal( 4294967296, 0) 6236 call assert_notequal(-4294967296, 0) 6237 call assert_equal( 4294967296, 0xFFFFffff + 1) 6238 call assert_equal(-4294967296, -0xFFFFffff - 1) 6239 6240 call assert_equal( 9223372036854775807, 1 / 0) 6241 call assert_equal(-9223372036854775807, -1 / 0) 6242 call assert_equal(-9223372036854775807 - 1, 0 / 0) 6243 6244 if has('float') 6245 call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150)) 6246 call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150)) 6247 endif 6248 6249 let rng = range(0xFFFFffff, 0x100000001) 6250 call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng) 6251 call assert_equal(0x100000001, max(rng)) 6252 call assert_equal(0xFFFFffff, min(rng)) 6253 call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N')) 6254endfunc 6255 6256"------------------------------------------------------------------------------- 6257" Test 95: lines of :append, :change, :insert {{{1 6258"------------------------------------------------------------------------------- 6259 6260function! DefineFunction(name, body) 6261 let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n") 6262 exec func 6263endfunction 6264 6265func Test_script_lines() 6266 " :append 6267 try 6268 call DefineFunction('T_Append', [ 6269 \ 'append', 6270 \ 'py <<EOS', 6271 \ '.', 6272 \ ]) 6273 catch 6274 call assert_report("Can't define function") 6275 endtry 6276 try 6277 call DefineFunction('T_Append', [ 6278 \ 'append', 6279 \ 'abc', 6280 \ ]) 6281 call assert_report("Shouldn't be able to define function") 6282 catch 6283 call assert_exception('Vim(function):E126: Missing :endfunction') 6284 endtry 6285 6286 " :change 6287 try 6288 call DefineFunction('T_Change', [ 6289 \ 'change', 6290 \ 'py <<EOS', 6291 \ '.', 6292 \ ]) 6293 catch 6294 call assert_report("Can't define function") 6295 endtry 6296 try 6297 call DefineFunction('T_Change', [ 6298 \ 'change', 6299 \ 'abc', 6300 \ ]) 6301 call assert_report("Shouldn't be able to define function") 6302 catch 6303 call assert_exception('Vim(function):E126: Missing :endfunction') 6304 endtry 6305 6306 " :insert 6307 try 6308 call DefineFunction('T_Insert', [ 6309 \ 'insert', 6310 \ 'py <<EOS', 6311 \ '.', 6312 \ ]) 6313 catch 6314 call assert_report("Can't define function") 6315 endtry 6316 try 6317 call DefineFunction('T_Insert', [ 6318 \ 'insert', 6319 \ 'abc', 6320 \ ]) 6321 call assert_report("Shouldn't be able to define function") 6322 catch 6323 call assert_exception('Vim(function):E126: Missing :endfunction') 6324 endtry 6325endfunc 6326 6327"------------------------------------------------------------------------------- 6328" Test 96: line continuation {{{1 6329" 6330" Undefined behavior was detected by ubsan with line continuation 6331" after an empty line. 6332"------------------------------------------------------------------------------- 6333func Test_script_emty_line_continuation() 6334 6335 \ 6336endfunc 6337 6338"------------------------------------------------------------------------------- 6339" Test 97: bitwise functions {{{1 6340"------------------------------------------------------------------------------- 6341func Test_bitwise_functions() 6342 " and 6343 call assert_equal(127, and(127, 127)) 6344 call assert_equal(16, and(127, 16)) 6345 eval 127->and(16)->assert_equal(16) 6346 call assert_equal(0, and(127, 128)) 6347 call assert_fails("call and([], 1)", 'E745:') 6348 call assert_fails("call and({}, 1)", 'E728:') 6349 if has('float') 6350 call assert_fails("call and(1.0, 1)", 'E805:') 6351 call assert_fails("call and(1, 1.0)", 'E805:') 6352 endif 6353 call assert_fails("call and(1, [])", 'E745:') 6354 call assert_fails("call and(1, {})", 'E728:') 6355 " or 6356 call assert_equal(23, or(16, 7)) 6357 call assert_equal(15, or(8, 7)) 6358 eval 8->or(7)->assert_equal(15) 6359 call assert_equal(123, or(0, 123)) 6360 call assert_fails("call or([], 1)", 'E745:') 6361 call assert_fails("call or({}, 1)", 'E728:') 6362 if has('float') 6363 call assert_fails("call or(1.0, 1)", 'E805:') 6364 call assert_fails("call or(1, 1.0)", 'E805:') 6365 endif 6366 call assert_fails("call or(1, [])", 'E745:') 6367 call assert_fails("call or(1, {})", 'E728:') 6368 " xor 6369 call assert_equal(0, xor(127, 127)) 6370 call assert_equal(111, xor(127, 16)) 6371 eval 127->xor(16)->assert_equal(111) 6372 call assert_equal(255, xor(127, 128)) 6373 if has('float') 6374 call assert_fails("call xor(1.0, 1)", 'E805:') 6375 call assert_fails("call xor(1, 1.0)", 'E805:') 6376 endif 6377 call assert_fails("call xor([], 1)", 'E745:') 6378 call assert_fails("call xor({}, 1)", 'E728:') 6379 call assert_fails("call xor(1, [])", 'E745:') 6380 call assert_fails("call xor(1, {})", 'E728:') 6381 " invert 6382 call assert_equal(65408, and(invert(127), 65535)) 6383 eval 127->invert()->and(65535)->assert_equal(65408) 6384 call assert_equal(65519, and(invert(16), 65535)) 6385 call assert_equal(65407, and(invert(128), 65535)) 6386 if has('float') 6387 call assert_fails("call invert(1.0)", 'E805:') 6388 endif 6389 call assert_fails("call invert([])", 'E745:') 6390 call assert_fails("call invert({})", 'E728:') 6391endfunc 6392 6393" Test using bang after user command {{{1 6394func Test_user_command_with_bang() 6395 command -bang Nieuw let nieuw = 1 6396 Ni! 6397 call assert_equal(1, nieuw) 6398 unlet nieuw 6399 delcommand Nieuw 6400endfunc 6401 6402func Test_script_expand_sfile() 6403 let lines =<< trim END 6404 func s:snr() 6405 return expand('<sfile>') 6406 endfunc 6407 let g:result = s:snr() 6408 END 6409 call writefile(lines, 'Xexpand') 6410 source Xexpand 6411 call assert_match('<SNR>\d\+_snr', g:result) 6412 source Xexpand 6413 call assert_match('<SNR>\d\+_snr', g:result) 6414 6415 call delete('Xexpand') 6416 unlet g:result 6417endfunc 6418 6419func Test_compound_assignment_operators() 6420 " Test for number 6421 let x = 1 6422 let x += 10 6423 call assert_equal(11, x) 6424 let x -= 5 6425 call assert_equal(6, x) 6426 let x *= 4 6427 call assert_equal(24, x) 6428 let x /= 3 6429 call assert_equal(8, x) 6430 let x %= 3 6431 call assert_equal(2, x) 6432 let x .= 'n' 6433 call assert_equal('2n', x) 6434 6435 " Test special cases: division or modulus with 0. 6436 let x = 1 6437 let x /= 0 6438 call assert_equal(0x7FFFFFFFFFFFFFFF, x) 6439 6440 let x = -1 6441 let x /= 0 6442 call assert_equal(-0x7FFFFFFFFFFFFFFF, x) 6443 6444 let x = 0 6445 let x /= 0 6446 call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x) 6447 6448 let x = 1 6449 let x %= 0 6450 call assert_equal(0, x) 6451 6452 let x = -1 6453 let x %= 0 6454 call assert_equal(0, x) 6455 6456 let x = 0 6457 let x %= 0 6458 call assert_equal(0, x) 6459 6460 " Test for string 6461 let x = 'str' 6462 let x .= 'ing' 6463 call assert_equal('string', x) 6464 let x += 1 6465 call assert_equal(1, x) 6466 6467 if has('float') 6468 " Test for float 6469 let x -= 1.5 6470 call assert_equal(-0.5, x) 6471 let x = 0.5 6472 let x += 4.5 6473 call assert_equal(5.0, x) 6474 let x -= 1.5 6475 call assert_equal(3.5, x) 6476 let x *= 3.0 6477 call assert_equal(10.5, x) 6478 let x /= 2.5 6479 call assert_equal(4.2, x) 6480 call assert_fails('let x %= 0.5', 'E734') 6481 call assert_fails('let x .= "f"', 'E734') 6482 let x = !3.14 6483 call assert_equal(0.0, x) 6484 6485 " integer and float operations 6486 let x = 1 6487 let x *= 2.1 6488 call assert_equal(2.1, x) 6489 let x = 1 6490 let x /= 0.25 6491 call assert_equal(4.0, x) 6492 let x = 1 6493 call assert_fails('let x %= 0.25', 'E734:') 6494 let x = 1 6495 call assert_fails('let x .= 0.25', 'E734:') 6496 let x = 1.0 6497 call assert_fails('let x += [1.1]', 'E734:') 6498 endif 6499 6500 " Test for environment variable 6501 let $FOO = 1 6502 call assert_fails('let $FOO += 1', 'E734') 6503 call assert_fails('let $FOO -= 1', 'E734') 6504 call assert_fails('let $FOO *= 1', 'E734') 6505 call assert_fails('let $FOO /= 1', 'E734') 6506 call assert_fails('let $FOO %= 1', 'E734') 6507 let $FOO .= 's' 6508 call assert_equal('1s', $FOO) 6509 unlet $FOO 6510 6511 " Test for option variable (type: number) 6512 let &scrolljump = 1 6513 let &scrolljump += 5 6514 call assert_equal(6, &scrolljump) 6515 let &scrolljump -= 2 6516 call assert_equal(4, &scrolljump) 6517 let &scrolljump *= 3 6518 call assert_equal(12, &scrolljump) 6519 let &scrolljump /= 2 6520 call assert_equal(6, &scrolljump) 6521 let &scrolljump %= 5 6522 call assert_equal(1, &scrolljump) 6523 call assert_fails('let &scrolljump .= "j"', 'E734') 6524 set scrolljump&vim 6525 6526 " Test for register 6527 let @/ = 1 6528 call assert_fails('let @/ += 1', 'E734') 6529 call assert_fails('let @/ -= 1', 'E734') 6530 call assert_fails('let @/ *= 1', 'E734') 6531 call assert_fails('let @/ /= 1', 'E734') 6532 call assert_fails('let @/ %= 1', 'E734') 6533 let @/ .= 's' 6534 call assert_equal('1s', @/) 6535 let @/ = '' 6536endfunc 6537 6538func Test_unlet_env() 6539 let $TESTVAR = 'yes' 6540 call assert_equal('yes', $TESTVAR) 6541 call assert_fails('lockvar $TESTVAR', 'E940') 6542 call assert_fails('unlockvar $TESTVAR', 'E940') 6543 call assert_equal('yes', $TESTVAR) 6544 if 0 6545 unlet $TESTVAR 6546 endif 6547 call assert_equal('yes', $TESTVAR) 6548 unlet $TESTVAR 6549 call assert_equal('', $TESTVAR) 6550endfunc 6551 6552func Test_refcount() 6553 " Immediate values 6554 call assert_equal(-1, test_refcount(1)) 6555 call assert_equal(-1, test_refcount('s')) 6556 call assert_equal(-1, test_refcount(v:true)) 6557 call assert_equal(0, test_refcount([])) 6558 call assert_equal(0, test_refcount({})) 6559 call assert_equal(0, test_refcount(0zff)) 6560 call assert_equal(0, test_refcount({-> line('.')})) 6561 if has('float') 6562 call assert_equal(-1, test_refcount(0.1)) 6563 endif 6564 if has('job') 6565 call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .']))) 6566 endif 6567 6568 " No refcount types 6569 let x = 1 6570 call assert_equal(-1, test_refcount(x)) 6571 let x = 's' 6572 call assert_equal(-1, test_refcount(x)) 6573 let x = v:true 6574 call assert_equal(-1, test_refcount(x)) 6575 if has('float') 6576 let x = 0.1 6577 call assert_equal(-1, test_refcount(x)) 6578 endif 6579 6580 " Check refcount 6581 let x = [] 6582 call assert_equal(1, test_refcount(x)) 6583 6584 let x = {} 6585 call assert_equal(1, x->test_refcount()) 6586 6587 let x = 0zff 6588 call assert_equal(1, test_refcount(x)) 6589 6590 let X = {-> line('.')} 6591 call assert_equal(1, test_refcount(X)) 6592 let Y = X 6593 call assert_equal(2, test_refcount(X)) 6594 6595 if has('job') 6596 let job = job_start([&shell, &shellcmdflag, 'echo .']) 6597 call assert_equal(1, test_refcount(job)) 6598 call assert_equal(1, test_refcount(job_getchannel(job))) 6599 call assert_equal(1, test_refcount(job)) 6600 endif 6601 6602 " Function arguments, copying and unassigning 6603 func ExprCheck(x, i) 6604 let i = a:i + 1 6605 call assert_equal(i, test_refcount(a:x)) 6606 let Y = a:x 6607 call assert_equal(i + 1, test_refcount(a:x)) 6608 call assert_equal(test_refcount(a:x), test_refcount(Y)) 6609 let Y = 0 6610 call assert_equal(i, test_refcount(a:x)) 6611 endfunc 6612 call ExprCheck([], 0) 6613 call ExprCheck({}, 0) 6614 call ExprCheck(0zff, 0) 6615 call ExprCheck({-> line('.')}, 0) 6616 if has('job') 6617 call ExprCheck(job, 1) 6618 call ExprCheck(job_getchannel(job), 1) 6619 call job_stop(job) 6620 endif 6621 delfunc ExprCheck 6622 6623 " Regarding function 6624 func Func(x) abort 6625 call assert_equal(2, test_refcount(function('Func'))) 6626 call assert_equal(0, test_refcount(funcref('Func'))) 6627 endfunc 6628 call assert_equal(1, test_refcount(function('Func'))) 6629 call assert_equal(0, test_refcount(function('Func', [1]))) 6630 call assert_equal(0, test_refcount(funcref('Func'))) 6631 call assert_equal(0, test_refcount(funcref('Func', [1]))) 6632 let X = function('Func') 6633 let Y = X 6634 call assert_equal(1, test_refcount(X)) 6635 let X = function('Func', [1]) 6636 let Y = X 6637 call assert_equal(2, test_refcount(X)) 6638 let X = funcref('Func') 6639 let Y = X 6640 call assert_equal(2, test_refcount(X)) 6641 let X = funcref('Func', [1]) 6642 let Y = X 6643 call assert_equal(2, test_refcount(X)) 6644 unlet X 6645 unlet Y 6646 call Func(1) 6647 delfunc Func 6648 6649 " Function with dict 6650 func DictFunc() dict 6651 call assert_equal(3, test_refcount(self)) 6652 endfunc 6653 let d = {'Func': function('DictFunc')} 6654 call assert_equal(1, test_refcount(d)) 6655 call assert_equal(0, test_refcount(d.Func)) 6656 call d.Func() 6657 unlet d 6658 delfunc DictFunc 6659endfunc 6660 6661" Test for missing :endif, :endfor, :endwhile and :endtry {{{1 6662func Test_missing_end() 6663 call writefile(['if 2 > 1', 'echo ">"'], 'Xscript') 6664 call assert_fails('source Xscript', 'E171:') 6665 call writefile(['for i in range(5)', 'echo i'], 'Xscript') 6666 call assert_fails('source Xscript', 'E170:') 6667 call writefile(['while v:true', 'echo "."'], 'Xscript') 6668 call assert_fails('source Xscript', 'E170:') 6669 call writefile(['try', 'echo "."'], 'Xscript') 6670 call assert_fails('source Xscript', 'E600:') 6671 call delete('Xscript') 6672 6673 " Using endfor with :while 6674 let caught_e732 = 0 6675 try 6676 while v:true 6677 endfor 6678 catch /E732:/ 6679 let caught_e732 = 1 6680 endtry 6681 call assert_equal(1, caught_e732) 6682 6683 " Using endwhile with :for 6684 let caught_e733 = 0 6685 try 6686 for i in range(1) 6687 endwhile 6688 catch /E733:/ 6689 let caught_e733 = 1 6690 endtry 6691 call assert_equal(1, caught_e733) 6692 6693 " Using endfunc with :if 6694 call assert_fails('exe "if 1 | endfunc | endif"', 'E193:') 6695 6696 " Missing 'in' in a :for statement 6697 call assert_fails('for i range(1) | endfor', 'E690:') 6698 6699 " Incorrect number of variables in for 6700 call assert_fails('for [i,] in range(3) | endfor', 'E475:') 6701endfunc 6702 6703" Test for deep nesting of if/for/while/try statements {{{1 6704func Test_deep_nest() 6705 CheckRunVimInTerminal 6706 6707 let lines =<< trim [SCRIPT] 6708 " Deep nesting of if ... endif 6709 func Test1() 6710 let @a = join(repeat(['if v:true'], 51), "\n") 6711 let @a ..= "\n" 6712 let @a ..= join(repeat(['endif'], 51), "\n") 6713 @a 6714 let @a = '' 6715 endfunc 6716 6717 " Deep nesting of for ... endfor 6718 func Test2() 6719 let @a = join(repeat(['for i in [1]'], 51), "\n") 6720 let @a ..= "\n" 6721 let @a ..= join(repeat(['endfor'], 51), "\n") 6722 @a 6723 let @a = '' 6724 endfunc 6725 6726 " Deep nesting of while ... endwhile 6727 func Test3() 6728 let @a = join(repeat(['while v:true'], 51), "\n") 6729 let @a ..= "\n" 6730 let @a ..= join(repeat(['endwhile'], 51), "\n") 6731 @a 6732 let @a = '' 6733 endfunc 6734 6735 " Deep nesting of try ... endtry 6736 func Test4() 6737 let @a = join(repeat(['try'], 51), "\n") 6738 let @a ..= "\necho v:true\n" 6739 let @a ..= join(repeat(['endtry'], 51), "\n") 6740 @a 6741 let @a = '' 6742 endfunc 6743 6744 " Deep nesting of function ... endfunction 6745 func Test5() 6746 let @a = join(repeat(['function X()'], 51), "\n") 6747 let @a ..= "\necho v:true\n" 6748 let @a ..= join(repeat(['endfunction'], 51), "\n") 6749 @a 6750 let @a = '' 6751 endfunc 6752 [SCRIPT] 6753 call writefile(lines, 'Xscript') 6754 6755 let buf = RunVimInTerminal('-S Xscript', {'rows': 6}) 6756 6757 " Deep nesting of if ... endif 6758 call term_sendkeys(buf, ":call Test1()\n") 6759 call TermWait(buf) 6760 call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))}) 6761 6762 " Deep nesting of for ... endfor 6763 call term_sendkeys(buf, ":call Test2()\n") 6764 call TermWait(buf) 6765 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))}) 6766 6767 " Deep nesting of while ... endwhile 6768 call term_sendkeys(buf, ":call Test3()\n") 6769 call TermWait(buf) 6770 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))}) 6771 6772 " Deep nesting of try ... endtry 6773 call term_sendkeys(buf, ":call Test4()\n") 6774 call TermWait(buf) 6775 call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))}) 6776 6777 " Deep nesting of function ... endfunction 6778 call term_sendkeys(buf, ":call Test5()\n") 6779 call TermWait(buf) 6780 call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))}) 6781 call term_sendkeys(buf, "\<C-C>\n") 6782 call TermWait(buf) 6783 6784 "let l = '' 6785 "for i in range(1, 6) 6786 " let l ..= term_getline(buf, i) . "\n" 6787 "endfor 6788 "call assert_report(l) 6789 6790 call StopVimInTerminal(buf) 6791 call delete('Xscript') 6792endfunc 6793 6794" Test for errors in converting to float from various types {{{1 6795func Test_float_conversion_errors() 6796 if has('float') 6797 call assert_fails('let x = 4.0 % 2.0', 'E804') 6798 call assert_fails('echo 1.1[0]', 'E806') 6799 call assert_fails('echo sort([function("min"), 1], "f")', 'E891:') 6800 call assert_fails('echo 3.2 == "vim"', 'E892:') 6801 call assert_fails('echo sort([[], 1], "f")', 'E893:') 6802 call assert_fails('echo sort([{}, 1], "f")', 'E894:') 6803 call assert_fails('echo 3.2 == v:true', 'E362:') 6804 call assert_fails('echo 3.2 == v:none', 'E907:') 6805 endif 6806endfunc 6807 6808" invalid function names {{{1 6809func Test_invalid_function_names() 6810 " function name not starting with capital 6811 let caught_e128 = 0 6812 try 6813 func! g:test() 6814 echo "test" 6815 endfunc 6816 catch /E128:/ 6817 let caught_e128 = 1 6818 endtry 6819 call assert_equal(1, caught_e128) 6820 6821 " function name includes a colon 6822 let caught_e884 = 0 6823 try 6824 func! b:test() 6825 echo "test" 6826 endfunc 6827 catch /E884:/ 6828 let caught_e884 = 1 6829 endtry 6830 call assert_equal(1, caught_e884) 6831 6832 " function name folowed by # 6833 let caught_e128 = 0 6834 try 6835 func! test2() "# 6836 echo "test2" 6837 endfunc 6838 catch /E128:/ 6839 let caught_e128 = 1 6840 endtry 6841 call assert_equal(1, caught_e128) 6842 6843 " function name starting with/without "g:", buffer-local funcref. 6844 function! g:Foo(n) 6845 return 'called Foo(' . a:n . ')' 6846 endfunction 6847 let b:my_func = function('Foo') 6848 call assert_equal('called Foo(1)', b:my_func(1)) 6849 call assert_equal('called Foo(2)', g:Foo(2)) 6850 call assert_equal('called Foo(3)', Foo(3)) 6851 delfunc g:Foo 6852 6853 " script-local function used in Funcref must exist. 6854 let lines =<< trim END 6855 func s:Testje() 6856 return "foo" 6857 endfunc 6858 let Bar = function('s:Testje') 6859 call assert_equal(0, exists('s:Testje')) 6860 call assert_equal(1, exists('*s:Testje')) 6861 call assert_equal(1, exists('Bar')) 6862 call assert_equal(1, exists('*Bar')) 6863 END 6864 call writefile(lines, 'Xscript') 6865 source Xscript 6866 call delete('Xscript') 6867endfunc 6868 6869" substring and variable name {{{1 6870func Test_substring_var() 6871 let str = 'abcdef' 6872 let n = 3 6873 call assert_equal('def', str[n:]) 6874 call assert_equal('abcd', str[:n]) 6875 call assert_equal('d', str[n:n]) 6876 unlet n 6877 let nn = 3 6878 call assert_equal('def', str[nn:]) 6879 call assert_equal('abcd', str[:nn]) 6880 call assert_equal('d', str[nn:nn]) 6881 unlet nn 6882 let b:nn = 4 6883 call assert_equal('ef', str[b:nn:]) 6884 call assert_equal('abcde', str[:b:nn]) 6885 call assert_equal('e', str[b:nn:b:nn]) 6886 unlet b:nn 6887endfunc 6888 6889" Test using s: with a typed command {{{1 6890func Test_typed_script_var() 6891 CheckRunVimInTerminal 6892 6893 let buf = RunVimInTerminal('', {'rows': 6}) 6894 6895 " Deep nesting of if ... endif 6896 call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n") 6897 call TermWait(buf) 6898 call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))}) 6899 6900 call StopVimInTerminal(buf) 6901endfunc 6902 6903"------------------------------------------------------------------------------- 6904" Modelines {{{1 6905" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 6906"------------------------------------------------------------------------------- 6907