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