" Tests for the Vim script debug commands
source shared.vim
source screendump.vim
source check.vim
CheckRunVimInTerminal
func CheckCWD()
" Check that the longer lines don't wrap due to the length of the script name
" in cwd
let script_len = len( getcwd() .. '/Xtest1.vim' )
let longest_line = len( 'Breakpoint in "" line 1' )
if script_len > ( 75 - longest_line )
throw 'Skipped: Your CWD has too many characters'
endif
endfunc
command! -nargs=0 -bar CheckCWD call CheckCWD()
" "options" argument can contain:
" 'msec' - time to wait for a match
" 'match' - "pattern" to use "lines" as pattern instead of text
func CheckDbgOutput(buf, lines, options = {})
" Verify the expected output
let lnum = 20 - len(a:lines)
let msec = get(a:options, 'msec', 1000)
for l in a:lines
if get(a:options, 'match', 'equal') ==# 'pattern'
call WaitForAssert({-> assert_match(l, term_getline(a:buf, lnum))}, msec)
else
call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, msec)
endif
let lnum += 1
endfor
endfunc
" Run a Vim debugger command
" If the expected output argument is supplied, then check for it.
func RunDbgCmd(buf, cmd, ...)
call term_sendkeys(a:buf, a:cmd . "\r")
call TermWait(a:buf)
if a:0 != 0
let options = #{match: 'equal'}
if a:0 > 1
call extend(options, a:2)
endif
call CheckDbgOutput(a:buf, a:1, options)
endif
endfunc
" Debugger tests
func Test_Debugger()
" Create a Vim script with some functions
let lines =<< trim END
func Foo()
let var1 = 1
let var2 = Bar(var1) + 9
return var2
endfunc
func Bar(var)
let var1 = 2 + a:var
let var2 = Bazz(var1) + 4
return var2
endfunc
func Bazz(var)
try
let var1 = 3 + a:var
let var3 = "another var"
let var3 = "value2"
catch
let var4 = "exception"
endtry
return var1
endfunc
END
call writefile(lines, 'Xtest.vim')
" Start Vim in a terminal
let buf = RunVimInTerminal('-S Xtest.vim', {})
" Start the Vim debugger
call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
" Create a few stack frames by stepping through functions
call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
call RunDbgCmd(buf, 'step', ['line 1: try'])
call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
" check backtrace
call RunDbgCmd(buf, 'backtrace', [
\ ' 2 function Foo[2]',
\ ' 1 Bar[2]',
\ '->0 Bazz',
\ 'line 3: let var3 = "another var"'])
" Check variables in different stack frames
call RunDbgCmd(buf, 'echo var1', ['6'])
call RunDbgCmd(buf, 'up')
call RunDbgCmd(buf, 'back', [
\ ' 2 function Foo[2]',
\ '->1 Bar[2]',
\ ' 0 Bazz',
\ 'line 3: let var3 = "another var"'])
call RunDbgCmd(buf, 'echo var1', ['3'])
call RunDbgCmd(buf, 'u')
call RunDbgCmd(buf, 'bt', [
\ '->2 function Foo[2]',
\ ' 1 Bar[2]',
\ ' 0 Bazz',
\ 'line 3: let var3 = "another var"'])
call RunDbgCmd(buf, 'echo var1', ['1'])
" Undefined variables
call RunDbgCmd(buf, 'step')
call RunDbgCmd(buf, 'frame 2')
call RunDbgCmd(buf, 'echo var3', [
\ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
\ 'line 4:',
\ 'E121: Undefined variable: var3'])
" var3 is defined in this level with some other value
call RunDbgCmd(buf, 'fr 0')
call RunDbgCmd(buf, 'echo var3', ['another var'])
call RunDbgCmd(buf, 'step')
call RunDbgCmd(