aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/testdir/test_vimscript.vim
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 21:52:58 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 21:52:58 +0000
commit931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch)
treed8c1843a95da5ea0bb4acc09f7e37843d9995c86 /src/nvim/testdir/test_vimscript.vim
parent142d9041391780ac15b89886a54015fdc5c73995 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-userreg.tar.gz
rneovim-userreg.tar.bz2
rneovim-userreg.zip
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'src/nvim/testdir/test_vimscript.vim')
-rw-r--r--src/nvim/testdir/test_vimscript.vim7284
1 files changed, 0 insertions, 7284 deletions
diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim
deleted file mode 100644
index b0c4baf7c2..0000000000
--- a/src/nvim/testdir/test_vimscript.vim
+++ /dev/null
@@ -1,7284 +0,0 @@
-" Test various aspects of the Vim script language.
-" Most of this was formerly in test49.vim (developed by Servatius Brandt
-" <Servatius.Brandt@fujitsu-siemens.com>)
-
-source check.vim
-source shared.vim
-source script_util.vim
-
-"-------------------------------------------------------------------------------
-" Test environment {{{1
-"-------------------------------------------------------------------------------
-
-" Append a message to the "messages" file
-func Xout(text)
- split messages
- $put =a:text
- wq
-endfunc
-
-com! -nargs=1 Xout call Xout(<args>)
-
-" Create a new instance of Vim and run the commands in 'test' and then 'verify'
-" The commands in 'test' are expected to store the test results in the Xtest.out
-" file. If the test passes successfully, then Xtest.out should be empty.
-func RunInNewVim(test, verify)
- let init =<< trim END
- set cpo-=C " support line-continuation in sourced script
- source script_util.vim
- XpathINIT
- XloopINIT
- END
- let cleanup =<< trim END
- call writefile(v:errors, 'Xtest.out')
- qall
- END
- call writefile(init, 'Xtest.vim')
- call writefile(a:test, 'Xtest.vim', 'a')
- call writefile(a:verify, 'Xverify.vim')
- call writefile(cleanup, 'Xverify.vim', 'a')
- call RunVim([], [], "-S Xtest.vim -S Xverify.vim")
- call assert_equal([], readfile('Xtest.out'))
- call delete('Xtest.out')
- call delete('Xtest.vim')
- call delete('Xverify.vim')
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 1: :endwhile in function {{{1
-"
-" Detect if a broken loop is (incorrectly) reactivated by the
-" :endwhile. Use a :return to prevent an endless loop, and make
-" this test first to get a meaningful result on an error before other
-" tests will hang.
-"-------------------------------------------------------------------------------
-
-func T1_F()
- Xpath 'a'
- let first = 1
- while 1
- Xpath 'b'
- if first
- Xpath 'c'
- let first = 0
- break
- else
- Xpath 'd'
- return
- endif
- endwhile
-endfunc
-
-func T1_G()
- Xpath 'h'
- let first = 1
- while 1
- Xpath 'i'
- if first
- Xpath 'j'
- let first = 0
- break
- else
- Xpath 'k'
- return
- endif
- if 1 " unmatched :if
- endwhile
-endfunc
-
-func Test_endwhile_function()
- XpathINIT
- call T1_F()
- Xpath 'F'
-
- try
- call T1_G()
- catch
- " Catch missing :endif
- call assert_true(v:exception =~ 'E171')
- Xpath 'x'
- endtry
- Xpath 'G'
-
- call assert_equal('abcFhijxG', g:Xpath)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 2: :endwhile in script {{{1
-"
-" Detect if a broken loop is (incorrectly) reactivated by the
-" :endwhile. Use a :finish to prevent an endless loop, and place
-" this test before others that might hang to get a meaningful result
-" on an error.
-"
-" This test executes the bodies of the functions T1_F and T1_G from
-" the previous test as script files (:return replaced by :finish).
-"-------------------------------------------------------------------------------
-
-func Test_endwhile_script()
- XpathINIT
- ExecAsScript T1_F
- Xpath 'F'
- call DeleteTheScript()
-
- try
- ExecAsScript T1_G
- catch
- " Catch missing :endif
- call assert_true(v:exception =~ 'E171')
- Xpath 'x'
- endtry
- Xpath 'G'
- call DeleteTheScript()
-
- call assert_equal('abcFhijxG', g:Xpath)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 3: :if, :elseif, :while, :continue, :break {{{1
-"-------------------------------------------------------------------------------
-
-func Test_if_while()
- XpathINIT
- if 1
- Xpath 'a'
- let loops = 3
- while loops > -1 " main loop: loops == 3, 2, 1 (which breaks)
- if loops <= 0
- let break_err = 1
- let loops = -1
- else
- Xpath 'b' . loops
- endif
- if (loops == 2)
- while loops == 2 " dummy loop
- Xpath 'c' . loops
- let loops = loops - 1
- continue " stop dummy loop
- Xpath 'd' . loops
- endwhile
- continue " continue main loop
- Xpath 'e' . loops
- elseif (loops == 1)
- let p = 1
- while p " dummy loop
- Xpath 'f' . loops
- let p = 0
- break " break dummy loop
- Xpath 'g' . loops
- endwhile
- Xpath 'h' . loops
- unlet p
- break " break main loop
- Xpath 'i' . loops
- endif
- if (loops > 0)
- Xpath 'j' . loops
- endif
- while loops == 3 " dummy loop
- let loops = loops - 1
- endwhile " end dummy loop
- endwhile " end main loop
- Xpath 'k'
- else
- Xpath 'l'
- endif
- Xpath 'm'
- if exists("break_err")
- Xpath 'm'
- unlet break_err
- endif
-
- unlet loops
-
- call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
-endfunc
-
-" Check double quote after skipped "elseif" does not give error E15
-func Test_skipped_elseif()
- if "foo" ==? "foo"
- let result = "first"
- elseif "foo" ==? "foo"
- let result = "second"
- endif
- call assert_equal('first', result)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 4: :return {{{1
-"-------------------------------------------------------------------------------
-
-func T4_F()
- if 1
- Xpath 'a'
- let loops = 3
- while loops > 0 " 3: 2: 1:
- Xpath 'b' . loops
- if (loops == 2)
- Xpath 'c' . loops
- return
- Xpath 'd' . loops
- endif
- Xpath 'e' . loops
- let loops = loops - 1
- endwhile
- Xpath 'f'
- else
- Xpath 'g'
- endif
-endfunc
-
-func Test_return()
- XpathINIT
- call T4_F()
- Xpath '4'
-
- call assert_equal('ab3e3b2c24', g:Xpath)
-endfunc
-
-
-"-------------------------------------------------------------------------------
-" Test 5: :finish {{{1
-"
-" This test executes the body of the function T4_F from the previous
-" test as a script file (:return replaced by :finish).
-"-------------------------------------------------------------------------------
-
-func Test_finish()
- XpathINIT
- ExecAsScript T4_F
- Xpath '5'
- call DeleteTheScript()
-
- call assert_equal('ab3e3b2c25', g:Xpath)
-endfunc
-
-
-
-"-------------------------------------------------------------------------------
-" Test 6: Defining functions in :while loops {{{1
-"
-" Functions can be defined inside other functions. An inner function
-" gets defined when the outer function is executed. Functions may
-" also be defined inside while loops. Expressions in braces for
-" defining the function name are allowed.
-"
-" The functions are defined when sourcing the script, only the
-" resulting path is checked in the test function.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-" The command CALL collects the argument of all its invocations in "calls"
-" when used from a function (that is, when the global variable "calls" needs
-" the "g:" prefix). This is to check that the function code is skipped when
-" the function is defined. For inner functions, do so only if the outer
-" function is not being executed.
-"
-let calls = ""
-com! -nargs=1 CALL
- \ if !exists("calls") && !exists("outer") |
- \ let g:calls = g:calls . <args> |
- \ endif
-
-let i = 0
-while i < 3
- let i = i + 1
- if i == 1
- Xpath 'a'
- function! F1(arg)
- CALL a:arg
- let outer = 1
-
- let j = 0
- while j < 1
- Xpath 'b'
- let j = j + 1
- function! G1(arg)
- CALL a:arg
- endfunction
- Xpath 'c'
- endwhile
- endfunction
- Xpath 'd'
-
- continue
- endif
-
- Xpath 'e' . i
- function! F{i}(i, arg)
- CALL a:arg
- let outer = 1
-
- if a:i == 3
- Xpath 'f'
- endif
- let k = 0
- while k < 3
- Xpath 'g' . k
- let k = k + 1
- function! G{a:i}{k}(arg)
- CALL a:arg
- endfunction
- Xpath 'h' . k
- endwhile
- endfunction
- Xpath 'i'
-
-endwhile
-
-if exists("*G1")
- Xpath 'j'
-endif
-if exists("*F1")
- call F1("F1")
- if exists("*G1")
- call G1("G1")
- endif
-endif
-
-if exists("G21") || exists("G22") || exists("G23")
- Xpath 'k'
-endif
-if exists("*F2")
- call F2(2, "F2")
- if exists("*G21")
- call G21("G21")
- endif
- if exists("*G22")
- call G22("G22")
- endif
- if exists("*G23")
- call G23("G23")
- endif
-endif
-
-if exists("G31") || exists("G32") || exists("G33")
- Xpath 'l'
-endif
-if exists("*F3")
- call F3(3, "F3")
- if exists("*G31")
- call G31("G31")
- endif
- if exists("*G32")
- call G32("G32")
- endif
- if exists("*G33")
- call G33("G33")
- endif
-endif
-
-Xpath 'm'
-
-let g:test6_result = g:Xpath
-let g:test6_calls = calls
-
-unlet calls
-delfunction F1
-delfunction G1
-delfunction F2
-delfunction G21
-delfunction G22
-delfunction G23
-delfunction G31
-delfunction G32
-delfunction G33
-
-func Test_defining_functions()
- call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
- call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 7: Continuing on errors outside functions {{{1
-"
-" On an error outside a function, the script processing continues
-" at the line following the outermost :endif or :endwhile. When not
-" inside an :if or :while, the script processing continues at the next
-" line.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-if 1
- Xpath 'a'
- while 1
- Xpath 'b'
- asdf
- Xpath 'c'
- break
- endwhile | Xpath 'd'
- Xpath 'e'
-endif | Xpath 'f'
-Xpath 'g'
-
-while 1
- Xpath 'h'
- if 1
- Xpath 'i'
- asdf
- Xpath 'j'
- endif | Xpath 'k'
- Xpath 'l'
- break
-endwhile | Xpath 'm'
-Xpath 'n'
-
-asdf
-Xpath 'o'
-
-asdf | Xpath 'p'
-Xpath 'q'
-
-let g:test7_result = g:Xpath
-
-func Test_error_in_script()
- call assert_equal('abghinoq', g:test7_result)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 8: Aborting and continuing on errors inside functions {{{1
-"
-" On an error inside a function without the "abort" attribute, the
-" script processing continues at the next line (unless the error was
-" in a :return command). On an error inside a function with the
-" "abort" attribute, the function is aborted and the script processing
-" continues after the function call; the value -1 is returned then.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-func T8_F()
- if 1
- Xpath 'a'
- while 1
- Xpath 'b'
- asdf
- Xpath 'c'
- asdf | Xpath 'd'
- Xpath 'e'
- break
- endwhile
- Xpath 'f'
- endif | Xpath 'g'
- Xpath 'h'
-
- while 1
- Xpath 'i'
- if 1
- Xpath 'j'
- asdf
- Xpath 'k'
- asdf | Xpath 'l'
- Xpath 'm'
- endif
- Xpath 'n'
- break
- endwhile | Xpath 'o'
- Xpath 'p'
-
- return novar " returns (default return value 0)
- Xpath 'q'
- return 1 " not reached
-endfunc
-
-func T8_G() abort
- if 1
- Xpath 'r'
- while 1
- Xpath 's'
- asdf " returns -1
- Xpath 't'
- break
- endwhile
- Xpath 'v'
- endif | Xpath 'w'
- Xpath 'x'
-
- return -4 " not reached
-endfunc
-
-func T8_H() abort
- while 1
- Xpath 'A'
- if 1
- Xpath 'B'
- asdf " returns -1
- Xpath 'C'
- endif
- Xpath 'D'
- break
- endwhile | Xpath 'E'
- Xpath 'F'
-
- return -4 " not reached
-endfunc
-
-" Aborted functions (T8_G and T8_H) return -1.
-let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
-Xpath 'X'
-let g:test8_result = g:Xpath
-
-func Test_error_in_function()
- call assert_equal(13, g:test8_sum)
- call assert_equal('abcefghijkmnoprsABX', g:test8_result)
-
- delfunction T8_F
- delfunction T8_G
- delfunction T8_H
-endfunc
-
-
-"-------------------------------------------------------------------------------
-" Test 9: Continuing after aborted functions {{{1
-"
-" When a function with the "abort" attribute is aborted due to an
-" error, the next function back in the call hierarchy without an
-" "abort" attribute continues; the value -1 is returned then.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-func F() abort
- Xpath 'a'
- let result = G() " not aborted
- Xpath 'b'
- if result != 2
- Xpath 'c'
- endif
- return 1
-endfunc
-
-func G() " no abort attribute
- Xpath 'd'
- if H() != -1 " aborted
- Xpath 'e'
- endif
- Xpath 'f'
- return 2
-endfunc
-
-func H() abort
- Xpath 'g'
- call I() " aborted
- Xpath 'h'
- return 4
-endfunc
-
-func I() abort
- Xpath 'i'
- asdf " error
- Xpath 'j'
- return 8
-endfunc
-
-if F() != 1
- Xpath 'k'
-endif
-
-let g:test9_result = g:Xpath
-
-delfunction F
-delfunction G
-delfunction H
-delfunction I
-
-func Test_func_abort()
- call assert_equal('adgifb', g:test9_result)
-endfunc
-
-
-"-------------------------------------------------------------------------------
-" Test 10: :if, :elseif, :while argument parsing {{{1
-"
-" A '"' or '|' in an argument expression must not be mixed up with
-" a comment or a next command after a bar. Parsing errors should
-" be recognized.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-func MSG(enr, emsg)
- let english = v:lang == "C" || v:lang =~ '^[Ee]n'
- if a:enr == ""
- Xout "TODO: Add message number for:" a:emsg
- let v:errmsg = ":" . v:errmsg
- endif
- let match = 1
- if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
- let match = 0
- if v:errmsg == ""
- Xout "Message missing."
- else
- let v:errmsg = v:errmsg->escape('"')
- Xout "Unexpected message:" v:errmsg
- endif
- endif
- return match
-endfunc
-
-if 1 || strlen("\"") | Xpath 'a'
- Xpath 'b'
-endif
-Xpath 'c'
-
-if 0
-elseif 1 || strlen("\"") | Xpath 'd'
- Xpath 'e'
-endif
-Xpath 'f'
-
-while 1 || strlen("\"") | Xpath 'g'
- Xpath 'h'
- break
-endwhile
-Xpath 'i'
-
-let v:errmsg = ""
-if 1 ||| strlen("\"") | Xpath 'j'
- Xpath 'k'
-endif
-Xpath 'l'
-if !MSG('E15', "Invalid expression")
- Xpath 'm'
-endif
-
-let v:errmsg = ""
-if 0
-elseif 1 ||| strlen("\"") | Xpath 'n'
- Xpath 'o'
-endif
-Xpath 'p'
-if !MSG('E15', "Invalid expression")
- Xpath 'q'
-endif
-
-let v:errmsg = ""
-while 1 ||| strlen("\"") | Xpath 'r'
- Xpath 's'
- break
-endwhile
-Xpath 't'
-if !MSG('E15', "Invalid expression")
- Xpath 'u'
-endif
-
-let g:test10_result = g:Xpath
-delfunction MSG
-
-func Test_expr_parsing()
- call assert_equal('abcdefghilpt', g:test10_result)
-endfunc
-
-
-"-------------------------------------------------------------------------------
-" Test 11: :if, :elseif, :while argument evaluation after abort {{{1
-"
-" When code is skipped over due to an error, the boolean argument to
-" an :if, :elseif, or :while must not be evaluated.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let calls = 0
-
-func P(num)
- let g:calls = g:calls + a:num " side effect on call
- return 0
-endfunc
-
-if 1
- Xpath 'a'
- asdf " error
- Xpath 'b'
- if P(1) " should not be called
- Xpath 'c'
- elseif !P(2) " should not be called
- Xpath 'd'
- else
- Xpath 'e'
- endif
- Xpath 'f'
- while P(4) " should not be called
- Xpath 'g'
- endwhile
- Xpath 'h'
-endif
-Xpath 'x'
-
-let g:test11_calls = calls
-let g:test11_result = g:Xpath
-
-unlet calls
-delfunction P
-
-func Test_arg_abort()
- call assert_equal(0, g:test11_calls)
- call assert_equal('ax', g:test11_result)
-endfunc
-
-
-"-------------------------------------------------------------------------------
-" Test 12: Expressions in braces in skipped code {{{1
-"
-" In code skipped over due to an error or inactive conditional,
-" an expression in braces as part of a variable or function name
-" should not be evaluated.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-func NULL()
- Xpath 'a'
- return 0
-endfunc
-
-func ZERO()
- Xpath 'b'
- return 0
-endfunc
-
-func! F0()
- Xpath 'c'
-endfunc
-
-func! F1(arg)
- Xpath 'e'
-endfunc
-
-let V0 = 1
-
-Xpath 'f'
-echo 0 ? F{NULL() + V{ZERO()}}() : 1
-
-Xpath 'g'
-if 0
- Xpath 'h'
- call F{NULL() + V{ZERO()}}()
-endif
-
-Xpath 'i'
-if 1
- asdf " error
- Xpath 'j'
- call F1(F{NULL() + V{ZERO()}}())
-endif
-
-Xpath 'k'
-if 1
- asdf " error
- Xpath 'l'
- call F{NULL() + V{ZERO()}}()
-endif
-
-let g:test12_result = g:Xpath
-
-func Test_braces_skipped()
- call assert_equal('fgik', g:test12_result)
-endfunc
-
-
-"-------------------------------------------------------------------------------
-" Test 13: Failure in argument evaluation for :while {{{1
-"
-" A failure in the expression evaluation for the condition of a :while
-" causes the whole :while loop until the matching :endwhile being
-" ignored. Continuation is at the next following line.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-Xpath 'a'
-while asdf
- Xpath 'b'
- while 1
- Xpath 'c'
- break
- endwhile
- Xpath 'd'
- break
-endwhile
-Xpath 'e'
-
-while asdf | Xpath 'f' | endwhile | Xpath 'g'
-Xpath 'h'
-let g:test13_result = g:Xpath
-
-func Test_while_fail()
- call assert_equal('aeh', g:test13_result)
-endfunc
-
-
-"-------------------------------------------------------------------------------
-" Test 14: Failure in argument evaluation for :if {{{1
-"
-" A failure in the expression evaluation for the condition of an :if
-" does not cause the corresponding :else or :endif being matched to
-" a previous :if/:elseif. Neither of both branches of the failed :if
-" are executed.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! F()
- Xpath 'a'
- let x = 0
- if x " false
- Xpath 'b'
- elseif !x " always true
- Xpath 'c'
- let x = 1
- if g:boolvar " possibly undefined
- Xpath 'd'
- else
- Xpath 'e'
- endif
- Xpath 'f'
- elseif x " never executed
- Xpath 'g'
- endif
- Xpath 'h'
-endfunction
-
-let boolvar = 1
-call F()
-Xpath '-'
-
-unlet boolvar
-call F()
-let g:test14_result = g:Xpath
-
-delfunction F
-
-func Test_if_fail()
- call assert_equal('acdfh-acfh', g:test14_result)
-endfunc
-
-
-"-------------------------------------------------------------------------------
-" Test 15: Failure in argument evaluation for :if (bar) {{{1
-"
-" Like previous test, except that the failing :if ... | ... | :endif
-" is in a single line.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! F()
- Xpath 'a'
- let x = 0
- if x " false
- Xpath 'b'
- elseif !x " always true
- Xpath 'c'
- let x = 1
- if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
- Xpath 'f'
- elseif x " never executed
- Xpath 'g'
- endif
- Xpath 'h'
-endfunction
-
-let boolvar = 1
-call F()
-Xpath '-'
-
-unlet boolvar
-call F()
-let g:test15_result = g:Xpath
-
-delfunction F
-
-func Test_if_bar_fail()
- call assert_equal('acdfh-acfh', g:test15_result)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 16: Double :else or :elseif after :else {{{1
-"
-" Multiple :elses or an :elseif after an :else are forbidden.
-"-------------------------------------------------------------------------------
-
-func T16_F() abort
- if 0
- Xpath 'a'
- else
- Xpath 'b'
- else " aborts function
- Xpath 'c'
- endif
- Xpath 'd'
-endfunc
-
-func T16_G() abort
- if 0
- Xpath 'a'
- else
- Xpath 'b'
- elseif 1 " aborts function
- Xpath 'c'
- else
- Xpath 'd'
- endif
- Xpath 'e'
-endfunc
-
-func T16_H() abort
- if 0
- Xpath 'a'
- elseif 0
- Xpath 'b'
- else
- Xpath 'c'
- else " aborts function
- Xpath 'd'
- endif
- Xpath 'e'
-endfunc
-
-func T16_I() abort
- if 0
- Xpath 'a'
- elseif 0
- Xpath 'b'
- else
- Xpath 'c'
- elseif 1 " aborts function
- Xpath 'd'
- else
- Xpath 'e'
- endif
- Xpath 'f'
-endfunc
-
-func Test_Multi_Else()
- XpathINIT
- try
- call T16_F()
- catch /E583:/
- Xpath 'e'
- endtry
- call assert_equal('be', g:Xpath)
-
- XpathINIT
- try
- call T16_G()
- catch /E584:/
- Xpath 'f'
- endtry
- call assert_equal('bf', g:Xpath)
-
- XpathINIT
- try
- call T16_H()
- catch /E583:/
- Xpath 'f'
- endtry
- call assert_equal('cf', g:Xpath)
-
- XpathINIT
- try
- call T16_I()
- catch /E584:/
- Xpath 'g'
- endtry
- call assert_equal('cg', g:Xpath)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1
-"
-" The :while/:endwhile takes precedence in nesting over an unclosed
-" :if or an unopened :endif.
-"-------------------------------------------------------------------------------
-
-" While loops inside a function are continued on error.
-func T17_F()
- let loops = 3
- while loops > 0
- let loops -= 1
- Xpath 'a' . loops
- if (loops == 1)
- Xpath 'b' . loops
- continue
- elseif (loops == 0)
- Xpath 'c' . loops
- break
- elseif 1
- Xpath 'd' . loops
- " endif missing!
- endwhile " :endwhile after :if 1
- Xpath 'e'
-endfunc
-
-func T17_G()
- let loops = 2
- while loops > 0
- let loops -= 1
- Xpath 'a' . loops
- if 0
- Xpath 'b' . loops
- " endif missing
- endwhile " :endwhile after :if 0
-endfunc
-
-func T17_H()
- let loops = 2
- while loops > 0
- let loops -= 1
- Xpath 'a' . loops
- " if missing!
- endif " :endif without :if in while
- Xpath 'b' . loops
- endwhile
-endfunc
-
-" Error continuation outside a function is at the outermost :endwhile or :endif.
-XpathINIT
-let v:errmsg = ''
-let loops = 2
-while loops > 0
- let loops -= 1
- Xpath 'a' . loops
- if 0
- Xpath 'b' . loops
- " endif missing! Following :endwhile fails.
-endwhile | Xpath 'c'
-Xpath 'd'
-call assert_match('E171:', v:errmsg)
-call assert_equal('a1d', g:Xpath)
-
-func Test_unmatched_if_in_while()
- XpathINIT
- call assert_fails('call T17_F()', 'E171:')
- call assert_equal('a2d2a1b1a0c0e', g:Xpath)
-
- XpathINIT
- call assert_fails('call T17_G()', 'E171:')
- call assert_equal('a1a0', g:Xpath)
-
- XpathINIT
- call assert_fails('call T17_H()', 'E580:')
- call assert_equal('a1b1a0b0', g:Xpath)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 18: Interrupt (Ctrl-C pressed) {{{1
-"
-" On an interrupt, the script processing is terminated immediately.
-"-------------------------------------------------------------------------------
-
-func Test_interrupt_while_if()
- let test =<< trim [CODE]
- try
- if 1
- Xpath 'a'
- while 1
- Xpath 'b'
- if 1
- Xpath 'c'
- call interrupt()
- call assert_report('should not get here')
- break
- finish
- endif | call assert_report('should not get here')
- call assert_report('should not get here')
- endwhile | call assert_report('should not get here')
- call assert_report('should not get here')
- endif | call assert_report('should not get here')
- call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'd'
- endtry | Xpath 'e'
- Xpath 'f'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdef', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_interrupt_try()
- let test =<< trim [CODE]
- try
- try
- Xpath 'a'
- call interrupt()
- call assert_report('should not get here')
- endtry | call assert_report('should not get here')
- call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'b'
- endtry | Xpath 'c'
- Xpath 'd'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcd', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_interrupt_func_while_if()
- let test =<< trim [CODE]
- func F()
- if 1
- Xpath 'a'
- while 1
- Xpath 'b'
- if 1
- Xpath 'c'
- call interrupt()
- call assert_report('should not get here')
- break
- return
- endif | call assert_report('should not get here')
- call assert_report('should not get here')
- endwhile | call assert_report('should not get here')
- call assert_report('should not get here')
- endif | call assert_report('should not get here')
- call assert_report('should not get here')
- endfunc
-
- Xpath 'd'
- try
- call F() | call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'e'
- endtry | Xpath 'f'
- Xpath 'g'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('dabcefg', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_interrupt_func_try()
- let test =<< trim [CODE]
- func G()
- try
- Xpath 'a'
- call interrupt()
- call assert_report('should not get here')
- endtry | call assert_report('should not get here')
- call assert_report('should not get here')
- endfunc
-
- Xpath 'b'
- try
- call G() | call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'c'
- endtry | Xpath 'd'
- Xpath 'e'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('bacde', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 19: Aborting on errors inside :try/:endtry {{{1
-"
-" An error in a command dynamically enclosed in a :try/:endtry region
-" aborts script processing immediately. It does not matter whether
-" the failing command is outside or inside a function and whether a
-" function has an "abort" attribute.
-"-------------------------------------------------------------------------------
-
-func Test_try_error_abort_1()
- let test =<< trim [CODE]
- func F() abort
- Xpath 'a'
- asdf
- call assert_report('should not get here')
- endfunc
-
- try
- Xpath 'b'
- call F()
- call assert_report('should not get here')
- endtry | call assert_report('should not get here')
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ba', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_try_error_abort_2()
- let test =<< trim [CODE]
- func G()
- Xpath 'a'
- asdf
- call assert_report('should not get here')
- endfunc
-
- try
- Xpath 'b'
- call G()
- call assert_report('should not get here')
- endtry | call assert_report('should not get here')
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ba', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_try_error_abort_3()
- let test =<< trim [CODE]
- try
- Xpath 'a'
- asdf
- call assert_report('should not get here')
- endtry | call assert_report('should not get here')
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_try_error_abort_4()
- let test =<< trim [CODE]
- if 1
- try
- Xpath 'a'
- asdf
- call assert_report('should not get here')
- endtry | call assert_report('should not get here')
- endif | call assert_report('should not get here')
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_try_error_abort_5()
- let test =<< trim [CODE]
- let p = 1
- while p
- let p = 0
- try
- Xpath 'a'
- asdf
- call assert_report('should not get here')
- endtry | call assert_report('should not get here')
- endwhile | call assert_report('should not get here')
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_try_error_abort_6()
- let test =<< trim [CODE]
- let p = 1
- Xpath 'a'
- while p
- Xpath 'b'
- let p = 0
- try
- Xpath 'c'
- endwhile | call assert_report('should not get here')
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 20: Aborting on errors after :try/:endtry {{{1
-"
-" When an error occurs after the last active :try/:endtry region has
-" been left, termination behavior is as if no :try/:endtry has been
-" seen.
-"-------------------------------------------------------------------------------
-
-func Test_error_after_try_1()
- let test =<< trim [CODE]
- let p = 1
- while p
- let p = 0
- Xpath 'a'
- try
- Xpath 'b'
- endtry
- asdf
- call assert_report('should not get here')
- endwhile | call assert_report('should not get here')
- Xpath 'c'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_error_after_try_2()
- let test =<< trim [CODE]
- while 1
- try
- Xpath 'a'
- break
- call assert_report('should not get here')
- endtry
- endwhile
- Xpath 'b'
- asdf
- Xpath 'c'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_error_after_try_3()
- let test =<< trim [CODE]
- while 1
- try
- Xpath 'a'
- break
- call assert_report('should not get here')
- finally
- Xpath 'b'
- endtry
- endwhile
- Xpath 'c'
- asdf
- Xpath 'd'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcd', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_error_after_try_4()
- let test =<< trim [CODE]
- while 1
- try
- Xpath 'a'
- finally
- Xpath 'b'
- break
- call assert_report('should not get here')
- endtry
- endwhile
- Xpath 'c'
- asdf
- Xpath 'd'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcd', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_error_after_try_5()
- let test =<< trim [CODE]
- let p = 1
- while p
- let p = 0
- try
- Xpath 'a'
- continue
- call assert_report('should not get here')
- endtry
- endwhile
- Xpath 'b'
- asdf
- Xpath 'c'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_error_after_try_6()
- let test =<< trim [CODE]
- let p = 1
- while p
- let p = 0
- try
- Xpath 'a'
- continue
- call assert_report('should not get here')
- finally
- Xpath 'b'
- endtry
- endwhile
- Xpath 'c'
- asdf
- Xpath 'd'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcd', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_error_after_try_7()
- let test =<< trim [CODE]
- let p = 1
- while p
- let p = 0
- try
- Xpath 'a'
- finally
- Xpath 'b'
- continue
- call assert_report('should not get here')
- endtry
- endwhile
- Xpath 'c'
- asdf
- Xpath 'd'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcd', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1
-"
-" If a :try conditional stays inactive due to a preceding :continue,
-" :break, :return, or :finish, its :finally clause should not be
-" executed.
-"-------------------------------------------------------------------------------
-
-func Test_finally_after_loop_ctrl_statement()
- let test =<< trim [CODE]
- func F()
- let loops = 2
- while loops > 0
- XloopNEXT
- let loops = loops - 1
- try
- if loops == 1
- Xloop 'a'
- continue
- call assert_report('should not get here')
- elseif loops == 0
- Xloop 'b'
- break
- call assert_report('should not get here')
- endif
-
- try " inactive
- call assert_report('should not get here')
- finally
- call assert_report('should not get here')
- endtry
- finally
- Xloop 'c'
- endtry
- call assert_report('should not get here')
- endwhile
-
- try
- Xpath 'd'
- return
- call assert_report('should not get here')
- try " inactive
- call assert_report('should not get here')
- finally
- call assert_report('should not get here')
- endtry
- finally
- Xpath 'e'
- endtry
- call assert_report('should not get here')
- endfunc
-
- try
- Xpath 'f'
- call F()
- Xpath 'g'
- finish
- call assert_report('should not get here')
- try " inactive
- call assert_report('should not get here')
- finally
- call assert_report('should not get here')
- endtry
- finally
- Xpath 'h'
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('fa2c2b3c3degh', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 22: :finally for a :try after an error/interrupt/:throw {{{1
-"
-" If a :try conditional stays inactive due to a preceding error or
-" interrupt or :throw, its :finally clause should not be executed.
-"-------------------------------------------------------------------------------
-
-func Test_finally_after_error_in_func()
- let test =<< trim [CODE]
- func Error()
- try
- Xpath 'b'
- asdf " aborting error, triggering error exception
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endfunc
-
- Xpath 'a'
- call Error()
- call assert_report('should not get here')
-
- if 1 " not active due to error
- try " not active since :if inactive
- call assert_report('should not get here')
- finally
- call assert_report('should not get here')
- endtry
- endif
-
- try " not active due to error
- call assert_report('should not get here')
- finally
- call assert_report('should not get here')
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ab', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_finally_after_interrupt()
- let test =<< trim [CODE]
- func Interrupt()
- try
- Xpath 'a'
- call interrupt() " triggering interrupt exception
- call assert_report('should not get here')
- endtry
- endfunc
-
- Xpath 'b'
- try
- call Interrupt()
- catch /^Vim:Interrupt$/
- Xpath 'c'
- finish
- endtry
- call assert_report('should not get here')
-
- if 1 " not active due to interrupt
- try " not active since :if inactive
- call assert_report('should not get here')
- finally
- call assert_report('should not get here')
- endtry
- endif
-
- try " not active due to interrupt
- call assert_report('should not get here')
- finally
- call assert_report('should not get here')
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('bac', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_finally_after_throw()
- let test =<< trim [CODE]
- func Throw()
- Xpath 'a'
- throw 'xyz'
- endfunc
-
- Xpath 'b'
- call Throw()
- call assert_report('should not get here')
-
- if 1 " not active due to :throw
- try " not active since :if inactive
- call assert_report('should not get here')
- finally
- call assert_report('should not get here')
- endtry
- endif
-
- try " not active due to :throw
- call assert_report('should not get here')
- finally
- call assert_report('should not get here')
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ba', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 23: :catch clauses for a :try after a :throw {{{1
-"
-" If a :try conditional stays inactive due to a preceding :throw,
-" none of its :catch clauses should be executed.
-"-------------------------------------------------------------------------------
-
-func Test_catch_after_throw()
- let test =<< trim [CODE]
- try
- Xpath 'a'
- throw "xyz"
- call assert_report('should not get here')
-
- if 1 " not active due to :throw
- try " not active since :if inactive
- call assert_report('should not get here')
- catch /xyz/
- call assert_report('should not get here')
- endtry
- endif
- catch /xyz/
- Xpath 'b'
- endtry
-
- Xpath 'c'
- throw "abc"
- call assert_report('should not get here')
-
- try " not active due to :throw
- call assert_report('should not get here')
- catch /abc/
- call assert_report('should not get here')
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 24: :endtry for a :try after a :throw {{{1
-"
-" If a :try conditional stays inactive due to a preceding :throw,
-" its :endtry should not rethrow the exception to the next surrounding
-" active :try conditional.
-"-------------------------------------------------------------------------------
-
-func Test_endtry_after_throw()
- let test =<< trim [CODE]
- try " try 1
- try " try 2
- Xpath 'a'
- throw "xyz" " makes try 2 inactive
- call assert_report('should not get here')
-
- try " try 3
- call assert_report('should not get here')
- endtry " no rethrow to try 1
- catch /xyz/ " should catch although try 2 inactive
- Xpath 'b'
- endtry
- catch /xyz/ " try 1 active, but exception already caught
- call assert_report('should not get here')
- endtry
- Xpath 'c'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 27: Executing :finally clauses after :return {{{1
-"
-" For a :return command dynamically enclosed in a :try/:endtry region,
-" :finally clauses are executed and the called function is ended.
-"-------------------------------------------------------------------------------
-
-func T27_F()
- try
- Xpath 'a'
- try
- Xpath 'b'
- return
- call assert_report('should not get here')
- finally
- Xpath 'c'
- endtry
- Xpath 'd'
- finally
- Xpath 'e'
- endtry
- call assert_report('should not get here')
-endfunc
-
-func T27_G()
- try
- Xpath 'f'
- return
- call assert_report('should not get here')
- finally
- Xpath 'g'
- call T27_F()
- Xpath 'h'
- endtry
- call assert_report('should not get here')
-endfunc
-
-func T27_H()
- try
- Xpath 'i'
- call T27_G()
- Xpath 'j'
- finally
- Xpath 'k'
- return
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
-endfunction
-
-func Test_finally_after_return()
- XpathINIT
- try
- Xpath 'l'
- call T27_H()
- Xpath 'm'
- finally
- Xpath 'n'
- endtry
- call assert_equal('lifgabcehjkmn', g:Xpath)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 28: Executing :finally clauses after :finish {{{1
-"
-" For a :finish command dynamically enclosed in a :try/:endtry region,
-" :finally clauses are executed and the sourced file is finished.
-"
-" This test executes the bodies of the functions F, G, and H from the
-" previous test as script files (:return replaced by :finish).
-"-------------------------------------------------------------------------------
-
-func Test_finally_after_finish()
- XpathINIT
-
- let scriptF = MakeScript("T27_F")
- let scriptG = MakeScript("T27_G", scriptF)
- let scriptH = MakeScript("T27_H", scriptG)
-
- try
- Xpath 'A'
- exec "source" scriptH
- Xpath 'B'
- finally
- Xpath 'C'
- endtry
- Xpath 'D'
- call assert_equal('AifgabcehjkBCD', g:Xpath)
- call delete(scriptF)
- call delete(scriptG)
- call delete(scriptH)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 29: Executing :finally clauses on errors {{{1
-"
-" After an error in a command dynamically enclosed in a :try/:endtry
-" region, :finally clauses are executed and the script processing is
-" terminated.
-"-------------------------------------------------------------------------------
-
-func Test_finally_after_error_1()
- let test =<< trim [CODE]
- func F()
- while 1
- try
- Xpath 'a'
- while 1
- try
- Xpath 'b'
- asdf " error
- call assert_report('should not get here')
- finally
- Xpath 'c'
- endtry | call assert_report('should not get here')
- call assert_report('should not get here')
- break
- endwhile
- call assert_report('should not get here')
- finally
- Xpath 'd'
- endtry | call assert_report('should not get here')
- call assert_report('should not get here')
- break
- endwhile
- call assert_report('should not get here')
- endfunc
-
- while 1
- try
- Xpath 'e'
- while 1
- call F()
- call assert_report('should not get here')
- break
- endwhile | call assert_report('should not get here')
- call assert_report('should not get here')
- finally
- Xpath 'f'
- endtry | call assert_report('should not get here')
- endwhile | call assert_report('should not get here')
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('eabcdf', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_finally_after_error_2()
- let test =<< trim [CODE]
- func G() abort
- if 1
- try
- Xpath 'a'
- asdf " error
- call assert_report('should not get here')
- finally
- Xpath 'b'
- endtry | Xpath 'c'
- endif | Xpath 'd'
- call assert_report('should not get here')
- endfunc
-
- if 1
- try
- Xpath 'e'
- call G()
- call assert_report('should not get here')
- finally
- Xpath 'f'
- endtry | call assert_report('should not get here')
- endif | call assert_report('should not get here')
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('eabf', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 30: Executing :finally clauses on interrupt {{{1
-"
-" After an interrupt in a command dynamically enclosed in
-" a :try/:endtry region, :finally clauses are executed and the
-" script processing is terminated.
-"-------------------------------------------------------------------------------
-
-func Test_finally_on_interrupt()
- let test =<< trim [CODE]
- func F()
- try
- Xloop 'a'
- call interrupt()
- call assert_report('should not get here')
- finally
- Xloop 'b'
- endtry
- call assert_report('should not get here')
- endfunc
-
- try
- try
- Xpath 'c'
- try
- Xpath 'd'
- call interrupt()
- call assert_report('should not get here')
- finally
- Xpath 'e'
- try
- Xpath 'f'
- try
- Xpath 'g'
- finally
- Xpath 'h'
- try
- Xpath 'i'
- call interrupt()
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- finally
- Xpath 'j'
- try
- Xpath 'k'
- call F()
- call assert_report('should not get here')
- finally
- Xpath 'l'
- try
- Xpath 'm'
- XloopNEXT
- ExecAsScript F
- call assert_report('should not get here')
- finally
- Xpath 'n'
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'o'
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('cdefghijka1b1lma2b2no', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 31: Executing :finally clauses after :throw {{{1
-"
-" After a :throw dynamically enclosed in a :try/:endtry region,
-" :finally clauses are executed and the script processing is
-" terminated.
-"-------------------------------------------------------------------------------
-
-func Test_finally_after_throw_2()
- let test =<< trim [CODE]
- func F()
- try
- Xloop 'a'
- throw "exception"
- call assert_report('should not get here')
- finally
- Xloop 'b'
- endtry
- call assert_report('should not get here')
- endfunc
-
- try
- Xpath 'c'
- try
- Xpath 'd'
- throw "exception"
- call assert_report('should not get here')
- finally
- Xpath 'e'
- try
- Xpath 'f'
- try
- Xpath 'g'
- finally
- Xpath 'h'
- try
- Xpath 'i'
- throw "exception"
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- finally
- Xpath 'j'
- try
- Xpath 'k'
- call F()
- call assert_report('should not get here')
- finally
- Xpath 'l'
- try
- Xpath 'm'
- XloopNEXT
- ExecAsScript F
- call assert_report('should not get here')
- finally
- Xpath 'n'
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('cdefghijka1b1lma2b2n', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 34: :finally reason discarded by :continue {{{1
-"
-" When a :finally clause is executed due to a :continue, :break,
-" :return, :finish, error, interrupt or :throw, the jump reason is
-" discarded by a :continue in the finally clause.
-"-------------------------------------------------------------------------------
-
-func Test_finally_after_continue()
- let test =<< trim [CODE]
- func C(jump)
- XloopNEXT
- let loop = 0
- while loop < 2
- let loop = loop + 1
- if loop == 1
- try
- if a:jump == "continue"
- continue
- elseif a:jump == "break"
- break
- elseif a:jump == "return" || a:jump == "finish"
- return
- elseif a:jump == "error"
- asdf
- elseif a:jump == "interrupt"
- call interrupt()
- let dummy = 0
- elseif a:jump == "throw"
- throw "abc"
- endif
- finally
- continue " discards jump that caused the :finally
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- elseif loop == 2
- Xloop 'a'
- endif
- endwhile
- endfunc
-
- call C("continue")
- Xpath 'b'
- call C("break")
- Xpath 'c'
- call C("return")
- Xpath 'd'
- let g:jump = "finish"
- ExecAsScript C
- unlet g:jump
- Xpath 'e'
- try
- call C("error")
- Xpath 'f'
- finally
- Xpath 'g'
- try
- call C("interrupt")
- Xpath 'h'
- finally
- Xpath 'i'
- call C("throw")
- Xpath 'j'
- endtry
- endtry
- Xpath 'k'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 35: :finally reason discarded by :break {{{1
-"
-" When a :finally clause is executed due to a :continue, :break,
-" :return, :finish, error, interrupt or :throw, the jump reason is
-" discarded by a :break in the finally clause.
-"-------------------------------------------------------------------------------
-
-func Test_finally_discard_by_break()
- let test =<< trim [CODE]
- func B(jump)
- XloopNEXT
- let loop = 0
- while loop < 2
- let loop = loop + 1
- if loop == 1
- try
- if a:jump == "continue"
- continue
- elseif a:jump == "break"
- break
- elseif a:jump == "return" || a:jump == "finish"
- return
- elseif a:jump == "error"
- asdf
- elseif a:jump == "interrupt"
- call interrupt()
- let dummy = 0
- elseif a:jump == "throw"
- throw "abc"
- endif
- finally
- break " discards jump that caused the :finally
- call assert_report('should not get here')
- endtry
- elseif loop == 2
- call assert_report('should not get here')
- endif
- endwhile
- Xloop 'a'
- endfunc
-
- call B("continue")
- Xpath 'b'
- call B("break")
- Xpath 'c'
- call B("return")
- Xpath 'd'
- let g:jump = "finish"
- ExecAsScript B
- unlet g:jump
- Xpath 'e'
- try
- call B("error")
- Xpath 'f'
- finally
- Xpath 'g'
- try
- call B("interrupt")
- Xpath 'h'
- finally
- Xpath 'i'
- call B("throw")
- Xpath 'j'
- endtry
- endtry
- Xpath 'k'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 36: :finally reason discarded by :return {{{1
-"
-" When a :finally clause is executed due to a :continue, :break,
-" :return, :finish, error, interrupt or :throw, the jump reason is
-" discarded by a :return in the finally clause.
-"-------------------------------------------------------------------------------
-
-func Test_finally_discard_by_return()
- let test =<< trim [CODE]
- func R(jump, retval) abort
- let loop = 0
- while loop < 2
- let loop = loop + 1
- if loop == 1
- try
- if a:jump == "continue"
- continue
- elseif a:jump == "break"
- break
- elseif a:jump == "return"
- return
- elseif a:jump == "error"
- asdf
- elseif a:jump == "interrupt"
- call interrupt()
- let dummy = 0
- elseif a:jump == "throw"
- throw "abc"
- endif
- finally
- return a:retval " discards jump that caused the :finally
- call assert_report('should not get here')
- endtry
- elseif loop == 2
- call assert_report('should not get here')
- endif
- endwhile
- call assert_report('should not get here')
- endfunc
-
- let sum = -R("continue", -8)
- Xpath 'a'
- let sum = sum - R("break", -16)
- Xpath 'b'
- let sum = sum - R("return", -32)
- Xpath 'c'
- try
- let sum = sum - R("error", -64)
- Xpath 'd'
- finally
- Xpath 'e'
- try
- let sum = sum - R("interrupt", -128)
- Xpath 'f'
- finally
- Xpath 'g'
- let sum = sum - R("throw", -256)
- Xpath 'h'
- endtry
- endtry
- Xpath 'i'
-
- let expected = 8 + 16 + 32 + 64 + 128 + 256
- call assert_equal(sum, expected)
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefghi', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 37: :finally reason discarded by :finish {{{1
-"
-" When a :finally clause is executed due to a :continue, :break,
-" :return, :finish, error, interrupt or :throw, the jump reason is
-" discarded by a :finish in the finally clause.
-"-------------------------------------------------------------------------------
-
-func Test_finally_discard_by_finish()
- let test =<< trim [CODE]
- func F(jump) " not executed as function, transformed to a script
- let loop = 0
- while loop < 2
- let loop = loop + 1
- if loop == 1
- try
- if a:jump == "continue"
- continue
- elseif a:jump == "break"
- break
- elseif a:jump == "finish"
- finish
- elseif a:jump == "error"
- asdf
- elseif a:jump == "interrupt"
- call interrupt()
- let dummy = 0
- elseif a:jump == "throw"
- throw "abc"
- endif
- finally
- finish " discards jump that caused the :finally
- call assert_report('should not get here')
- endtry
- elseif loop == 2
- call assert_report('should not get here')
- endif
- endwhile
- call assert_report('should not get here')
- endfunc
-
- let scriptF = MakeScript("F")
- delfunction F
-
- let g:jump = "continue"
- exec "source" scriptF
- Xpath 'a'
- let g:jump = "break"
- exec "source" scriptF
- Xpath 'b'
- let g:jump = "finish"
- exec "source" scriptF
- Xpath 'c'
- try
- let g:jump = "error"
- exec "source" scriptF
- Xpath 'd'
- finally
- Xpath 'e'
- try
- let g:jump = "interrupt"
- exec "source" scriptF
- Xpath 'f'
- finally
- Xpath 'g'
- try
- let g:jump = "throw"
- exec "source" scriptF
- Xpath 'h'
- finally
- Xpath 'i'
- endtry
- endtry
- endtry
- unlet g:jump
- call delete(scriptF)
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefghi', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 38: :finally reason discarded by an error {{{1
-"
-" When a :finally clause is executed due to a :continue, :break,
-" :return, :finish, error, interrupt or :throw, the jump reason is
-" discarded by an error in the finally clause.
-"-------------------------------------------------------------------------------
-
-func Test_finally_discard_by_error()
- let test =<< trim [CODE]
- func E(jump)
- let loop = 0
- while loop < 2
- let loop = loop + 1
- if loop == 1
- try
- if a:jump == "continue"
- continue
- elseif a:jump == "break"
- break
- elseif a:jump == "return" || a:jump == "finish"
- return
- elseif a:jump == "error"
- asdf
- elseif a:jump == "interrupt"
- call interrupt()
- let dummy = 0
- elseif a:jump == "throw"
- throw "abc"
- endif
- finally
- asdf " error; discards jump that caused the :finally
- endtry
- elseif loop == 2
- call assert_report('should not get here')
- endif
- endwhile
- call assert_report('should not get here')
- endfunc
-
- try
- Xpath 'a'
- call E("continue")
- call assert_report('should not get here')
- finally
- try
- Xpath 'b'
- call E("break")
- call assert_report('should not get here')
- finally
- try
- Xpath 'c'
- call E("return")
- call assert_report('should not get here')
- finally
- try
- Xpath 'd'
- let g:jump = "finish"
- ExecAsScript E
- call assert_report('should not get here')
- finally
- unlet g:jump
- try
- Xpath 'e'
- call E("error")
- call assert_report('should not get here')
- finally
- try
- Xpath 'f'
- call E("interrupt")
- call assert_report('should not get here')
- finally
- try
- Xpath 'g'
- call E("throw")
- call assert_report('should not get here')
- finally
- Xpath 'h'
- delfunction E
- endtry
- endtry
- endtry
- endtry
- endtry
- endtry
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefgh', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 39: :finally reason discarded by an interrupt {{{1
-"
-" When a :finally clause is executed due to a :continue, :break,
-" :return, :finish, error, interrupt or :throw, the jump reason is
-" discarded by an interrupt in the finally clause.
-"-------------------------------------------------------------------------------
-
-func Test_finally_discarded_by_interrupt()
- let test =<< trim [CODE]
- func I(jump)
- let loop = 0
- while loop < 2
- let loop = loop + 1
- if loop == 1
- try
- if a:jump == "continue"
- continue
- elseif a:jump == "break"
- break
- elseif a:jump == "return" || a:jump == "finish"
- return
- elseif a:jump == "error"
- asdf
- elseif a:jump == "interrupt"
- call interrupt()
- let dummy = 0
- elseif a:jump == "throw"
- throw "abc"
- endif
- finally
- call interrupt()
- let dummy = 0
- endtry
- elseif loop == 2
- call assert_report('should not get here')
- endif
- endwhile
- call assert_report('should not get here')
- endfunc
-
- try
- try
- Xpath 'a'
- call I("continue")
- call assert_report('should not get here')
- finally
- try
- Xpath 'b'
- call I("break")
- call assert_report('should not get here')
- finally
- try
- Xpath 'c'
- call I("return")
- call assert_report('should not get here')
- finally
- try
- Xpath 'd'
- let g:jump = "finish"
- ExecAsScript I
- call assert_report('should not get here')
- finally
- unlet g:jump
- try
- Xpath 'e'
- call I("error")
- call assert_report('should not get here')
- finally
- try
- Xpath 'f'
- call I("interrupt")
- call assert_report('should not get here')
- finally
- try
- Xpath 'g'
- call I("throw")
- call assert_report('should not get here')
- finally
- Xpath 'h'
- delfunction I
- endtry
- endtry
- endtry
- endtry
- endtry
- endtry
- endtry
- call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'A'
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefghA', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 40: :finally reason discarded by :throw {{{1
-"
-" When a :finally clause is executed due to a :continue, :break,
-" :return, :finish, error, interrupt or :throw, the jump reason is
-" discarded by a :throw in the finally clause.
-"-------------------------------------------------------------------------------
-
-func Test_finally_discard_by_throw()
- let test =<< trim [CODE]
- func T(jump)
- let loop = 0
- while loop < 2
- let loop = loop + 1
- if loop == 1
- try
- if a:jump == "continue"
- continue
- elseif a:jump == "break"
- break
- elseif a:jump == "return" || a:jump == "finish"
- return
- elseif a:jump == "error"
- asdf
- elseif a:jump == "interrupt"
- call interrupt()
- let dummy = 0
- elseif a:jump == "throw"
- throw "abc"
- endif
- finally
- throw "xyz" " discards jump that caused the :finally
- endtry
- elseif loop == 2
- call assert_report('should not get here')
- endif
- endwhile
- call assert_report('should not get here')
- endfunc
-
- try
- Xpath 'a'
- call T("continue")
- call assert_report('should not get here')
- finally
- try
- Xpath 'b'
- call T("break")
- call assert_report('should not get here')
- finally
- try
- Xpath 'c'
- call T("return")
- call assert_report('should not get here')
- finally
- try
- Xpath 'd'
- let g:jump = "finish"
- ExecAsScript T
- call assert_report('should not get here')
- finally
- unlet g:jump
- try
- Xpath 'e'
- call T("error")
- call assert_report('should not get here')
- finally
- try
- Xpath 'f'
- call T("interrupt")
- call assert_report('should not get here')
- finally
- try
- Xpath 'g'
- call T("throw")
- call assert_report('should not get here')
- finally
- Xpath 'h'
- delfunction T
- endtry
- endtry
- endtry
- endtry
- endtry
- endtry
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefgh', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 49: Throwing exceptions across functions {{{1
-"
-" When an exception is thrown but not caught inside a function, the
-" caller is checked for a matching :catch clause.
-"-------------------------------------------------------------------------------
-
-func T49_C()
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')
- catch /arrgh/
- Xpath 'b'
- endtry
- Xpath 'c'
-endfunc
-
-func T49_T1()
- XloopNEXT
- try
- Xloop 'd'
- throw "arrgh"
- call assert_report('should not get here')
- finally
- Xloop 'e'
- endtry
- Xloop 'f'
-endfunc
-
-func T49_T2()
- try
- Xpath 'g'
- call T49_T1()
- call assert_report('should not get here')
- finally
- Xpath 'h'
- endtry
- call assert_report('should not get here')
-endfunc
-
-func Test_throw_exception_across_funcs()
- XpathINIT
- XloopINIT
- try
- Xpath 'i'
- call T49_C() " throw and catch
- Xpath 'j'
- catch /.*/
- call assert_report('should not get here')
- endtry
-
- try
- Xpath 'k'
- call T49_T1() " throw, one level
- call assert_report('should not get here')
- catch /arrgh/
- Xpath 'l'
- catch /.*/
- call assert_report('should not get here')
- endtry
-
- try
- Xpath 'm'
- call T49_T2() " throw, two levels
- call assert_report('should not get here')
- catch /arrgh/
- Xpath 'n'
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'o'
-
- call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 50: Throwing exceptions across script files {{{1
-"
-" When an exception is thrown but not caught inside a script file,
-" the sourcing script or function is checked for a matching :catch
-" clause.
-"
-" This test executes the bodies of the functions C, T1, and T2 from
-" the previous test as script files (:return replaced by :finish).
-"-------------------------------------------------------------------------------
-
-func T50_F()
- try
- Xpath 'A'
- exec "source" g:scriptC
- Xpath 'B'
- catch /.*/
- call assert_report('should not get here')
- endtry
-
- try
- Xpath 'C'
- exec "source" g:scriptT1
- call assert_report('should not get here')
- catch /arrgh/
- Xpath 'D'
- catch /.*/
- call assert_report('should not get here')
- endtry
-endfunc
-
-func Test_throw_across_script()
- XpathINIT
- XloopINIT
- let g:scriptC = MakeScript("T49_C")
- let g:scriptT1 = MakeScript("T49_T1")
- let scriptT2 = MakeScript("T49_T2", g:scriptT1)
-
- try
- Xpath 'E'
- call T50_F()
- Xpath 'F'
- exec "source" scriptT2
- call assert_report('should not get here')
- catch /arrgh/
- Xpath 'G'
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'H'
- call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath)
-
- call delete(g:scriptC)
- call delete(g:scriptT1)
- call delete(scriptT2)
- unlet g:scriptC g:scriptT1 scriptT2
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 52: Uncaught exceptions {{{1
-"
-" When an exception is thrown but not caught, an error message is
-" displayed when the script is terminated. In case of an interrupt
-" or error exception, the normal interrupt or error message(s) are
-" displayed.
-"-------------------------------------------------------------------------------
-
-func Test_uncaught_exception_1()
- CheckEnglish
-
- let test =<< trim [CODE]
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')`
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('E605: Exception not caught: arrgh', v:errmsg)
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_uncaught_exception_2()
- CheckEnglish
-
- let test =<< trim [CODE]
- try
- Xpath 'a'
- throw "oops"
- call assert_report('should not get here')`
- catch /arrgh/
- call assert_report('should not get here')`
- endtry
- call assert_report('should not get here')`
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('E605: Exception not caught: oops', v:errmsg)
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_uncaught_exception_3()
- CheckEnglish
-
- let test =<< trim [CODE]
- func T()
- Xpath 'c'
- throw "brrr"
- call assert_report('should not get here')`
- endfunc
-
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')`
- catch /.*/
- Xpath 'b'
- call T()
- call assert_report('should not get here')`
- endtry
- call assert_report('should not get here')`
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('E605: Exception not caught: brrr', v:errmsg)
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_uncaught_exception_4()
- CheckEnglish
-
- let test =<< trim [CODE]
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')`
- finally
- Xpath 'b'
- throw "brrr"
- call assert_report('should not get here')`
- endtry
- call assert_report('should not get here')`
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('E605: Exception not caught: brrr', v:errmsg)
- call assert_equal('ab', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_uncaught_exception_5()
- CheckEnglish
-
- " Need to catch and handle interrupt, otherwise the test will wait for the
- " user to press <Enter> to continue
- let test =<< trim [CODE]
- try
- try
- Xpath 'a'
- call interrupt()
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'b'
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ab', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_uncaught_exception_6()
- CheckEnglish
-
- let test =<< trim [CODE]
- try
- Xpath 'a'
- let x = novar " error E121; exception: E121
- catch /E15:/ " should not catch
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- call assert_equal('E121: Undefined variable: novar', v:errmsg)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_uncaught_exception_7()
- CheckEnglish
-
- let test =<< trim [CODE]
- try
- Xpath 'a'
- " error E108/E488; exception: E488
- unlet novar #
- catch /E108:/ " should not catch
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- call assert_equal('E488: Trailing characters: #', v:errmsg)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 53: Nesting errors: :endif/:else/:elseif {{{1
-"
-" For nesting errors of :if conditionals the correct error messages
-" should be given.
-"-------------------------------------------------------------------------------
-
-func Test_nested_if_else_errors()
- CheckEnglish
-
- " :endif without :if
- let code =<< trim END
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
-
- " :endif without :if
- let code =<< trim END
- while 1
- endif
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
-
- " :endif without :if
- let code =<< trim END
- try
- finally
- endif
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
-
- " :endif without :if
- let code =<< trim END
- try
- endif
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
-
- " :endif without :if
- let code =<< trim END
- try
- throw "a"
- catch /a/
- endif
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
-
- " :else without :if
- let code =<< trim END
- else
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
-
- " :else without :if
- let code =<< trim END
- while 1
- else
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
-
- " :else without :if
- let code =<< trim END
- try
- finally
- else
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
-
- " :else without :if
- let code =<< trim END
- try
- else
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
-
- " :else without :if
- let code =<< trim END
- try
- throw "a"
- catch /a/
- else
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
-
- " :elseif without :if
- let code =<< trim END
- elseif 1
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
-
- " :elseif without :if
- let code =<< trim END
- while 1
- elseif 1
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
-
- " :elseif without :if
- let code =<< trim END
- try
- finally
- elseif 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
-
- " :elseif without :if
- let code =<< trim END
- try
- elseif 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
-
- " :elseif without :if
- let code =<< trim END
- try
- throw "a"
- catch /a/
- elseif 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
-
- " multiple :else
- let code =<< trim END
- if 1
- else
- else
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(else):E583: multiple :else')
-
- " :elseif after :else
- let code =<< trim END
- if 1
- else
- elseif 1
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(elseif):E584: :elseif after :else')
-
- call delete('Xtest')
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 54: Nesting errors: :while/:endwhile {{{1
-"
-" For nesting errors of :while conditionals the correct error messages
-" should be given.
-"
-" This test reuses the function MESSAGES() from the previous test.
-" This functions checks the messages in g:msgfile.
-"-------------------------------------------------------------------------------
-
-func Test_nested_while_error()
- CheckEnglish
-
- " :endwhile without :while
- let code =<< trim END
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
-
- " :endwhile without :while
- let code =<< trim END
- if 1
- endwhile
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
-
- " Missing :endif
- let code =<< trim END
- while 1
- if 1
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
-
- " :endwhile without :while
- let code =<< trim END
- try
- finally
- endwhile
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
-
- " Missing :endtry
- let code =<< trim END
- while 1
- try
- finally
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
-
- " Missing :endtry
- let code =<< trim END
- while 1
- if 1
- try
- finally
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
-
- " Missing :endif
- let code =<< trim END
- while 1
- try
- finally
- if 1
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
-
- " :endwhile without :while
- let code =<< trim END
- try
- endwhile
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
-
- " :endwhile without :while
- let code =<< trim END
- while 1
- try
- endwhile
- endtry
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
-
- " :endwhile without :while
- let code =<< trim END
- try
- throw "a"
- catch /a/
- endwhile
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
-
- " :endwhile without :while
- let code =<< trim END
- while 1
- try
- throw "a"
- catch /a/
- endwhile
- endtry
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
-
- call delete('Xtest')
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 55: Nesting errors: :continue/:break {{{1
-"
-" For nesting errors of :continue and :break commands the correct
-" error messages should be given.
-"
-" This test reuses the function MESSAGES() from the previous test.
-" This functions checks the messages in g:msgfile.
-"-------------------------------------------------------------------------------
-
-func Test_nested_cont_break_error()
- CheckEnglish
-
- " :continue without :while
- let code =<< trim END
- continue
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
-
- " :continue without :while
- let code =<< trim END
- if 1
- continue
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
-
- " :continue without :while
- let code =<< trim END
- try
- finally
- continue
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
-
- " :continue without :while
- let code =<< trim END
- try
- continue
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
-
- " :continue without :while
- let code =<< trim END
- try
- throw "a"
- catch /a/
- continue
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
-
- " :break without :while
- let code =<< trim END
- break
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
-
- " :break without :while
- let code =<< trim END
- if 1
- break
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
-
- " :break without :while
- let code =<< trim END
- try
- finally
- break
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
-
- " :break without :while
- let code =<< trim END
- try
- break
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
-
- " :break without :while
- let code =<< trim END
- try
- throw "a"
- catch /a/
- break
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
-
- call delete('Xtest')
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 56: Nesting errors: :endtry {{{1
-"
-" For nesting errors of :try conditionals the correct error messages
-" should be given.
-"
-" This test reuses the function MESSAGES() from the previous test.
-" This functions checks the messages in g:msgfile.
-"-------------------------------------------------------------------------------
-
-func Test_nested_endtry_error()
- CheckEnglish
-
- " :endtry without :try
- let code =<< trim END
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
-
- " :endtry without :try
- let code =<< trim END
- if 1
- endtry
- endif
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
-
- " :endtry without :try
- let code =<< trim END
- while 1
- endtry
- endwhile
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
-
- " Missing :endif
- let code =<< trim END
- try
- if 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
-
- " Missing :endwhile
- let code =<< trim END
- try
- while 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
-
- " Missing :endif
- let code =<< trim END
- try
- finally
- if 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
-
- " Missing :endwhile
- let code =<< trim END
- try
- finally
- while 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
-
- " Missing :endif
- let code =<< trim END
- try
- throw "a"
- catch /a/
- if 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
-
- " Missing :endwhile
- let code =<< trim END
- try
- throw "a"
- catch /a/
- while 1
- endtry
- END
- call writefile(code, 'Xtest')
- call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
-
- call delete('Xtest')
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 57: v:exception and v:throwpoint for user exceptions {{{1
-"
-" v:exception evaluates to the value of the exception that was caught
-" most recently and is not finished. (A caught exception is finished
-" when the next ":catch", ":finally", or ":endtry" is reached.)
-" v:throwpoint evaluates to the script/function name and line number
-" where that exception has been thrown.
-"-------------------------------------------------------------------------------
-
-func Test_user_exception_info()
- CheckEnglish
-
- XpathINIT
- XloopINIT
-
- func FuncException()
- let g:exception = v:exception
- endfunc
-
- func FuncThrowpoint()
- let g:throwpoint = v:throwpoint
- endfunc
-
- let scriptException = MakeScript("FuncException")
- let scriptThrowPoint = MakeScript("FuncThrowpoint")
-
- command! CmdException let g:exception = v:exception
- command! CmdThrowpoint let g:throwpoint = v:throwpoint
-
- func T(arg, line)
- if a:line == 2
- throw a:arg " in line 2
- elseif a:line == 4
- throw a:arg " in line 4
- elseif a:line == 6
- throw a:arg " in line 6
- elseif a:line == 8
- throw a:arg " in line 8
- endif
- endfunc
-
- func G(arg, line)
- call T(a:arg, a:line)
- endfunc
-
- func F(arg, line)
- call G(a:arg, a:line)
- endfunc
-
- let scriptT = MakeScript("T")
- let scriptG = MakeScript("G", scriptT)
- let scriptF = MakeScript("F", scriptG)
-
- try
- Xpath 'a'
- call F("oops", 2)
- catch /.*/
- Xpath 'b'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
-
- exec "let exception = v:exception"
- exec "let throwpoint = v:throwpoint"
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
-
- CmdException
- CmdThrowpoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
-
- call FuncException()
- call FuncThrowpoint()
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
-
- exec "source" scriptException
- exec "source" scriptThrowPoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
-
- try
- Xpath 'c'
- call G("arrgh", 4)
- catch /.*/
- Xpath 'd'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
-
- try
- Xpath 'e'
- let g:arg = "autsch"
- let g:line = 6
- exec "source" scriptF
- catch /.*/
- Xpath 'f'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("autsch", v:exception)
- call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
- call assert_match('\<6\>', v:throwpoint)
- finally
- Xpath 'g'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
- try
- Xpath 'h'
- let g:arg = "brrrr"
- let g:line = 8
- exec "source" scriptG
- catch /.*/
- Xpath 'i'
- let exception = v:exception
- let throwpoint = v:throwpoint
- " Resolve scriptT for matching it against v:throwpoint.
- call assert_equal("brrrr", v:exception)
- call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
- call assert_match('\<8\>', v:throwpoint)
- finally
- Xpath 'j'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
- endtry
- Xpath 'k'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
- endtry
- Xpath 'l'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("arrgh", v:exception)
- call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<4\>', v:throwpoint)
- finally
- Xpath 'm'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
- endtry
- Xpath 'n'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("oops", v:exception)
- call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
- call assert_match('\<2\>', v:throwpoint)
- finally
- Xpath 'o'
- let exception = v:exception
- let throwpoint = v:throwpoint
- call assert_equal("", v:exception)
- call assert_match('^$', v:throwpoint)
- call assert_match('^$', v:throwpoint)
- endtry
-
- call assert_equal('abcdefghijklmno', g:Xpath)
-
- unlet exception throwpoint
- delfunction FuncException
- delfunction FuncThrowpoint
- call delete(scriptException)
- call delete(scriptThrowPoint)
- unlet scriptException scriptThrowPoint
- delcommand CmdException
- delcommand CmdThrowpoint
- delfunction T
- delfunction G
- delfunction F
- call delete(scriptT)
- call delete(scriptG)
- call delete(scriptF)
- unlet scriptT scriptG scriptF
-endfunc
-
-"-------------------------------------------------------------------------------
-"
-" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
-"
-" v:exception and v:throwpoint work also for error and interrupt
-" exceptions.
-"-------------------------------------------------------------------------------
-
-func Test_execption_info_for_error()
- CheckEnglish
-
- let test =<< trim [CODE]
- func T(line)
- if a:line == 2
- delfunction T " error (function in use) in line 2
- elseif a:line == 4
- call interrupt()
- endif
- endfunc
-
- while 1
- try
- Xpath 'a'
- call T(2)
- call assert_report('should not get here')
- catch /.*/
- Xpath 'b'
- if v:exception !~ 'Vim(delfunction):'
- call assert_report('should not get here')
- endif
- if v:throwpoint !~ '\<T\>'
- call assert_report('should not get here')
- endif
- if v:throwpoint !~ '\<2\>'
- call assert_report('should not get here')
- endif
- finally
- Xpath 'c'
- if v:exception != ""
- call assert_report('should not get here')
- endif
- if v:throwpoint != ""
- call assert_report('should not get here')
- endif
- break
- endtry
- endwhile
-
- Xpath 'd'
- if v:exception != ""
- call assert_report('should not get here')
- endif
- if v:throwpoint != ""
- call assert_report('should not get here')
- endif
-
- while 1
- try
- Xpath 'e'
- call T(4)
- call assert_report('should not get here')
- catch /.*/
- Xpath 'f'
- if v:exception != 'Vim:Interrupt'
- call assert_report('should not get here')
- endif
- if v:throwpoint !~ 'function T'
- call assert_report('should not get here')
- endif
- if v:throwpoint !~ '\<4\>'
- call assert_report('should not get here')
- endif
- finally
- Xpath 'g'
- if v:exception != ""
- call assert_report('should not get here')
- endif
- if v:throwpoint != ""
- call assert_report('should not get here')
- endif
- break
- endtry
- endwhile
-
- Xpath 'h'
- if v:exception != ""
- call assert_report('should not get here')
- endif
- if v:throwpoint != ""
- call assert_report('should not get here')
- endif
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefgh', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-"
-" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1
-"
-" When a :catch clause is left by a ":break" etc or an error or
-" interrupt exception, v:exception and v:throwpoint are reset. They
-" are not affected by an exception that is discarded before being
-" caught.
-"-------------------------------------------------------------------------------
-func Test_exception_info_on_discard()
- CheckEnglish
-
- let test =<< trim [CODE]
- let sfile = expand("<sfile>")
-
- while 1
- try
- throw "x1"
- catch /.*/
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- while 1
- try
- throw "x2"
- catch /.*/
- break
- finally
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- endtry
- break
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- while 1
- try
- let errcaught = 0
- try
- try
- throw "x3"
- catch /.*/
- let lnum = expand("<sflnum>")
- asdf
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim:E492: Not an editor command:', v:exception)
- call assert_match('line ' .. (lnum + 1), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- Xpath 'a'
-
- while 1
- try
- let intcaught = 0
- try
- try
- throw "x4"
- catch /.*/
- let lnum = expand("<sflnum>")
- call interrupt()
- endtry
- catch /.*/
- let intcaught = 1
- call assert_match('Vim:Interrupt', v:exception)
- call assert_match('line ' .. (lnum + 1), v:throwpoint)
- endtry
- finally
- call assert_equal(1, intcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- Xpath 'b'
-
- while 1
- try
- let errcaught = 0
- try
- try
- if 1
- let lnum = expand("<sflnum>")
- throw "x5"
- " missing endif
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim(catch):E171: Missing :endif:', v:exception)
- call assert_match('line ' .. (lnum + 3), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- Xpath 'c'
-
- try
- while 1
- try
- throw "x6"
- finally
- break
- endtry
- break
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- try
- while 1
- try
- throw "x7"
- finally
- break
- endtry
- break
- endwhile
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- endtry
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- while 1
- try
- let errcaught = 0
- try
- try
- throw "x8"
- finally
- let lnum = expand("<sflnum>")
- asdf
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim:E492: Not an editor command:', v:exception)
- call assert_match('line ' .. (lnum + 1), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- Xpath 'd'
-
- while 1
- try
- let intcaught = 0
- try
- try
- throw "x9"
- finally
- let lnum = expand("<sflnum>")
- call interrupt()
- endtry
- catch /.*/
- let intcaught = 1
- call assert_match('Vim:Interrupt', v:exception)
- call assert_match('line ' .. (lnum + 1), v:throwpoint)
- endtry
- finally
- call assert_equal(1, intcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- Xpath 'e'
-
- while 1
- try
- let errcaught = 0
- try
- try
- if 1
- let lnum = expand("<sflnum>")
- throw "x10"
- " missing endif
- finally
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim(finally):E171: Missing :endif:', v:exception)
- call assert_match('line ' .. (lnum + 3), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- Xpath 'f'
-
- while 1
- try
- let errcaught = 0
- try
- try
- if 1
- let lnum = expand("<sflnum>")
- throw "x11"
- " missing endif
- endtry
- catch /.*/
- let errcaught = 1
- call assert_match('Vim(endtry):E171: Missing :endif:', v:exception)
- call assert_match('line ' .. (lnum + 3), v:throwpoint)
- endtry
- finally
- call assert_equal(1, errcaught)
- break
- endtry
- endwhile
- call assert_equal('', v:exception)
- call assert_equal('', v:throwpoint)
-
- Xpath 'g'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefg', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-"
-" Test 60: (Re)throwing v:exception; :echoerr. {{{1
-"
-" A user exception can be rethrown after catching by throwing
-" v:exception. An error or interrupt exception cannot be rethrown
-" because Vim exceptions cannot be faked. A Vim exception using the
-" value of v:exception can, however, be triggered by the :echoerr
-" command.
-"-------------------------------------------------------------------------------
-
-func Test_rethrow_exception_1()
- XpathINIT
- try
- try
- Xpath 'a'
- throw "oops"
- catch /oops/
- Xpath 'b'
- throw v:exception " rethrow user exception
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^oops$/ " catches rethrown user exception
- Xpath 'c'
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_equal('abc', g:Xpath)
-endfunc
-
-func Test_rethrow_exception_2()
- XpathINIT
- try
- let caught = 0
- try
- Xpath 'a'
- write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
- call assert_report('should not get here')
- catch /^Vim(write):/
- let caught = 1
- throw v:exception " throw error: cannot fake Vim exception
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- endtry
- catch /^Vim(throw):/ " catches throw error
- let caught = caught + 1
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- call assert_equal(2, caught)
- endtry
- call assert_equal('abc', g:Xpath)
-endfunc
-
-func Test_rethrow_exception_3()
- XpathINIT
- try
- let caught = 0
- try
- Xpath 'a'
- asdf
- catch /^Vim/ " catch error exception
- let caught = 1
- " Trigger Vim error exception with value specified after :echoerr
- let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
- echoerr value
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- endtry
- catch /^Vim(echoerr):/
- let caught = caught + 1
- call assert_match(value, v:exception)
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- call assert_equal(2, caught)
- endtry
- call assert_equal('abc', g:Xpath)
-endfunc
-
-func Test_rethrow_exception_3()
- XpathINIT
- try
- let errcaught = 0
- try
- Xpath 'a'
- let intcaught = 0
- call interrupt()
- catch /^Vim:/ " catch interrupt exception
- let intcaught = 1
- " Trigger Vim error exception with value specified after :echoerr
- echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'b'
- call assert_equal(1, intcaught)
- endtry
- catch /^Vim(echoerr):/
- let errcaught = 1
- call assert_match('Interrupt', v:exception)
- finally
- Xpath 'c'
- call assert_equal(1, errcaught)
- endtry
- call assert_equal('abc', g:Xpath)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 61: Catching interrupt exceptions {{{1
-"
-" When an interrupt occurs inside a :try/:endtry region, an
-" interrupt exception is thrown and can be caught. Its value is
-" "Vim:Interrupt". If the interrupt occurs after an error or a :throw
-" but before a matching :catch is reached, all following :catches of
-" that try block are ignored, but the interrupt exception can be
-" caught by the next surrounding try conditional. An interrupt is
-" ignored when there is a previous interrupt that has not been caught
-" or causes a :finally clause to be executed.
-"-------------------------------------------------------------------------------
-
-func Test_catch_intr_exception()
- let test =<< trim [CODE]
- while 1
- try
- try
- Xpath 'a'
- call interrupt()
- call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'b'
- finally
- Xpath 'c'
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- endwhile
-
- while 1
- try
- try
- try
- Xpath 'e'
- asdf
- call assert_report('should not get here')
- catch /do_not_catch/
- call assert_report('should not get here')
- catch /.*/
- Xpath 'f'
- call interrupt()
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'g'
- call interrupt()
- call assert_report('should not get here')
- endtry
- catch /^Vim:Interrupt$/
- Xpath 'h'
- finally
- Xpath 'i'
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'j'
- break
- endtry
- endwhile
-
- while 1
- try
- try
- try
- Xpath 'k'
- throw "x"
- call assert_report('should not get here')
- catch /do_not_catch/
- call assert_report('should not get here')
- catch /x/
- Xpath 'l'
- call interrupt()
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^Vim:Interrupt$/
- Xpath 'm'
- finally
- Xpath 'n'
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'o'
- break
- endtry
- endwhile
-
- while 1
- try
- try
- Xpath 'p'
- call interrupt()
- call assert_report('should not get here')
- catch /do_not_catch/
- call interrupt()
- call assert_report('should not get here')
- catch /^Vim:Interrupt$/
- Xpath 'q'
- finally
- Xpath 'r'
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 's'
- break
- endtry
- endwhile
-
- Xpath 't'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefghijklmnopqrst', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 62: Catching error exceptions {{{1
-"
-" An error inside a :try/:endtry region is converted to an exception
-" and can be caught. The error exception has a "Vim(cmdname):" prefix
-" where cmdname is the name of the failing command, or a "Vim:" prefix
-" if no command name is known. The "Vim" prefixes cannot be faked.
-"-------------------------------------------------------------------------------
-
-func Test_catch_err_exception_1()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- unlet novar
- catch /^Vim(unlet):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match('E108: No such variable: "novar"', v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
-endfunc
-
-func Test_catch_err_exception_2()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- throw novar " error in :throw
- catch /^Vim(throw):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match('E121: Undefined variable: novar', v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
-endfunc
-
-func Test_catch_err_exception_3()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- throw "Vim:faked" " error: cannot fake Vim exception
- catch /^Vim(throw):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E608: Cannot :throw exceptions with 'Vim' prefix",
- \ v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
-endfunc
-
-func Test_catch_err_exception_4()
- XpathINIT
- func F()
- while 1
- " Missing :endwhile
- endfunc
-
- while 1
- try
- try
- let caught = 0
- call F()
- catch /^Vim(endfunction):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E170: Missing :endwhile", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- delfunc F
-endfunc
-
-func Test_catch_err_exception_5()
- XpathINIT
- func F()
- while 1
- " Missing :endwhile
- endfunc
-
- while 1
- try
- try
- let caught = 0
- ExecAsScript F
- catch /^Vim:/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim:', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E170: Missing :endwhile", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- delfunc F
-endfunc
-
-func Test_catch_err_exception_6()
- XpathINIT
- func G()
- call G()
- endfunc
-
- while 1
- try
- let mfd_save = &mfd
- set mfd=3
- try
- let caught = 0
- call G()
- catch /^Vim(call):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- let &mfd = mfd_save
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abc', g:Xpath)
- delfunc G
-endfunc
-
-func Test_catch_err_exception_7()
- XpathINIT
- func H()
- return H()
- endfunc
-
- while 1
- try
- let mfd_save = &mfd
- set mfd=3
- try
- let caught = 0
- call H()
- catch /^Vim(return):/
- Xpath 'a'
- let caught = 1
- let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
- finally
- Xpath 'b'
- call assert_equal(1, caught)
- call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- let &mfd = mfd_save
- break " discard error for $VIMNOERRTHROW
- endtry
- call assert_report('should not get here')
- endwhile
-
- call assert_equal('abc', g:Xpath)
- delfunc H
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 63: Suppressing error exceptions by :silent!. {{{1
-"
-" A :silent! command inside a :try/:endtry region suppresses the
-" conversion of errors to an exception and the immediate abortion on
-" error. When the commands executed by the :silent! themselves open
-" a new :try/:endtry region, conversion of errors to exception and
-" immediate abortion is switched on again - until the next :silent!
-" etc. The :silent! has the effect of setting v:errmsg to the error
-" message text (without displaying it) and continuing with the next
-" script line.
-"
-" When a command triggering autocommands is executed by :silent!
-" inside a :try/:endtry, the autocommand execution is not suppressed
-" on error.
-"
-" This test reuses the function MSG() from the previous test.
-"-------------------------------------------------------------------------------
-
-func Test_silent_exception()
- XpathINIT
- XloopINIT
- let g:taken = ""
-
- func S(n) abort
- XloopNEXT
- let g:taken = g:taken . "E" . a:n
- let v:errmsg = ""
- exec "asdf" . a:n
-
- " Check that ":silent!" continues:
- Xloop 'a'
-
- " Check that ":silent!" sets "v:errmsg":
- call assert_match("E492: Not an editor command", v:errmsg)
- endfunc
-
- func Foo()
- while 1
- try
- try
- let caught = 0
- " This is not silent:
- call S(3)
- catch /^Vim:/
- Xpath 'b'
- let caught = 1
- let errmsg3 = substitute(v:exception, '^Vim:', '', "")
- silent! call S(4)
- finally
- call assert_equal(1, caught)
- Xpath 'c'
- call assert_match("E492: Not an editor command", errmsg3)
- silent! call S(5)
- " Break out of try conditionals that cover ":silent!". This also
- " discards the aborting error when $VIMNOERRTHROW is non-zero.
- break
- endtry
- catch /.*/
- call assert_report('should not get here')
- endtry
- endwhile
- " This is a double ":silent!" (see caller).
- silent! call S(6)
- endfunc
-
- func Bar()
- try
- silent! call S(2)
- silent! execute "call Foo() | call S(7)"
- silent! call S(8)
- endtry " normal end of try cond that covers ":silent!"
- " This has a ":silent!" from the caller:
- call S(9)
- endfunc
-
- silent! call S(1)
- silent! call Bar()
- silent! call S(10)
-
- call assert_equal("E1E2E3E4E5E6E7E8E9E10", g:taken)
-
- augroup TMP
- au!
- autocmd BufWritePost * Xpath 'd'
- augroup END
-
- Xpath 'e'
- silent! write /i/m/p/o/s/s/i/b/l/e
- Xpath 'f'
-
- call assert_equal('a2a3ba5ca6a7a8a9a10a11edf', g:Xpath)
-
- augroup TMP
- au!
- augroup END
- augroup! TMP
- delfunction S
- delfunction Foo
- delfunction Bar
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 64: Error exceptions after error, interrupt or :throw {{{1
-"
-" When an error occurs after an interrupt or a :throw but before
-" a matching :catch is reached, all following :catches of that try
-" block are ignored, but the error exception can be caught by the next
-" surrounding try conditional. Any previous error exception is
-" discarded. An error is ignored when there is a previous error that
-" has not been caught.
-"-------------------------------------------------------------------------------
-
-func Test_exception_after_error_1()
- XpathINIT
- while 1
- try
- try
- Xpath 'a'
- let caught = 0
- while 1
- if 1
- " Missing :endif
- endwhile " throw error exception
- catch /^Vim(/
- Xpath 'b'
- let caught = 1
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
-endfunc
-
-func Test_exception_after_error_2()
- XpathINIT
- while 1
- try
- try
- Xpath 'a'
- let caught = 0
- try
- if 1
- " Missing :endif
- catch /.*/ " throw error exception
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^Vim(/
- Xpath 'b'
- let caught = 1
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
-endfunc
-
-func Test_exception_after_error_3()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- try
- Xpath 'a'
- call interrupt()
- catch /do_not_catch/
- call assert_report('should not get here')
- if 1
- " Missing :endif
- catch /.*/ " throw error exception
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^Vim(/
- Xpath 'b'
- let caught = 1
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
-endfunc
-
-func Test_exception_after_error_4()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- try
- Xpath 'a'
- throw "x"
- catch /do_not_catch/
- call assert_report('should not get here')
- if 1
- " Missing :endif
- catch /x/ " throw error exception
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- catch /^Vim(/
- Xpath 'b'
- let caught = 1
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
-endfunc
-
-func Test_exception_after_error_5()
- XpathINIT
- while 1
- try
- try
- let caught = 0
- Xpath 'a'
- endif " :endif without :if; throw error exception
- if 1
- " Missing :endif
- catch /do_not_catch/ " ignore new error
- call assert_report('should not get here')
- catch /^Vim(endif):/
- Xpath 'b'
- let caught = 1
- catch /^Vim(/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- call assert_equal(1, caught)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'd'
- break
- endtry
- call assert_report('should not get here')
- endwhile
- call assert_equal('abcd', g:Xpath)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 65: Errors in the /pattern/ argument of a :catch {{{1
-"
-" On an error in the /pattern/ argument of a :catch, the :catch does
-" not match. Any following :catches of the same :try/:endtry don't
-" match either. Finally clauses are executed.
-"-------------------------------------------------------------------------------
-
-func Test_catch_pattern_error()
- CheckEnglish
- XpathINIT
-
- try
- try
- Xpath 'a'
- throw "oops"
- catch /^oops$/
- Xpath 'b'
- catch /\)/ " not checked; exception has already been caught
- call assert_report('should not get here')
- endtry
- Xpath 'c'
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_equal('abc', g:Xpath)
-
- XpathINIT
- func F()
- try
- try
- try
- Xpath 'a'
- throw "ab"
- catch /abc/ " does not catch
- call assert_report('should not get here')
- catch /\)/ " error; discards exception
- call assert_report('should not get here')
- catch /.*/ " not checked
- call assert_report('should not get here')
- finally
- Xpath 'b'
- endtry
- call assert_report('should not get here')
- catch /^ab$/ " checked, but original exception is discarded
- call assert_report('should not get here')
- catch /^Vim(catch):/
- Xpath 'c'
- call assert_match('Vim(catch):E475: Invalid argument:', v:exception)
- finally
- Xpath 'd'
- endtry
- Xpath 'e'
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'f'
- endfunc
-
- call F()
- call assert_equal('abcdef', g:Xpath)
-
- delfunc F
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 66: Stop range :call on error, interrupt, or :throw {{{1
-"
-" When a function which is multiply called for a range since it
-" doesn't handle the range itself has an error in a command
-" dynamically enclosed by :try/:endtry or gets an interrupt or
-" executes a :throw, no more calls for the remaining lines in the
-" range are made. On an error in a command not dynamically enclosed
-" by :try/:endtry, the function is executed again for the remaining
-" lines in the range.
-"-------------------------------------------------------------------------------
-
-func Test_stop_range_on_error()
- let test =<< trim [CODE]
- let file = tempname()
- exec "edit" file
- call setline(1, ['line 1', 'line 2', 'line 3'])
- let taken = ""
- let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
-
- func F(reason, n) abort
- let g:taken = g:taken .. "F" .. a:n ..
- \ substitute(a:reason, '\(\l\).*', '\u\1', "") ..
- \ "(" .. line(".") .. ")"
-
- if a:reason == "error"
- asdf
- elseif a:reason == "interrupt"
- call interrupt()
- elseif a:reason == "throw"
- throw "xyz"
- elseif a:reason == "aborting error"
- XloopNEXT
- call assert_equal(g:taken, g:expected)
- try
- bwipeout!
- call delete(g:file)
- asdf
- endtry
- endif
- endfunc
-
- func G(reason, n)
- let g:taken = g:taken .. "G" .. a:n ..
- \ substitute(a:reason, '\(\l\).*', '\u\1', "")
- 1,3call F(a:reason, a:n)
- endfunc
-
- Xpath 'a'
- call G("error", 1)
- try
- Xpath 'b'
- try
- call G("error", 2)
- call assert_report('should not get here')
- finally
- Xpath 'c'
- try
- call G("interrupt", 3)
- call assert_report('should not get here')
- finally
- Xpath 'd'
- try
- call G("throw", 4)
- call assert_report('should not get here')
- endtry
- endtry
- endtry
- catch /xyz/
- Xpath 'e'
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'f'
- call G("aborting error", 5)
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdef', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 67: :throw across :call command {{{1
-"
-" On a call command, an exception might be thrown when evaluating the
-" function name, during evaluation of the arguments, or when the
-" function is being executed. The exception can be caught by the
-" caller.
-"-------------------------------------------------------------------------------
-
-func THROW(x, n)
- if a:n == 1
- Xpath 'A'
- elseif a:n == 2
- Xpath 'B'
- elseif a:n == 3
- Xpath 'C'
- endif
- throw a:x
-endfunc
-
-func NAME(x, n)
- if a:n == 1
- call assert_report('should not get here')
- elseif a:n == 2
- Xpath 'D'
- elseif a:n == 3
- Xpath 'E'
- elseif a:n == 4
- Xpath 'F'
- endif
- return a:x
-endfunc
-
-func ARG(x, n)
- if a:n == 1
- call assert_report('should not get here')
- elseif a:n == 2
- call assert_report('should not get here')
- elseif a:n == 3
- Xpath 'G'
- elseif a:n == 4
- Xpath 'I'
- endif
- return a:x
-endfunc
-
-func Test_throw_across_call_cmd()
- XpathINIT
-
- func F(x, n)
- if a:n == 2
- call assert_report('should not get here')
- elseif a:n == 4
- Xpath 'a'
- endif
- endfunc
-
- while 1
- try
- let v:errmsg = ""
-
- while 1
- try
- Xpath 'b'
- call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
- call assert_report('should not get here')
- catch /^name$/
- Xpath 'c'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
-
- while 1
- try
- Xpath 'd'
- call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
- call assert_report('should not get here')
- catch /^arg$/
- Xpath 'e'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
-
- while 1
- try
- Xpath 'f'
- call {NAME("THROW", 3)}(ARG("call", 3), 3)
- call assert_report('should not get here')
- catch /^call$/
- Xpath 'g'
- catch /^0$/ " default return value
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
-
- while 1
- try
- Xpath 'h'
- call {NAME("F", 4)}(ARG(4711, 4), 4)
- Xpath 'i'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
-
- catch /^0$/ " default return value
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
-
- call assert_equal('bAcdDBefEGCghFIai', g:Xpath)
- delfunction F
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 68: :throw across function calls in expressions {{{1
-"
-" On a function call within an expression, an exception might be
-" thrown when evaluating the function name, during evaluation of the
-" arguments, or when the function is being executed. The exception
-" can be caught by the caller.
-"
-" This test reuses the functions THROW(), NAME(), and ARG() from the
-" previous test.
-"-------------------------------------------------------------------------------
-
-func Test_throw_across_call_expr()
- XpathINIT
-
- func F(x, n)
- if a:n == 2
- call assert_report('should not get here')
- elseif a:n == 4
- Xpath 'a'
- endif
- return a:x
- endfunction
-
- while 1
- try
- let error = 0
- let v:errmsg = ""
-
- while 1
- try
- Xpath 'b'
- let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
- call assert_report('should not get here')
- catch /^name$/
- Xpath 'c'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- call assert_true(!exists('var1'))
-
- while 1
- try
- Xpath 'd'
- let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
- call assert_report('should not get here')
- catch /^arg$/
- Xpath 'e'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- call assert_true(!exists('var2'))
-
- while 1
- try
- Xpath 'f'
- let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
- call assert_report('should not get here')
- catch /^call$/
- Xpath 'g'
- catch /^0$/ " default return value
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- call assert_true(!exists('var3'))
-
- while 1
- try
- Xpath 'h'
- let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
- Xpath 'i'
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- let v:errmsg = ""
- break
- endtry
- endwhile
- call assert_true(exists('var4') && var4 == 4711)
-
- catch /^0$/ " default return value
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- finally
- call assert_equal("", v:errmsg)
- break
- endtry
- endwhile
-
- call assert_equal('bAcdDBefEGCghFIai', g:Xpath)
- delfunc F
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 76: Errors, interrupts, :throw during expression evaluation {{{1
-"
-" When a function call made during expression evaluation is aborted
-" due to an error inside a :try/:endtry region or due to an interrupt
-" or a :throw, the expression evaluation is aborted as well. No
-" message is displayed for the cancelled expression evaluation. On an
-" error not inside :try/:endtry, the expression evaluation continues.
-"-------------------------------------------------------------------------------
-
-func Test_expr_eval_error()
- let test =<< trim [CODE]
- let taken = ""
-
- func ERR(n)
- let g:taken = g:taken .. "E" .. a:n
- asdf
- endfunc
-
- func ERRabort(n) abort
- let g:taken = g:taken .. "A" .. a:n
- asdf
- endfunc " returns -1; may cause follow-up msg for illegal var/func name
-
- func WRAP(n, arg)
- let g:taken = g:taken .. "W" .. a:n
- let g:saved_errmsg = v:errmsg
- return arg
- endfunc
-
- func INT(n)
- let g:taken = g:taken .. "I" .. a:n
- call interrupt()
- endfunc
-
- func THR(n)
- let g:taken = g:taken .. "T" .. a:n
- throw "should not be caught"
- endfunc
-
- func CONT(n)
- let g:taken = g:taken .. "C" .. a:n
- endfunc
-
- func MSG(n)
- let g:taken = g:taken .. "M" .. a:n
- let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
- let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
- call assert_match(msgptn, errmsg)
- let v:errmsg = ""
- let g:saved_errmsg = ""
- endfunc
-
- let v:errmsg = ""
-
- try
- let t = 1
- while t <= 9
- Xloop 'a'
- try
- if t == 1
- let v{ERR(t) + CONT(t)} = 0
- elseif t == 2
- let v{ERR(t) + CONT(t)}
- elseif t == 3
- let var = exists('v{ERR(t) + CONT(t)}')
- elseif t == 4
- unlet v{ERR(t) + CONT(t)}
- elseif t == 5
- function F{ERR(t) + CONT(t)}()
- endfunction
- elseif t == 6
- function F{ERR(t) + CONT(t)}
- elseif t == 7
- let var = exists('*F{ERR(t) + CONT(t)}')
- elseif t == 8
- delfunction F{ERR(t) + CONT(t)}
- elseif t == 9
- let var = ERR(t) + CONT(t)
- endif
- catch /asdf/
- " v:errmsg is not set when the error message is converted to an
- " exception. Set it to the original error message.
- let v:errmsg = substitute(v:exception, '^Vim:', '', "")
- catch /^Vim\((\a\+)\)\=:/
- " An error exception has been thrown after the original error.
- let v:errmsg = ""
- finally
- call MSG(t)
- let t = t + 1
- XloopNEXT
- continue " discard an aborting error
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
-
- try
- let t = 10
- while t <= 18
- Xloop 'b'
- try
- if t == 10
- let v{INT(t) + CONT(t)} = 0
- elseif t == 11
- let v{INT(t) + CONT(t)}
- elseif t == 12
- let var = exists('v{INT(t) + CONT(t)}')
- elseif t == 13
- unlet v{INT(t) + CONT(t)}
- elseif t == 14
- function F{INT(t) + CONT(t)}()
- endfunction
- elseif t == 15
- function F{INT(t) + CONT(t)}
- elseif t == 16
- let var = exists('*F{INT(t) + CONT(t)}')
- elseif t == 17
- delfunction F{INT(t) + CONT(t)}
- elseif t == 18
- let var = INT(t) + CONT(t)
- endif
- catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
- " An error exception has been triggered after the interrupt.
- let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
- finally
- call MSG(t)
- let t = t + 1
- XloopNEXT
- continue " discard interrupt
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
-
- try
- let t = 19
- while t <= 27
- Xloop 'c'
- try
- if t == 19
- let v{THR(t) + CONT(t)} = 0
- elseif t == 20
- let v{THR(t) + CONT(t)}
- elseif t == 21
- let var = exists('v{THR(t) + CONT(t)}')
- elseif t == 22
- unlet v{THR(t) + CONT(t)}
- elseif t == 23
- function F{THR(t) + CONT(t)}()
- endfunction
- elseif t == 24
- function F{THR(t) + CONT(t)}
- elseif t == 25
- let var = exists('*F{THR(t) + CONT(t)}')
- elseif t == 26
- delfunction F{THR(t) + CONT(t)}
- elseif t == 27
- let var = THR(t) + CONT(t)
- endif
- catch /^Vim\((\a\+)\)\=:/
- " An error exception has been triggered after the :throw.
- let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
- finally
- call MSG(t)
- let t = t + 1
- XloopNEXT
- continue " discard exception
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
-
- let v{ERR(28) + CONT(28)} = 0
- call MSG(28)
- let v{ERR(29) + CONT(29)}
- call MSG(29)
- let var = exists('v{ERR(30) + CONT(30)}')
- call MSG(30)
- unlet v{ERR(31) + CONT(31)}
- call MSG(31)
- function F{ERR(32) + CONT(32)}()
- endfunction
- call MSG(32)
- function F{ERR(33) + CONT(33)}
- call MSG(33)
- let var = exists('*F{ERR(34) + CONT(34)}')
- call MSG(34)
- delfunction F{ERR(35) + CONT(35)}
- call MSG(35)
- let var = ERR(36) + CONT(36)
- call MSG(36)
-
- let saved_errmsg = ""
-
- let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
- call MSG(37)
- let v{WRAP(38, ERRabort(38)) + CONT(38)}
- call MSG(38)
- let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
- call MSG(39)
- unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
- call MSG(40)
- function F{WRAP(41, ERRabort(41)) + CONT(41)}()
- endfunction
- call MSG(41)
- function F{WRAP(42, ERRabort(42)) + CONT(42)}
- call MSG(42)
- let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
- call MSG(43)
- delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
- call MSG(44)
- let var = ERRabort(45) + CONT(45)
- call MSG(45)
- Xpath 'd'
-
- let expected = ""
- \ .. "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
- \ .. "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
- \ .. "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
- \ .. "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
- \ .. "E34C34M34E35C35M35E36C36M36"
- \ .. "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
- \ .. "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
- call assert_equal(expected, taken)
- [CODE]
- let verify =<< trim [CODE]
- let expected = "a1a2a3a4a5a6a7a8a9"
- \ .. "b10b11b12b13b14b15b16b17b18"
- \ .. "c19c20c21c22c23c24c25c26c27d"
- call assert_equal(expected, g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1
-"
-" When a function call made during evaluation of an expression in
-" braces as part of a function name after ":function" is aborted due
-" to an error inside a :try/:endtry region or due to an interrupt or
-" a :throw, the expression evaluation is aborted as well, and the
-" function definition is ignored, skipping all commands to the
-" ":endfunction". On an error not inside :try/:endtry, the expression
-" evaluation continues and the function gets defined, and can be
-" called and deleted.
-"-------------------------------------------------------------------------------
-func Test_brace_expr_error()
- let test =<< trim [CODE]
- func ERR() abort
- Xloop 'a'
- asdf
- endfunc " returns -1
-
- func OK()
- Xloop 'b'
- let v:errmsg = ""
- return 0
- endfunc
-
- let v:errmsg = ""
-
- Xpath 'c'
- func F{1 + ERR() + OK()}(arg)
- " F0 should be defined.
- if exists("a:arg") && a:arg == "calling"
- Xpath 'd'
- else
- call assert_report('should not get here')
- endif
- endfunction
- call assert_equal("", v:errmsg)
- XloopNEXT
-
- Xpath 'e'
- call F{1 + ERR() + OK()}("calling")
- call assert_equal("", v:errmsg)
- XloopNEXT
-
- Xpath 'f'
- delfunction F{1 + ERR() + OK()}
- call assert_equal("", v:errmsg)
- XloopNEXT
-
- try
- while 1
- try
- Xpath 'g'
- func G{1 + ERR() + OK()}(arg)
- " G0 should not be defined, and the function body should be
- " skipped.
- call assert_report('should not get here')
- " Use an unmatched ":finally" to check whether the body is
- " skipped when an error occurs in ERR(). This works whether or
- " not the exception is converted to an exception.
- finally
- call assert_report('should not get here')
- endtry
- try
- call assert_report('should not get here')
- endfunction
-
- call assert_report('should not get here')
- catch /asdf/
- " Jumped to when the function is not defined and the body is
- " skipped.
- Xpath 'h'
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'i'
- break
- endtry " jumped to when the body is not skipped
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ca1b1ea2b2dfa3b3ga4hi', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 78: Messages on parsing errors in expression evaluation {{{1
-"
-" When an expression evaluation detects a parsing error, an error
-" message is given and converted to an exception, and the expression
-" evaluation is aborted.
-"-------------------------------------------------------------------------------
-func Test_expr_eval_error_msg()
- CheckEnglish
-
- let test =<< trim [CODE]
- let taken = ""
-
- func F(n)
- let g:taken = g:taken . "F" . a:n
- endfunc
-
- func MSG(n, enr, emsg)
- let g:taken = g:taken . "M" . a:n
- call assert_match('^' .. a:enr .. ':', v:errmsg)
- call assert_match(a:emsg, v:errmsg)
- endfunc
-
- func CONT(n)
- let g:taken = g:taken . "C" . a:n
- endfunc
-
- let v:errmsg = ""
- try
- let t = 1
- while t <= 14
- let g:taken = g:taken . "T" . t
- let v:errmsg = ""
- try
- if t == 1
- let v{novar + CONT(t)} = 0
- elseif t == 2
- let v{novar + CONT(t)}
- elseif t == 3
- let var = exists('v{novar + CONT(t)}')
- elseif t == 4
- unlet v{novar + CONT(t)}
- elseif t == 5
- function F{novar + CONT(t)}()
- endfunction
- elseif t == 6
- function F{novar + CONT(t)}
- elseif t == 7
- let var = exists('*F{novar + CONT(t)}')
- elseif t == 8
- delfunction F{novar + CONT(t)}
- elseif t == 9
- echo novar + CONT(t)
- elseif t == 10
- echo v{novar + CONT(t)}
- elseif t == 11
- echo F{novar + CONT(t)}
- elseif t == 12
- let var = novar + CONT(t)
- elseif t == 13
- let var = v{novar + CONT(t)}
- elseif t == 14
- let var = F{novar + CONT(t)}()
- endif
- catch /^Vim\((\a\+)\)\=:/
- Xloop 'a'
- " v:errmsg is not set when the error message is converted to an
- " exception. Set it to the original error message.
- let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
- finally
- Xloop 'b'
- if t <= 8 && t != 3 && t != 7
- call MSG(t, 'E475', 'Invalid argument\>')
- else
- call MSG(t, 'E121', "Undefined variable")
- endif
- let t = t + 1
- XloopNEXT
- continue " discard an aborting error
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
-
- func T(n, expr, enr, emsg)
- try
- let g:taken = g:taken . "T" . a:n
- let v:errmsg = ""
- try
- execute "let var = " . a:expr
- catch /^Vim\((\a\+)\)\=:/
- Xloop 'c'
- " v:errmsg is not set when the error message is converted to an
- " exception. Set it to the original error message.
- let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
- finally
- Xloop 'd'
- call MSG(a:n, a:enr, a:emsg)
- XloopNEXT
- " Discard an aborting error:
- return
- endtry
- catch /.*/
- call assert_report('should not get here')
- endtry
- endfunc
-
- call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function")
- call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments")
- call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments")
- call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments")
- call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'")
- call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'")
- call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression")
- call T(22, '1 2 + CONT(22)', 'E488', "Trailing characters: 2 +")
- call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'")
- call T(24, '("abc) + CONT(24)', 'E114', "Missing quote")
- call T(25, "('abc) + CONT(25)", 'E115', "Missing quote")
- call T(26, '& + CONT(26)', 'E112', "Option name missing")
- call T(27, '&asdf + CONT(27)', 'E113', "Unknown option")
-
- let expected = ""
- \ .. "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
- \ .. "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
- \ .. "T26M26T27M27"
-
- call assert_equal(expected, taken)
- [CODE]
- let verify =<< trim [CODE]
- let expected = "a1b1a2b2a3b3a4b4a5b5a6b6a7b7a8b8a9b9a10b10a11b11a12b12"
- \ .. "a13b13a14b14c15d15c16d16c17d17c18d18c19d19c20d20"
- \ .. "c21d21c22d22c23d23c24d24c25d25c26d26c27d27"
- call assert_equal(expected, g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 79: Throwing one of several errors for the same command {{{1
-"
-" When several errors appear in a row (for instance during expression
-" evaluation), the first as the most specific one is used when
-" throwing an error exception. If, however, a syntax error is
-" detected afterwards, this one is used for the error exception.
-" On a syntax error, the next command is not executed, on a normal
-" error, however, it is (relevant only in a function without the
-" "abort" flag). v:errmsg is not set.
-"
-" If throwing error exceptions is configured off, v:errmsg is always
-" set to the latest error message, that is, to the more general
-" message or the syntax error, respectively.
-"-------------------------------------------------------------------------------
-func Test_throw_multi_error()
- CheckEnglish
-
- let test =<< trim [CODE]
- func NEXT(cmd)
- exec a:cmd . " | Xloop 'a'"
- endfun
-
- call NEXT('echo novar') " (checks nextcmd)
- XloopNEXT
- call NEXT('let novar #') " (skips nextcmd)
- XloopNEXT
- call NEXT('unlet novar #') " (skips nextcmd)
- XloopNEXT
- call NEXT('let {novar}') " (skips nextcmd)
- XloopNEXT
- call NEXT('unlet{ novar}') " (skips nextcmd)
-
- call assert_equal('a1', g:Xpath)
- XpathINIT
- XloopINIT
-
- func EXEC(cmd)
- exec a:cmd
- endfunc
-
- try
- while 1 " dummy loop
- try
- let v:errmsg = ""
- call EXEC('echo novar') " normal error
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'b'
- call assert_match('E121: Undefined variable: novar', v:exception)
- finally
- Xpath 'c'
- call assert_equal("", v:errmsg)
- break
- endtry
- endwhile
-
- Xpath 'd'
- let cmd = "let"
- while cmd != ""
- try
- let v:errmsg = ""
- call EXEC(cmd . ' novar #') " normal plus syntax error
- catch /^Vim\((\a\+)\)\=:/
- Xloop 'e'
- call assert_match('E488: Trailing characters', v:exception)
- finally
- Xloop 'f'
- call assert_equal("", v:errmsg)
- if cmd == "let"
- let cmd = "unlet"
- else
- let cmd = ""
- endif
- XloopNEXT
- continue
- endtry
- endwhile
-
- Xpath 'g'
- let cmd = "let"
- while cmd != ""
- try
- let v:errmsg = ""
- call EXEC(cmd . ' {novar}') " normal plus syntax error
- catch /^Vim\((\a\+)\)\=:/
- Xloop 'h'
- call assert_match('E475: Invalid argument: {novar}', v:exception)
- finally
- Xloop 'i'
- call assert_equal("", v:errmsg)
- if cmd == "let"
- let cmd = "unlet"
- else
- let cmd = ""
- endif
- XloopNEXT
- continue
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'j'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('bcde1f1e2f2gh3i3h4i4j', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 80: Syntax error in expression for illegal :elseif {{{1
-"
-" If there is a syntax error in the expression after an illegal
-" :elseif, an error message is given (or an error exception thrown)
-" for the illegal :elseif rather than the expression error.
-"-------------------------------------------------------------------------------
-func Test_if_syntax_error()
- CheckEnglish
-
- let test =<< trim [CODE]
- let v:errmsg = ""
- if 0
- else
- elseif 1 ||| 2
- endif
- Xpath 'a'
- call assert_match('E584: :elseif after :else', v:errmsg)
-
- let v:errmsg = ""
- if 1
- else
- elseif 1 ||| 2
- endif
- Xpath 'b'
- call assert_match('E584: :elseif after :else', v:errmsg)
-
- let v:errmsg = ""
- elseif 1 ||| 2
- Xpath 'c'
- call assert_match('E582: :elseif without :if', v:errmsg)
-
- let v:errmsg = ""
- while 1
- elseif 1 ||| 2
- endwhile
- Xpath 'd'
- call assert_match('E582: :elseif without :if', v:errmsg)
-
- while 1
- try
- try
- let v:errmsg = ""
- if 0
- else
- elseif 1 ||| 2
- endif
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'e'
- call assert_match('E584: :elseif after :else', v:exception)
- finally
- Xpath 'f'
- call assert_equal("", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'g'
- break
- endtry
- endwhile
-
- while 1
- try
- try
- let v:errmsg = ""
- if 1
- else
- elseif 1 ||| 2
- endif
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'h'
- call assert_match('E584: :elseif after :else', v:exception)
- finally
- Xpath 'i'
- call assert_equal("", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'j'
- break
- endtry
- endwhile
-
- while 1
- try
- try
- let v:errmsg = ""
- elseif 1 ||| 2
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'k'
- call assert_match('E582: :elseif without :if', v:exception)
- finally
- Xpath 'l'
- call assert_equal("", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'm'
- break
- endtry
- endwhile
-
- while 1
- try
- try
- let v:errmsg = ""
- while 1
- elseif 1 ||| 2
- endwhile
- catch /^Vim\((\a\+)\)\=:/
- Xpath 'n'
- call assert_match('E582: :elseif without :if', v:exception)
- finally
- Xpath 'o'
- call assert_equal("", v:errmsg)
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'p'
- break
- endtry
- endwhile
- Xpath 'q'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefghijklmnopq', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 81: Discarding exceptions after an error or interrupt {{{1
-"
-" When an exception is thrown from inside a :try conditional without
-" :catch and :finally clauses and an error or interrupt occurs before
-" the :endtry is reached, the exception is discarded.
-"-------------------------------------------------------------------------------
-
-func Test_discard_exception_after_error_1()
- let test =<< trim [CODE]
- try
- Xpath 'a'
- try
- Xpath 'b'
- throw "arrgh"
- call assert_report('should not get here')
- if 1
- call assert_report('should not get here')
- " error after :throw: missing :endif
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('ab', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-" interrupt the code before the endtry is invoked
-func Test_discard_exception_after_error_2()
- XpathINIT
- let lines =<< trim [CODE]
- try
- Xpath 'a'
- try
- Xpath 'b'
- throw "arrgh"
- call assert_report('should not get here')
- endtry " interrupt here
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- call writefile(lines, 'Xscript')
-
- breakadd file 7 Xscript
- try
- let caught_intr = 0
- debuggreedy
- call feedkeys(":source Xscript\<CR>quit\<CR>", "xt")
- catch /^Vim:Interrupt$/
- call assert_match('Xscript, line 7', v:throwpoint)
- let caught_intr = 1
- endtry
- 0debuggreedy
- call assert_equal(1, caught_intr)
- call assert_equal('ab', g:Xpath)
- breakdel *
- call delete('Xscript')
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 82: Ignoring :catch clauses after an error or interrupt {{{1
-"
-" When an exception is thrown and an error or interrupt occurs before
-" the matching :catch clause is reached, the exception is discarded
-" and the :catch clause is ignored (also for the error or interrupt
-" exception being thrown then).
-"-------------------------------------------------------------------------------
-
-func Test_ignore_catch_after_error_1()
- let test =<< trim [CODE]
- try
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')
- if 1
- call assert_report('should not get here')
- " error after :throw: missing :endif
- catch /.*/
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-func Test_ignore_catch_after_error_2()
- let test =<< trim [CODE]
- func E()
- try
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')
- if 1
- call assert_report('should not get here')
- " error after :throw: missing :endif
- catch /.*/
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- endfunc
-
- call E()
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('a', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-" interrupt right before a catch is invoked in a script
-func Test_ignore_catch_after_intr_1()
- XpathINIT
- let lines =<< trim [CODE]
- try
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')
- catch /.*/ " interrupt here
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- call writefile(lines, 'Xscript')
-
- breakadd file 6 Xscript
- try
- let caught_intr = 0
- debuggreedy
- call feedkeys(":source Xscript\<CR>quit\<CR>", "xt")
- catch /^Vim:Interrupt$/
- call assert_match('Xscript, line 6', v:throwpoint)
- let caught_intr = 1
- endtry
- 0debuggreedy
- call assert_equal(1, caught_intr)
- call assert_equal('a', g:Xpath)
- breakdel *
- call delete('Xscript')
-endfunc
-
-" interrupt right before a catch is invoked inside a function.
-func Test_ignore_catch_after_intr_2()
- XpathINIT
- func F()
- try
- try
- Xpath 'a'
- throw "arrgh"
- call assert_report('should not get here')
- catch /.*/ " interrupt here
- call assert_report('should not get here')
- catch /.*/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- endfunc
-
- breakadd func 6 F
- try
- let caught_intr = 0
- debuggreedy
- call feedkeys(":call F()\<CR>quit\<CR>", "xt")
- catch /^Vim:Interrupt$/
- call assert_match('\.F, line 6', v:throwpoint)
- let caught_intr = 1
- endtry
- 0debuggreedy
- call assert_equal(1, caught_intr)
- call assert_equal('a', g:Xpath)
- breakdel *
- delfunc F
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 83: Executing :finally clauses after an error or interrupt {{{1
-"
-" When an exception is thrown and an error or interrupt occurs before
-" the :finally of the innermost :try is reached, the exception is
-" discarded and the :finally clause is executed.
-"-------------------------------------------------------------------------------
-
-func Test_finally_after_error()
- let test =<< trim [CODE]
- try
- Xpath 'a'
- try
- Xpath 'b'
- throw "arrgh"
- call assert_report('should not get here')
- if 1
- call assert_report('should not get here')
- " error after :throw: missing :endif
- finally
- Xpath 'c'
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abc', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-" interrupt the code right before the finally is invoked
-func Test_finally_after_intr()
- XpathINIT
- let lines =<< trim [CODE]
- try
- Xpath 'a'
- try
- Xpath 'b'
- throw "arrgh"
- call assert_report('should not get here')
- finally " interrupt here
- Xpath 'c'
- endtry
- call assert_report('should not get here')
- catch /arrgh/
- call assert_report('should not get here')
- endtry
- call assert_report('should not get here')
- [CODE]
- call writefile(lines, 'Xscript')
-
- breakadd file 7 Xscript
- try
- let caught_intr = 0
- debuggreedy
- call feedkeys(":source Xscript\<CR>quit\<CR>", "xt")
- catch /^Vim:Interrupt$/
- call assert_match('Xscript, line 7', v:throwpoint)
- let caught_intr = 1
- endtry
- 0debuggreedy
- call assert_equal(1, caught_intr)
- call assert_equal('abc', g:Xpath)
- breakdel *
- call delete('Xscript')
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 84: Exceptions in autocommand sequences. {{{1
-"
-" When an exception occurs in a sequence of autocommands for
-" a specific event, the rest of the sequence is not executed. The
-" command that triggered the autocommand execution aborts, and the
-" exception is propagated to the caller.
-"
-" For the FuncUndefined event under a function call expression or
-" :call command, the function is not executed, even when it has
-" been defined by the autocommands before the exception occurred.
-"-------------------------------------------------------------------------------
-
-func Test_autocmd_exception()
- let test =<< trim [CODE]
- func INT()
- call interrupt()
- endfunc
-
- aug TMP
- autocmd!
-
- autocmd User x1 Xpath 'a'
- autocmd User x1 throw "x1"
- autocmd User x1 call assert_report('should not get here')
-
- autocmd User x2 Xpath 'b'
- autocmd User x2 asdf
- autocmd User x2 call assert_report('should not get here')
-
- autocmd User x3 Xpath 'c'
- autocmd User x3 call INT()
- autocmd User x3 call assert_report('should not get here')
-
- autocmd FuncUndefined U1 func U1()
- autocmd FuncUndefined U1 call assert_report('should not get here')
- autocmd FuncUndefined U1 endfunc
- autocmd FuncUndefined U1 Xpath 'd'
- autocmd FuncUndefined U1 throw "U1"
- autocmd FuncUndefined U1 call assert_report('should not get here')
-
- autocmd FuncUndefined U2 func U2()
- autocmd FuncUndefined U2 call assert_report('should not get here')
- autocmd FuncUndefined U2 endfunc
- autocmd FuncUndefined U2 Xpath 'e'
- autocmd FuncUndefined U2 ASDF
- autocmd FuncUndefined U2 call assert_report('should not get here')
-
- autocmd FuncUndefined U3 func U3()
- autocmd FuncUndefined U3 call assert_report('should not get here')
- autocmd FuncUndefined U3 endfunc
- autocmd FuncUndefined U3 Xpath 'f'
- autocmd FuncUndefined U3 call INT()
- autocmd FuncUndefined U3 call assert_report('should not get here')
- aug END
-
- try
- try
- Xpath 'g'
- doautocmd User x1
- catch /x1/
- Xpath 'h'
- endtry
-
- while 1
- try
- Xpath 'i'
- doautocmd User x2
- catch /asdf/
- Xpath 'j'
- finally
- Xpath 'k'
- break
- endtry
- endwhile
-
- while 1
- try
- Xpath 'l'
- doautocmd User x3
- catch /Vim:Interrupt/
- Xpath 'm'
- finally
- Xpath 'n'
- " ... but break loop for caught interrupt exception,
- " or discard interrupt and break loop if $VIMNOINTTHROW
- break
- endtry
- endwhile
-
- if exists("*U1") | delfunction U1 | endif
- if exists("*U2") | delfunction U2 | endif
- if exists("*U3") | delfunction U3 | endif
-
- try
- Xpath 'o'
- call U1()
- catch /U1/
- Xpath 'p'
- endtry
-
- while 1
- try
- Xpath 'q'
- call U2()
- catch /ASDF/
- Xpath 'r'
- finally
- Xpath 's'
- " ... but break loop for caught error exception,
- " or discard error and break loop if $VIMNOERRTHROW
- break
- endtry
- endwhile
-
- while 1
- try
- Xpath 't'
- call U3()
- catch /Vim:Interrupt/
- Xpath 'u'
- finally
- Xpath 'v'
- " ... but break loop for caught interrupt exception,
- " or discard interrupt and break loop if $VIMNOINTTHROW
- break
- endtry
- endwhile
- catch /.*/
- call assert_report('should not get here')
- endtry
- Xpath 'w'
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('gahibjklcmnodpqerstfuvw', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 85: Error exceptions in autocommands for I/O command events {{{1
-"
-" When an I/O command is inside :try/:endtry, autocommands to be
-" executed after it should be skipped on an error (exception) in the
-" command itself or in autocommands to be executed before the command.
-" In the latter case, the I/O command should not be executed either.
-" Example 1: BufWritePre, :write, BufWritePost
-" Example 2: FileReadPre, :read, FileReadPost.
-"-------------------------------------------------------------------------------
-
-func Test_autocmd_error_io_exception()
- let test =<< trim [CODE]
- " Remove the autocommands for the events specified as arguments in all used
- " autogroups.
- func Delete_autocommands(...)
- let augfile = tempname()
- while 1
- try
- exec "redir >" . augfile
- aug
- redir END
- exec "edit" augfile
- g/^$/d
- norm G$
- let wrap = "w"
- while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0
- let wrap = "W"
- exec "norm y/ \n"
- let argno = 1
- while argno <= a:0
- exec "au!" escape(@", " ") a:{argno}
- let argno = argno + 1
- endwhile
- endwhile
- catch /.*/
- finally
- bwipeout!
- call delete(augfile)
- break
- endtry
- endwhile
- endfunc
-
- call Delete_autocommands("BufWritePre", "BufWritePost")
-
- while 1
- try
- try
- let post = 0
- aug TMP
- au! BufWritePost * let post = 1
- aug END
- write /n/o/n/e/x/i/s/t/e/n/t
- catch /^Vim(write):/
- Xpath 'a'
- call assert_match("E212: Can't open file for writing", v:exception)
- finally
- Xpath 'b'
- call assert_equal(0, post)
- au! TMP
- aug! TMP
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'c'
- break
- endtry
- endwhile
-
- while 1
- try
- try
- let post = 0
- aug TMP
- au! BufWritePre * asdf
- au! BufWritePost * let post = 1
- aug END
- let tmpfile = tempname()
- exec "write" tmpfile
- catch /^Vim\((write)\)\=:/
- Xpath 'd'
- call assert_match('E492: Not an editor command', v:exception)
- finally
- Xpath 'e'
- if filereadable(tmpfile)
- call assert_report('should not get here')
- endif
- call assert_equal(0, post)
- au! TMP
- aug! TMP
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'f'
- break
- endtry
- endwhile
-
- call delete(tmpfile)
-
- call Delete_autocommands("BufWritePre", "BufWritePost",
- \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost")
-
- while 1
- try
- try
- let post = 0
- aug TMP
- au! FileReadPost * let post = 1
- aug END
- let caught = 0
- read /n/o/n/e/x/i/s/t/e/n/t
- catch /^Vim(read):/
- Xpath 'g'
- call assert_match("E484: Can't open file", v:exception)
- finally
- Xpath 'h'
- call assert_equal(0, post)
- au! TMP
- aug! TMP
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'i'
- break
- endtry
- endwhile
-
- while 1
- try
- let infile = tempname()
- let tmpfile = tempname()
- call writefile(["XYZ"], infile)
- exec "edit" tmpfile
- try
- Xpath 'j'
- try
- let post = 0
- aug TMP
- au! FileReadPre * asdf
- au! FileReadPost * let post = 1
- aug END
- exec "0read" infile
- catch /^Vim\((read)\)\=:/
- Xpath 'k'
- call assert_match('E492: Not an editor command', v:exception)
- finally
- Xpath 'l'
- if getline("1") == "XYZ"
- call assert_report('should not get here')
- endif
- call assert_equal(0, post)
- au! TMP
- aug! TMP
- endtry
- finally
- Xpath 'm'
- bwipeout!
- endtry
- catch /.*/
- call assert_report('should not get here')
- finally
- Xpath 'n'
- break
- endtry
- endwhile
-
- call delete(infile)
- call delete(tmpfile)
- [CODE]
- let verify =<< trim [CODE]
- call assert_equal('abcdefghijklmn', g:Xpath)
- [CODE]
- call RunInNewVim(test, verify)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 87 using (expr) ? funcref : funcref {{{1
-"
-" Vim needs to correctly parse the funcref and even when it does
-" not execute the funcref, it needs to consume the trailing ()
-"-------------------------------------------------------------------------------
-
-func Add2(x1, x2)
- return a:x1 + a:x2
-endfu
-
-func GetStr()
- return "abcdefghijklmnopqrstuvwxyp"
-endfu
-
-func Test_funcref_with_condexpr()
- call assert_equal(5, function('Add2')(2,3))
-
- call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3))
- call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3))
- " Make sure, GetStr() still works.
- call assert_equal('abcdefghijk', GetStr()[0:10])
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 90: Recognizing {} in variable name. {{{1
-"-------------------------------------------------------------------------------
-
-func Test_curlies()
- let s:var = 66
- let ns = 's'
- call assert_equal(66, {ns}:var)
-
- let g:a = {}
- let g:b = 't'
- let g:a[g:b] = 77
- call assert_equal(77, g:a['t'])
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 91: using type(). {{{1
-"-------------------------------------------------------------------------------
-
-func Test_type()
- call assert_equal(0, type(0))
- call assert_equal(1, type(""))
- call assert_equal(2, type(function("tr")))
- call assert_equal(2, type(function("tr", [8])))
- call assert_equal(3, type([]))
- call assert_equal(4, type({}))
- call assert_equal(5, type(0.0))
- call assert_equal(6, type(v:false))
- call assert_equal(6, type(v:true))
- call assert_equal(7, type(v:null))
- call assert_equal(v:t_number, type(0))
- call assert_equal(v:t_string, type(""))
- call assert_equal(v:t_func, type(function("tr")))
- call assert_equal(v:t_list, type([]))
- call assert_equal(v:t_dict, type({}))
- call assert_equal(v:t_float, type(0.0))
- call assert_equal(v:t_bool, type(v:false))
- call assert_equal(v:t_bool, type(v:true))
- call assert_equal(v:t_string, type(v:_null_string))
- call assert_equal(v:t_list, type(v:_null_list))
- call assert_equal(v:t_dict, type(v:_null_dict))
- call assert_equal(v:t_blob, type(v:_null_blob))
-
- call assert_equal(0, 0 + v:false)
- call assert_equal(1, 0 + v:true)
- " call assert_equal(0, 0 + v:none)
- call assert_equal(0, 0 + v:null)
-
- call assert_equal('v:false', '' . v:false)
- call assert_equal('v:true', '' . v:true)
- " call assert_equal('v:none', '' . v:none)
- call assert_equal('v:null', '' . v:null)
-
- call assert_true(v:false == 0)
- call assert_false(v:false != 0)
- call assert_true(v:true == 1)
- call assert_false(v:true != 1)
- call assert_false(v:true == v:false)
- call assert_true(v:true != v:false)
-
- call assert_true(v:null == 0)
- call assert_false(v:null != 0)
- " call assert_true(v:none == 0)
- " call assert_false(v:none != 0)
-
- call assert_true(v:false is v:false)
- call assert_true(v:true is v:true)
- " call assert_true(v:none is v:none)
- call assert_true(v:null is v:null)
-
- call assert_false(v:false isnot v:false)
- call assert_false(v:true isnot v:true)
- " call assert_false(v:none isnot v:none)
- call assert_false(v:null isnot v:null)
-
- call assert_false(v:false is 0)
- call assert_false(v:true is 1)
- call assert_false(v:true is v:false)
- " call assert_false(v:none is 0)
- call assert_false(v:null is 0)
- " call assert_false(v:null is v:none)
-
- call assert_true(v:false isnot 0)
- call assert_true(v:true isnot 1)
- call assert_true(v:true isnot v:false)
- " call assert_true(v:none isnot 0)
- call assert_true(v:null isnot 0)
- " call assert_true(v:null isnot v:none)
-
- call assert_equal(v:false, eval(string(v:false)))
- call assert_equal(v:true, eval(string(v:true)))
- " call assert_equal(v:none, eval(string(v:none)))
- call assert_equal(v:null, eval(string(v:null)))
-
- call assert_equal(v:false, copy(v:false))
- call assert_equal(v:true, copy(v:true))
- " call assert_equal(v:none, copy(v:none))
- call assert_equal(v:null, copy(v:null))
-
- call assert_equal([v:false], deepcopy([v:false]))
- call assert_equal([v:true], deepcopy([v:true]))
- " call assert_equal([v:none], deepcopy([v:none]))
- call assert_equal([v:null], deepcopy([v:null]))
-
- call assert_true(empty(v:false))
- call assert_false(empty(v:true))
- call assert_true(empty(v:null))
- " call assert_true(empty(v:none))
-
- func ChangeYourMind()
- try
- return v:true
- finally
- return 'something else'
- endtry
- endfunc
-
- call ChangeYourMind()
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 92: skipping code {{{1
-"-------------------------------------------------------------------------------
-
-func Test_skip()
- let Fn = function('Test_type')
- call assert_false(0 && Fn[1])
- call assert_false(0 && string(Fn))
- call assert_false(0 && len(Fn))
- let l = []
- call assert_false(0 && l[1])
- call assert_false(0 && string(l))
- call assert_false(0 && len(l))
- let f = 1.0
- call assert_false(0 && f[1])
- call assert_false(0 && string(f))
- call assert_false(0 && len(f))
- let sp = v:null
- call assert_false(0 && sp[1])
- call assert_false(0 && string(sp))
- call assert_false(0 && len(sp))
-
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 93: :echo and string() {{{1
-"-------------------------------------------------------------------------------
-
-func Test_echo_and_string()
- " String
- let a = 'foo bar'
- redir => result
- echo a
- echo string(a)
- redir END
- let l = split(result, "\n")
- call assert_equal(["foo bar",
- \ "'foo bar'"], l)
-
- " Float
- if has('float')
- let a = -1.2e0
- redir => result
- echo a
- echo string(a)
- redir END
- let l = split(result, "\n")
- call assert_equal(["-1.2",
- \ "-1.2"], l)
- endif
-
- " Funcref
- redir => result
- echo function('string')
- echo string(function('string'))
- redir END
- let l = split(result, "\n")
- call assert_equal(["string",
- \ "function('string')"], l)
-
- " Empty dictionaries in a list
- let a = {}
- redir => result
- echo [a, a, a]
- echo string([a, a, a])
- redir END
- let l = split(result, "\n")
- call assert_equal(["[{}, {}, {}]",
- \ "[{}, {}, {}]"], l)
-
- " Empty dictionaries in a dictionary
- let a = {}
- let b = {"a": a, "b": a}
- redir => result
- echo b
- echo string(b)
- redir END
- let l = split(result, "\n")
- call assert_equal(["{'a': {}, 'b': {}}",
- \ "{'a': {}, 'b': {}}"], l)
-
- " Empty lists in a list
- let a = []
- redir => result
- echo [a, a, a]
- echo string([a, a, a])
- redir END
- let l = split(result, "\n")
- call assert_equal(["[[], [], []]",
- \ "[[], [], []]"], l)
-
- " Empty lists in a dictionary
- let a = []
- let b = {"a": a, "b": a}
- redir => result
- echo b
- echo string(b)
- redir END
- let l = split(result, "\n")
- call assert_equal(["{'a': [], 'b': []}",
- \ "{'a': [], 'b': []}"], l)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 94: 64-bit Numbers {{{1
-"-------------------------------------------------------------------------------
-
-func Test_num64()
- call assert_notequal( 4294967296, 0)
- call assert_notequal(-4294967296, 0)
- call assert_equal( 4294967296, 0xFFFFffff + 1)
- call assert_equal(-4294967296, -0xFFFFffff - 1)
-
- call assert_equal( 9223372036854775807, 1 / 0)
- call assert_equal(-9223372036854775807, -1 / 0)
- call assert_equal(-9223372036854775807 - 1, 0 / 0)
-
- if has('float')
- call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
- call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
- endif
-
- let rng = range(0xFFFFffff, 0x100000001)
- call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
- call assert_equal(0x100000001, max(rng))
- call assert_equal(0xFFFFffff, min(rng))
- call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 95: lines of :append, :change, :insert {{{1
-"-------------------------------------------------------------------------------
-
-func DefineFunction(name, body)
- let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
- exec func
-endfunc
-
-func Test_script_lines()
- " :append
- try
- call DefineFunction('T_Append', [
- \ 'append',
- \ 'py <<EOS',
- \ '.',
- \ ])
- catch
- call assert_report("Can't define function")
- endtry
- try
- call DefineFunction('T_Append', [
- \ 'append',
- \ 'abc',
- \ ])
- call assert_report("Shouldn't be able to define function")
- catch
- call assert_exception('Vim(function):E126: Missing :endfunction')
- endtry
-
- " :change
- try
- call DefineFunction('T_Change', [
- \ 'change',
- \ 'py <<EOS',
- \ '.',
- \ ])
- catch
- call assert_report("Can't define function")
- endtry
- try
- call DefineFunction('T_Change', [
- \ 'change',
- \ 'abc',
- \ ])
- call assert_report("Shouldn't be able to define function")
- catch
- call assert_exception('Vim(function):E126: Missing :endfunction')
- endtry
-
- " :insert
- try
- call DefineFunction('T_Insert', [
- \ 'insert',
- \ 'py <<EOS',
- \ '.',
- \ ])
- catch
- call assert_report("Can't define function")
- endtry
- try
- call DefineFunction('T_Insert', [
- \ 'insert',
- \ 'abc',
- \ ])
- call assert_report("Shouldn't be able to define function")
- catch
- call assert_exception('Vim(function):E126: Missing :endfunction')
- endtry
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 96: line continuation {{{1
-"
-" Undefined behavior was detected by ubsan with line continuation
-" after an empty line.
-"-------------------------------------------------------------------------------
-func Test_script_empty_line_continuation()
-
- \
-endfunc
-
-"-------------------------------------------------------------------------------
-" Test 97: bitwise functions {{{1
-"-------------------------------------------------------------------------------
-func Test_bitwise_functions()
- " and
- call assert_equal(127, and(127, 127))
- call assert_equal(16, and(127, 16))
- eval 127->and(16)->assert_equal(16)
- call assert_equal(0, and(127, 128))
- call assert_fails("call and(1.0, 1)", 'E805:')
- call assert_fails("call and([], 1)", 'E745:')
- call assert_fails("call and({}, 1)", 'E728:')
- call assert_fails("call and(1, 1.0)", 'E805:')
- call assert_fails("call and(1, [])", 'E745:')
- call assert_fails("call and(1, {})", 'E728:')
- " or
- call assert_equal(23, or(16, 7))
- call assert_equal(15, or(8, 7))
- eval 8->or(7)->assert_equal(15)
- call assert_equal(123, or(0, 123))
- call assert_fails("call or(1.0, 1)", 'E805:')
- call assert_fails("call or([], 1)", 'E745:')
- call assert_fails("call or({}, 1)", 'E728:')
- call assert_fails("call or(1, 1.0)", 'E805:')
- call assert_fails("call or(1, [])", 'E745:')
- call assert_fails("call or(1, {})", 'E728:')
- " xor
- call assert_equal(0, xor(127, 127))
- call assert_equal(111, xor(127, 16))
- eval 127->xor(16)->assert_equal(111)
- call assert_equal(255, xor(127, 128))
- call assert_fails("call xor(1.0, 1)", 'E805:')
- call assert_fails("call xor([], 1)", 'E745:')
- call assert_fails("call xor({}, 1)", 'E728:')
- call assert_fails("call xor(1, 1.0)", 'E805:')
- call assert_fails("call xor(1, [])", 'E745:')
- call assert_fails("call xor(1, {})", 'E728:')
- " invert
- call assert_equal(65408, and(invert(127), 65535))
- eval 127->invert()->and(65535)->assert_equal(65408)
- call assert_equal(65519, and(invert(16), 65535))
- call assert_equal(65407, and(invert(128), 65535))
- call assert_fails("call invert(1.0)", 'E805:')
- call assert_fails("call invert([])", 'E745:')
- call assert_fails("call invert({})", 'E728:')
-endfunc
-
-" Test using bang after user command {{{1
-func Test_user_command_with_bang()
- command -bang Nieuw let nieuw = 1
- Ni!
- call assert_equal(1, nieuw)
- unlet nieuw
- delcommand Nieuw
-endfunc
-
-func Test_script_expand_sfile()
- let lines =<< trim END
- func s:snr()
- return expand('<sfile>')
- endfunc
- let g:result = s:snr()
- END
- call writefile(lines, 'Xexpand')
- source Xexpand
- call assert_match('<SNR>\d\+_snr', g:result)
- source Xexpand
- call assert_match('<SNR>\d\+_snr', g:result)
-
- call delete('Xexpand')
- unlet g:result
-endfunc
-
-func Test_compound_assignment_operators()
- " Test for number
- let x = 1
- let x += 10
- call assert_equal(11, x)
- let x -= 5
- call assert_equal(6, x)
- let x *= 4
- call assert_equal(24, x)
- let x /= 3
- call assert_equal(8, x)
- let x %= 3
- call assert_equal(2, x)
- let x .= 'n'
- call assert_equal('2n', x)
-
- " Test special cases: division or modulus with 0.
- let x = 1
- let x /= 0
- call assert_equal(0x7FFFFFFFFFFFFFFF, x)
-
- let x = -1
- let x /= 0
- call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
-
- let x = 0
- let x /= 0
- call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
-
- let x = 1
- let x %= 0
- call assert_equal(0, x)
-
- let x = -1
- let x %= 0
- call assert_equal(0, x)
-
- let x = 0
- let x %= 0
- call assert_equal(0, x)
-
- " Test for string
- let x = 'str'
- let x .= 'ing'
- call assert_equal('string', x)
- let x += 1
- call assert_equal(1, x)
-
- if has('float')
- " Test for float
- let x -= 1.5
- call assert_equal(-0.5, x)
- let x = 0.5
- let x += 4.5
- call assert_equal(5.0, x)
- let x -= 1.5
- call assert_equal(3.5, x)
- let x *= 3.0
- call assert_equal(10.5, x)
- let x /= 2.5
- call assert_equal(4.2, x)
- call assert_fails('let x %= 0.5', 'E734')
- call assert_fails('let x .= "f"', 'E734')
- let x = !3.14
- call assert_equal(0.0, x)
-
- " integer and float operations
- let x = 1
- let x *= 2.1
- call assert_equal(2.1, x)
- let x = 1
- let x /= 0.25
- call assert_equal(4.0, x)
- let x = 1
- call assert_fails('let x %= 0.25', 'E734:')
- let x = 1
- call assert_fails('let x .= 0.25', 'E734:')
- let x = 1.0
- call assert_fails('let x += [1.1]', 'E734:')
- endif
-
- " Test for environment variable
- let $FOO = 1
- call assert_fails('let $FOO += 1', 'E734')
- call assert_fails('let $FOO -= 1', 'E734')
- call assert_fails('let $FOO *= 1', 'E734')
- call assert_fails('let $FOO /= 1', 'E734')
- call assert_fails('let $FOO %= 1', 'E734')
- let $FOO .= 's'
- call assert_equal('1s', $FOO)
- unlet $FOO
-
- " Test for option variable (type: number)
- let &scrolljump = 1
- let &scrolljump += 5
- call assert_equal(6, &scrolljump)
- let &scrolljump -= 2
- call assert_equal(4, &scrolljump)
- let &scrolljump *= 3
- call assert_equal(12, &scrolljump)
- let &scrolljump /= 2
- call assert_equal(6, &scrolljump)
- let &scrolljump %= 5
- call assert_equal(1, &scrolljump)
- call assert_fails('let &scrolljump .= "j"', 'E734:')
- set scrolljump&vim
-
- let &foldlevelstart = 2
- let &foldlevelstart -= 1
- call assert_equal(1, &foldlevelstart)
- let &foldlevelstart -= 1
- call assert_equal(0, &foldlevelstart)
- let &foldlevelstart = 2
- let &foldlevelstart -= 2
- call assert_equal(0, &foldlevelstart)
-
- " Test for register
- let @/ = 1
- call assert_fails('let @/ += 1', 'E734:')
- call assert_fails('let @/ -= 1', 'E734:')
- call assert_fails('let @/ *= 1', 'E734:')
- call assert_fails('let @/ /= 1', 'E734:')
- call assert_fails('let @/ %= 1', 'E734:')
- let @/ .= 's'
- call assert_equal('1s', @/)
- let @/ = ''
-endfunc
-
-func Test_unlet_env()
- let $TESTVAR = 'yes'
- call assert_equal('yes', $TESTVAR)
- call assert_fails('lockvar $TESTVAR', 'E940')
- call assert_fails('unlockvar $TESTVAR', 'E940')
- call assert_equal('yes', $TESTVAR)
- if 0
- unlet $TESTVAR
- endif
- call assert_equal('yes', $TESTVAR)
- unlet $TESTVAR
- call assert_equal('', $TESTVAR)
-endfunc
-
-" Test for missing :endif, :endfor, :endwhile and :endtry {{{1
-func Test_missing_end()
- call writefile(['if 2 > 1', 'echo ">"'], 'Xscript')
- call assert_fails('source Xscript', 'E171:')
- call writefile(['for i in range(5)', 'echo i'], 'Xscript')
- call assert_fails('source Xscript', 'E170:')
- call writefile(['while v:true', 'echo "."'], 'Xscript')
- call assert_fails('source Xscript', 'E170:')
- call writefile(['try', 'echo "."'], 'Xscript')
- call assert_fails('source Xscript', 'E600:')
- call delete('Xscript')
-
- " Using endfor with :while
- let caught_e732 = 0
- try
- while v:true
- endfor
- catch /E732:/
- let caught_e732 = 1
- endtry
- call assert_equal(1, caught_e732)
-
- " Using endwhile with :for
- let caught_e733 = 0
- try
- for i in range(1)
- endwhile
- catch /E733:/
- let caught_e733 = 1
- endtry
- call assert_equal(1, caught_e733)
-
- " Using endfunc with :if
- call assert_fails('exe "if 1 | endfunc | endif"', 'E193:')
-
- " Missing 'in' in a :for statement
- call assert_fails('for i range(1) | endfor', 'E690:')
-
- " Incorrect number of variables in for
- call assert_fails('for [i,] in range(3) | endfor', 'E475:')
-endfunc
-
-" Test for deep nesting of if/for/while/try statements {{{1
-func Test_deep_nest()
- CheckRunVimInTerminal
-
- let lines =<< trim [SCRIPT]
- " Deep nesting of if ... endif
- func Test1()
- let @a = join(repeat(['if v:true'], 51), "\n")
- let @a ..= "\n"
- let @a ..= join(repeat(['endif'], 51), "\n")
- @a
- let @a = ''
- endfunc
-
- " Deep nesting of for ... endfor
- func Test2()
- let @a = join(repeat(['for i in [1]'], 51), "\n")
- let @a ..= "\n"
- let @a ..= join(repeat(['endfor'], 51), "\n")
- @a
- let @a = ''
- endfunc
-
- " Deep nesting of while ... endwhile
- func Test3()
- let @a = join(repeat(['while v:true'], 51), "\n")
- let @a ..= "\n"
- let @a ..= join(repeat(['endwhile'], 51), "\n")
- @a
- let @a = ''
- endfunc
-
- " Deep nesting of try ... endtry
- func Test4()
- let @a = join(repeat(['try'], 51), "\n")
- let @a ..= "\necho v:true\n"
- let @a ..= join(repeat(['endtry'], 51), "\n")
- @a
- let @a = ''
- endfunc
-
- " Deep nesting of function ... endfunction
- func Test5()
- let @a = join(repeat(['function X()'], 51), "\n")
- let @a ..= "\necho v:true\n"
- let @a ..= join(repeat(['endfunction'], 51), "\n")
- @a
- let @a = ''
- endfunc
- [SCRIPT]
- call writefile(lines, 'Xscript')
-
- let buf = RunVimInTerminal('-S Xscript', {'rows': 6})
-
- " Deep nesting of if ... endif
- call term_sendkeys(buf, ":call Test1()\n")
- call term_wait(buf)
- call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))})
-
- " Deep nesting of for ... endfor
- call term_sendkeys(buf, ":call Test2()\n")
- call term_wait(buf)
- call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
-
- " Deep nesting of while ... endwhile
- call term_sendkeys(buf, ":call Test3()\n")
- call term_wait(buf)
- call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
-
- " Deep nesting of try ... endtry
- call term_sendkeys(buf, ":call Test4()\n")
- call term_wait(buf)
- call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))})
-
- " Deep nesting of function ... endfunction
- call term_sendkeys(buf, ":call Test5()\n")
- call term_wait(buf)
- call WaitForAssert({-> assert_match('^E1058:', term_getline(buf, 4))})
- call term_sendkeys(buf, "\<C-C>\n")
- call term_wait(buf)
-
- "let l = ''
- "for i in range(1, 6)
- " let l ..= term_getline(buf, i) . "\n"
- "endfor
- "call assert_report(l)
-
- call StopVimInTerminal(buf)
- call delete('Xscript')
-endfunc
-
-" Test for errors in converting to float from various types {{{1
-func Test_float_conversion_errors()
- if has('float')
- call assert_fails('let x = 4.0 % 2.0', 'E804')
- call assert_fails('echo 1.1[0]', 'E806')
- call assert_fails('echo sort([function("min"), 1], "f")', 'E891:')
- call assert_fails('echo 3.2 == "vim"', 'E892:')
- call assert_fails('echo sort([[], 1], "f")', 'E893:')
- call assert_fails('echo sort([{}, 1], "f")', 'E894:')
- call assert_fails('echo 3.2 == v:true', 'E362:')
- " call assert_fails('echo 3.2 == v:none', 'E907:')
- endif
-endfunc
-
-" invalid function names {{{1
-func Test_invalid_function_names()
- " function name not starting with capital
- let caught_e128 = 0
- try
- func! g:test()
- echo "test"
- endfunc
- catch /E128:/
- let caught_e128 = 1
- endtry
- call assert_equal(1, caught_e128)
-
- " function name includes a colon
- let caught_e884 = 0
- try
- func! b:test()
- echo "test"
- endfunc
- catch /E884:/
- let caught_e884 = 1
- endtry
- call assert_equal(1, caught_e884)
-
- " function name followed by #
- let caught_e128 = 0
- try
- func! test2() "#
- echo "test2"
- endfunc
- catch /E128:/
- let caught_e128 = 1
- endtry
- call assert_equal(1, caught_e128)
-
- " function name starting with/without "g:", buffer-local funcref.
- function! g:Foo(n)
- return 'called Foo(' . a:n . ')'
- endfunction
- let b:my_func = function('Foo')
- call assert_equal('called Foo(1)', b:my_func(1))
- call assert_equal('called Foo(2)', g:Foo(2))
- call assert_equal('called Foo(3)', Foo(3))
- delfunc g:Foo
-
- " script-local function used in Funcref must exist.
- let lines =<< trim END
- func s:Testje()
- return "foo"
- endfunc
- let Bar = function('s:Testje')
- call assert_equal(0, exists('s:Testje'))
- call assert_equal(1, exists('*s:Testje'))
- call assert_equal(1, exists('Bar'))
- call assert_equal(1, exists('*Bar'))
- END
- call writefile(lines, 'Xscript')
- source Xscript
- call delete('Xscript')
-endfunc
-
-" substring and variable name {{{1
-func Test_substring_var()
- let str = 'abcdef'
- let n = 3
- call assert_equal('def', str[n:])
- call assert_equal('abcd', str[:n])
- call assert_equal('d', str[n:n])
- unlet n
- let nn = 3
- call assert_equal('def', str[nn:])
- call assert_equal('abcd', str[:nn])
- call assert_equal('d', str[nn:nn])
- unlet nn
- let b:nn = 4
- call assert_equal('ef', str[b:nn:])
- call assert_equal('abcde', str[:b:nn])
- call assert_equal('e', str[b:nn:b:nn])
- unlet b:nn
-endfunc
-
-" Test using s: with a typed command {{{1
-func Test_typed_script_var()
- CheckRunVimInTerminal
-
- let buf = RunVimInTerminal('', {'rows': 6})
-
- " Deep nesting of if ... endif
- call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n")
- call TermWait(buf)
- call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))})
-
- call StopVimInTerminal(buf)
-endfunc
-
-func Test_for_over_string()
- let res = ''
- for c in 'aéc̀d'
- let res ..= c .. '-'
- endfor
- call assert_equal('a-é-c̀-d-', res)
-
- let res = ''
- for c in ''
- let res ..= c .. '-'
- endfor
- call assert_equal('', res)
-
- let res = ''
- for c in v:_null_string
- let res ..= c .. '-'
- endfor
- call assert_equal('', res)
-endfunc
-
-"-------------------------------------------------------------------------------
-" Modelines {{{1
-" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
-"-------------------------------------------------------------------------------