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