2019-06-15 19:23:56 -07:00
|
|
|
" Test various aspects of the Vim script language.
|
2016-04-17 03:32:23 -07:00
|
|
|
" Most of this was formerly in test49.
|
2016-04-14 12:35:16 -07:00
|
|
|
|
2022-02-14 03:56:30 -07:00
|
|
|
source check.vim
|
|
|
|
source shared.vim
|
2022-11-05 05:23:29 -07:00
|
|
|
source script_util.vim
|
2022-02-14 03:56:30 -07:00
|
|
|
|
2016-04-14 12:35:16 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" Test environment {{{1
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
" Append a message to the "messages" file
|
2020-11-29 23:08:27 -07:00
|
|
|
func Xout(text)
|
2016-04-14 12:35:16 -07:00
|
|
|
split messages
|
|
|
|
$put =a:text
|
|
|
|
wq
|
|
|
|
endfunc
|
|
|
|
|
|
|
|
com! -nargs=1 Xout call Xout(<args>)
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
" 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
|
|
|
|
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')
|
2016-07-25 05:12:24 -07:00
|
|
|
endfunc
|
|
|
|
|
2016-04-14 12:35:16 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" 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.
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func T1_F()
|
2016-04-14 12:35:16 -07:00
|
|
|
Xpath 'a'
|
|
|
|
let first = 1
|
|
|
|
while 1
|
|
|
|
Xpath 'b'
|
|
|
|
if first
|
|
|
|
Xpath 'c'
|
|
|
|
let first = 0
|
|
|
|
break
|
|
|
|
else
|
|
|
|
Xpath 'd'
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
endwhile
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:35:16 -07:00
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func T1_G()
|
2016-04-14 12:35:16 -07:00
|
|
|
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
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:35:16 -07:00
|
|
|
|
|
|
|
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'
|
2016-07-25 05:12:24 -07:00
|
|
|
call DeleteTheScript()
|
2016-04-14 12:35:16 -07:00
|
|
|
|
|
|
|
try
|
|
|
|
ExecAsScript T1_G
|
|
|
|
catch
|
|
|
|
" Catch missing :endif
|
|
|
|
call assert_true(v:exception =~ 'E171')
|
|
|
|
Xpath 'x'
|
|
|
|
endtry
|
|
|
|
Xpath 'G'
|
2016-07-25 05:12:24 -07:00
|
|
|
call DeleteTheScript()
|
2016-04-14 12:35:16 -07:00
|
|
|
|
|
|
|
call assert_equal('abcFhijxG', g:Xpath)
|
|
|
|
endfunc
|
|
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" Test 3: :if, :elseif, :while, :continue, :break {{{1
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func Test_if_while()
|
2016-04-14 12:35:16 -07:00
|
|
|
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
|
|
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" Test 4: :return {{{1
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func T4_F()
|
2016-04-14 12:35:16 -07:00
|
|
|
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
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:35:16 -07:00
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func Test_return()
|
2016-04-14 12:35:16 -07:00
|
|
|
XpathINIT
|
|
|
|
call T4_F()
|
|
|
|
Xpath '4'
|
|
|
|
|
|
|
|
call assert_equal('ab3e3b2c24', g:Xpath)
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:35:16 -07:00
|
|
|
|
|
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" 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).
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func Test_finish()
|
2016-04-14 12:35:16 -07:00
|
|
|
XpathINIT
|
|
|
|
ExecAsScript T4_F
|
|
|
|
Xpath '5'
|
2016-07-25 05:12:24 -07:00
|
|
|
call DeleteTheScript()
|
2016-04-14 12:35:16 -07:00
|
|
|
|
|
|
|
call assert_equal('ab3e3b2c25', g:Xpath)
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:35:16 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" 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
|
2020-11-29 23:08:27 -07:00
|
|
|
\ if !exists("calls") && !exists("outer") |
|
|
|
|
\ let g:calls = g:calls . <args> |
|
|
|
|
\ endif
|
2016-04-14 12:35:16 -07:00
|
|
|
|
|
|
|
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")
|
2020-11-29 23:08:27 -07:00
|
|
|
call G1("G1")
|
2016-04-14 12:35:16 -07:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
|
|
|
if exists("G21") || exists("G22") || exists("G23")
|
|
|
|
Xpath 'k'
|
|
|
|
endif
|
|
|
|
if exists("*F2")
|
|
|
|
call F2(2, "F2")
|
|
|
|
if exists("*G21")
|
2020-11-29 23:08:27 -07:00
|
|
|
call G21("G21")
|
2016-04-14 12:35:16 -07:00
|
|
|
endif
|
|
|
|
if exists("*G22")
|
2020-11-29 23:08:27 -07:00
|
|
|
call G22("G22")
|
2016-04-14 12:35:16 -07:00
|
|
|
endif
|
|
|
|
if exists("*G23")
|
2020-11-29 23:08:27 -07:00
|
|
|
call G23("G23")
|
2016-04-14 12:35:16 -07:00
|
|
|
endif
|
|
|
|
endif
|
|
|
|
|
|
|
|
if exists("G31") || exists("G32") || exists("G33")
|
|
|
|
Xpath 'l'
|
|
|
|
endif
|
|
|
|
if exists("*F3")
|
|
|
|
call F3(3, "F3")
|
|
|
|
if exists("*G31")
|
2020-11-29 23:08:27 -07:00
|
|
|
call G31("G31")
|
2016-04-14 12:35:16 -07:00
|
|
|
endif
|
|
|
|
if exists("*G32")
|
2020-11-29 23:08:27 -07:00
|
|
|
call G32("G32")
|
2016-04-14 12:35:16 -07:00
|
|
|
endif
|
|
|
|
if exists("*G33")
|
2020-11-29 23:08:27 -07:00
|
|
|
call G33("G33")
|
2016-04-14 12:35:16 -07:00
|
|
|
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
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func Test_defining_functions()
|
2016-04-14 12:35:16 -07:00
|
|
|
call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
|
|
|
|
call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
|
|
|
|
endfunc
|
|
|
|
|
2016-04-14 12:43:53 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" 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
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func T8_F()
|
2016-04-14 12:43:53 -07:00
|
|
|
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
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func T8_G() abort
|
2016-04-14 12:43:53 -07:00
|
|
|
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
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func T8_H() abort
|
2016-04-14 12:43:53 -07:00
|
|
|
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
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
|
|
|
" 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
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func F() abort
|
2016-04-14 12:43:53 -07:00
|
|
|
Xpath 'a'
|
|
|
|
let result = G() " not aborted
|
|
|
|
Xpath 'b'
|
|
|
|
if result != 2
|
|
|
|
Xpath 'c'
|
|
|
|
endif
|
|
|
|
return 1
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func G() " no abort attribute
|
2016-04-14 12:43:53 -07:00
|
|
|
Xpath 'd'
|
|
|
|
if H() != -1 " aborted
|
|
|
|
Xpath 'e'
|
|
|
|
endif
|
|
|
|
Xpath 'f'
|
|
|
|
return 2
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func H() abort
|
2016-04-14 12:43:53 -07:00
|
|
|
Xpath 'g'
|
|
|
|
call I() " aborted
|
|
|
|
Xpath 'h'
|
|
|
|
return 4
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func I() abort
|
2016-04-14 12:43:53 -07:00
|
|
|
Xpath 'i'
|
|
|
|
asdf " error
|
|
|
|
Xpath 'j'
|
|
|
|
return 8
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func MSG(enr, emsg)
|
2016-04-14 12:43:53 -07:00
|
|
|
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
|
2021-08-08 08:07:40 -07:00
|
|
|
let v:errmsg = v:errmsg->escape('"')
|
2016-04-14 12:43:53 -07:00
|
|
|
Xout "Unexpected message:" v:errmsg
|
|
|
|
endif
|
|
|
|
endif
|
|
|
|
return match
|
2020-11-29 23:08:27 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2022-11-05 05:23:29 -07:00
|
|
|
func P(num)
|
2016-04-14 12:43:53 -07:00
|
|
|
let g:calls = g:calls + a:num " side effect on call
|
|
|
|
return 0
|
2022-11-05 05:23:29 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2022-10-06 16:06:38 -07:00
|
|
|
func NULL()
|
2016-04-14 12:43:53 -07:00
|
|
|
Xpath 'a'
|
|
|
|
return 0
|
2022-10-06 16:06:38 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
2022-10-06 16:06:38 -07:00
|
|
|
func ZERO()
|
2016-04-14 12:43:53 -07:00
|
|
|
Xpath 'b'
|
|
|
|
return 0
|
2022-10-06 16:06:38 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
2022-10-06 16:06:38 -07:00
|
|
|
func! F0()
|
2016-04-14 12:43:53 -07:00
|
|
|
Xpath 'c'
|
2022-10-06 16:06:38 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
2022-10-06 16:06:38 -07:00
|
|
|
func! F1(arg)
|
2016-04-14 12:43:53 -07:00
|
|
|
Xpath 'e'
|
2022-10-06 16:06:38 -07:00
|
|
|
endfunc
|
2016-04-14 12:43:53 -07:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2020-10-20 21:04:27 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" 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
|
|
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
2022-11-05 05:23:29 -07:00
|
|
|
" 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.
|
2020-10-20 21:04:27 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
2022-11-05 05:23:29 -07:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2020-10-20 21:04:27 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" 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
|
2016-04-14 12:43:53 -07:00
|
|
|
|
2016-04-17 03:32:23 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
2020-10-20 21:04:27 -07:00
|
|
|
" Test 90: Recognizing {} in variable name. {{{1
|
2016-04-17 03:32:23 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2016-05-10 23:37:48 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" 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")))
|
2016-10-27 13:53:53 -07:00
|
|
|
call assert_equal(2, type(function("tr", [8])))
|
2016-05-10 23:37:48 -07:00
|
|
|
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))
|
2016-11-21 23:04:02 -07:00
|
|
|
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))
|
2021-07-29 14:32:22 -07:00
|
|
|
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))
|
2022-02-06 14:34:20 -07:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2022-08-13 06:31:00 -07:00
|
|
|
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)
|
2022-02-06 14:34:20 -07:00
|
|
|
|
|
|
|
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)
|
2022-02-06 14:34:20 -07:00
|
|
|
|
|
|
|
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)
|
2022-02-06 14:34:20 -07:00
|
|
|
|
|
|
|
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)))
|
2022-02-06 14:34:20 -07:00
|
|
|
|
2022-02-06 14:34:20 -07:00
|
|
|
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]))
|
|
|
|
|
2022-02-06 14:34:20 -07:00
|
|
|
call assert_true(empty(v:false))
|
|
|
|
call assert_false(empty(v:true))
|
|
|
|
call assert_true(empty(v:null))
|
|
|
|
" call assert_true(empty(v:none))
|
2022-02-06 14:34:20 -07:00
|
|
|
|
|
|
|
func ChangeYourMind()
|
2022-02-06 14:34:20 -07:00
|
|
|
try
|
|
|
|
return v:true
|
|
|
|
finally
|
|
|
|
return 'something else'
|
|
|
|
endtry
|
2022-02-06 14:34:20 -07:00
|
|
|
endfunc
|
|
|
|
|
|
|
|
call ChangeYourMind()
|
2016-05-10 23:37:48 -07:00
|
|
|
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
|
2016-04-17 03:32:23 -07:00
|
|
|
|
2016-12-06 22:47:40 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" 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)
|
2018-07-07 04:14:06 -07:00
|
|
|
endfunc
|
2016-12-06 22:47:40 -07:00
|
|
|
|
2016-11-16 09:09:04 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" 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)
|
2017-01-23 10:55:27 -07:00
|
|
|
call assert_equal(-9223372036854775807 - 1, 0 / 0)
|
2016-11-16 09:09:04 -07:00
|
|
|
|
2021-05-24 11:43:47 -07:00
|
|
|
if has('float')
|
|
|
|
call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
|
|
|
|
call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
|
|
|
|
endif
|
2016-11-16 09:09:04 -07:00
|
|
|
|
|
|
|
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'))
|
2016-12-06 22:47:40 -07:00
|
|
|
endfunc
|
|
|
|
|
2017-06-06 02:19:28 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" Test 95: lines of :append, :change, :insert {{{1
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
|
2022-10-06 16:06:38 -07:00
|
|
|
func DefineFunction(name, body)
|
2017-06-06 02:19:28 -07:00
|
|
|
let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n")
|
|
|
|
exec func
|
2022-10-06 16:06:38 -07:00
|
|
|
endfunc
|
2017-06-06 02:19:28 -07:00
|
|
|
|
|
|
|
func Test_script_lines()
|
|
|
|
" :append
|
|
|
|
try
|
2020-11-29 23:08:27 -07:00
|
|
|
call DefineFunction('T_Append', [
|
|
|
|
\ 'append',
|
|
|
|
\ 'py <<EOS',
|
|
|
|
\ '.',
|
|
|
|
\ ])
|
2017-06-06 02:19:28 -07:00
|
|
|
catch
|
2020-11-29 23:08:27 -07:00
|
|
|
call assert_report("Can't define function")
|
2017-06-06 02:19:28 -07:00
|
|
|
endtry
|
|
|
|
try
|
2020-11-29 23:08:27 -07:00
|
|
|
call DefineFunction('T_Append', [
|
|
|
|
\ 'append',
|
|
|
|
\ 'abc',
|
|
|
|
\ ])
|
|
|
|
call assert_report("Shouldn't be able to define function")
|
2017-06-06 02:19:28 -07:00
|
|
|
catch
|
2020-11-29 23:08:27 -07:00
|
|
|
call assert_exception('Vim(function):E126: Missing :endfunction')
|
2017-06-06 02:19:28 -07:00
|
|
|
endtry
|
|
|
|
|
|
|
|
" :change
|
|
|
|
try
|
2020-11-29 23:08:27 -07:00
|
|
|
call DefineFunction('T_Change', [
|
|
|
|
\ 'change',
|
|
|
|
\ 'py <<EOS',
|
|
|
|
\ '.',
|
|
|
|
\ ])
|
2017-06-06 02:19:28 -07:00
|
|
|
catch
|
2020-11-29 23:08:27 -07:00
|
|
|
call assert_report("Can't define function")
|
2017-06-06 02:19:28 -07:00
|
|
|
endtry
|
|
|
|
try
|
2020-11-29 23:08:27 -07:00
|
|
|
call DefineFunction('T_Change', [
|
|
|
|
\ 'change',
|
|
|
|
\ 'abc',
|
|
|
|
\ ])
|
|
|
|
call assert_report("Shouldn't be able to define function")
|
2017-06-06 02:19:28 -07:00
|
|
|
catch
|
2020-11-29 23:08:27 -07:00
|
|
|
call assert_exception('Vim(function):E126: Missing :endfunction')
|
2017-06-06 02:19:28 -07:00
|
|
|
endtry
|
|
|
|
|
|
|
|
" :insert
|
|
|
|
try
|
2020-11-29 23:08:27 -07:00
|
|
|
call DefineFunction('T_Insert', [
|
|
|
|
\ 'insert',
|
|
|
|
\ 'py <<EOS',
|
|
|
|
\ '.',
|
|
|
|
\ ])
|
2017-06-06 02:19:28 -07:00
|
|
|
catch
|
2020-11-29 23:08:27 -07:00
|
|
|
call assert_report("Can't define function")
|
2017-06-06 02:19:28 -07:00
|
|
|
endtry
|
|
|
|
try
|
2020-11-29 23:08:27 -07:00
|
|
|
call DefineFunction('T_Insert', [
|
|
|
|
\ 'insert',
|
|
|
|
\ 'abc',
|
|
|
|
\ ])
|
|
|
|
call assert_report("Shouldn't be able to define function")
|
2017-06-06 02:19:28 -07:00
|
|
|
catch
|
2020-11-29 23:08:27 -07:00
|
|
|
call assert_exception('Vim(function):E126: Missing :endfunction')
|
2017-06-06 02:19:28 -07:00
|
|
|
endtry
|
|
|
|
endfunc
|
|
|
|
|
2017-06-06 02:28:23 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" Test 96: line continuation {{{1
|
|
|
|
"
|
2020-11-29 23:08:27 -07:00
|
|
|
" Undefined behavior was detected by ubsan with line continuation
|
|
|
|
" after an empty line.
|
2017-06-06 02:28:23 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
2022-10-23 01:17:45 -07:00
|
|
|
func Test_script_empty_line_continuation()
|
2017-06-06 02:28:23 -07:00
|
|
|
|
|
|
|
\
|
|
|
|
endfunc
|
|
|
|
|
2017-06-06 04:34:25 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" Test 97: bitwise functions {{{1
|
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
func Test_bitwise_functions()
|
|
|
|
" and
|
|
|
|
call assert_equal(127, and(127, 127))
|
|
|
|
call assert_equal(16, and(127, 16))
|
2021-08-07 09:06:08 -07:00
|
|
|
eval 127->and(16)->assert_equal(16)
|
2017-06-06 04:34:25 -07:00
|
|
|
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))
|
2021-08-07 09:06:08 -07:00
|
|
|
eval 8->or(7)->assert_equal(15)
|
2017-06-06 04:34:25 -07:00
|
|
|
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))
|
2021-08-07 09:06:08 -07:00
|
|
|
eval 127->xor(16)->assert_equal(111)
|
2017-06-06 04:34:25 -07:00
|
|
|
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))
|
2021-08-07 09:06:08 -07:00
|
|
|
eval 127->invert()->and(65535)->assert_equal(65408)
|
2017-06-06 04:34:25 -07:00
|
|
|
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
|
|
|
|
|
2018-01-21 03:55:27 -07:00
|
|
|
" 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
|
|
|
|
|
2022-08-13 00:46:20 -07:00
|
|
|
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
|
|
|
|
|
2019-05-28 17:33:43 -07:00
|
|
|
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)
|
|
|
|
|
2019-07-28 13:54:06 -07:00
|
|
|
" Test special cases: division or modulus with 0.
|
|
|
|
let x = 1
|
|
|
|
let x /= 0
|
2020-11-26 20:36:57 -07:00
|
|
|
call assert_equal(0x7FFFFFFFFFFFFFFF, x)
|
2019-07-28 13:54:06 -07:00
|
|
|
|
|
|
|
let x = -1
|
|
|
|
let x /= 0
|
2020-11-26 20:36:57 -07:00
|
|
|
call assert_equal(-0x7FFFFFFFFFFFFFFF, x)
|
2019-07-28 13:54:06 -07:00
|
|
|
|
|
|
|
let x = 0
|
|
|
|
let x /= 0
|
2020-11-26 20:36:57 -07:00
|
|
|
call assert_equal(-0x7FFFFFFFFFFFFFFF - 1, x)
|
2019-07-28 13:54:06 -07:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2019-05-28 17:33:43 -07:00
|
|
|
" 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')
|
2021-05-24 11:43:47 -07:00
|
|
|
" 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')
|
2022-10-25 22:41:43 -07:00
|
|
|
let x = !3.14
|
|
|
|
call assert_equal(0.0, x)
|
2022-10-26 04:53:54 -07:00
|
|
|
|
|
|
|
" 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:')
|
2019-05-28 17:33:43 -07:00
|
|
|
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)
|
2022-07-25 03:11:37 -07:00
|
|
|
call assert_fails('let &scrolljump .= "j"', 'E734:')
|
2019-05-28 17:33:43 -07:00
|
|
|
set scrolljump&vim
|
|
|
|
|
2022-07-25 03:11:37 -07:00
|
|
|
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)
|
|
|
|
|
2019-05-28 17:33:43 -07:00
|
|
|
" Test for register
|
|
|
|
let @/ = 1
|
2022-07-25 03:11:37 -07:00
|
|
|
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:')
|
2019-05-28 17:33:43 -07:00
|
|
|
let @/ .= 's'
|
|
|
|
call assert_equal('1s', @/)
|
|
|
|
let @/ = ''
|
|
|
|
endfunc
|
|
|
|
|
2020-12-02 06:44:13 -07:00
|
|
|
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
|
|
|
|
|
2022-07-08 02:43:05 -07:00
|
|
|
" 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')
|
2022-07-11 23:45:36 -07:00
|
|
|
|
|
|
|
" 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)
|
|
|
|
|
2022-08-22 19:38:53 -07:00
|
|
|
" Using endfunc with :if
|
|
|
|
call assert_fails('exe "if 1 | endfunc | endif"', 'E193:')
|
|
|
|
|
2022-07-11 23:45:36 -07:00
|
|
|
" Missing 'in' in a :for statement
|
|
|
|
call assert_fails('for i range(1) | endfor', 'E690:')
|
2022-10-26 04:53:54 -07:00
|
|
|
|
|
|
|
" Incorrect number of variables in for
|
|
|
|
call assert_fails('for [i,] in range(3) | endfor', 'E475:')
|
2022-07-08 02:43:05 -07:00
|
|
|
endfunc
|
|
|
|
|
|
|
|
" Test for deep nesting of if/for/while/try statements {{{1
|
|
|
|
func Test_deep_nest()
|
2022-11-04 17:07:06 -07:00
|
|
|
CheckRunVimInTerminal
|
2022-07-08 02:43:05 -07:00
|
|
|
|
|
|
|
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
|
2022-08-22 19:38:53 -07:00
|
|
|
|
|
|
|
" 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
|
2022-07-08 02:43:05 -07:00
|
|
|
[SCRIPT]
|
|
|
|
call writefile(lines, 'Xscript')
|
|
|
|
|
|
|
|
let buf = RunVimInTerminal('-S Xscript', {'rows': 6})
|
|
|
|
|
|
|
|
" Deep nesting of if ... endif
|
|
|
|
call term_sendkeys(buf, ":call Test1()\n")
|
2022-08-22 19:38:53 -07:00
|
|
|
call term_wait(buf)
|
2022-07-08 02:43:05 -07:00
|
|
|
call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))})
|
|
|
|
|
|
|
|
" Deep nesting of for ... endfor
|
|
|
|
call term_sendkeys(buf, ":call Test2()\n")
|
2022-08-22 19:38:53 -07:00
|
|
|
call term_wait(buf)
|
2022-07-08 02:43:05 -07:00
|
|
|
call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
|
|
|
|
|
|
|
|
" Deep nesting of while ... endwhile
|
|
|
|
call term_sendkeys(buf, ":call Test3()\n")
|
2022-08-22 19:38:53 -07:00
|
|
|
call term_wait(buf)
|
2022-07-08 02:43:05 -07:00
|
|
|
call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
|
|
|
|
|
|
|
|
" Deep nesting of try ... endtry
|
|
|
|
call term_sendkeys(buf, ":call Test4()\n")
|
2022-08-22 19:38:53 -07:00
|
|
|
call term_wait(buf)
|
2022-07-08 02:43:05 -07:00
|
|
|
call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))})
|
|
|
|
|
2022-08-22 19:38:53 -07:00
|
|
|
" 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)
|
|
|
|
|
2022-07-08 02:43:05 -07:00
|
|
|
"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
|
|
|
|
|
2022-10-25 22:41:43 -07:00
|
|
|
" 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
|
|
|
|
|
2022-11-05 05:16:29 -07:00
|
|
|
" invalid function names {{{1
|
2022-10-26 04:04:38 -07:00
|
|
|
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 folowed 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
|
|
|
|
|
2022-11-05 05:16:29 -07:00
|
|
|
" substring and variable name {{{1
|
2022-10-26 04:04:38 -07:00
|
|
|
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
|
|
|
|
|
2022-11-05 05:16:29 -07:00
|
|
|
" 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
|
|
|
|
|
2022-01-01 00:27:46 -07:00
|
|
|
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
|
|
|
|
|
2016-04-14 12:35:16 -07:00
|
|
|
"-------------------------------------------------------------------------------
|
|
|
|
" Modelines {{{1
|
2020-10-20 21:04:27 -07:00
|
|
|
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
2016-04-14 12:35:16 -07:00
|
|
|
"-------------------------------------------------------------------------------
|