" Test various aspects of the Vim language.
" Most of this was formerly in test49.
"-------------------------------------------------------------------------------
" Test environment {{{1
"-------------------------------------------------------------------------------
com! XpathINIT let g:Xpath = ''
com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args>
" Append a message to the "messages" file
func! Xout(text)
split messages
$put =a:text
wq
endfunc
com! -nargs=1 Xout call Xout(<args>)
" MakeScript() - Make a script file from a function. {{{2
"
" Create a script that consists of the body of the function a:funcname.
" Replace any ":return" by a ":finish", any argument variable by a global
" variable, and and every ":call" by a ":source" for the next following argument
" in the variable argument list. This function is useful if similar tests are
" to be made for a ":return" from a function call or a ":finish" in a script
" file.
function! MakeScript(funcname, ...)
let script = tempname()
execute "redir! >" . script
execute "function" a:funcname
redir END
execute "edit" script
" Delete the "function" and the "endfunction" lines. Do not include the
" word "function" in the pattern since it might be translated if LANG is
" set. When MakeScript() is being debugged, this deletes also the debugging
" output of its line 3 and 4.
exec '1,/.*' . a:funcname . '(.*)/d'
/^\d*\s*endfunction\>/,$d
%s/^\d*//e
%s/return/finish/e
%s/\<a:\(\h\w*\)/g:\1/ge
normal gg0
let cnt = 0
while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
let cnt = cnt + 1
s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
endwhile
g/^\s*$/d
write
bwipeout
return script
endfunction
" ExecAsScript - Source a temporary script made from a function. {{{2
"
" Make a temporary script file from the function a:funcname, ":source" it, and
" delete it afterwards. However, if an exception is thrown the file may remain,
" the caller should call DeleteTheScript() afterwards.
let s:script_name = ''
function! ExecAsScript(funcname)
" Make a script from the function passed as argument.
let s:script_name = MakeScript(a:funcname)
" Source and delete the script.
exec "source" s:script_name
call delete(s:script_name)
let s:script_name = ''
endfunction
function! DeleteTheScript()
if s:script_name
call delete(s:script_name)
let s:script_name = ''
endif
endfunc
com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
"-------------------------------------------------------------------------------
" 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.
"-------------------------------------------------------------------------------
function! T1_F()
Xpath 'a'
let first = 1
while 1
Xpath 'b'
if first
Xpath 'c'
let first = 0
break
else
Xpath 'd'
return
endif
endwhile
endfunction
function! T1_G()
Xpath 'h'
let first = 1
while 1
Xpath 'i'
if first
Xpath 'j'
let first = 0
break
else
Xpath 'k'
return
endif
if 1 " unmatched :if
endwhile
endfunction
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).
"--------------------------------------------------