1" Test various aspects of the Vim script language. 2" Most of this was formerly in test49. 3 4source check.vim 5source shared.vim 6source script_util.vim 7 8"------------------------------------------------------------------------------- 9" Test environment {{{1 10"------------------------------------------------------------------------------- 11 12" Append a message to the "messages" file 13func Xout(text) 14 split messages 15 $put =a:text 16 wq 17endfunc 18 19com! -nargs=1 Xout call Xout(<args>) 20 21" Create a new instance of Vim and run the commands in 'test' and then 'verify' 22" The commands in 'test' are expected to store the test results in the Xtest.out 23" file. If the test passes successfully, then Xtest.out should be empty. 24func RunInNewVim(test, verify) 25 let init =<< trim END 26 source script_util.vim 27 XpathINIT 28 XloopINIT 29 END 30 let cleanup =<< trim END 31 call writefile(v:errors, 'Xtest.out') 32 qall 33 END 34 call writefile(init, 'Xtest.vim') 35 call writefile(a:test, 'Xtest.vim', 'a') 36 call writefile(a:verify, 'Xverify.vim') 37 call writefile(cleanup, 'Xverify.vim', 'a') 38 call RunVim([], [], "-S Xtest.vim -S Xverify.vim") 39 call assert_equal([], readfile('Xtest.out')) 40 call delete('Xtest.out') 41 call delete('Xtest.vim') 42 call delete('Xverify.vim') 43endfunc 44 45"------------------------------------------------------------------------------- 46" Test 1: :endwhile in function {{{1 47" 48" Detect if a broken loop is (incorrectly) reactivated by the 49" :endwhile. Use a :return to prevent an endless loop, and make 50" this test first to get a meaningful result on an error before other 51" tests will hang. 52"------------------------------------------------------------------------------- 53 54func T1_F() 55 Xpath 'a' 56 let first = 1 57 while 1 58 Xpath 'b' 59 if first 60 Xpath 'c' 61 let first = 0 62 break 63 else 64 Xpath 'd' 65 return 66 endif 67 endwhile 68endfunc 69 70func T1_G() 71 Xpath 'h' 72 let first = 1 73 while 1 74 Xpath 'i' 75 if first 76 Xpath 'j' 77 let first = 0 78 break 79 else 80 Xpath 'k' 81 return 82 endif 83 if 1 " unmatched :if 84 endwhile 85endfunc 86 87func Test_endwhile_function() 88 XpathINIT 89 call T1_F() 90 Xpath 'F' 91 92 try 93 call T1_G() 94 catch 95 " Catch missing :endif 96 call assert_true(v:exception =~ 'E171') 97 Xpath 'x' 98 endtry 99 Xpath 'G' 100 101 call assert_equal('abcFhijxG', g:Xpath) 102endfunc 103 104"------------------------------------------------------------------------------- 105" Test 2: :endwhile in script {{{1 106" 107" Detect if a broken loop is (incorrectly) reactivated by the 108" :endwhile. Use a :finish to prevent an endless loop, and place 109" this test before others that might hang to get a meaningful result 110" on an error. 111" 112" This test executes the bodies of the functions T1_F and T1_G from 113" the previous test as script files (:return replaced by :finish). 114"------------------------------------------------------------------------------- 115 116func Test_endwhile_script() 117 XpathINIT 118 ExecAsScript T1_F 119 Xpath 'F' 120 call DeleteTheScript() 121 122 try 123 ExecAsScript T1_G 124 catch 125 " Catch missing :endif 126 call assert_true(v:exception =~ 'E171') 127 Xpath 'x' 128 endtry 129 Xpath 'G' 130 call DeleteTheScript() 131 132 call assert_equal('abcFhijxG', g:Xpath) 133endfunc 134 135"------------------------------------------------------------------------------- 136" Test 3: :if, :elseif, :while, :continue, :break {{{1 137"------------------------------------------------------------------------------- 138 139func Test_if_while() 140 XpathINIT 141 if 1 142 Xpath 'a' 143 let loops = 3 144 while loops > -1 " main loop: loops == 3, 2, 1 (which breaks) 145 if loops <= 0 146 let break_err = 1 147 let loops = -1 148 else 149 Xpath 'b' . loops 150 endif 151 if (loops == 2) 152 while loops == 2 " dummy loop 153 Xpath 'c' . loops 154 let loops = loops - 1 155 continue " stop dummy loop 156 Xpath 'd' . loops 157 endwhile 158 continue " continue main loop 159 Xpath 'e' . loops 160 elseif (loops == 1) 161 let p = 1 162 while p " dummy loop 163 Xpath 'f' . loops 164 let p = 0 165 break " break dummy loop 166 Xpath 'g' . loops 167 endwhile 168 Xpath 'h' . loops 169 unlet p 170 break " break main loop 171 Xpath 'i' . loops 172 endif 173 if (loops > 0) 174 Xpath 'j' . loops 175 endif 176 while loops == 3 " dummy loop 177 let loops = loops - 1 178 endwhile " end dummy loop 179 endwhile " end main loop 180 Xpath 'k' 181 else 182 Xpath 'l' 183 endif 184 Xpath 'm' 185 if exists("break_err") 186 Xpath 'm' 187 unlet break_err 188 endif 189 190 unlet loops 191 192 call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath) 193endfunc 194 195"------------------------------------------------------------------------------- 196" Test 4: :return {{{1 197"------------------------------------------------------------------------------- 198 199func T4_F() 200 if 1 201 Xpath 'a' 202 let loops = 3 203 while loops > 0 " 3: 2: 1: 204 Xpath 'b' . loops 205 if (loops == 2) 206 Xpath 'c' . loops 207 return 208 Xpath 'd' . loops 209 endif 210 Xpath 'e' . loops 211 let loops = loops - 1 212 endwhile 213 Xpath 'f' 214 else 215 Xpath 'g' 216 endif 217endfunc 218 219func Test_return() 220 XpathINIT 221 call T4_F() 222 Xpath '4' 223 224 call assert_equal('ab3e3b2c24', g:Xpath) 225endfunc 226 227 228"------------------------------------------------------------------------------- 229" Test 5: :finish {{{1 230" 231" This test executes the body of the function T4_F from the previous 232" test as a script file (:return replaced by :finish). 233"------------------------------------------------------------------------------- 234 235func Test_finish() 236 XpathINIT 237 ExecAsScript T4_F 238 Xpath '5' 239 call DeleteTheScript() 240 241 call assert_equal('ab3e3b2c25', g:Xpath) 242endfunc 243 244 245 246"------------------------------------------------------------------------------- 247" Test 6: Defining functions in :while loops {{{1 248" 249" Functions can be defined inside other functions. An inner function 250" gets defined when the outer function is executed. Functions may 251" also be defined inside while loops. Expressions in braces for 252" defining the function name are allowed. 253" 254" The functions are defined when sourcing the script, only the 255" resulting path is checked in the test function. 256"------------------------------------------------------------------------------- 257 258XpathINIT 259 260" The command CALL collects the argument of all its invocations in "calls" 261" when used from a function (that is, when the global variable "calls" needs 262" the "g:" prefix). This is to check that the function code is skipped when 263" the function is defined. For inner functions, do so only if the outer 264" function is not being executed. 265" 266let calls = "" 267com! -nargs=1 CALL 268 \ if !exists("calls") && !exists("outer") | 269 \ let g:calls = g:calls . <args> | 270 \ endif 271 272let i = 0 273while i < 3 274 let i = i + 1 275 if i == 1 276 Xpath 'a' 277 function! F1(arg) 278 CALL a:arg 279 let outer = 1 280 281 let j = 0 282 while j < 1 283 Xpath 'b' 284 let j = j + 1 285 function! G1(arg) 286 CALL a:arg 287 endfunction 288 Xpath 'c' 289 endwhile 290 endfunction 291 Xpath 'd' 292 293 continue 294 endif 295 296 Xpath 'e' . i 297 function! F{i}(i, arg) 298 CALL a:arg 299 let outer = 1 300 301 if a:i == 3 302 Xpath 'f' 303 endif 304 let k = 0 305 while k < 3 306 Xpath 'g' . k 307 let k = k + 1 308 function! G{a:i}{k}(arg) 309 CALL a:arg 310 endfunction 311 Xpath 'h' . k 312 endwhile 313 endfunction 314 Xpath 'i' 315 316endwhile 317 318if exists("*G1") 319 Xpath 'j' 320endif 321if exists("*F1") 322 call F1("F1") 323 if exists("*G1") 324 call G1("G1") 325 endif 326endif 327 328if exists("G21") || exists("G22") || exists("G23") 329 Xpath 'k' 330endif 331if exists("*F2") 332 call F2(2, "F2") 333 if exists("*G21") 334 call G21("G21") 335 endif 336 if exists("*G22") 337 call G22("G22") 338 endif 339 if exists("*G23") 340 call G23("G23") 341 endif 342endif 343 344if exists("G31") || exists("G32") || exists("G33") 345 Xpath 'l' 346endif 347if exists("*F3") 348 call F3(3, "F3") 349 if exists("*G31") 350 call G31("G31") 351 endif 352 if exists("*G32") 353 call G32("G32") 354 endif 355 if exists("*G33") 356 call G33("G33") 357 endif 358endif 359 360Xpath 'm' 361 362let g:test6_result = g:Xpath 363let g:test6_calls = calls 364 365unlet calls 366delfunction F1 367delfunction G1 368delfunction F2 369delfunction G21 370delfunction G22 371delfunction G23 372delfunction G31 373delfunction G32 374delfunction G33 375 376func Test_defining_functions() 377 call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result) 378 call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls) 379endfunc 380 381"------------------------------------------------------------------------------- 382" Test 7: Continuing on errors outside functions {{{1 383" 384" On an error outside a function, the script processing continues 385" at the line following the outermost :endif or :endwhile. When not 386" inside an :if or :while, the script processing continues at the next 387" line. 388"------------------------------------------------------------------------------- 389 390XpathINIT 391 392if 1 393 Xpath 'a' 394 while 1 395 Xpath 'b' 396 asdf 397 Xpath 'c' 398 break 399 endwhile | Xpath 'd' 400 Xpath 'e' 401endif | Xpath 'f' 402Xpath 'g' 403 404while 1 405 Xpath 'h' 406 if 1 407 Xpath 'i' 408 asdf 409 Xpath 'j' 410 endif | Xpath 'k' 411 Xpath 'l' 412 break 413endwhile | Xpath 'm' 414Xpath 'n' 415 416asdf 417Xpath 'o' 418 419asdf | Xpath 'p' 420Xpath 'q' 421 422let g:test7_result = g:Xpath 423 424func Test_error_in_script() 425 call assert_equal('abghinoq', g:test7_result) 426endfunc 427 428"------------------------------------------------------------------------------- 429" Test 8: Aborting and continuing on errors inside functions {{{1 430" 431" On an error inside a function without the "abort" attribute, the 432" script processing continues at the next line (unless the error was 433" in a :return command). On an error inside a function with the 434" "abort" attribute, the function is aborted and the script processing 435" continues after the function call; the value -1 is returned then. 436"------------------------------------------------------------------------------- 437 438XpathINIT 439 440func T8_F() 441 if 1 442 Xpath 'a' 443 while 1 444 Xpath 'b' 445 asdf 446 Xpath 'c' 447 asdf | Xpath 'd' 448 Xpath 'e' 449 break 450 endwhile 451 Xpath 'f' 452 endif | Xpath 'g' 453 Xpath 'h' 454 455 while 1 456 Xpath 'i' 457 if 1 458 Xpath 'j' 459 asdf 460 Xpath 'k' 461 asdf | Xpath 'l' 462 Xpath 'm' 463 endif 464 Xpath 'n' 465 break 466 endwhile | Xpath 'o' 467 Xpath 'p' 468 469 return novar " returns (default return value 0) 470 Xpath 'q' 471 return 1 " not reached 472endfunc 473 474func T8_G() abort 475 if 1 476 Xpath 'r' 477 while 1 478 Xpath 's' 479 asdf " returns -1 480 Xpath 't' 481 break 482 endwhile 483 Xpath 'v' 484 endif | Xpath 'w' 485 Xpath 'x' 486 487 return -4 " not reached 488endfunc 489 490func T8_H() abort 491 while 1 492 Xpath 'A' 493 if 1 494 Xpath 'B' 495 asdf " returns -1 496 Xpath 'C' 497 endif 498 Xpath 'D' 499 break 500 endwhile | Xpath 'E' 501 Xpath 'F' 502 503 return -4 " not reached 504endfunc 505 506" Aborted functions (T8_G and T8_H) return -1. 507let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H() 508Xpath 'X' 509let g:test8_result = g:Xpath 510 511func Test_error_in_function() 512 call assert_equal(13, g:test8_sum) 513 call assert_equal('abcefghijkmnoprsABX', g:test8_result) 514 515 delfunction T8_F 516 delfunction T8_G 517 delfunction T8_H 518endfunc 519 520 521"------------------------------------------------------------------------------- 522" Test 9: Continuing after aborted functions {{{1 523" 524" When a function with the "abort" attribute is aborted due to an 525" error, the next function back in the call hierarchy without an 526" "abort" attribute continues; the value -1 is returned then. 527"------------------------------------------------------------------------------- 528 529XpathINIT 530 531func F() abort 532 Xpath 'a' 533 let result = G() " not aborted 534 Xpath 'b' 535 if result != 2 536 Xpath 'c' 537 endif 538 return 1 539endfunc 540 541func G() " no abort attribute 542 Xpath 'd' 543 if H() != -1 " aborted 544 Xpath 'e' 545 endif 546 Xpath 'f' 547 return 2 548endfunc 549 550func H() abort 551 Xpath 'g' 552 call I() " aborted 553 Xpath 'h' 554 return 4 555endfunc 556 557func I() abort 558 Xpath 'i' 559 asdf " error 560 Xpath 'j' 561 return 8 562endfunc 563 564if F() != 1 565 Xpath 'k' 566endif 567 568let g:test9_result = g:Xpath 569 570delfunction F 571delfunction G 572delfunction H 573delfunction I 574 575func Test_func_abort() 576 call assert_equal('adgifb', g:test9_result) 577endfunc 578 579 580"------------------------------------------------------------------------------- 581" Test 10: :if, :elseif, :while argument parsing {{{1 582" 583" A '"' or '|' in an argument expression must not be mixed up with 584" a comment or a next command after a bar. Parsing errors should 585" be recognized. 586"------------------------------------------------------------------------------- 587 588XpathINIT 589 590func MSG(enr, emsg) 591 let english = v:lang == "C" || v:lang =~ '^[Ee]n' 592 if a:enr == "" 593 Xout "TODO: Add message number for:" a:emsg 594 let v:errmsg = ":" . v:errmsg 595 endif 596 let match = 1 597 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) 598 let match = 0 599 if v:errmsg == "" 600 Xout "Message missing." 601 else 602 let v:errmsg = v:errmsg->escape('"') 603 Xout "Unexpected message:" v:errmsg 604 endif 605 endif 606 return match 607endfunc 608 609if 1 || strlen("\"") | Xpath 'a' 610 Xpath 'b' 611endif 612Xpath 'c' 613 614if 0 615elseif 1 || strlen("\"") | Xpath 'd' 616 Xpath 'e' 617endif 618Xpath 'f' 619 620while 1 || strlen("\"") | Xpath 'g' 621 Xpath 'h' 622 break 623endwhile 624Xpath 'i' 625 626let v:errmsg = "" 627if 1 ||| strlen("\"") | Xpath 'j' 628 Xpath 'k' 629endif 630Xpath 'l' 631if !MSG('E15', "Invalid expression") 632 Xpath 'm' 633endif 634 635let v:errmsg = "" 636if 0 637elseif 1 ||| strlen("\"") | Xpath 'n' 638 Xpath 'o' 639endif 640Xpath 'p' 641if !MSG('E15', "Invalid expression") 642 Xpath 'q' 643endif 644 645let v:errmsg = "" 646while 1 ||| strlen("\"") | Xpath 'r' 647 Xpath 's' 648 break 649endwhile 650Xpath 't' 651if !MSG('E15', "Invalid expression") 652 Xpath 'u' 653endif 654 655let g:test10_result = g:Xpath 656delfunction MSG 657 658func Test_expr_parsing() 659 call assert_equal('abcdefghilpt', g:test10_result) 660endfunc 661 662 663"------------------------------------------------------------------------------- 664" Test 11: :if, :elseif, :while argument evaluation after abort {{{1 665" 666" When code is skipped over due to an error, the boolean argument to 667" an :if, :elseif, or :while must not be evaluated. 668"------------------------------------------------------------------------------- 669 670XpathINIT 671 672let calls = 0 673 674func P(num) 675 let g:calls = g:calls + a:num " side effect on call 676 return 0 677endfunc 678 679if 1 680 Xpath 'a' 681 asdf " error 682 Xpath 'b' 683 if P(1) " should not be called 684 Xpath 'c' 685 elseif !P(2) " should not be called 686 Xpath 'd' 687 else 688 Xpath 'e' 689 endif 690 Xpath 'f' 691 while P(4) " should not be called 692 Xpath 'g' 693 endwhile 694 Xpath 'h' 695endif 696Xpath 'x' 697 698let g:test11_calls = calls 699let g:test11_result = g:Xpath 700 701unlet calls 702delfunction P 703 704func Test_arg_abort() 705 call assert_equal(0, g:test11_calls) 706 call assert_equal('ax', g:test11_result) 707endfunc 708 709 710"------------------------------------------------------------------------------- 711" Test 12: Expressions in braces in skipped code {{{1 712" 713" In code skipped over due to an error or inactive conditional, 714" an expression in braces as part of a variable or function name 715" should not be evaluated. 716"------------------------------------------------------------------------------- 717 718XpathINIT 719 720function! NULL() 721 Xpath 'a' 722 return 0 723endfunction 724 725function! ZERO() 726 Xpath 'b' 727 return 0 728endfunction 729 730function! F0() 731 Xpath 'c' 732endfunction 733 734function! F1(arg) 735 Xpath 'e' 736endfunction 737 738let V0 = 1 739 740Xpath 'f' 741echo 0 ? F{NULL() + V{ZERO()}}() : 1 742 743Xpath 'g' 744if 0 745 Xpath 'h' 746 call F{NULL() + V{ZERO()}}() 747endif 748 749Xpath 'i' 750if 1 751 asdf " error 752 Xpath 'j' 753 call F1(F{NULL() + V{ZERO()}}()) 754endif 755 756Xpath 'k' 757if 1 758 asdf " error 759 Xpath 'l' 760 call F{NULL() + V{ZERO()}}() 761endif 762 763let g:test12_result = g:Xpath 764 765func Test_braces_skipped() 766 call assert_equal('fgik', g:test12_result) 767endfunc 768 769 770"------------------------------------------------------------------------------- 771" Test 13: Failure in argument evaluation for :while {{{1 772" 773" A failure in the expression evaluation for the condition of a :while 774" causes the whole :while loop until the matching :endwhile being 775" ignored. Continuation is at the next following line. 776"------------------------------------------------------------------------------- 777 778XpathINIT 779 780Xpath 'a' 781while asdf 782 Xpath 'b' 783 while 1 784 Xpath 'c' 785 break 786 endwhile 787 Xpath 'd' 788 break 789endwhile 790Xpath 'e' 791 792while asdf | Xpath 'f' | endwhile | Xpath 'g' 793Xpath 'h' 794let g:test13_result = g:Xpath 795 796func Test_while_fail() 797 call assert_equal('aeh', g:test13_result) 798endfunc 799 800 801"------------------------------------------------------------------------------- 802" Test 14: Failure in argument evaluation for :if {{{1 803" 804" A failure in the expression evaluation for the condition of an :if 805" does not cause the corresponding :else or :endif being matched to 806" a previous :if/:elseif. Neither of both branches of the failed :if 807" are executed. 808"------------------------------------------------------------------------------- 809 810XpathINIT 811 812function! F() 813 Xpath 'a' 814 let x = 0 815 if x " false 816 Xpath 'b' 817 elseif !x " always true 818 Xpath 'c' 819 let x = 1 820 if g:boolvar " possibly undefined 821 Xpath 'd' 822 else 823 Xpath 'e' 824 endif 825 Xpath 'f' 826 elseif x " never executed 827 Xpath 'g' 828 endif 829 Xpath 'h' 830endfunction 831 832let boolvar = 1 833call F() 834Xpath '-' 835 836unlet boolvar 837call F() 838let g:test14_result = g:Xpath 839 840delfunction F 841 842func Test_if_fail() 843 call assert_equal('acdfh-acfh', g:test14_result) 844endfunc 845 846 847"------------------------------------------------------------------------------- 848" Test 15: Failure in argument evaluation for :if (bar) {{{1 849" 850" Like previous test, except that the failing :if ... | ... | :endif 851" is in a single line. 852"------------------------------------------------------------------------------- 853 854XpathINIT 855 856function! F() 857 Xpath 'a' 858 let x = 0 859 if x " false 860 Xpath 'b' 861 elseif !x " always true 862 Xpath 'c' 863 let x = 1 864 if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif 865 Xpath 'f' 866 elseif x " never executed 867 Xpath 'g' 868 endif 869 Xpath 'h' 870endfunction 871 872let boolvar = 1 873call F() 874Xpath '-' 875 876unlet boolvar 877call F() 878let g:test15_result = g:Xpath 879 880delfunction F 881 882func Test_if_bar_fail() 883 call assert_equal('acdfh-acfh', g:test15_result) 884endfunc 885 886"------------------------------------------------------------------------------- 887" Test 16: Double :else or :elseif after :else {{{1 888" 889" Multiple :elses or an :elseif after an :else are forbidden. 890"------------------------------------------------------------------------------- 891 892func T16_F() abort 893 if 0 894 Xpath 'a' 895 else 896 Xpath 'b' 897 else " aborts function 898 Xpath 'c' 899 endif 900 Xpath 'd' 901endfunc 902 903func T16_G() abort 904 if 0 905 Xpath 'a' 906 else 907 Xpath 'b' 908 elseif 1 " aborts function 909 Xpath 'c' 910 else 911 Xpath 'd' 912 endif 913 Xpath 'e' 914endfunc 915 916func T16_H() abort 917 if 0 918 Xpath 'a' 919 elseif 0 920 Xpath 'b' 921 else 922 Xpath 'c' 923 else " aborts function 924 Xpath 'd' 925 endif 926 Xpath 'e' 927endfunc 928 929func T16_I() abort 930 if 0 931 Xpath 'a' 932 elseif 0 933 Xpath 'b' 934 else 935 Xpath 'c' 936 elseif 1 " aborts function 937 Xpath 'd' 938 else 939 Xpath 'e' 940 endif 941 Xpath 'f' 942endfunc 943 944func Test_Multi_Else() 945 XpathINIT 946 try 947 call T16_F() 948 catch /E583:/ 949 Xpath 'e' 950 endtry 951 call assert_equal('be', g:Xpath) 952 953 XpathINIT 954 try 955 call T16_G() 956 catch /E584:/ 957 Xpath 'f' 958 endtry 959 call assert_equal('bf', g:Xpath) 960 961 XpathINIT 962 try 963 call T16_H() 964 catch /E583:/ 965 Xpath 'f' 966 endtry 967 call assert_equal('cf', g:Xpath) 968 969 XpathINIT 970 try 971 call T16_I() 972 catch /E584:/ 973 Xpath 'g' 974 endtry 975 call assert_equal('cg', g:Xpath) 976endfunc 977 978"------------------------------------------------------------------------------- 979" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1 980" 981" The :while/:endwhile takes precedence in nesting over an unclosed 982" :if or an unopened :endif. 983"------------------------------------------------------------------------------- 984 985" While loops inside a function are continued on error. 986func T17_F() 987 let loops = 3 988 while loops > 0 989 let loops -= 1 990 Xpath 'a' . loops 991 if (loops == 1) 992 Xpath 'b' . loops 993 continue 994 elseif (loops == 0) 995 Xpath 'c' . loops 996 break 997 elseif 1 998 Xpath 'd' . loops 999 " endif missing! 1000 endwhile " :endwhile after :if 1 1001 Xpath 'e' 1002endfunc 1003 1004func T17_G() 1005 let loops = 2 1006 while loops > 0 1007 let loops -= 1 1008 Xpath 'a' . loops 1009 if 0 1010 Xpath 'b' . loops 1011 " endif missing 1012 endwhile " :endwhile after :if 0 1013endfunc 1014 1015func T17_H() 1016 let loops = 2 1017 while loops > 0 1018 let loops -= 1 1019 Xpath 'a' . loops 1020 " if missing! 1021 endif " :endif without :if in while 1022 Xpath 'b' . loops 1023 endwhile 1024endfunc 1025 1026" Error continuation outside a function is at the outermost :endwhile or :endif. 1027XpathINIT 1028let v:errmsg = '' 1029let loops = 2 1030while loops > 0 1031 let loops -= 1 1032 Xpath 'a' . loops 1033 if 0 1034 Xpath 'b' . loops 1035 " endif missing! Following :endwhile fails. 1036endwhile | Xpath 'c' 1037Xpath 'd' 1038call assert_match('E171:', v:errmsg) 1039call assert_equal('a1d', g:Xpath) 1040 1041func Test_unmatched_if_in_while() 1042 XpathINIT 1043 call assert_fails('call T17_F()', 'E171:') 1044 call assert_equal('a2d2a1b1a0c0e', g:Xpath) 1045 1046 XpathINIT 1047 call assert_fails('call T17_G()', 'E171:') 1048 call assert_equal('a1a0', g:Xpath) 1049 1050 XpathINIT 1051 call assert_fails('call T17_H()', 'E580:') 1052 call assert_equal('a1b1a0b0', g:Xpath) 1053endfunc 1054 1055"------------------------------------------------------------------------------- 1056" Test 18: Interrupt (Ctrl-C pressed) {{{1 1057" 1058" On an interrupt, the script processing is terminated immediately. 1059"------------------------------------------------------------------------------- 1060 1061func Test_interrupt_while_if() 1062 let test =<< trim [CODE] 1063 try 1064 if 1 1065 Xpath 'a' 1066 while 1 1067 Xpath 'b' 1068 if 1 1069 Xpath 'c' 1070 call interrupt() 1071 call assert_report('should not get here') 1072 break 1073 finish 1074 endif | call assert_report('should not get here') 1075 call assert_report('should not get here') 1076 endwhile | call assert_report('should not get here') 1077 call assert_report('should not get here') 1078 endif | call assert_report('should not get here') 1079 call assert_report('should not get here') 1080 catch /^Vim:Interrupt$/ 1081 Xpath 'd' 1082 endtry | Xpath 'e' 1083 Xpath 'f' 1084 [CODE] 1085 let verify =<< trim [CODE] 1086 call assert_equal('abcdef', g:Xpath) 1087 [CODE] 1088 call RunInNewVim(test, verify) 1089endfunc 1090 1091func Test_interrupt_try() 1092 let test =<< trim [CODE] 1093 try 1094 try 1095 Xpath 'a' 1096 call interrupt() 1097 call assert_report('should not get here') 1098 endtry | call assert_report('should not get here') 1099 call assert_report('should not get here') 1100 catch /^Vim:Interrupt$/ 1101 Xpath 'b' 1102 endtry | Xpath 'c' 1103 Xpath 'd' 1104 [CODE] 1105 let verify =<< trim [CODE] 1106 call assert_equal('abcd', g:Xpath) 1107 [CODE] 1108 call RunInNewVim(test, verify) 1109endfunc 1110 1111func Test_interrupt_func_while_if() 1112 let test =<< trim [CODE] 1113 func F() 1114 if 1 1115 Xpath 'a' 1116 while 1 1117 Xpath 'b' 1118 if 1 1119 Xpath 'c' 1120 call interrupt() 1121 call assert_report('should not get here') 1122 break 1123 return 1124 endif | call assert_report('should not get here') 1125 call assert_report('should not get here') 1126 endwhile | call assert_report('should not get here') 1127 call assert_report('should not get here') 1128 endif | call assert_report('should not get here') 1129 call assert_report('should not get here') 1130 endfunc 1131 1132 Xpath 'd' 1133 try 1134 call F() | call assert_report('should not get here') 1135 catch /^Vim:Interrupt$/ 1136 Xpath 'e' 1137 endtry | Xpath 'f' 1138 Xpath 'g' 1139 [CODE] 1140 let verify =<< trim [CODE] 1141 call assert_equal('dabcefg', g:Xpath) 1142 [CODE] 1143 call RunInNewVim(test, verify) 1144endfunc 1145 1146func Test_interrupt_func_try() 1147 let test =<< trim [CODE] 1148 func G() 1149 try 1150 Xpath 'a' 1151 call interrupt() 1152 call assert_report('should not get here') 1153 endtry | call assert_report('should not get here') 1154 call assert_report('should not get here') 1155 endfunc 1156 1157 Xpath 'b' 1158 try 1159 call G() | call assert_report('should not get here') 1160 catch /^Vim:Interrupt$/ 1161 Xpath 'c' 1162 endtry | Xpath 'd' 1163 Xpath 'e' 1164 [CODE] 1165 let verify =<< trim [CODE] 1166 call assert_equal('bacde', g:Xpath) 1167 [CODE] 1168 call RunInNewVim(test, verify) 1169endfunc 1170 1171"------------------------------------------------------------------------------- 1172" Test 19: Aborting on errors inside :try/:endtry {{{1 1173" 1174" An error in a command dynamically enclosed in a :try/:endtry region 1175" aborts script processing immediately. It does not matter whether 1176" the failing command is outside or inside a function and whether a 1177" function has an "abort" attribute. 1178"------------------------------------------------------------------------------- 1179 1180func Test_try_error_abort_1() 1181 let test =<< trim [CODE] 1182 func F() abort 1183 Xpath 'a' 1184 asdf 1185 call assert_report('should not get here') 1186 endfunc 1187 1188 try 1189 Xpath 'b' 1190 call F() 1191 call assert_report('should not get here') 1192 endtry | call assert_report('should not get here') 1193 call assert_report('should not get here') 1194 [CODE] 1195 let verify =<< trim [CODE] 1196 call assert_equal('ba', g:Xpath) 1197 [CODE] 1198 call RunInNewVim(test, verify) 1199endfunc 1200 1201func Test_try_error_abort_2() 1202 let test =<< trim [CODE] 1203 func G() 1204 Xpath 'a' 1205 asdf 1206 call assert_report('should not get here') 1207 endfunc 1208 1209 try 1210 Xpath 'b' 1211 call G() 1212 call assert_report('should not get here') 1213 endtry | call assert_report('should not get here') 1214 call assert_report('should not get here') 1215 [CODE] 1216 let verify =<< trim [CODE] 1217 call assert_equal('ba', g:Xpath) 1218 [CODE] 1219 call RunInNewVim(test, verify) 1220endfunc 1221 1222func Test_try_error_abort_3() 1223 let test =<< trim [CODE] 1224 try 1225 Xpath 'a' 1226 asdf 1227 call assert_report('should not get here') 1228 endtry | call assert_report('should not get here') 1229 call assert_report('should not get here') 1230 [CODE] 1231 let verify =<< trim [CODE] 1232 call assert_equal('a', g:Xpath) 1233 [CODE] 1234 call RunInNewVim(test, verify) 1235endfunc 1236 1237func Test_try_error_abort_4() 1238 let test =<< trim [CODE] 1239 if 1 1240 try 1241 Xpath 'a' 1242 asdf 1243 call assert_report('should not get here') 1244 endtry | call assert_report('should not get here') 1245 endif | call assert_report('should not get here') 1246 call assert_report('should not get here') 1247 [CODE] 1248 let verify =<< trim [CODE] 1249 call assert_equal('a', g:Xpath) 1250 [CODE] 1251 call RunInNewVim(test, verify) 1252endfunc 1253 1254func Test_try_error_abort_5() 1255 let test =<< trim [CODE] 1256 let p = 1 1257 while p 1258 let p = 0 1259 try 1260 Xpath 'a' 1261 asdf 1262 call assert_report('should not get here') 1263 endtry | call assert_report('should not get here') 1264 endwhile | call assert_report('should not get here') 1265 call assert_report('should not get here') 1266 [CODE] 1267 let verify =<< trim [CODE] 1268 call assert_equal('a', g:Xpath) 1269 [CODE] 1270 call RunInNewVim(test, verify) 1271endfunc 1272 1273func Test_try_error_abort_6() 1274 let test =<< trim [CODE] 1275 let p = 1 1276 Xpath 'a' 1277 while p 1278 Xpath 'b' 1279 let p = 0 1280 try 1281 Xpath 'c' 1282 endwhile | call assert_report('should not get here') 1283 call assert_report('should not get here') 1284 [CODE] 1285 let verify =<< trim [CODE] 1286 call assert_equal('abc', g:Xpath) 1287 [CODE] 1288 call RunInNewVim(test, verify) 1289endfunc 1290 1291"------------------------------------------------------------------------------- 1292" Test 20: Aborting on errors after :try/:endtry {{{1 1293" 1294" When an error occurs after the last active :try/:endtry region has 1295" been left, termination behavior is as if no :try/:endtry has been 1296" seen. 1297"------------------------------------------------------------------------------- 1298 1299func Test_error_after_try_1() 1300 let test =<< trim [CODE] 1301 let p = 1 1302 while p 1303 let p = 0 1304 Xpath 'a' 1305 try 1306 Xpath 'b' 1307 endtry 1308 asdf 1309 call assert_report('should not get here') 1310 endwhile | call assert_report('should not get here') 1311 Xpath 'c' 1312 [CODE] 1313 let verify =<< trim [CODE] 1314 call assert_equal('abc', g:Xpath) 1315 [CODE] 1316 call RunInNewVim(test, verify) 1317endfunc 1318 1319func Test_error_after_try_2() 1320 let test =<< trim [CODE] 1321 while 1 1322 try 1323 Xpath 'a' 1324 break 1325 call assert_report('should not get here') 1326 endtry 1327 endwhile 1328 Xpath 'b' 1329 asdf 1330 Xpath 'c' 1331 [CODE] 1332 let verify =<< trim [CODE] 1333 call assert_equal('abc', g:Xpath) 1334 [CODE] 1335 call RunInNewVim(test, verify) 1336endfunc 1337 1338func Test_error_after_try_3() 1339 let test =<< trim [CODE] 1340 while 1 1341 try 1342 Xpath 'a' 1343 break 1344 call assert_report('should not get here') 1345 finally 1346 Xpath 'b' 1347 endtry 1348 endwhile 1349 Xpath 'c' 1350 asdf 1351 Xpath 'd' 1352 [CODE] 1353 let verify =<< trim [CODE] 1354 call assert_equal('abcd', g:Xpath) 1355 [CODE] 1356 call RunInNewVim(test, verify) 1357endfunc 1358 1359func Test_error_after_try_4() 1360 let test =<< trim [CODE] 1361 while 1 1362 try 1363 Xpath 'a' 1364 finally 1365 Xpath 'b' 1366 break 1367 call assert_report('should not get here') 1368 endtry 1369 endwhile 1370 Xpath 'c' 1371 asdf 1372 Xpath 'd' 1373 [CODE] 1374 let verify =<< trim [CODE] 1375 call assert_equal('abcd', g:Xpath) 1376 [CODE] 1377 call RunInNewVim(test, verify) 1378endfunc 1379 1380func Test_error_after_try_5() 1381 let test =<< trim [CODE] 1382 let p = 1 1383 while p 1384 let p = 0 1385 try 1386 Xpath 'a' 1387 continue 1388 call assert_report('should not get here') 1389 endtry 1390 endwhile 1391 Xpath 'b' 1392 asdf 1393 Xpath 'c' 1394 [CODE] 1395 let verify =<< trim [CODE] 1396 call assert_equal('abc', g:Xpath) 1397 [CODE] 1398 call RunInNewVim(test, verify) 1399endfunc 1400 1401func Test_error_after_try_6() 1402 let test =<< trim [CODE] 1403 let p = 1 1404 while p 1405 let p = 0 1406 try 1407 Xpath 'a' 1408 continue 1409 call assert_report('should not get here') 1410 finally 1411 Xpath 'b' 1412 endtry 1413 endwhile 1414 Xpath 'c' 1415 asdf 1416 Xpath 'd' 1417 [CODE] 1418 let verify =<< trim [CODE] 1419 call assert_equal('abcd', g:Xpath) 1420 [CODE] 1421 call RunInNewVim(test, verify) 1422endfunc 1423 1424func Test_error_after_try_7() 1425 let test =<< trim [CODE] 1426 let p = 1 1427 while p 1428 let p = 0 1429 try 1430 Xpath 'a' 1431 finally 1432 Xpath 'b' 1433 continue 1434 call assert_report('should not get here') 1435 endtry 1436 endwhile 1437 Xpath 'c' 1438 asdf 1439 Xpath 'd' 1440 [CODE] 1441 let verify =<< trim [CODE] 1442 call assert_equal('abcd', g:Xpath) 1443 [CODE] 1444 call RunInNewVim(test, verify) 1445endfunc 1446 1447"------------------------------------------------------------------------------- 1448" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1 1449" 1450" If a :try conditional stays inactive due to a preceding :continue, 1451" :break, :return, or :finish, its :finally clause should not be 1452" executed. 1453"------------------------------------------------------------------------------- 1454 1455func Test_finally_after_loop_ctrl_statement() 1456 let test =<< trim [CODE] 1457 func F() 1458 let loops = 2 1459 while loops > 0 1460 XloopNEXT 1461 let loops = loops - 1 1462 try 1463 if loops == 1 1464 Xloop 'a' 1465 continue 1466 call assert_report('should not get here') 1467 elseif loops == 0 1468 Xloop 'b' 1469 break 1470 call assert_report('should not get here') 1471 endif 1472 1473 try " inactive 1474 call assert_report('should not get here') 1475 finally 1476 call assert_report('should not get here') 1477 endtry 1478 finally 1479 Xloop 'c' 1480 endtry 1481 call assert_report('should not get here') 1482 endwhile 1483 1484 try 1485 Xpath 'd' 1486 return 1487 call assert_report('should not get here') 1488 try " inactive 1489 call assert_report('should not get here') 1490 finally 1491 call assert_report('should not get here') 1492 endtry 1493 finally 1494 Xpath 'e' 1495 endtry 1496 call assert_report('should not get here') 1497 endfunc 1498 1499 try 1500 Xpath 'f' 1501 call F() 1502 Xpath 'g' 1503 finish 1504 call assert_report('should not get here') 1505 try " inactive 1506 call assert_report('should not get here') 1507 finally 1508 call assert_report('should not get here') 1509 endtry 1510 finally 1511 Xpath 'h' 1512 endtry 1513 call assert_report('should not get here') 1514 [CODE] 1515 let verify =<< trim [CODE] 1516 call assert_equal('fa2c2b3c3degh', g:Xpath) 1517 [CODE] 1518 call RunInNewVim(test, verify) 1519endfunc 1520 1521"------------------------------------------------------------------------------- 1522" Test 22: :finally for a :try after an error/interrupt/:throw {{{1 1523" 1524" If a :try conditional stays inactive due to a preceding error or 1525" interrupt or :throw, its :finally clause should not be executed. 1526"------------------------------------------------------------------------------- 1527 1528func Test_finally_after_error_in_func() 1529 let test =<< trim [CODE] 1530 func Error() 1531 try 1532 Xpath 'b' 1533 asdf " aborting error, triggering error exception 1534 call assert_report('should not get here') 1535 endtry 1536 call assert_report('should not get here') 1537 endfunc 1538 1539 Xpath 'a' 1540 call Error() 1541 call assert_report('should not get here') 1542 1543 if 1 " not active due to error 1544 try " not active since :if inactive 1545 call assert_report('should not get here') 1546 finally 1547 call assert_report('should not get here') 1548 endtry 1549 endif 1550 1551 try " not active due to error 1552 call assert_report('should not get here') 1553 finally 1554 call assert_report('should not get here') 1555 endtry 1556 [CODE] 1557 let verify =<< trim [CODE] 1558 call assert_equal('ab', g:Xpath) 1559 [CODE] 1560 call RunInNewVim(test, verify) 1561endfunc 1562 1563func Test_finally_after_interrupt() 1564 let test =<< trim [CODE] 1565 func Interrupt() 1566 try 1567 Xpath 'a' 1568 call interrupt() " triggering interrupt exception 1569 call assert_report('should not get here') 1570 endtry 1571 endfunc 1572 1573 Xpath 'b' 1574 try 1575 call Interrupt() 1576 catch /^Vim:Interrupt$/ 1577 Xpath 'c' 1578 finish 1579 endtry 1580 call assert_report('should not get here') 1581 1582 if 1 " not active due to interrupt 1583 try " not active since :if inactive 1584 call assert_report('should not get here') 1585 finally 1586 call assert_report('should not get here') 1587 endtry 1588 endif 1589 1590 try " not active due to interrupt 1591 call assert_report('should not get here') 1592 finally 1593 call assert_report('should not get here') 1594 endtry 1595 [CODE] 1596 let verify =<< trim [CODE] 1597 call assert_equal('bac', g:Xpath) 1598 [CODE] 1599 call RunInNewVim(test, verify) 1600endfunc 1601 1602func Test_finally_after_throw() 1603 let test =<< trim [CODE] 1604 func Throw() 1605 Xpath 'a' 1606 throw 'xyz' 1607 endfunc 1608 1609 Xpath 'b' 1610 call Throw() 1611 call assert_report('should not get here') 1612 1613 if 1 " not active due to :throw 1614 try " not active since :if inactive 1615 call assert_report('should not get here') 1616 finally 1617 call assert_report('should not get here') 1618 endtry 1619 endif 1620 1621 try " not active due to :throw 1622 call assert_report('should not get here') 1623 finally 1624 call assert_report('should not get here') 1625 endtry 1626 [CODE] 1627 let verify =<< trim [CODE] 1628 call assert_equal('ba', g:Xpath) 1629 [CODE] 1630 call RunInNewVim(test, verify) 1631endfunc 1632 1633"------------------------------------------------------------------------------- 1634" Test 23: :catch clauses for a :try after a :throw {{{1 1635" 1636" If a :try conditional stays inactive due to a preceding :throw, 1637" none of its :catch clauses should be executed. 1638"------------------------------------------------------------------------------- 1639 1640func Test_catch_after_throw() 1641 let test =<< trim [CODE] 1642 try 1643 Xpath 'a' 1644 throw "xyz" 1645 call assert_report('should not get here') 1646 1647 if 1 " not active due to :throw 1648 try " not active since :if inactive 1649 call assert_report('should not get here') 1650 catch /xyz/ 1651 call assert_report('should not get here') 1652 endtry 1653 endif 1654 catch /xyz/ 1655 Xpath 'b' 1656 endtry 1657 1658 Xpath 'c' 1659 throw "abc" 1660 call assert_report('should not get here') 1661 1662 try " not active due to :throw 1663 call assert_report('should not get here') 1664 catch /abc/ 1665 call assert_report('should not get here') 1666 endtry 1667 [CODE] 1668 let verify =<< trim [CODE] 1669 call assert_equal('abc', g:Xpath) 1670 [CODE] 1671 call RunInNewVim(test, verify) 1672endfunc 1673 1674"------------------------------------------------------------------------------- 1675" Test 24: :endtry for a :try after a :throw {{{1 1676" 1677" If a :try conditional stays inactive due to a preceding :throw, 1678" its :endtry should not rethrow the exception to the next surrounding 1679" active :try conditional. 1680"------------------------------------------------------------------------------- 1681 1682func Test_endtry_after_throw() 1683 let test =<< trim [CODE] 1684 try " try 1 1685 try " try 2 1686 Xpath 'a' 1687 throw "xyz" " makes try 2 inactive 1688 call assert_report('should not get here') 1689 1690 try " try 3 1691 call assert_report('should not get here') 1692 endtry " no rethrow to try 1 1693 catch /xyz/ " should catch although try 2 inactive 1694 Xpath 'b' 1695 endtry 1696 catch /xyz/ " try 1 active, but exception already caught 1697 call assert_report('should not get here') 1698 endtry 1699 Xpath 'c' 1700 [CODE] 1701 let verify =<< trim [CODE] 1702 call assert_equal('abc', g:Xpath) 1703 [CODE] 1704 call RunInNewVim(test, verify) 1705endfunc 1706 1707"------------------------------------------------------------------------------- 1708" Test 27: Executing :finally clauses after :return {{{1 1709" 1710" For a :return command dynamically enclosed in a :try/:endtry region, 1711" :finally clauses are executed and the called function is ended. 1712"------------------------------------------------------------------------------- 1713 1714func T27_F() 1715 try 1716 Xpath 'a' 1717 try 1718 Xpath 'b' 1719 return 1720 call assert_report('should not get here') 1721 finally 1722 Xpath 'c' 1723 endtry 1724 Xpath 'd' 1725 finally 1726 Xpath 'e' 1727 endtry 1728 call assert_report('should not get here') 1729endfunc 1730 1731func T27_G() 1732 try 1733 Xpath 'f' 1734 return 1735 call assert_report('should not get here') 1736 finally 1737 Xpath 'g' 1738 call T27_F() 1739 Xpath 'h' 1740 endtry 1741 call assert_report('should not get here') 1742endfunc 1743 1744func T27_H() 1745 try 1746 Xpath 'i' 1747 call T27_G() 1748 Xpath 'j' 1749 finally 1750 Xpath 'k' 1751 return 1752 call assert_report('should not get here') 1753 endtry 1754 call assert_report('should not get here') 1755endfunction 1756 1757func Test_finally_after_return() 1758 XpathINIT 1759 try 1760 Xpath 'l' 1761 call T27_H() 1762 Xpath 'm' 1763 finally 1764 Xpath 'n' 1765 endtry 1766 call assert_equal('lifgabcehjkmn', g:Xpath) 1767endfunc 1768 1769"------------------------------------------------------------------------------- 1770" Test 28: Executing :finally clauses after :finish {{{1 1771" 1772" For a :finish command dynamically enclosed in a :try/:endtry region, 1773" :finally clauses are executed and the sourced file is finished. 1774" 1775" This test executes the bodies of the functions F, G, and H from the 1776" previous test as script files (:return replaced by :finish). 1777"------------------------------------------------------------------------------- 1778 1779func Test_finally_after_finish() 1780 XpathINIT 1781 1782 let scriptF = MakeScript("T27_F") 1783 let scriptG = MakeScript("T27_G", scriptF) 1784 let scriptH = MakeScript("T27_H", scriptG) 1785 1786 try 1787 Xpath 'A' 1788 exec "source" scriptH 1789 Xpath 'B' 1790 finally 1791 Xpath 'C' 1792 endtry 1793 Xpath 'D' 1794 call assert_equal('AifgabcehjkBCD', g:Xpath) 1795 call delete(scriptF) 1796 call delete(scriptG) 1797 call delete(scriptH) 1798endfunc 1799 1800"------------------------------------------------------------------------------- 1801" Test 29: Executing :finally clauses on errors {{{1 1802" 1803" After an error in a command dynamically enclosed in a :try/:endtry 1804" region, :finally clauses are executed and the script processing is 1805" terminated. 1806"------------------------------------------------------------------------------- 1807 1808func Test_finally_after_error_1() 1809 let test =<< trim [CODE] 1810 func F() 1811 while 1 1812 try 1813 Xpath 'a' 1814 while 1 1815 try 1816 Xpath 'b' 1817 asdf " error 1818 call assert_report('should not get here') 1819 finally 1820 Xpath 'c' 1821 endtry | call assert_report('should not get here') 1822 call assert_report('should not get here') 1823 break 1824 endwhile 1825 call assert_report('should not get here') 1826 finally 1827 Xpath 'd' 1828 endtry | call assert_report('should not get here') 1829 call assert_report('should not get here') 1830 break 1831 endwhile 1832 call assert_report('should not get here') 1833 endfunc 1834 1835 while 1 1836 try 1837 Xpath 'e' 1838 while 1 1839 call F() 1840 call assert_report('should not get here') 1841 break 1842 endwhile | call assert_report('should not get here') 1843 call assert_report('should not get here') 1844 finally 1845 Xpath 'f' 1846 endtry | call assert_report('should not get here') 1847 endwhile | call assert_report('should not get here') 1848 call assert_report('should not get here') 1849 [CODE] 1850 let verify =<< trim [CODE] 1851 call assert_equal('eabcdf', g:Xpath) 1852 [CODE] 1853 call RunInNewVim(test, verify) 1854endfunc 1855 1856func Test_finally_after_error_2() 1857 let test =<< trim [CODE] 1858 func G() abort 1859 if 1 1860 try 1861 Xpath 'a' 1862 asdf " error 1863 call assert_report('should not get here') 1864 finally 1865 Xpath 'b' 1866 endtry | Xpath 'c' 1867 endif | Xpath 'd' 1868 call assert_report('should not get here') 1869 endfunc 1870 1871 if 1 1872 try 1873 Xpath 'e' 1874 call G() 1875 call assert_report('should not get here') 1876 finally 1877 Xpath 'f' 1878 endtry | call assert_report('should not get here') 1879 endif | call assert_report('should not get here') 1880 call assert_report('should not get here') 1881 [CODE] 1882 let verify =<< trim [CODE] 1883 call assert_equal('eabf', g:Xpath) 1884 [CODE] 1885 call RunInNewVim(test, verify) 1886endfunc 1887 1888"------------------------------------------------------------------------------- 1889" Test 30: Executing :finally clauses on interrupt {{{1 1890" 1891" After an interrupt in a command dynamically enclosed in 1892" a :try/:endtry region, :finally clauses are executed and the 1893" script processing is terminated. 1894"------------------------------------------------------------------------------- 1895 1896func Test_finally_on_interrupt() 1897 let test =<< trim [CODE] 1898 func F() 1899 try 1900 Xloop 'a' 1901 call interrupt() 1902 call assert_report('should not get here') 1903 finally 1904 Xloop 'b' 1905 endtry 1906 call assert_report('should not get here') 1907 endfunc 1908 1909 try 1910 try 1911 Xpath 'c' 1912 try 1913 Xpath 'd' 1914 call interrupt() 1915 call assert_report('should not get here') 1916 finally 1917 Xpath 'e' 1918 try 1919 Xpath 'f' 1920 try 1921 Xpath 'g' 1922 finally 1923 Xpath 'h' 1924 try 1925 Xpath 'i' 1926 call interrupt() 1927 call assert_report('should not get here') 1928 endtry 1929 call assert_report('should not get here') 1930 endtry 1931 call assert_report('should not get here') 1932 endtry 1933 call assert_report('should not get here') 1934 endtry 1935 call assert_report('should not get here') 1936 finally 1937 Xpath 'j' 1938 try 1939 Xpath 'k' 1940 call F() 1941 call assert_report('should not get here') 1942 finally 1943 Xpath 'l' 1944 try 1945 Xpath 'm' 1946 XloopNEXT 1947 ExecAsScript F 1948 call assert_report('should not get here') 1949 finally 1950 Xpath 'n' 1951 endtry 1952 call assert_report('should not get here') 1953 endtry 1954 call assert_report('should not get here') 1955 endtry 1956 call assert_report('should not get here') 1957 catch /^Vim:Interrupt$/ 1958 Xpath 'o' 1959 endtry 1960 [CODE] 1961 let verify =<< trim [CODE] 1962 call assert_equal('cdefghijka1b1lma2b2no', g:Xpath) 1963 [CODE] 1964 call RunInNewVim(test, verify) 1965endfunc 1966 1967"------------------------------------------------------------------------------- 1968" Test 31: Executing :finally clauses after :throw {{{1 1969" 1970" After a :throw dynamically enclosed in a :try/:endtry region, 1971" :finally clauses are executed and the script processing is 1972" terminated. 1973"------------------------------------------------------------------------------- 1974 1975func Test_finally_after_throw_2() 1976 let test =<< trim [CODE] 1977 func F() 1978 try 1979 Xloop 'a' 1980 throw "exception" 1981 call assert_report('should not get here') 1982 finally 1983 Xloop 'b' 1984 endtry 1985 call assert_report('should not get here') 1986 endfunc 1987 1988 try 1989 Xpath 'c' 1990 try 1991 Xpath 'd' 1992 throw "exception" 1993 call assert_report('should not get here') 1994 finally 1995 Xpath 'e' 1996 try 1997 Xpath 'f' 1998 try 1999 Xpath 'g' 2000 finally 2001 Xpath 'h' 2002 try 2003 Xpath 'i' 2004 throw "exception" 2005 call assert_report('should not get here') 2006 endtry 2007 call assert_report('should not get here') 2008 endtry 2009 call assert_report('should not get here') 2010 endtry 2011 call assert_report('should not get here') 2012 endtry 2013 call assert_report('should not get here') 2014 finally 2015 Xpath 'j' 2016 try 2017 Xpath 'k' 2018 call F() 2019 call assert_report('should not get here') 2020 finally 2021 Xpath 'l' 2022 try 2023 Xpath 'm' 2024 XloopNEXT 2025 ExecAsScript F 2026 call assert_report('should not get here') 2027 finally 2028 Xpath 'n' 2029 endtry 2030 call assert_report('should not get here') 2031 endtry 2032 call assert_report('should not get here') 2033 endtry 2034 call assert_report('should not get here') 2035 [CODE] 2036 let verify =<< trim [CODE] 2037 call assert_equal('cdefghijka1b1lma2b2n', g:Xpath) 2038 [CODE] 2039 call RunInNewVim(test, verify) 2040endfunc 2041 2042"------------------------------------------------------------------------------- 2043" Test 34: :finally reason discarded by :continue {{{1 2044" 2045" When a :finally clause is executed due to a :continue, :break, 2046" :return, :finish, error, interrupt or :throw, the jump reason is 2047" discarded by a :continue in the finally clause. 2048"------------------------------------------------------------------------------- 2049 2050func Test_finally_after_continue() 2051 let test =<< trim [CODE] 2052 func C(jump) 2053 XloopNEXT 2054 let loop = 0 2055 while loop < 2 2056 let loop = loop + 1 2057 if loop == 1 2058 try 2059 if a:jump == "continue" 2060 continue 2061 elseif a:jump == "break" 2062 break 2063 elseif a:jump == "return" || a:jump == "finish" 2064 return 2065 elseif a:jump == "error" 2066 asdf 2067 elseif a:jump == "interrupt" 2068 call interrupt() 2069 let dummy = 0 2070 elseif a:jump == "throw" 2071 throw "abc" 2072 endif 2073 finally 2074 continue " discards jump that caused the :finally 2075 call assert_report('should not get here') 2076 endtry 2077 call assert_report('should not get here') 2078 elseif loop == 2 2079 Xloop 'a' 2080 endif 2081 endwhile 2082 endfunc 2083 2084 call C("continue") 2085 Xpath 'b' 2086 call C("break") 2087 Xpath 'c' 2088 call C("return") 2089 Xpath 'd' 2090 let g:jump = "finish" 2091 ExecAsScript C 2092 unlet g:jump 2093 Xpath 'e' 2094 try 2095 call C("error") 2096 Xpath 'f' 2097 finally 2098 Xpath 'g' 2099 try 2100 call C("interrupt") 2101 Xpath 'h' 2102 finally 2103 Xpath 'i' 2104 call C("throw") 2105 Xpath 'j' 2106 endtry 2107 endtry 2108 Xpath 'k' 2109 [CODE] 2110 let verify =<< trim [CODE] 2111 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) 2112 [CODE] 2113 call RunInNewVim(test, verify) 2114endfunc 2115 2116"------------------------------------------------------------------------------- 2117" Test 35: :finally reason discarded by :break {{{1 2118" 2119" When a :finally clause is executed due to a :continue, :break, 2120" :return, :finish, error, interrupt or :throw, the jump reason is 2121" discarded by a :break in the finally clause. 2122"------------------------------------------------------------------------------- 2123 2124func Test_finally_discard_by_break() 2125 let test =<< trim [CODE] 2126 func B(jump) 2127 XloopNEXT 2128 let loop = 0 2129 while loop < 2 2130 let loop = loop + 1 2131 if loop == 1 2132 try 2133 if a:jump == "continue" 2134 continue 2135 elseif a:jump == "break" 2136 break 2137 elseif a:jump == "return" || a:jump == "finish" 2138 return 2139 elseif a:jump == "error" 2140 asdf 2141 elseif a:jump == "interrupt" 2142 call interrupt() 2143 let dummy = 0 2144 elseif a:jump == "throw" 2145 throw "abc" 2146 endif 2147 finally 2148 break " discards jump that caused the :finally 2149 call assert_report('should not get here') 2150 endtry 2151 elseif loop == 2 2152 call assert_report('should not get here') 2153 endif 2154 endwhile 2155 Xloop 'a' 2156 endfunc 2157 2158 call B("continue") 2159 Xpath 'b' 2160 call B("break") 2161 Xpath 'c' 2162 call B("return") 2163 Xpath 'd' 2164 let g:jump = "finish" 2165 ExecAsScript B 2166 unlet g:jump 2167 Xpath 'e' 2168 try 2169 call B("error") 2170 Xpath 'f' 2171 finally 2172 Xpath 'g' 2173 try 2174 call B("interrupt") 2175 Xpath 'h' 2176 finally 2177 Xpath 'i' 2178 call B("throw") 2179 Xpath 'j' 2180 endtry 2181 endtry 2182 Xpath 'k' 2183 [CODE] 2184 let verify =<< trim [CODE] 2185 call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath) 2186 [CODE] 2187 call RunInNewVim(test, verify) 2188endfunc 2189 2190"------------------------------------------------------------------------------- 2191" Test 36: :finally reason discarded by :return {{{1 2192" 2193" When a :finally clause is executed due to a :continue, :break, 2194" :return, :finish, error, interrupt or :throw, the jump reason is 2195" discarded by a :return in the finally clause. 2196"------------------------------------------------------------------------------- 2197 2198func Test_finally_discard_by_return() 2199 let test =<< trim [CODE] 2200 func R(jump, retval) abort 2201 let loop = 0 2202 while loop < 2 2203 let loop = loop + 1 2204 if loop == 1 2205 try 2206 if a:jump == "continue" 2207 continue 2208 elseif a:jump == "break" 2209 break 2210 elseif a:jump == "return" 2211 return 2212 elseif a:jump == "error" 2213 asdf 2214 elseif a:jump == "interrupt" 2215 call interrupt() 2216 let dummy = 0 2217 elseif a:jump == "throw" 2218 throw "abc" 2219 endif 2220 finally 2221 return a:retval " discards jump that caused the :finally 2222 call assert_report('should not get here') 2223 endtry 2224 elseif loop == 2 2225 call assert_report('should not get here') 2226 endif 2227 endwhile 2228 call assert_report('should not get here') 2229 endfunc 2230 2231 let sum = -R("continue", -8) 2232 Xpath 'a' 2233 let sum = sum - R("break", -16) 2234 Xpath 'b' 2235 let sum = sum - R("return", -32) 2236 Xpath 'c' 2237 try 2238 let sum = sum - R("error", -64) 2239 Xpath 'd' 2240 finally 2241 Xpath 'e' 2242 try 2243 let sum = sum - R("interrupt", -128) 2244 Xpath 'f' 2245 finally 2246 Xpath 'g' 2247 let sum = sum - R("throw", -256) 2248 Xpath 'h' 2249 endtry 2250 endtry 2251 Xpath 'i' 2252 2253 let expected = 8 + 16 + 32 + 64 + 128 + 256 2254 call assert_equal(sum, expected) 2255 [CODE] 2256 let verify =<< trim [CODE] 2257 call assert_equal('abcdefghi', g:Xpath) 2258 [CODE] 2259 call RunInNewVim(test, verify) 2260endfunc 2261 2262"------------------------------------------------------------------------------- 2263" Test 37: :finally reason discarded by :finish {{{1 2264" 2265" When a :finally clause is executed due to a :continue, :break, 2266" :return, :finish, error, interrupt or :throw, the jump reason is 2267" discarded by a :finish in the finally clause. 2268"------------------------------------------------------------------------------- 2269 2270func Test_finally_discard_by_finish() 2271 let test =<< trim [CODE] 2272 func F(jump) " not executed as function, transformed to a script 2273 let loop = 0 2274 while loop < 2 2275 let loop = loop + 1 2276 if loop == 1 2277 try 2278 if a:jump == "continue" 2279 continue 2280 elseif a:jump == "break" 2281 break 2282 elseif a:jump == "finish" 2283 finish 2284 elseif a:jump == "error" 2285 asdf 2286 elseif a:jump == "interrupt" 2287 call interrupt() 2288 let dummy = 0 2289 elseif a:jump == "throw" 2290 throw "abc" 2291 endif 2292 finally 2293 finish " discards jump that caused the :finally 2294 call assert_report('should not get here') 2295 endtry 2296 elseif loop == 2 2297 call assert_report('should not get here') 2298 endif 2299 endwhile 2300 call assert_report('should not get here') 2301 endfunc 2302 2303 let scriptF = MakeScript("F") 2304 delfunction F 2305 2306 let g:jump = "continue" 2307 exec "source" scriptF 2308 Xpath 'a' 2309 let g:jump = "break" 2310 exec "source" scriptF 2311 Xpath 'b' 2312 let g:jump = "finish" 2313 exec "source" scriptF 2314 Xpath 'c' 2315 try 2316 let g:jump = "error" 2317 exec "source" scriptF 2318 Xpath 'd' 2319 finally 2320 Xpath 'e' 2321 try 2322 let g:jump = "interrupt" 2323 exec "source" scriptF 2324 Xpath 'f' 2325 finally 2326 Xpath 'g' 2327 try 2328 let g:jump = "throw" 2329 exec "source" scriptF 2330 Xpath 'h' 2331 finally 2332 Xpath 'i' 2333 endtry 2334 endtry 2335 endtry 2336 unlet g:jump 2337 call delete(scriptF) 2338 [CODE] 2339 let verify =<< trim [CODE] 2340 call assert_equal('abcdefghi', g:Xpath) 2341 [CODE] 2342 call RunInNewVim(test, verify) 2343endfunc 2344 2345"------------------------------------------------------------------------------- 2346" Test 38: :finally reason discarded by an error {{{1 2347" 2348" When a :finally clause is executed due to a :continue, :break, 2349" :return, :finish, error, interrupt or :throw, the jump reason is 2350" discarded by an error in the finally clause. 2351"------------------------------------------------------------------------------- 2352 2353func Test_finally_discard_by_error() 2354 let test =<< trim [CODE] 2355 func E(jump) 2356 let loop = 0 2357 while loop < 2 2358 let loop = loop + 1 2359 if loop == 1 2360 try 2361 if a:jump == "continue" 2362 continue 2363 elseif a:jump == "break" 2364 break 2365 elseif a:jump == "return" || a:jump == "finish" 2366 return 2367 elseif a:jump == "error" 2368 asdf 2369 elseif a:jump == "interrupt" 2370 call interrupt() 2371 let dummy = 0 2372 elseif a:jump == "throw" 2373 throw "abc" 2374 endif 2375 finally 2376 asdf " error; discards jump that caused the :finally 2377 endtry 2378 elseif loop == 2 2379 call assert_report('should not get here') 2380 endif 2381 endwhile 2382 call assert_report('should not get here') 2383 endfunc 2384 2385 try 2386 Xpath 'a' 2387 call E("continue") 2388 call assert_report('should not get here') 2389 finally 2390 try 2391 Xpath 'b' 2392 call E("break") 2393 call assert_report('should not get here') 2394 finally 2395 try 2396 Xpath 'c' 2397 call E("return") 2398 call assert_report('should not get here') 2399 finally 2400 try 2401 Xpath 'd' 2402 let g:jump = "finish" 2403 ExecAsScript E 2404 call assert_report('should not get here') 2405 finally 2406 unlet g:jump 2407 try 2408 Xpath 'e' 2409 call E("error") 2410 call assert_report('should not get here') 2411 finally 2412 try 2413 Xpath 'f' 2414 call E("interrupt") 2415 call assert_report('should not get here') 2416 finally 2417 try 2418 Xpath 'g' 2419 call E("throw") 2420 call assert_report('should not get here') 2421 finally 2422 Xpath 'h' 2423 delfunction E 2424 endtry 2425 endtry 2426 endtry 2427 endtry 2428 endtry 2429 endtry 2430 endtry 2431 call assert_report('should not get here') 2432 [CODE] 2433 let verify =<< trim [CODE] 2434 call assert_equal('abcdefgh', g:Xpath) 2435 [CODE] 2436 call RunInNewVim(test, verify) 2437endfunc 2438 2439"------------------------------------------------------------------------------- 2440" Test 39: :finally reason discarded by an interrupt {{{1 2441" 2442" When a :finally clause is executed due to a :continue, :break, 2443" :return, :finish, error, interrupt or :throw, the jump reason is 2444" discarded by an interrupt in the finally clause. 2445"------------------------------------------------------------------------------- 2446 2447func Test_finally_discarded_by_interrupt() 2448 let test =<< trim [CODE] 2449 func I(jump) 2450 let loop = 0 2451 while loop < 2 2452 let loop = loop + 1 2453 if loop == 1 2454 try 2455 if a:jump == "continue" 2456 continue 2457 elseif a:jump == "break" 2458 break 2459 elseif a:jump == "return" || a:jump == "finish" 2460 return 2461 elseif a:jump == "error" 2462 asdf 2463 elseif a:jump == "interrupt" 2464 call interrupt() 2465 let dummy = 0 2466 elseif a:jump == "throw" 2467 throw "abc" 2468 endif 2469 finally 2470 call interrupt() 2471 let dummy = 0 2472 endtry 2473 elseif loop == 2 2474 call assert_report('should not get here') 2475 endif 2476 endwhile 2477 call assert_report('should not get here') 2478 endfunc 2479 2480 try 2481 try 2482 Xpath 'a' 2483 call I("continue") 2484 call assert_report('should not get here') 2485 finally 2486 try 2487 Xpath 'b' 2488 call I("break") 2489 call assert_report('should not get here') 2490 finally 2491 try 2492 Xpath 'c' 2493 call I("return") 2494 call assert_report('should not get here') 2495 finally 2496 try 2497 Xpath 'd' 2498 let g:jump = "finish" 2499 ExecAsScript I 2500 call assert_report('should not get here') 2501 finally 2502 unlet g:jump 2503 try 2504 Xpath 'e' 2505 call I("error") 2506 call assert_report('should not get here') 2507 finally 2508 try 2509 Xpath 'f' 2510 call I("interrupt") 2511 call assert_report('should not get here') 2512 finally 2513 try 2514 Xpath 'g' 2515 call I("throw") 2516 call assert_report('should not get here') 2517 finally 2518 Xpath 'h' 2519 delfunction I 2520 endtry 2521 endtry 2522 endtry 2523 endtry 2524 endtry 2525 endtry 2526 endtry 2527 call assert_report('should not get here') 2528 catch /^Vim:Interrupt$/ 2529 Xpath 'A' 2530 endtry 2531 [CODE] 2532 let verify =<< trim [CODE] 2533 call assert_equal('abcdefghA', g:Xpath) 2534 [CODE] 2535 call RunInNewVim(test, verify) 2536endfunc 2537 2538"------------------------------------------------------------------------------- 2539" Test 40: :finally reason discarded by :throw {{{1 2540" 2541" When a :finally clause is executed due to a :continue, :break, 2542" :return, :finish, error, interrupt or :throw, the jump reason is 2543" discarded by a :throw in the finally clause. 2544"------------------------------------------------------------------------------- 2545 2546func Test_finally_discard_by_throw() 2547 let test =<< trim [CODE] 2548 func T(jump) 2549 let loop = 0 2550 while loop < 2 2551 let loop = loop + 1 2552 if loop == 1 2553 try 2554 if a:jump == "continue" 2555 continue 2556 elseif a:jump == "break" 2557 break 2558 elseif a:jump == "return" || a:jump == "finish" 2559 return 2560 elseif a:jump == "error" 2561 asdf 2562 elseif a:jump == "interrupt" 2563 call interrupt() 2564 let dummy = 0 2565 elseif a:jump == "throw" 2566 throw "abc" 2567 endif 2568 finally 2569 throw "xyz" " discards jump that caused the :finally 2570 endtry 2571 elseif loop == 2 2572 call assert_report('should not get here') 2573 endif 2574 endwhile 2575 call assert_report('should not get here') 2576 endfunc 2577 2578 try 2579 Xpath 'a' 2580 call T("continue") 2581 call assert_report('should not get here') 2582 finally 2583 try 2584 Xpath 'b' 2585 call T("break") 2586 call assert_report('should not get here') 2587 finally 2588 try 2589 Xpath 'c' 2590 call T("return") 2591 call assert_report('should not get here') 2592 finally 2593 try 2594 Xpath 'd' 2595 let g:jump = "finish" 2596 ExecAsScript T 2597 call assert_report('should not get here') 2598 finally 2599 unlet g:jump 2600 try 2601 Xpath 'e' 2602 call T("error") 2603 call assert_report('should not get here') 2604 finally 2605 try 2606 Xpath 'f' 2607 call T("interrupt") 2608 call assert_report('should not get here') 2609 finally 2610 try 2611 Xpath 'g' 2612 call T("throw") 2613 call assert_report('should not get here') 2614 finally 2615 Xpath 'h' 2616 delfunction T 2617 endtry 2618 endtry 2619 endtry 2620 endtry 2621 endtry 2622 endtry 2623 endtry 2624 call assert_report('should not get here') 2625 [CODE] 2626 let verify =<< trim [CODE] 2627 call assert_equal('abcdefgh', g:Xpath) 2628 [CODE] 2629 call RunInNewVim(test, verify) 2630endfunc 2631 2632"------------------------------------------------------------------------------- 2633" Test 49: Throwing exceptions across functions {{{1 2634" 2635" When an exception is thrown but not caught inside a function, the 2636" caller is checked for a matching :catch clause. 2637"------------------------------------------------------------------------------- 2638 2639func T49_C() 2640 try 2641 Xpath 'a' 2642 throw "arrgh" 2643 call assert_report('should not get here') 2644 catch /arrgh/ 2645 Xpath 'b' 2646 endtry 2647 Xpath 'c' 2648endfunc 2649 2650func T49_T1() 2651 XloopNEXT 2652 try 2653 Xloop 'd' 2654 throw "arrgh" 2655 call assert_report('should not get here') 2656 finally 2657 Xloop 'e' 2658 endtry 2659 Xloop 'f' 2660endfunc 2661 2662func T49_T2() 2663 try 2664 Xpath 'g' 2665 call T49_T1() 2666 call assert_report('should not get here') 2667 finally 2668 Xpath 'h' 2669 endtry 2670 call assert_report('should not get here') 2671endfunc 2672 2673func Test_throw_exception_across_funcs() 2674 XpathINIT 2675 XloopINIT 2676 try 2677 Xpath 'i' 2678 call T49_C() " throw and catch 2679 Xpath 'j' 2680 catch /.*/ 2681 call assert_report('should not get here') 2682 endtry 2683 2684 try 2685 Xpath 'k' 2686 call T49_T1() " throw, one level 2687 call assert_report('should not get here') 2688 catch /arrgh/ 2689 Xpath 'l' 2690 catch /.*/ 2691 call assert_report('should not get here') 2692 endtry 2693 2694 try 2695 Xpath 'm' 2696 call T49_T2() " throw, two levels 2697 call assert_report('should not get here') 2698 catch /arrgh/ 2699 Xpath 'n' 2700 catch /.*/ 2701 call assert_report('should not get here') 2702 endtry 2703 Xpath 'o' 2704 2705 call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath) 2706endfunc 2707 2708"------------------------------------------------------------------------------- 2709" Test 50: Throwing exceptions across script files {{{1 2710" 2711" When an exception is thrown but not caught inside a script file, 2712" the sourcing script or function is checked for a matching :catch 2713" clause. 2714" 2715" This test executes the bodies of the functions C, T1, and T2 from 2716" the previous test as script files (:return replaced by :finish). 2717"------------------------------------------------------------------------------- 2718 2719func T50_F() 2720 try 2721 Xpath 'A' 2722 exec "source" g:scriptC 2723 Xpath 'B' 2724 catch /.*/ 2725 call assert_report('should not get here') 2726 endtry 2727 2728 try 2729 Xpath 'C' 2730 exec "source" g:scriptT1 2731 call assert_report('should not get here') 2732 catch /arrgh/ 2733 Xpath 'D' 2734 catch /.*/ 2735 call assert_report('should not get here') 2736 endtry 2737endfunc 2738 2739func Test_throw_across_script() 2740 XpathINIT 2741 XloopINIT 2742 let g:scriptC = MakeScript("T49_C") 2743 let g:scriptT1 = MakeScript("T49_T1") 2744 let scriptT2 = MakeScript("T49_T2", g:scriptT1) 2745 2746 try 2747 Xpath 'E' 2748 call T50_F() 2749 Xpath 'F' 2750 exec "source" scriptT2 2751 call assert_report('should not get here') 2752 catch /arrgh/ 2753 Xpath 'G' 2754 catch /.*/ 2755 call assert_report('should not get here') 2756 endtry 2757 Xpath 'H' 2758 call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath) 2759 2760 call delete(g:scriptC) 2761 call delete(g:scriptT1) 2762 call delete(scriptT2) 2763 unlet g:scriptC g:scriptT1 scriptT2 2764endfunc 2765 2766"------------------------------------------------------------------------------- 2767" Test 52: Uncaught exceptions {{{1 2768" 2769" When an exception is thrown but not caught, an error message is 2770" displayed when the script is terminated. In case of an interrupt 2771" or error exception, the normal interrupt or error message(s) are 2772" displayed. 2773"------------------------------------------------------------------------------- 2774 2775func Test_uncaught_exception_1() 2776 CheckEnglish 2777 2778 let test =<< trim [CODE] 2779 Xpath 'a' 2780 throw "arrgh" 2781 call assert_report('should not get here')` 2782 [CODE] 2783 let verify =<< trim [CODE] 2784 call assert_equal('E605: Exception not caught: arrgh', v:errmsg) 2785 call assert_equal('a', g:Xpath) 2786 [CODE] 2787 call RunInNewVim(test, verify) 2788endfunc 2789 2790func Test_uncaught_exception_2() 2791 CheckEnglish 2792 2793 let test =<< trim [CODE] 2794 try 2795 Xpath 'a' 2796 throw "oops" 2797 call assert_report('should not get here')` 2798 catch /arrgh/ 2799 call assert_report('should not get here')` 2800 endtry 2801 call assert_report('should not get here')` 2802 [CODE] 2803 let verify =<< trim [CODE] 2804 call assert_equal('E605: Exception not caught: oops', v:errmsg) 2805 call assert_equal('a', g:Xpath) 2806 [CODE] 2807 call RunInNewVim(test, verify) 2808endfunc 2809 2810func Test_uncaught_exception_3() 2811 CheckEnglish 2812 2813 let test =<< trim [CODE] 2814 func T() 2815 Xpath 'c' 2816 throw "brrr" 2817 call assert_report('should not get here')` 2818 endfunc 2819 2820 try 2821 Xpath 'a' 2822 throw "arrgh" 2823 call assert_report('should not get here')` 2824 catch /.*/ 2825 Xpath 'b' 2826 call T() 2827 call assert_report('should not get here')` 2828 endtry 2829 call assert_report('should not get here')` 2830 [CODE] 2831 let verify =<< trim [CODE] 2832 call assert_equal('E605: Exception not caught: brrr', v:errmsg) 2833 call assert_equal('abc', g:Xpath) 2834 [CODE] 2835 call RunInNewVim(test, verify) 2836endfunc 2837 2838func Test_uncaught_exception_4() 2839 CheckEnglish 2840 2841 let test =<< trim [CODE] 2842 try 2843 Xpath 'a' 2844 throw "arrgh" 2845 call assert_report('should not get here')` 2846 finally 2847 Xpath 'b' 2848 throw "brrr" 2849 call assert_report('should not get here')` 2850 endtry 2851 call assert_report('should not get here')` 2852 [CODE] 2853 let verify =<< trim [CODE] 2854 call assert_equal('E605: Exception not caught: brrr', v:errmsg) 2855 call assert_equal('ab', g:Xpath) 2856 [CODE] 2857 call RunInNewVim(test, verify) 2858endfunc 2859 2860func Test_uncaught_exception_5() 2861 CheckEnglish 2862 2863 " Need to catch and handle interrupt, otherwise the test will wait for the 2864 " user to press <Enter> to continue 2865 let test =<< trim [CODE] 2866 try 2867 try 2868 Xpath 'a' 2869 call interrupt() 2870 call assert_report('should not get here') 2871 endtry 2872 call assert_report('should not get here') 2873 catch /^Vim:Interrupt$/ 2874 Xpath 'b' 2875 endtry 2876 [CODE] 2877 let verify =<< trim [CODE] 2878 call assert_equal('ab', g:Xpath) 2879 [CODE] 2880 call RunInNewVim(test, verify) 2881endfunc 2882 2883func Test_uncaught_exception_6() 2884 CheckEnglish 2885 2886 let test =<< trim [CODE] 2887 try 2888 Xpath 'a' 2889 let x = novar " error E121; exception: E121 2890 catch /E15:/ " should not catch 2891 call assert_report('should not get here') 2892 endtry 2893 call assert_report('should not get here') 2894 [CODE] 2895 let verify =<< trim [CODE] 2896 call assert_equal('a', g:Xpath) 2897 call assert_equal('E121: Undefined variable: novar', v:errmsg) 2898 [CODE] 2899 call RunInNewVim(test, verify) 2900endfunc 2901 2902func Test_uncaught_exception_7() 2903 CheckEnglish 2904 2905 let test =<< trim [CODE] 2906 try 2907 Xpath 'a' 2908 " error E108/E488; exception: E488 2909 unlet novar # 2910 catch /E108:/ " should not catch 2911 call assert_report('should not get here') 2912 endtry 2913 call assert_report('should not get here') 2914 [CODE] 2915 let verify =<< trim [CODE] 2916 call assert_equal('a', g:Xpath) 2917 call assert_equal('E488: Trailing characters: #', v:errmsg) 2918 [CODE] 2919 call RunInNewVim(test, verify) 2920endfunc 2921 2922"------------------------------------------------------------------------------- 2923" Test 53: Nesting errors: :endif/:else/:elseif {{{1 2924" 2925" For nesting errors of :if conditionals the correct error messages 2926" should be given. 2927"------------------------------------------------------------------------------- 2928 2929func Test_nested_if_else_errors() 2930 CheckEnglish 2931 2932 " :endif without :if 2933 let code =<< trim END 2934 endif 2935 END 2936 call writefile(code, 'Xtest') 2937 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2938 2939 " :endif without :if 2940 let code =<< trim END 2941 while 1 2942 endif 2943 endwhile 2944 END 2945 call writefile(code, 'Xtest') 2946 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2947 2948 " :endif without :if 2949 let code =<< trim END 2950 try 2951 finally 2952 endif 2953 endtry 2954 END 2955 call writefile(code, 'Xtest') 2956 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2957 2958 " :endif without :if 2959 let code =<< trim END 2960 try 2961 endif 2962 endtry 2963 END 2964 call writefile(code, 'Xtest') 2965 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2966 2967 " :endif without :if 2968 let code =<< trim END 2969 try 2970 throw "a" 2971 catch /a/ 2972 endif 2973 endtry 2974 END 2975 call writefile(code, 'Xtest') 2976 call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if') 2977 2978 " :else without :if 2979 let code =<< trim END 2980 else 2981 END 2982 call writefile(code, 'Xtest') 2983 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 2984 2985 " :else without :if 2986 let code =<< trim END 2987 while 1 2988 else 2989 endwhile 2990 END 2991 call writefile(code, 'Xtest') 2992 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 2993 2994 " :else without :if 2995 let code =<< trim END 2996 try 2997 finally 2998 else 2999 endtry 3000 END 3001 call writefile(code, 'Xtest') 3002 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 3003 3004 " :else without :if 3005 let code =<< trim END 3006 try 3007 else 3008 endtry 3009 END 3010 call writefile(code, 'Xtest') 3011 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 3012 3013 " :else without :if 3014 let code =<< trim END 3015 try 3016 throw "a" 3017 catch /a/ 3018 else 3019 endtry 3020 END 3021 call writefile(code, 'Xtest') 3022 call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if') 3023 3024 " :elseif without :if 3025 let code =<< trim END 3026 elseif 3027 END 3028 call writefile(code, 'Xtest') 3029 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3030 3031 " :elseif without :if 3032 let code =<< trim END 3033 while 1 3034 elseif 3035 endwhile 3036 END 3037 call writefile(code, 'Xtest') 3038 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3039 3040 " :elseif without :if 3041 let code =<< trim END 3042 try 3043 finally 3044 elseif 3045 endtry 3046 END 3047 call writefile(code, 'Xtest') 3048 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3049 3050 " :elseif without :if 3051 let code =<< trim END 3052 try 3053 elseif 3054 endtry 3055 END 3056 call writefile(code, 'Xtest') 3057 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3058 3059 " :elseif without :if 3060 let code =<< trim END 3061 try 3062 throw "a" 3063 catch /a/ 3064 elseif 3065 endtry 3066 END 3067 call writefile(code, 'Xtest') 3068 call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if') 3069 3070 " multiple :else 3071 let code =<< trim END 3072 if 1 3073 else 3074 else 3075 endif 3076 END 3077 call writefile(code, 'Xtest') 3078 call AssertException(['source Xtest'], 'Vim(else):E583: multiple :else') 3079 3080 " :elseif after :else 3081 let code =<< trim END 3082 if 1 3083 else 3084 elseif 1 3085 endif 3086 END 3087 call writefile(code, 'Xtest') 3088 call AssertException(['source Xtest'], 'Vim(elseif):E584: :elseif after :else') 3089 3090 call delete('Xtest') 3091endfunc 3092 3093"------------------------------------------------------------------------------- 3094" Test 54: Nesting errors: :while/:endwhile {{{1 3095" 3096" For nesting errors of :while conditionals the correct error messages 3097" should be given. 3098" 3099" This test reuses the function MESSAGES() from the previous test. 3100" This functions checks the messages in g:msgfile. 3101"------------------------------------------------------------------------------- 3102 3103func Test_nested_while_error() 3104 CheckEnglish 3105 3106 " :endwhile without :while 3107 let code =<< trim END 3108 endwhile 3109 END 3110 call writefile(code, 'Xtest') 3111 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3112 3113 " :endwhile without :while 3114 let code =<< trim END 3115 if 1 3116 endwhile 3117 endif 3118 END 3119 call writefile(code, 'Xtest') 3120 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3121 3122 " Missing :endif 3123 let code =<< trim END 3124 while 1 3125 if 1 3126 endwhile 3127 END 3128 call writefile(code, 'Xtest') 3129 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif') 3130 3131 " :endwhile without :while 3132 let code =<< trim END 3133 try 3134 finally 3135 endwhile 3136 endtry 3137 END 3138 call writefile(code, 'Xtest') 3139 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3140 3141 " Missing :endtry 3142 let code =<< trim END 3143 while 1 3144 try 3145 finally 3146 endwhile 3147 END 3148 call writefile(code, 'Xtest') 3149 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry') 3150 3151 " Missing :endtry 3152 let code =<< trim END 3153 while 1 3154 if 1 3155 try 3156 finally 3157 endwhile 3158 END 3159 call writefile(code, 'Xtest') 3160 call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry') 3161 3162 " Missing :endif 3163 let code =<< trim END 3164 while 1 3165 try 3166 finally 3167 if 1 3168 endwhile 3169 END 3170 call writefile(code, 'Xtest') 3171 call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif') 3172 3173 " :endwhile without :while 3174 let code =<< trim END 3175 try 3176 endwhile 3177 endtry 3178 END 3179 call writefile(code, 'Xtest') 3180 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3181 3182 " :endwhile without :while 3183 let code =<< trim END 3184 while 1 3185 try 3186 endwhile 3187 endtry 3188 endwhile 3189 END 3190 call writefile(code, 'Xtest') 3191 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3192 3193 " :endwhile without :while 3194 let code =<< trim END 3195 try 3196 throw "a" 3197 catch /a/ 3198 endwhile 3199 endtry 3200 END 3201 call writefile(code, 'Xtest') 3202 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3203 3204 " :endwhile without :while 3205 let code =<< trim END 3206 while 1 3207 try 3208 throw "a" 3209 catch /a/ 3210 endwhile 3211 endtry 3212 endwhile 3213 END 3214 call writefile(code, 'Xtest') 3215 call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while') 3216 3217 call delete('Xtest') 3218endfunc 3219 3220"------------------------------------------------------------------------------- 3221" Test 55: Nesting errors: :continue/:break {{{1 3222" 3223" For nesting errors of :continue and :break commands the correct 3224" error messages should be given. 3225" 3226" This test reuses the function MESSAGES() from the previous test. 3227" This functions checks the messages in g:msgfile. 3228"------------------------------------------------------------------------------- 3229 3230func Test_nested_cont_break_error() 3231 CheckEnglish 3232 3233 " :continue without :while 3234 let code =<< trim END 3235 continue 3236 END 3237 call writefile(code, 'Xtest') 3238 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3239 3240 " :continue without :while 3241 let code =<< trim END 3242 if 1 3243 continue 3244 endif 3245 END 3246 call writefile(code, 'Xtest') 3247 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3248 3249 " :continue without :while 3250 let code =<< trim END 3251 try 3252 finally 3253 continue 3254 endtry 3255 END 3256 call writefile(code, 'Xtest') 3257 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3258 3259 " :continue without :while 3260 let code =<< trim END 3261 try 3262 continue 3263 endtry 3264 END 3265 call writefile(code, 'Xtest') 3266 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3267 3268 " :continue without :while 3269 let code =<< trim END 3270 try 3271 throw "a" 3272 catch /a/ 3273 continue 3274 endtry 3275 END 3276 call writefile(code, 'Xtest') 3277 call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for') 3278 3279 " :break without :while 3280 let code =<< trim END 3281 break 3282 END 3283 call writefile(code, 'Xtest') 3284 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3285 3286 " :break without :while 3287 let code =<< trim END 3288 if 1 3289 break 3290 endif 3291 END 3292 call writefile(code, 'Xtest') 3293 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3294 3295 " :break without :while 3296 let code =<< trim END 3297 try 3298 finally 3299 break 3300 endtry 3301 END 3302 call writefile(code, 'Xtest') 3303 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3304 3305 " :break without :while 3306 let code =<< trim END 3307 try 3308 break 3309 endtry 3310 END 3311 call writefile(code, 'Xtest') 3312 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3313 3314 " :break without :while 3315 let code =<< trim END 3316 try 3317 throw "a" 3318 catch /a/ 3319 break 3320 endtry 3321 END 3322 call writefile(code, 'Xtest') 3323 call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for') 3324 3325 call delete('Xtest') 3326endfunc 3327 3328"------------------------------------------------------------------------------- 3329" Test 56: Nesting errors: :endtry {{{1 3330" 3331" For nesting errors of :try conditionals the correct error messages 3332" should be given. 3333" 3334" This test reuses the function MESSAGES() from the previous test. 3335" This functions checks the messages in g:msgfile. 3336"------------------------------------------------------------------------------- 3337 3338func Test_nested_endtry_error() 3339 CheckEnglish 3340 3341 " :endtry without :try 3342 let code =<< trim END 3343 endtry 3344 END 3345 call writefile(code, 'Xtest') 3346 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try') 3347 3348 " :endtry without :try 3349 let code =<< trim END 3350 if 1 3351 endtry 3352 endif 3353 END 3354 call writefile(code, 'Xtest') 3355 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try') 3356 3357 " :endtry without :try 3358 let code =<< trim END 3359 while 1 3360 endtry 3361 endwhile 3362 END 3363 call writefile(code, 'Xtest') 3364 call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try') 3365 3366 " Missing :endif 3367 let code =<< trim END 3368 try 3369 if 1 3370 endtry 3371 END 3372 call writefile(code, 'Xtest') 3373 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif') 3374 3375 " Missing :endwhile 3376 let code =<< trim END 3377 try 3378 while 1 3379 endtry 3380 END 3381 call writefile(code, 'Xtest') 3382 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile') 3383 3384 " Missing :endif 3385 let code =<< trim END 3386 try 3387 finally 3388 if 1 3389 endtry 3390 END 3391 call writefile(code, 'Xtest') 3392 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif') 3393 3394 " Missing :endwhile 3395 let code =<< trim END 3396 try 3397 finally 3398 while 1 3399 endtry 3400 END 3401 call writefile(code, 'Xtest') 3402 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile') 3403 3404 " Missing :endif 3405 let code =<< trim END 3406 try 3407 throw "a" 3408 catch /a/ 3409 if 1 3410 endtry 3411 END 3412 call writefile(code, 'Xtest') 3413 call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif') 3414 3415 " Missing :endwhile 3416 let code =<< trim END 3417 try 3418 throw "a" 3419 catch /a/ 3420 while 1 3421 endtry 3422 END 3423 call writefile(code, 'Xtest') 3424 call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile') 3425 3426 call delete('Xtest') 3427endfunc 3428 3429"------------------------------------------------------------------------------- 3430" Test 57: v:exception and v:throwpoint for user exceptions {{{1 3431" 3432" v:exception evaluates to the value of the exception that was caught 3433" most recently and is not finished. (A caught exception is finished 3434" when the next ":catch", ":finally", or ":endtry" is reached.) 3435" v:throwpoint evaluates to the script/function name and line number 3436" where that exception has been thrown. 3437"------------------------------------------------------------------------------- 3438 3439func Test_user_exception_info() 3440 CheckEnglish 3441 3442 XpathINIT 3443 XloopINIT 3444 3445 func FuncException() 3446 let g:exception = v:exception 3447 endfunc 3448 3449 func FuncThrowpoint() 3450 let g:throwpoint = v:throwpoint 3451 endfunc 3452 3453 let scriptException = MakeScript("FuncException") 3454 let scriptThrowPoint = MakeScript("FuncThrowpoint") 3455 3456 command! CmdException let g:exception = v:exception 3457 command! CmdThrowpoint let g:throwpoint = v:throwpoint 3458 3459 func T(arg, line) 3460 if a:line == 2 3461 throw a:arg " in line 2 3462 elseif a:line == 4 3463 throw a:arg " in line 4 3464 elseif a:line == 6 3465 throw a:arg " in line 6 3466 elseif a:line == 8 3467 throw a:arg " in line 8 3468 endif 3469 endfunc 3470 3471 func G(arg, line) 3472 call T(a:arg, a:line) 3473 endfunc 3474 3475 func F(arg, line) 3476 call G(a:arg, a:line) 3477 endfunc 3478 3479 let scriptT = MakeScript("T") 3480 let scriptG = MakeScript("G", scriptT) 3481 let scriptF = MakeScript("F", scriptG) 3482 3483 try 3484 Xpath 'a' 3485 call F("oops", 2) 3486 catch /.*/ 3487 Xpath 'b' 3488 let exception = v:exception 3489 let throwpoint = v:throwpoint 3490 call assert_equal("oops", v:exception) 3491 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3492 call assert_match('\<2\>', v:throwpoint) 3493 3494 exec "let exception = v:exception" 3495 exec "let throwpoint = v:throwpoint" 3496 call assert_equal("oops", v:exception) 3497 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3498 call assert_match('\<2\>', v:throwpoint) 3499 3500 CmdException 3501 CmdThrowpoint 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 call FuncException() 3507 call FuncThrowpoint() 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 exec "source" scriptException 3513 exec "source" scriptThrowPoint 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 try 3519 Xpath 'c' 3520 call G("arrgh", 4) 3521 catch /.*/ 3522 Xpath 'd' 3523 let exception = v:exception 3524 let throwpoint = v:throwpoint 3525 call assert_equal("arrgh", v:exception) 3526 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3527 call assert_match('\<4\>', v:throwpoint) 3528 3529 try 3530 Xpath 'e' 3531 let g:arg = "autsch" 3532 let g:line = 6 3533 exec "source" scriptF 3534 catch /.*/ 3535 Xpath 'f' 3536 let exception = v:exception 3537 let throwpoint = v:throwpoint 3538 call assert_equal("autsch", v:exception) 3539 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint) 3540 call assert_match('\<6\>', v:throwpoint) 3541 finally 3542 Xpath 'g' 3543 let exception = v:exception 3544 let throwpoint = v:throwpoint 3545 call assert_equal("arrgh", v:exception) 3546 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3547 call assert_match('\<4\>', v:throwpoint) 3548 try 3549 Xpath 'h' 3550 let g:arg = "brrrr" 3551 let g:line = 8 3552 exec "source" scriptG 3553 catch /.*/ 3554 Xpath 'i' 3555 let exception = v:exception 3556 let throwpoint = v:throwpoint 3557 " Resolve scriptT for matching it against v:throwpoint. 3558 call assert_equal("brrrr", v:exception) 3559 call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint) 3560 call assert_match('\<8\>', v:throwpoint) 3561 finally 3562 Xpath 'j' 3563 let exception = v:exception 3564 let throwpoint = v:throwpoint 3565 call assert_equal("arrgh", v:exception) 3566 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3567 call assert_match('\<4\>', v:throwpoint) 3568 endtry 3569 Xpath 'k' 3570 let exception = v:exception 3571 let throwpoint = v:throwpoint 3572 call assert_equal("arrgh", v:exception) 3573 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3574 call assert_match('\<4\>', v:throwpoint) 3575 endtry 3576 Xpath 'l' 3577 let exception = v:exception 3578 let throwpoint = v:throwpoint 3579 call assert_equal("arrgh", v:exception) 3580 call assert_match('\<G\[1]\.\.T\>', v:throwpoint) 3581 call assert_match('\<4\>', v:throwpoint) 3582 finally 3583 Xpath 'm' 3584 let exception = v:exception 3585 let throwpoint = v:throwpoint 3586 call assert_equal("oops", v:exception) 3587 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3588 call assert_match('\<2\>', v:throwpoint) 3589 endtry 3590 Xpath 'n' 3591 let exception = v:exception 3592 let throwpoint = v:throwpoint 3593 call assert_equal("oops", v:exception) 3594 call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint) 3595 call assert_match('\<2\>', v:throwpoint) 3596 finally 3597 Xpath 'o' 3598 let exception = v:exception 3599 let throwpoint = v:throwpoint 3600 call assert_equal("", v:exception) 3601 call assert_match('^$', v:throwpoint) 3602 call assert_match('^$', v:throwpoint) 3603 endtry 3604 3605 call assert_equal('abcdefghijklmno', g:Xpath) 3606 3607 unlet exception throwpoint 3608 delfunction FuncException 3609 delfunction FuncThrowpoint 3610 call delete(scriptException) 3611 call delete(scriptThrowPoint) 3612 unlet scriptException scriptThrowPoint 3613 delcommand CmdException 3614 delcommand CmdThrowpoint 3615 delfunction T 3616 delfunction G 3617 delfunction F 3618 call delete(scriptT) 3619 call delete(scriptG) 3620 call delete(scriptF) 3621 unlet scriptT scriptG scriptF 3622endfunc 3623 3624"------------------------------------------------------------------------------- 3625" 3626" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1 3627" 3628" v:exception and v:throwpoint work also for error and interrupt 3629" exceptions. 3630"------------------------------------------------------------------------------- 3631 3632func Test_execption_info_for_error() 3633 CheckEnglish 3634 3635 let test =<< trim [CODE] 3636 func T(line) 3637 if a:line == 2 3638 delfunction T " error (function in use) in line 2 3639 elseif a:line == 4 3640 call interrupt() 3641 endif 3642 endfunc 3643 3644 while 1 3645 try 3646 Xpath 'a' 3647 call T(2) 3648 call assert_report('should not get here') 3649 catch /.*/ 3650 Xpath 'b' 3651 if v:exception !~ 'Vim(delfunction):' 3652 call assert_report('should not get here') 3653 endif 3654 if v:throwpoint !~ '\<T\>' 3655 call assert_report('should not get here') 3656 endif 3657 if v:throwpoint !~ '\<2\>' 3658 call assert_report('should not get here') 3659 endif 3660 finally 3661 Xpath 'c' 3662 if v:exception != "" 3663 call assert_report('should not get here') 3664 endif 3665 if v:throwpoint != "" 3666 call assert_report('should not get here') 3667 endif 3668 break 3669 endtry 3670 endwhile 3671 3672 Xpath 'd' 3673 if v:exception != "" 3674 call assert_report('should not get here') 3675 endif 3676 if v:throwpoint != "" 3677 call assert_report('should not get here') 3678 endif 3679 3680 while 1 3681 try 3682 Xpath 'e' 3683 call T(4) 3684 call assert_report('should not get here') 3685 catch /.*/ 3686 Xpath 'f' 3687 if v:exception != 'Vim:Interrupt' 3688 call assert_report('should not get here') 3689 endif 3690 if v:throwpoint !~ 'function T' 3691 call assert_report('should not get here') 3692 endif 3693 if v:throwpoint !~ '\<4\>' 3694 call assert_report('should not get here') 3695 endif 3696 finally 3697 Xpath 'g' 3698 if v:exception != "" 3699 call assert_report('should not get here') 3700 endif 3701 if v:throwpoint != "" 3702 call assert_report('should not get here') 3703 endif 3704 break 3705 endtry 3706 endwhile 3707 3708 Xpath 'h' 3709 if v:exception != "" 3710 call assert_report('should not get here') 3711 endif 3712 if v:throwpoint != "" 3713 call assert_report('should not get here') 3714 endif 3715 [CODE] 3716 let verify =<< trim [CODE] 3717 call assert_equal('abcdefgh', g:Xpath) 3718 [CODE] 3719 call RunInNewVim(test, verify) 3720endfunc 3721 3722"------------------------------------------------------------------------------- 3723" Test 61: Catching interrupt exceptions {{{1 3724" 3725" When an interrupt occurs inside a :try/:endtry region, an 3726" interrupt exception is thrown and can be caught. Its value is 3727" "Vim:Interrupt". If the interrupt occurs after an error or a :throw 3728" but before a matching :catch is reached, all following :catches of 3729" that try block are ignored, but the interrupt exception can be 3730" caught by the next surrounding try conditional. An interrupt is 3731" ignored when there is a previous interrupt that has not been caught 3732" or causes a :finally clause to be executed. 3733"------------------------------------------------------------------------------- 3734 3735func Test_catch_intr_exception() 3736 let test =<< trim [CODE] 3737 while 1 3738 try 3739 try 3740 Xpath 'a' 3741 call interrupt() 3742 call assert_report('should not get here') 3743 catch /^Vim:Interrupt$/ 3744 Xpath 'b' 3745 finally 3746 Xpath 'c' 3747 endtry 3748 catch /.*/ 3749 call assert_report('should not get here') 3750 finally 3751 Xpath 'd' 3752 break 3753 endtry 3754 endwhile 3755 3756 while 1 3757 try 3758 try 3759 try 3760 Xpath 'e' 3761 asdf 3762 call assert_report('should not get here') 3763 catch /do_not_catch/ 3764 call assert_report('should not get here') 3765 catch /.*/ 3766 Xpath 'f' 3767 call interrupt() 3768 call assert_report('should not get here') 3769 catch /.*/ 3770 call assert_report('should not get here') 3771 finally 3772 Xpath 'g' 3773 call interrupt() 3774 call assert_report('should not get here') 3775 endtry 3776 catch /^Vim:Interrupt$/ 3777 Xpath 'h' 3778 finally 3779 Xpath 'i' 3780 endtry 3781 catch /.*/ 3782 call assert_report('should not get here') 3783 finally 3784 Xpath 'j' 3785 break 3786 endtry 3787 endwhile 3788 3789 while 1 3790 try 3791 try 3792 try 3793 Xpath 'k' 3794 throw "x" 3795 call assert_report('should not get here') 3796 catch /do_not_catch/ 3797 call assert_report('should not get here') 3798 catch /x/ 3799 Xpath 'l' 3800 call interrupt() 3801 call assert_report('should not get here') 3802 catch /.*/ 3803 call assert_report('should not get here') 3804 endtry 3805 catch /^Vim:Interrupt$/ 3806 Xpath 'm' 3807 finally 3808 Xpath 'n' 3809 endtry 3810 catch /.*/ 3811 call assert_report('should not get here') 3812 finally 3813 Xpath 'o' 3814 break 3815 endtry 3816 endwhile 3817 3818 while 1 3819 try 3820 try 3821 Xpath 'p' 3822 call interrupt() 3823 call assert_report('should not get here') 3824 catch /do_not_catch/ 3825 call interrupt() 3826 call assert_report('should not get here') 3827 catch /^Vim:Interrupt$/ 3828 Xpath 'q' 3829 finally 3830 Xpath 'r' 3831 endtry 3832 catch /.*/ 3833 call assert_report('should not get here') 3834 finally 3835 Xpath 's' 3836 break 3837 endtry 3838 endwhile 3839 3840 Xpath 't' 3841 [CODE] 3842 let verify =<< trim [CODE] 3843 call assert_equal('abcdefghijklmnopqrst', g:Xpath) 3844 [CODE] 3845 call RunInNewVim(test, verify) 3846endfunc 3847 3848"------------------------------------------------------------------------------- 3849" Test 65: Errors in the /pattern/ argument of a :catch {{{1 3850" 3851" On an error in the /pattern/ argument of a :catch, the :catch does 3852" not match. Any following :catches of the same :try/:endtry don't 3853" match either. Finally clauses are executed. 3854"------------------------------------------------------------------------------- 3855 3856func Test_catch_pattern_error() 3857 CheckEnglish 3858 XpathINIT 3859 3860 try 3861 try 3862 Xpath 'a' 3863 throw "oops" 3864 catch /^oops$/ 3865 Xpath 'b' 3866 catch /\)/ " not checked; exception has already been caught 3867 call assert_report('should not get here') 3868 endtry 3869 Xpath 'c' 3870 catch /.*/ 3871 call assert_report('should not get here') 3872 endtry 3873 call assert_equal('abc', g:Xpath) 3874 3875 XpathINIT 3876 func F() 3877 try 3878 try 3879 try 3880 Xpath 'a' 3881 throw "ab" 3882 catch /abc/ " does not catch 3883 call assert_report('should not get here') 3884 catch /\)/ " error; discards exception 3885 call assert_report('should not get here') 3886 catch /.*/ " not checked 3887 call assert_report('should not get here') 3888 finally 3889 Xpath 'b' 3890 endtry 3891 call assert_report('should not get here') 3892 catch /^ab$/ " checked, but original exception is discarded 3893 call assert_report('should not get here') 3894 catch /^Vim(catch):/ 3895 Xpath 'c' 3896 call assert_match('Vim(catch):E475: Invalid argument:', v:exception) 3897 finally 3898 Xpath 'd' 3899 endtry 3900 Xpath 'e' 3901 catch /.*/ 3902 call assert_report('should not get here') 3903 endtry 3904 Xpath 'f' 3905 endfunc 3906 3907 call F() 3908 call assert_equal('abcdef', g:Xpath) 3909 3910 delfunc F 3911endfunc 3912 3913"------------------------------------------------------------------------------- 3914" Test 87 using (expr) ? funcref : funcref {{{1 3915" 3916" Vim needs to correctly parse the funcref and even when it does 3917" not execute the funcref, it needs to consume the trailing () 3918"------------------------------------------------------------------------------- 3919 3920func Add2(x1, x2) 3921 return a:x1 + a:x2 3922endfu 3923 3924func GetStr() 3925 return "abcdefghijklmnopqrstuvwxyp" 3926endfu 3927 3928func Test_funcref_with_condexpr() 3929 call assert_equal(5, function('Add2')(2,3)) 3930 3931 call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3)) 3932 call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3)) 3933 " Make sure, GetStr() still works. 3934 call assert_equal('abcdefghijk', GetStr()[0:10]) 3935endfunc 3936 3937" Test 90: Recognizing {} in variable name. {{{1 3938"------------------------------------------------------------------------------- 3939 3940func Test_curlies() 3941 let s:var = 66 3942 let ns = 's' 3943 call assert_equal(66, {ns}:var) 3944 3945 let g:a = {} 3946 let g:b = 't' 3947 let g:a[g:b] = 77 3948 call assert_equal(77, g:a['t']) 3949endfunc 3950 3951"------------------------------------------------------------------------------- 3952" Test 91: using type(). {{{1 3953"------------------------------------------------------------------------------- 3954 3955func Test_type() 3956 call assert_equal(0, type(0)) 3957 call assert_equal(1, type("")) 3958 call assert_equal(2, type(function("tr"))) 3959 call assert_equal(2, type(function("tr", [8]))) 3960 call assert_equal(3, type([])) 3961 call assert_equal(4, type({})) 3962 if has('float') 3963 call assert_equal(5, type(0.0)) 3964 endif 3965 call assert_equal(6, type(v:false)) 3966 call assert_equal(6, type(v:true)) 3967 call assert_equal(7, type(v:none)) 3968 call assert_equal(7, type(v:null)) 3969 call assert_equal(8, v:t_job) 3970 call assert_equal(9, v:t_channel) 3971 call assert_equal(v:t_number, type(0)) 3972 call assert_equal(v:t_string, type("")) 3973 call assert_equal(v:t_func, type(function("tr"))) 3974 call assert_equal(v:t_func, type(function("tr", [8]))) 3975 call assert_equal(v:t_list, type([])) 3976 call assert_equal(v:t_dict, type({})) 3977 if has('float') 3978 call assert_equal(v:t_float, type(0.0)) 3979 endif 3980 call assert_equal(v:t_bool, type(v:false)) 3981 call assert_equal(v:t_bool, type(v:true)) 3982 call assert_equal(v:t_none, type(v:none)) 3983 call assert_equal(v:t_none, type(v:null)) 3984 call assert_equal(v:t_string, type(test_null_string())) 3985 call assert_equal(v:t_func, type(test_null_function())) 3986 call assert_equal(v:t_func, type(test_null_partial())) 3987 call assert_equal(v:t_list, type(test_null_list())) 3988 call assert_equal(v:t_dict, type(test_null_dict())) 3989 if has('job') 3990 call assert_equal(v:t_job, type(test_null_job())) 3991 endif 3992 if has('channel') 3993 call assert_equal(v:t_channel, type(test_null_channel())) 3994 endif 3995 call assert_equal(v:t_blob, type(test_null_blob())) 3996 3997 call assert_fails("call type(test_void())", 'E685:') 3998 call assert_fails("call type(test_unknown())", 'E685:') 3999 4000 call assert_equal(0, 0 + v:false) 4001 call assert_equal(1, 0 + v:true) 4002 call assert_equal(0, 0 + v:none) 4003 call assert_equal(0, 0 + v:null) 4004 4005 call assert_equal('v:false', '' . v:false) 4006 call assert_equal('v:true', '' . v:true) 4007 call assert_equal('v:none', '' . v:none) 4008 call assert_equal('v:null', '' . v:null) 4009 4010 call assert_true(v:false == 0) 4011 call assert_false(v:false != 0) 4012 call assert_true(v:true == 1) 4013 call assert_false(v:true != 1) 4014 call assert_false(v:true == v:false) 4015 call assert_true(v:true != v:false) 4016 4017 call assert_true(v:null == 0) 4018 call assert_false(v:null != 0) 4019 call assert_true(v:none == 0) 4020 call assert_false(v:none != 0) 4021 4022 call assert_true(v:false is v:false) 4023 call assert_true(v:true is v:true) 4024 call assert_true(v:none is v:none) 4025 call assert_true(v:null is v:null) 4026 4027 call assert_false(v:false isnot v:false) 4028 call assert_false(v:true isnot v:true) 4029 call assert_false(v:none isnot v:none) 4030 call assert_false(v:null isnot v:null) 4031 4032 call assert_false(v:false is 0) 4033 call assert_false(v:true is 1) 4034 call assert_false(v:true is v:false) 4035 call assert_false(v:none is 0) 4036 call assert_false(v:null is 0) 4037 call assert_false(v:null is v:none) 4038 4039 call assert_true(v:false isnot 0) 4040 call assert_true(v:true isnot 1) 4041 call assert_true(v:true isnot v:false) 4042 call assert_true(v:none isnot 0) 4043 call assert_true(v:null isnot 0) 4044 call assert_true(v:null isnot v:none) 4045 4046 call assert_equal(v:false, eval(string(v:false))) 4047 call assert_equal(v:true, eval(string(v:true))) 4048 call assert_equal(v:none, eval(string(v:none))) 4049 call assert_equal(v:null, eval(string(v:null))) 4050 4051 call assert_equal(v:false, copy(v:false)) 4052 call assert_equal(v:true, copy(v:true)) 4053 call assert_equal(v:none, copy(v:none)) 4054 call assert_equal(v:null, copy(v:null)) 4055 4056 call assert_equal([v:false], deepcopy([v:false])) 4057 call assert_equal([v:true], deepcopy([v:true])) 4058 call assert_equal([v:none], deepcopy([v:none])) 4059 call assert_equal([v:null], deepcopy([v:null])) 4060 4061 call assert_true(empty(v:false)) 4062 call assert_false(empty(v:true)) 4063 call assert_true(empty(v:null)) 4064 call assert_true(empty(v:none)) 4065 4066 func ChangeYourMind() 4067 try 4068 return v:true 4069 finally 4070 return 'something else' 4071 endtry 4072 endfunc 4073 4074 call ChangeYourMind() 4075endfunc 4076 4077"------------------------------------------------------------------------------- 4078" Test 92: skipping code {{{1 4079"------------------------------------------------------------------------------- 4080 4081func Test_skip() 4082 let Fn = function('Test_type') 4083 call assert_false(0 && Fn[1]) 4084 call assert_false(0 && string(Fn)) 4085 call assert_false(0 && len(Fn)) 4086 let l = [] 4087 call assert_false(0 && l[1]) 4088 call assert_false(0 && string(l)) 4089 call assert_false(0 && len(l)) 4090 let f = 1.0 4091 call assert_false(0 && f[1]) 4092 call assert_false(0 && string(f)) 4093 call assert_false(0 && len(f)) 4094 let sp = v:null 4095 call assert_false(0 && sp[1]) 4096 call assert_false(0 && string(sp)) 4097 call assert_false(0 && len(sp)) 4098 4099endfunc 4100 4101"------------------------------------------------------------------------------- 4102" Test 93: :echo and string() {{{1 4103"------------------------------------------------------------------------------- 4104 4105func Test_echo_and_string() 4106 " String 4107 let a = 'foo bar' 4108 redir => result 4109 echo a 4110 echo string(a) 4111 redir END 4112 let l = split(result, "\n") 4113 call assert_equal(["foo bar", 4114 \ "'foo bar'"], l) 4115 4116 " Float 4117 if has('float') 4118 let a = -1.2e0 4119 redir => result 4120 echo a 4121 echo string(a) 4122 redir END 4123 let l = split(result, "\n") 4124 call assert_equal(["-1.2", 4125 \ "-1.2"], l) 4126 endif 4127 4128 " Funcref 4129 redir => result 4130 echo function('string') 4131 echo string(function('string')) 4132 redir END 4133 let l = split(result, "\n") 4134 call assert_equal(["string", 4135 \ "function('string')"], l) 4136 4137 " Recursive dictionary 4138 let a = {} 4139 let a["a"] = a 4140 redir => result 4141 echo a 4142 echo string(a) 4143 redir END 4144 let l = split(result, "\n") 4145 call assert_equal(["{'a': {...}}", 4146 \ "{'a': {...}}"], l) 4147 4148 " Recursive list 4149 let a = [0] 4150 let a[0] = a 4151 redir => result 4152 echo a 4153 echo string(a) 4154 redir END 4155 let l = split(result, "\n") 4156 call assert_equal(["[[...]]", 4157 \ "[[...]]"], l) 4158 4159 " Empty dictionaries in a list 4160 let a = {} 4161 redir => result 4162 echo [a, a, a] 4163 echo string([a, a, a]) 4164 redir END 4165 let l = split(result, "\n") 4166 call assert_equal(["[{}, {}, {}]", 4167 \ "[{}, {}, {}]"], l) 4168 4169 " Empty dictionaries in a dictionary 4170 let a = {} 4171 let b = {"a": a, "b": a} 4172 redir => result 4173 echo b 4174 echo string(b) 4175 redir END 4176 let l = split(result, "\n") 4177 call assert_equal(["{'a': {}, 'b': {}}", 4178 \ "{'a': {}, 'b': {}}"], l) 4179 4180 " Empty lists in a list 4181 let a = [] 4182 redir => result 4183 echo [a, a, a] 4184 echo string([a, a, a]) 4185 redir END 4186 let l = split(result, "\n") 4187 call assert_equal(["[[], [], []]", 4188 \ "[[], [], []]"], l) 4189 4190 " Empty lists in a dictionary 4191 let a = [] 4192 let b = {"a": a, "b": a} 4193 redir => result 4194 echo b 4195 echo string(b) 4196 redir END 4197 let l = split(result, "\n") 4198 call assert_equal(["{'a': [], 'b': []}", 4199 \ "{'a': [], 'b': []}"], l) 4200 4201 " Dictionaries in a list 4202 let a = {"one": "yes", "two": "yes", "three": "yes"} 4203 redir => result 4204 echo [a, a, a] 4205 echo string([a, a, a]) 4206 redir END 4207 let l = split(result, "\n") 4208 call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, {...}]", 4209 \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 'yes'}]"], l) 4210 4211 " Dictionaries in a dictionary 4212 let a = {"one": "yes", "two": "yes", "three": "yes"} 4213 let b = {"a": a, "b": a} 4214 redir => result 4215 echo b 4216 echo string(b) 4217 redir END 4218 let l = split(result, "\n") 4219 call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {...}}", 4220 \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l) 4221 4222 " Lists in a list 4223 let a = [1, 2, 3] 4224 redir => result 4225 echo [a, a, a] 4226 echo string([a, a, a]) 4227 redir END 4228 let l = split(result, "\n") 4229 call assert_equal(["[[1, 2, 3], [...], [...]]", 4230 \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l) 4231 4232 " Lists in a dictionary 4233 let a = [1, 2, 3] 4234 let b = {"a": a, "b": a} 4235 redir => result 4236 echo b 4237 echo string(b) 4238 redir END 4239 let l = split(result, "\n") 4240 call assert_equal(["{'a': [1, 2, 3], 'b': [...]}", 4241 \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l) 4242 4243 call assert_fails('echo &:', 'E112:') 4244 call assert_fails('echo &g:', 'E112:') 4245 call assert_fails('echo &l:', 'E112:') 4246 4247endfunc 4248 4249"------------------------------------------------------------------------------- 4250" Test 94: 64-bit Numbers {{{1 4251"------------------------------------------------------------------------------- 4252 4253func Test_num64() 4254 call assert_notequal( 4294967296, 0) 4255 call assert_notequal(-4294967296, 0) 4256 call assert_equal( 4294967296, 0xFFFFffff + 1) 4257 call assert_equal(-4294967296, -0xFFFFffff - 1) 4258 4259 call assert_equal( 9223372036854775807, 1 / 0) 4260 call assert_equal(-9223372036854775807, -1 / 0) 4261 call assert_equal(-9223372036854775807 - 1, 0 / 0) 4262 4263 if has('float') 4264 call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150)) 4265 call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150)) 4266 endif 4267 4268 let rng = range(0xFFFFffff, 0x100000001) 4269 call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng) 4270 call assert_equal(0x100000001, max(rng)) 4271 call assert_equal(0xFFFFffff, min(rng)) 4272 call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N')) 4273endfunc 4274 4275"------------------------------------------------------------------------------- 4276" Test 95: lines of :append, :change, :insert {{{1 4277"------------------------------------------------------------------------------- 4278 4279function! DefineFunction(name, body) 4280 let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n") 4281 exec func 4282endfunction 4283 4284func Test_script_lines() 4285 " :append 4286 try 4287 call DefineFunction('T_Append', [ 4288 \ 'append', 4289 \ 'py <<EOS', 4290 \ '.', 4291 \ ]) 4292 catch 4293 call assert_report("Can't define function") 4294 endtry 4295 try 4296 call DefineFunction('T_Append', [ 4297 \ 'append', 4298 \ 'abc', 4299 \ ]) 4300 call assert_report("Shouldn't be able to define function") 4301 catch 4302 call assert_exception('Vim(function):E126: Missing :endfunction') 4303 endtry 4304 4305 " :change 4306 try 4307 call DefineFunction('T_Change', [ 4308 \ 'change', 4309 \ 'py <<EOS', 4310 \ '.', 4311 \ ]) 4312 catch 4313 call assert_report("Can't define function") 4314 endtry 4315 try 4316 call DefineFunction('T_Change', [ 4317 \ 'change', 4318 \ 'abc', 4319 \ ]) 4320 call assert_report("Shouldn't be able to define function") 4321 catch 4322 call assert_exception('Vim(function):E126: Missing :endfunction') 4323 endtry 4324 4325 " :insert 4326 try 4327 call DefineFunction('T_Insert', [ 4328 \ 'insert', 4329 \ 'py <<EOS', 4330 \ '.', 4331 \ ]) 4332 catch 4333 call assert_report("Can't define function") 4334 endtry 4335 try 4336 call DefineFunction('T_Insert', [ 4337 \ 'insert', 4338 \ 'abc', 4339 \ ]) 4340 call assert_report("Shouldn't be able to define function") 4341 catch 4342 call assert_exception('Vim(function):E126: Missing :endfunction') 4343 endtry 4344endfunc 4345 4346"------------------------------------------------------------------------------- 4347" Test 96: line continuation {{{1 4348" 4349" Undefined behavior was detected by ubsan with line continuation 4350" after an empty line. 4351"------------------------------------------------------------------------------- 4352func Test_script_emty_line_continuation() 4353 4354 \ 4355endfunc 4356 4357"------------------------------------------------------------------------------- 4358" Test 97: bitwise functions {{{1 4359"------------------------------------------------------------------------------- 4360func Test_bitwise_functions() 4361 " and 4362 call assert_equal(127, and(127, 127)) 4363 call assert_equal(16, and(127, 16)) 4364 eval 127->and(16)->assert_equal(16) 4365 call assert_equal(0, and(127, 128)) 4366 call assert_fails("call and([], 1)", 'E745:') 4367 call assert_fails("call and({}, 1)", 'E728:') 4368 if has('float') 4369 call assert_fails("call and(1.0, 1)", 'E805:') 4370 call assert_fails("call and(1, 1.0)", 'E805:') 4371 endif 4372 call assert_fails("call and(1, [])", 'E745:') 4373 call assert_fails("call and(1, {})", 'E728:') 4374 " or 4375 call assert_equal(23, or(16, 7)) 4376 call assert_equal(15, or(8, 7)) 4377 eval 8->or(7)->assert_equal(15) 4378 call assert_equal(123, or(0, 123)) 4379 call assert_fails("call or([], 1)", 'E745:') 4380 call assert_fails("call or({}, 1)", 'E728:') 4381 if has('float') 4382 call assert_fails("call or(1.0, 1)", 'E805:') 4383 call assert_fails("call or(1, 1.0)", 'E805:') 4384 endif 4385 call assert_fails("call or(1, [])", 'E745:') 4386 call assert_fails("call or(1, {})", 'E728:') 4387 " xor 4388 call assert_equal(0, xor(127, 127)) 4389 call assert_equal(111, xor(127, 16)) 4390 eval 127->xor(16)->assert_equal(111) 4391 call assert_equal(255, xor(127, 128)) 4392 if has('float') 4393 call assert_fails("call xor(1.0, 1)", 'E805:') 4394 call assert_fails("call xor(1, 1.0)", 'E805:') 4395 endif 4396 call assert_fails("call xor([], 1)", 'E745:') 4397 call assert_fails("call xor({}, 1)", 'E728:') 4398 call assert_fails("call xor(1, [])", 'E745:') 4399 call assert_fails("call xor(1, {})", 'E728:') 4400 " invert 4401 call assert_equal(65408, and(invert(127), 65535)) 4402 eval 127->invert()->and(65535)->assert_equal(65408) 4403 call assert_equal(65519, and(invert(16), 65535)) 4404 call assert_equal(65407, and(invert(128), 65535)) 4405 if has('float') 4406 call assert_fails("call invert(1.0)", 'E805:') 4407 endif 4408 call assert_fails("call invert([])", 'E745:') 4409 call assert_fails("call invert({})", 'E728:') 4410endfunc 4411 4412" Test using bang after user command {{{1 4413func Test_user_command_with_bang() 4414 command -bang Nieuw let nieuw = 1 4415 Ni! 4416 call assert_equal(1, nieuw) 4417 unlet nieuw 4418 delcommand Nieuw 4419endfunc 4420 4421func Test_script_expand_sfile() 4422 let lines =<< trim END 4423 func s:snr() 4424 return expand('<sfile>') 4425 endfunc 4426 let g:result = s:snr() 4427 END 4428 call writefile(lines, 'Xexpand') 4429 source Xexpand 4430 call assert_match('<SNR>\d\+_snr', g:result) 4431 source Xexpand 4432 call assert_match('<SNR>\d\+_snr', g:result) 4433 4434 call delete('Xexpand') 4435 unlet g:result 4436endfunc 4437 4438func Test_compound_assignment_operators() 4439 " Test for number 4440 let x = 1 4441 let x += 10 4442 call assert_equal(11, x) 4443 let x -= 5 4444 call assert_equal(6, x) 4445 let x *= 4 4446 call assert_equal(24, x) 4447 let x /= 3 4448 call assert_equal(8, x) 4449 let x %= 3 4450 call assert_equal(2, x) 4451 let x .= 'n' 4452 call assert_equal('2n', x) 4453 4454 " Test special cases: division or modulus with 0. 4455 let x = 1 4456 let x /= 0 4457 call assert_equal(0x7FFFFFFFFFFFFFFF, x) 4458 4459 let x = -1 4460 let x /= 0 4461 call assert_equal(-0x7FFFFFFFFFFFFFFF, x) 4462 4463 let x = 0 4464 let x /= 0 4465 call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x) 4466 4467 let x = 1 4468 let x %= 0 4469 call assert_equal(0, x) 4470 4471 let x = -1 4472 let x %= 0 4473 call assert_equal(0, x) 4474 4475 let x = 0 4476 let x %= 0 4477 call assert_equal(0, x) 4478 4479 " Test for string 4480 let x = 'str' 4481 let x .= 'ing' 4482 call assert_equal('string', x) 4483 let x += 1 4484 call assert_equal(1, x) 4485 4486 if has('float') 4487 " Test for float 4488 let x -= 1.5 4489 call assert_equal(-0.5, x) 4490 let x = 0.5 4491 let x += 4.5 4492 call assert_equal(5.0, x) 4493 let x -= 1.5 4494 call assert_equal(3.5, x) 4495 let x *= 3.0 4496 call assert_equal(10.5, x) 4497 let x /= 2.5 4498 call assert_equal(4.2, x) 4499 call assert_fails('let x %= 0.5', 'E734') 4500 call assert_fails('let x .= "f"', 'E734') 4501 let x = !3.14 4502 call assert_equal(0.0, x) 4503 4504 " integer and float operations 4505 let x = 1 4506 let x *= 2.1 4507 call assert_equal(2.1, x) 4508 let x = 1 4509 let x /= 0.25 4510 call assert_equal(4.0, x) 4511 let x = 1 4512 call assert_fails('let x %= 0.25', 'E734:') 4513 let x = 1 4514 call assert_fails('let x .= 0.25', 'E734:') 4515 let x = 1.0 4516 call assert_fails('let x += [1.1]', 'E734:') 4517 endif 4518 4519 " Test for environment variable 4520 let $FOO = 1 4521 call assert_fails('let $FOO += 1', 'E734') 4522 call assert_fails('let $FOO -= 1', 'E734') 4523 call assert_fails('let $FOO *= 1', 'E734') 4524 call assert_fails('let $FOO /= 1', 'E734') 4525 call assert_fails('let $FOO %= 1', 'E734') 4526 let $FOO .= 's' 4527 call assert_equal('1s', $FOO) 4528 unlet $FOO 4529 4530 " Test for option variable (type: number) 4531 let &scrolljump = 1 4532 let &scrolljump += 5 4533 call assert_equal(6, &scrolljump) 4534 let &scrolljump -= 2 4535 call assert_equal(4, &scrolljump) 4536 let &scrolljump *= 3 4537 call assert_equal(12, &scrolljump) 4538 let &scrolljump /= 2 4539 call assert_equal(6, &scrolljump) 4540 let &scrolljump %= 5 4541 call assert_equal(1, &scrolljump) 4542 call assert_fails('let &scrolljump .= "j"', 'E734') 4543 set scrolljump&vim 4544 4545 " Test for register 4546 let @/ = 1 4547 call assert_fails('let @/ += 1', 'E734') 4548 call assert_fails('let @/ -= 1', 'E734') 4549 call assert_fails('let @/ *= 1', 'E734') 4550 call assert_fails('let @/ /= 1', 'E734') 4551 call assert_fails('let @/ %= 1', 'E734') 4552 let @/ .= 's' 4553 call assert_equal('1s', @/) 4554 let @/ = '' 4555endfunc 4556 4557func Test_unlet_env() 4558 let $TESTVAR = 'yes' 4559 call assert_equal('yes', $TESTVAR) 4560 call assert_fails('lockvar $TESTVAR', 'E940') 4561 call assert_fails('unlockvar $TESTVAR', 'E940') 4562 call assert_equal('yes', $TESTVAR) 4563 if 0 4564 unlet $TESTVAR 4565 endif 4566 call assert_equal('yes', $TESTVAR) 4567 unlet $TESTVAR 4568 call assert_equal('', $TESTVAR) 4569endfunc 4570 4571func Test_refcount() 4572 " Immediate values 4573 call assert_equal(-1, test_refcount(1)) 4574 call assert_equal(-1, test_refcount('s')) 4575 call assert_equal(-1, test_refcount(v:true)) 4576 call assert_equal(0, test_refcount([])) 4577 call assert_equal(0, test_refcount({})) 4578 call assert_equal(0, test_refcount(0zff)) 4579 call assert_equal(0, test_refcount({-> line('.')})) 4580 if has('float') 4581 call assert_equal(-1, test_refcount(0.1)) 4582 endif 4583 if has('job') 4584 call assert_equal(0, test_refcount(job_start([&shell, &shellcmdflag, 'echo .']))) 4585 endif 4586 4587 " No refcount types 4588 let x = 1 4589 call assert_equal(-1, test_refcount(x)) 4590 let x = 's' 4591 call assert_equal(-1, test_refcount(x)) 4592 let x = v:true 4593 call assert_equal(-1, test_refcount(x)) 4594 if has('float') 4595 let x = 0.1 4596 call assert_equal(-1, test_refcount(x)) 4597 endif 4598 4599 " Check refcount 4600 let x = [] 4601 call assert_equal(1, test_refcount(x)) 4602 4603 let x = {} 4604 call assert_equal(1, x->test_refcount()) 4605 4606 let x = 0zff 4607 call assert_equal(1, test_refcount(x)) 4608 4609 let X = {-> line('.')} 4610 call assert_equal(1, test_refcount(X)) 4611 let Y = X 4612 call assert_equal(2, test_refcount(X)) 4613 4614 if has('job') 4615 let job = job_start([&shell, &shellcmdflag, 'echo .']) 4616 call assert_equal(1, test_refcount(job)) 4617 call assert_equal(1, test_refcount(job_getchannel(job))) 4618 call assert_equal(1, test_refcount(job)) 4619 endif 4620 4621 " Function arguments, copying and unassigning 4622 func ExprCheck(x, i) 4623 let i = a:i + 1 4624 call assert_equal(i, test_refcount(a:x)) 4625 let Y = a:x 4626 call assert_equal(i + 1, test_refcount(a:x)) 4627 call assert_equal(test_refcount(a:x), test_refcount(Y)) 4628 let Y = 0 4629 call assert_equal(i, test_refcount(a:x)) 4630 endfunc 4631 call ExprCheck([], 0) 4632 call ExprCheck({}, 0) 4633 call ExprCheck(0zff, 0) 4634 call ExprCheck({-> line('.')}, 0) 4635 if has('job') 4636 call ExprCheck(job, 1) 4637 call ExprCheck(job_getchannel(job), 1) 4638 call job_stop(job) 4639 endif 4640 delfunc ExprCheck 4641 4642 " Regarding function 4643 func Func(x) abort 4644 call assert_equal(2, test_refcount(function('Func'))) 4645 call assert_equal(0, test_refcount(funcref('Func'))) 4646 endfunc 4647 call assert_equal(1, test_refcount(function('Func'))) 4648 call assert_equal(0, test_refcount(function('Func', [1]))) 4649 call assert_equal(0, test_refcount(funcref('Func'))) 4650 call assert_equal(0, test_refcount(funcref('Func', [1]))) 4651 let X = function('Func') 4652 let Y = X 4653 call assert_equal(1, test_refcount(X)) 4654 let X = function('Func', [1]) 4655 let Y = X 4656 call assert_equal(2, test_refcount(X)) 4657 let X = funcref('Func') 4658 let Y = X 4659 call assert_equal(2, test_refcount(X)) 4660 let X = funcref('Func', [1]) 4661 let Y = X 4662 call assert_equal(2, test_refcount(X)) 4663 unlet X 4664 unlet Y 4665 call Func(1) 4666 delfunc Func 4667 4668 " Function with dict 4669 func DictFunc() dict 4670 call assert_equal(3, test_refcount(self)) 4671 endfunc 4672 let d = {'Func': function('DictFunc')} 4673 call assert_equal(1, test_refcount(d)) 4674 call assert_equal(0, test_refcount(d.Func)) 4675 call d.Func() 4676 unlet d 4677 delfunc DictFunc 4678endfunc 4679 4680" Test for missing :endif, :endfor, :endwhile and :endtry {{{1 4681func Test_missing_end() 4682 call writefile(['if 2 > 1', 'echo ">"'], 'Xscript') 4683 call assert_fails('source Xscript', 'E171:') 4684 call writefile(['for i in range(5)', 'echo i'], 'Xscript') 4685 call assert_fails('source Xscript', 'E170:') 4686 call writefile(['while v:true', 'echo "."'], 'Xscript') 4687 call assert_fails('source Xscript', 'E170:') 4688 call writefile(['try', 'echo "."'], 'Xscript') 4689 call assert_fails('source Xscript', 'E600:') 4690 call delete('Xscript') 4691 4692 " Using endfor with :while 4693 let caught_e732 = 0 4694 try 4695 while v:true 4696 endfor 4697 catch /E732:/ 4698 let caught_e732 = 1 4699 endtry 4700 call assert_equal(1, caught_e732) 4701 4702 " Using endwhile with :for 4703 let caught_e733 = 0 4704 try 4705 for i in range(1) 4706 endwhile 4707 catch /E733:/ 4708 let caught_e733 = 1 4709 endtry 4710 call assert_equal(1, caught_e733) 4711 4712 " Using endfunc with :if 4713 call assert_fails('exe "if 1 | endfunc | endif"', 'E193:') 4714 4715 " Missing 'in' in a :for statement 4716 call assert_fails('for i range(1) | endfor', 'E690:') 4717 4718 " Incorrect number of variables in for 4719 call assert_fails('for [i,] in range(3) | endfor', 'E475:') 4720endfunc 4721 4722" Test for deep nesting of if/for/while/try statements {{{1 4723func Test_deep_nest() 4724 CheckRunVimInTerminal 4725 4726 let lines =<< trim [SCRIPT] 4727 " Deep nesting of if ... endif 4728 func Test1() 4729 let @a = join(repeat(['if v:true'], 51), "\n") 4730 let @a ..= "\n" 4731 let @a ..= join(repeat(['endif'], 51), "\n") 4732 @a 4733 let @a = '' 4734 endfunc 4735 4736 " Deep nesting of for ... endfor 4737 func Test2() 4738 let @a = join(repeat(['for i in [1]'], 51), "\n") 4739 let @a ..= "\n" 4740 let @a ..= join(repeat(['endfor'], 51), "\n") 4741 @a 4742 let @a = '' 4743 endfunc 4744 4745 " Deep nesting of while ... endwhile 4746 func Test3() 4747 let @a = join(repeat(['while v:true'], 51), "\n") 4748 let @a ..= "\n" 4749 let @a ..= join(repeat(['endwhile'], 51), "\n") 4750 @a 4751 let @a = '' 4752 endfunc 4753 4754 " Deep nesting of try ... endtry 4755 func Test4() 4756 let @a = join(repeat(['try'], 51), "\n") 4757 let @a ..= "\necho v:true\n" 4758 let @a ..= join(repeat(['endtry'], 51), "\n") 4759 @a 4760 let @a = '' 4761 endfunc 4762 4763 " Deep nesting of function ... endfunction 4764 func Test5() 4765 let @a = join(repeat(['function X()'], 51), "\n") 4766 let @a ..= "\necho v:true\n" 4767 let @a ..= join(repeat(['endfunction'], 51), "\n") 4768 @a 4769 let @a = '' 4770 endfunc 4771 [SCRIPT] 4772 call writefile(lines, 'Xscript') 4773 4774 let buf = RunVimInTerminal('-S Xscript', {'rows': 6}) 4775 4776 " Deep nesting of if ... endif 4777 call term_sendkeys(buf, ":call Test1()\n") 4778 call TermWait(buf) 4779 call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))}) 4780 4781 " Deep nesting of for ... endfor 4782 call term_sendkeys(buf, ":call Test2()\n") 4783 call TermWait(buf) 4784 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))}) 4785 4786 " Deep nesting of while ... endwhile 4787 call term_sendkeys(buf, ":call Test3()\n") 4788 call TermWait(buf) 4789 call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))}) 4790 4791 " Deep nesting of try ... endtry 4792 call term_sendkeys(buf, ":call Test4()\n") 4793 call TermWait(buf) 4794 call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))}) 4795 4796 " Deep nesting of function ... endfunction 4797 call term_sendkeys(buf, ":call Test5()\n") 4798 call TermWait(buf) 4799 call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))}) 4800 call term_sendkeys(buf, "\<C-C>\n") 4801 call TermWait(buf) 4802 4803 "let l = '' 4804 "for i in range(1, 6) 4805 " let l ..= term_getline(buf, i) . "\n" 4806 "endfor 4807 "call assert_report(l) 4808 4809 call StopVimInTerminal(buf) 4810 call delete('Xscript') 4811endfunc 4812 4813" Test for errors in converting to float from various types {{{1 4814func Test_float_conversion_errors() 4815 if has('float') 4816 call assert_fails('let x = 4.0 % 2.0', 'E804') 4817 call assert_fails('echo 1.1[0]', 'E806') 4818 call assert_fails('echo sort([function("min"), 1], "f")', 'E891:') 4819 call assert_fails('echo 3.2 == "vim"', 'E892:') 4820 call assert_fails('echo sort([[], 1], "f")', 'E893:') 4821 call assert_fails('echo sort([{}, 1], "f")', 'E894:') 4822 call assert_fails('echo 3.2 == v:true', 'E362:') 4823 call assert_fails('echo 3.2 == v:none', 'E907:') 4824 endif 4825endfunc 4826 4827" invalid function names {{{1 4828func Test_invalid_function_names() 4829 " function name not starting with capital 4830 let caught_e128 = 0 4831 try 4832 func! g:test() 4833 echo "test" 4834 endfunc 4835 catch /E128:/ 4836 let caught_e128 = 1 4837 endtry 4838 call assert_equal(1, caught_e128) 4839 4840 " function name includes a colon 4841 let caught_e884 = 0 4842 try 4843 func! b:test() 4844 echo "test" 4845 endfunc 4846 catch /E884:/ 4847 let caught_e884 = 1 4848 endtry 4849 call assert_equal(1, caught_e884) 4850 4851 " function name folowed by # 4852 let caught_e128 = 0 4853 try 4854 func! test2() "# 4855 echo "test2" 4856 endfunc 4857 catch /E128:/ 4858 let caught_e128 = 1 4859 endtry 4860 call assert_equal(1, caught_e128) 4861 4862 " function name starting with/without "g:", buffer-local funcref. 4863 function! g:Foo(n) 4864 return 'called Foo(' . a:n . ')' 4865 endfunction 4866 let b:my_func = function('Foo') 4867 call assert_equal('called Foo(1)', b:my_func(1)) 4868 call assert_equal('called Foo(2)', g:Foo(2)) 4869 call assert_equal('called Foo(3)', Foo(3)) 4870 delfunc g:Foo 4871 4872 " script-local function used in Funcref must exist. 4873 let lines =<< trim END 4874 func s:Testje() 4875 return "foo" 4876 endfunc 4877 let Bar = function('s:Testje') 4878 call assert_equal(0, exists('s:Testje')) 4879 call assert_equal(1, exists('*s:Testje')) 4880 call assert_equal(1, exists('Bar')) 4881 call assert_equal(1, exists('*Bar')) 4882 END 4883 call writefile(lines, 'Xscript') 4884 source Xscript 4885 call delete('Xscript') 4886endfunc 4887 4888" substring and variable name {{{1 4889func Test_substring_var() 4890 let str = 'abcdef' 4891 let n = 3 4892 call assert_equal('def', str[n:]) 4893 call assert_equal('abcd', str[:n]) 4894 call assert_equal('d', str[n:n]) 4895 unlet n 4896 let nn = 3 4897 call assert_equal('def', str[nn:]) 4898 call assert_equal('abcd', str[:nn]) 4899 call assert_equal('d', str[nn:nn]) 4900 unlet nn 4901 let b:nn = 4 4902 call assert_equal('ef', str[b:nn:]) 4903 call assert_equal('abcde', str[:b:nn]) 4904 call assert_equal('e', str[b:nn:b:nn]) 4905 unlet b:nn 4906endfunc 4907 4908" Test using s: with a typed command {{{1 4909func Test_typed_script_var() 4910 CheckRunVimInTerminal 4911 4912 let buf = RunVimInTerminal('', {'rows': 6}) 4913 4914 " Deep nesting of if ... endif 4915 call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n") 4916 call TermWait(buf) 4917 call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))}) 4918 4919 call StopVimInTerminal(buf) 4920endfunc 4921 4922"------------------------------------------------------------------------------- 4923" Modelines {{{1 4924" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 4925"------------------------------------------------------------------------------- 4926