From 2eae5db069dc171f74cd863487655f6a88e5384d Mon Sep 17 00:00:00 2001 From: Mehmet Samet Duman Date: Fri, 3 Apr 2026 22:21:25 +0300 Subject: NOISSUE rebrand vim to MNV's not Vim Signed-off-by: Mehmet Samet Duman --- uvim/src/testdir/test_debugger.vim | 1569 ------------------------------------ 1 file changed, 1569 deletions(-) delete mode 100644 uvim/src/testdir/test_debugger.vim (limited to 'uvim/src/testdir/test_debugger.vim') diff --git a/uvim/src/testdir/test_debugger.vim b/uvim/src/testdir/test_debugger.vim deleted file mode 100644 index aa014c4342..0000000000 --- a/uvim/src/testdir/test_debugger.vim +++ /dev/null @@ -1,1569 +0,0 @@ -" Tests for the Vim script debug commands - -source util/screendump.vim - -CheckRunVimInTerminal - -func CheckCWD() - " Check that the longer lines don't wrap due to the length of the script name - " in cwd. Need to subtract by 1 since Vim will still wrap the message if it - " just fits. - let script_len = len( getcwd() .. '/Xtest1.vim' ) - let longest_line = len( 'Breakpoint in "" line 1' ) - if script_len > ( 75 - longest_line - 1 ) - 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 -def s:CheckDbgOutput(buf: number, lines: list, options = {}) - # Verify the expected output - var lnum = 20 - len(lines) - var msec = get(options, 'msec', 1000) - for l in lines - if get(options, 'match', 'equal') ==# 'pattern' - g:WaitForAssert(() => assert_match(l, term_getline(buf, lnum)), msec) - else - g:WaitForAssert(() => assert_equal(l, term_getline(buf, lnum)), msec) - endif - lnum += 1 - endfor -enddef - -" Run a Vim debugger command -" If the expected output argument is supplied, then check for it. -def s:RunDbgCmd(buf: number, cmd: string, ...extra: list) - term_sendkeys(buf, cmd .. "\r") - g:TermWait(buf) - - if len(extra) > 0 - var options = {match: 'equal'} - if len(extra) > 1 - extend(options, extra[1]) - endif - s:CheckDbgOutput(buf, extra[0], options) - endif -enddef - -" Debugger tests -def Test_Debugger() - # Create a Vim script with some functions - var 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 - def Vim9Func() - for cmd in ['confirm', 'xxxxxxx'] - for _ in [1, 2] - echo cmd - endfor - endfor - enddef - END - writefile(lines, 'XtestDebug.vim', 'D') - - # Start Vim in a terminal - var buf = g:RunVimInTerminal('-S XtestDebug.vim', {}) - - # Start the Vim debugger - s:RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()']) - - # Create a few stack frames by stepping through functions - s:RunDbgCmd(buf, 'step', ['line 1: let var1 = 1']) - s:RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9']) - s:RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var']) - s:RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4']) - s:RunDbgCmd(buf, 'step', ['line 1: try']) - s:RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var']) - s:RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"']) - - # check backtrace - s:RunDbgCmd(buf, 'backtrace', [ - ' 2 function Foo[2]', - ' 1 Bar[2]', - '->0 Bazz', - 'line 3: let var3 = "another var"']) - - # Check variables in different stack frames - s:RunDbgCmd(buf, 'echo var1', ['6']) - - s:RunDbgCmd(buf, 'up') - s:RunDbgCmd(buf, 'back', [ - ' 2 function Foo[2]', - '->1 Bar[2]', - ' 0 Bazz', - 'line 3: let var3 = "another var"']) - s:RunDbgCmd(buf, 'echo var1', ['3']) - - s:RunDbgCmd(buf, 'u') - s:RunDbgCmd(buf, 'bt', [ - '->2 function Foo[2]', - ' 1 Bar[2]', - ' 0 Bazz', - 'line 3: let var3 = "another var"']) - s:RunDbgCmd(buf, 'echo var1', ['1']) - - # Undefined variables - s:RunDbgCmd(buf, 'step') - s:RunDbgCmd(buf, 'frame 2') - s: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 - s:RunDbgCmd(buf, 'fr 0') - s:RunDbgCmd(buf, 'echo var3', ['another var']) - - s:RunDbgCmd(buf, 'step') - s:RunDbgCmd(buf, '') - s:RunDbgCmd(buf, '') - s:RunDbgCmd(buf, '') - s:RunDbgCmd(buf, '') - s:RunDbgCmd(buf, 'step', [ - 'function Foo[2]..Bar', - 'line 3: End of function']) - s:RunDbgCmd(buf, 'up') - - # Undefined var2 - s:RunDbgCmd(buf, 'echo var2', [ - 'Error detected while processing function Foo[2]..Bar:', - 'line 3:', - 'E121: Undefined variable: var2']) - - # Var2 is defined with 10 - s:RunDbgCmd(buf, 'down') - s:RunDbgCmd(buf, 'echo var2', ['10']) - - # Backtrace movements - s:RunDbgCmd(buf, 'b', [ - ' 1 function Foo[2]', - '->0 Bar', - 'line 3: End of function']) - - # next command cannot go down, we are on bottom - s:RunDbgCmd(buf, 'down', ['frame is zero']) - s:RunDbgCmd(buf, 'up') - - # next command cannot go up, we are on top - s:RunDbgCmd(buf, 'up', ['frame at highest level: 1']) - s:RunDbgCmd(buf, 'where', [ - '->1 function Foo[2]', - ' 0 Bar', - 'line 3: End of function']) - - # fil is not frame or finish, it is file - s:RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--']) - - # relative backtrace movement - s:RunDbgCmd(buf, 'fr -1') - s:RunDbgCmd(buf, 'frame', [ - ' 1 function Foo[2]', - '->0 Bar', - 'line 3: End of function']) - - s:RunDbgCmd(buf, 'fr +1') - s:RunDbgCmd(buf, 'fram', [ - '->1 function Foo[2]', - ' 0 Bar', - 'line 3: End of function']) - - # go beyond limits does not crash - s:RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1']) - s:RunDbgCmd(buf, 'fra', [ - '->1 function Foo[2]', - ' 0 Bar', - 'line 3: End of function']) - - s:RunDbgCmd(buf, 'frame -40', ['frame is zero']) - s:RunDbgCmd(buf, 'fram', [ - ' 1 function Foo[2]', - '->0 Bar', - 'line 3: End of function']) - - # final result 19 - s:RunDbgCmd(buf, 'cont', ['19']) - - # breakpoints tests - - # Start a debug session, so that reading the last line from the terminal - # works properly. - s:RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()']) - - # No breakpoints - s:RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) - - # Place some breakpoints - s:RunDbgCmd(buf, 'breaka func Bar') - s:RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1']) - s:RunDbgCmd(buf, 'breakadd func 3 Bazz') - s:RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1', - ' 2 func Bazz line 3']) - - # Check whether the breakpoints are hit - s:RunDbgCmd(buf, 'cont', [ - 'Breakpoint in "Bar" line 1', - 'function Foo[2]..Bar', - 'line 1: let var1 = 2 + a:var']) - s:RunDbgCmd(buf, 'cont', [ - 'Breakpoint in "Bazz" line 3', - 'function Foo[2]..Bar[2]..Bazz', - 'line 3: let var3 = "another var"']) - - # Delete the breakpoints - s:RunDbgCmd(buf, 'breakd 1') - s:RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3']) - s:RunDbgCmd(buf, 'breakdel func 3 Bazz') - s:RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) - - s:RunDbgCmd(buf, 'cont') - - # Make sure the breakpoints are removed - s:RunDbgCmd(buf, ':echo Foo()', ['19']) - - # Delete a non-existing breakpoint - s:RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2']) - - # Expression breakpoint - s:RunDbgCmd(buf, ':breakadd func 2 Bazz') - s:RunDbgCmd(buf, ':echo Bazz(1)', [ - 'Entering Debug mode. Type "cont" to continue.', - 'function Bazz', - 'line 2: let var1 = 3 + a:var']) - s:RunDbgCmd(buf, 'step') - s:RunDbgCmd(buf, 'step') - s:RunDbgCmd(buf, 'breaka expr var3') - s:RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2', - \ ' 4 expr var3']) - s:RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5', - 'Oldval = "''another var''"', - 'Newval = "''value2''"', - 'function Bazz', - 'line 5: catch']) - - s:RunDbgCmd(buf, 'breakdel *') - s:RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) - - # Check for error cases - s:RunDbgCmd(buf, 'breakadd abcd', [ - 'Error detected while processing function Bazz:', - 'line 5:', - 'E475: Invalid argument: abcd']) - s:RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func']) - s:RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2']) - s:RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()']) - s:RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd']) - s:RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func']) - s:RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()']) - s:RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a']) - s:RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr']) - s:RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x']) - - # finish the current function - s:RunDbgCmd(buf, 'finish', [ - 'function Bazz', - 'line 8: End of function']) - s:RunDbgCmd(buf, 'cont') - - # Test for :next - s:RunDbgCmd(buf, ':debug echo Bar(1)') - s:RunDbgCmd(buf, 'step') - s:RunDbgCmd(buf, 'next') - s:RunDbgCmd(buf, '', [ - 'function Bar', - 'line 3: return var2']) - s:RunDbgCmd(buf, 'c') - - # Test for :interrupt - s:RunDbgCmd(buf, ':debug echo Bazz(1)') - s:RunDbgCmd(buf, 'step') - s:RunDbgCmd(buf, 'step') - s:RunDbgCmd(buf, 'interrupt', [ - 'Exception thrown: Vim:Interrupt', - 'function Bazz', - 'line 5: catch']) - s:RunDbgCmd(buf, 'c') - - # Test showing local variable in :def function - s:RunDbgCmd(buf, ':breakadd func 2 Vim9Func') - s:RunDbgCmd(buf, ':call Vim9Func()', ['line 2: for _ in [1, 2]']) - s:RunDbgCmd(buf, 'next', ['line 2: for _ in [1, 2]']) - s:RunDbgCmd(buf, 'echo cmd', ['confirm']) - s:RunDbgCmd(buf, 'breakdel *') - s:RunDbgCmd(buf, 'cont') - - # Test for :quit - s:RunDbgCmd(buf, ':debug echo Foo()') - s:RunDbgCmd(buf, 'breakdel *') - s:RunDbgCmd(buf, 'breakadd func 3 Foo') - s:RunDbgCmd(buf, 'breakadd func 3 Bazz') - s:RunDbgCmd(buf, 'cont', [ - 'Breakpoint in "Bazz" line 3', - 'function Foo[2]..Bar[2]..Bazz', - 'line 3: let var3 = "another var"']) - s:RunDbgCmd(buf, 'quit', [ - 'Breakpoint in "Foo" line 3', - 'function Foo', - 'line 3: return var2']) - s:RunDbgCmd(buf, 'breakdel *') - s:RunDbgCmd(buf, 'quit') - s:RunDbgCmd(buf, 'enew! | only!') - - g:StopVimInTerminal(buf) -enddef - -func Test_Debugger_breakadd() - " Tests for :breakadd file and :breakadd here - " Breakpoints should be set before sourcing the file - - let lines =<< trim END - let var1 = 10 - let var2 = 20 - let var3 = 30 - let var4 = 40 - END - call writefile(lines, 'XdebugBreakadd.vim', 'D') - - " Start Vim in a terminal - let buf = RunVimInTerminal('XdebugBreakadd.vim', {}) - call s:RunDbgCmd(buf, ':breakadd file 2 XdebugBreakadd.vim') - call s:RunDbgCmd(buf, ':4 | breakadd here') - call s:RunDbgCmd(buf, ':source XdebugBreakadd.vim', ['line 2: let var2 = 20']) - call s:RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40']) - call s:RunDbgCmd(buf, 'cont') - - call StopVimInTerminal(buf) - - %bw! - - call assert_fails('breakadd here', 'E32:') - call assert_fails('breakadd file Xtest.vim /\)/', 'E55:') -endfunc - -" Test for expression breakpoint set using ":breakadd expr " -" FIXME: This doesn't seem to work as documented. The breakpoint is not -" triggered until the next function call. -func Test_Debugger_breakadd_expr() - CheckCWD - - let lines =<< trim END - func Foo() - eval 1 - eval 2 - endfunc - - let g:Xtest_var += 1 - call Foo() - let g:Xtest_var += 1 - call Foo() - END - call writefile(lines, 'XbreakExpr.vim', 'D') - - " Start Vim in a terminal - let buf = RunVimInTerminal('XbreakExpr.vim', {}) - call s:RunDbgCmd(buf, ':let g:Xtest_var = 10') - call s:RunDbgCmd(buf, ':breakadd expr g:Xtest_var') - let expected =<< trim eval END - Oldval = "10" - Newval = "11" - {fnamemodify('XbreakExpr.vim', ':p')}[7]..function Foo - line 1: eval 1 - END - call s:RunDbgCmd(buf, ':source %', expected) - let expected =<< trim eval END - Oldval = "11" - Newval = "12" - {fnamemodify('XbreakExpr.vim', ':p')}[9]..function Foo - line 1: eval 1 - END - call s:RunDbgCmd(buf, 'cont', expected) - call s:RunDbgCmd(buf, 'cont') - - " Check the behavior without the g: prefix. - " FIXME: The Oldval and Newval don't look right here. - call s:RunDbgCmd(buf, ':breakdel *') - call s:RunDbgCmd(buf, ':breakadd expr Xtest_var') - let expected =<< trim eval END - Oldval = "13" - Newval = "(does not exist)" - {fnamemodify('XbreakExpr.vim', ':p')}[7]..function Foo - line 1: eval 1 - END - call s:RunDbgCmd(buf, ':source %', expected) - let expected =<< trim eval END - {fnamemodify('XbreakExpr.vim', ':p')}[7]..function Foo - line 2: eval 2 - END - call s:RunDbgCmd(buf, 'cont', expected) - let expected =<< trim eval END - Oldval = "14" - Newval = "(does not exist)" - {fnamemodify('XbreakExpr.vim', ':p')}[9]..function Foo - line 1: eval 1 - END - call s:RunDbgCmd(buf, 'cont', expected) - let expected =<< trim eval END - {fnamemodify('XbreakExpr.vim', ':p')}[9]..function Foo - line 2: eval 2 - END - call s:RunDbgCmd(buf, 'cont', expected) - call s:RunDbgCmd(buf, 'cont') - - call StopVimInTerminal(buf) -endfunc - -def Test_Debugger_breakadd_vim9_expr() - var lines =<< trim END - vim9script - func g:EarlyFunc() - endfunc - breakadd expr DoesNotExist() - func g:LaterFunc() - endfunc - breakdel * - END - writefile(lines, 'XdebugBreak9expr.vim', 'D') - - # Start Vim in a terminal - var buf = g:RunVimInTerminal('-S XdebugBreak9expr.vim', {wait_for_ruler: 0}) - call g:TermWait(buf, g:RunningWithValgrind() ? 1000 : 50) - - # Despite the failure the functions are defined - s:RunDbgCmd(buf, ':function g:EarlyFunc', - ['function EarlyFunc()', 'endfunction'], {match: 'pattern'}) - s:RunDbgCmd(buf, ':function g:LaterFunc', - ['function LaterFunc()', 'endfunction'], {match: 'pattern'}) - - call g:StopVimInTerminal(buf) -enddef - -def Test_Debugger_break_at_return() - var lines =<< trim END - vim9script - def g:GetNum(): number - return 1 - + 2 - + 3 - enddef - breakadd func GetNum - END - writefile(lines, 'XdebugBreakRet.vim', 'D') - - # Start Vim in a terminal - var buf = g:RunVimInTerminal('-S XdebugBreakRet.vim', {wait_for_ruler: 0}) - call g:TermWait(buf, g:RunningWithValgrind() ? 1000 : 50) - - s:RunDbgCmd(buf, ':call GetNum()', - ['line 1: return 1 + 2 + 3'], {match: 'pattern'}) - - call g:StopVimInTerminal(buf) -enddef - -func Test_Backtrace_Through_Source() - CheckCWD - let file1 =<< trim END - func SourceAnotherFile() - source Xtest2.vim - endfunc - - func CallAFunction() - call SourceAnotherFile() - call File2Function() - endfunc - - func GlobalFunction() - call CallAFunction() - endfunc - END - call writefile(file1, 'Xtest1.vim', 'D') - - let file2 =<< trim END - func DoAThing() - echo "DoAThing" - endfunc - - func File2Function() - call DoAThing() - endfunc - - call File2Function() - END - call writefile(file2, 'Xtest2.vim', 'D') - - let buf = RunVimInTerminal('-S Xtest1.vim', {}) - - call s:RunDbgCmd(buf, - \ ':debug call GlobalFunction()', - \ ['cmd: call GlobalFunction()']) - call s:RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) - - call s:RunDbgCmd(buf, 'backtrace', ['>backtrace', - \ '->0 function GlobalFunction', - \ 'line 1: call CallAFunction()']) - - call s:RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()']) - call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) - - call s:RunDbgCmd(buf, 'backtrace', ['>backtrace', - \ ' 2 function GlobalFunction[1]', - \ ' 1 CallAFunction[1]', - \ '->0 SourceAnotherFile', - \ 'line 1: source Xtest2.vim']) - - " Step into the 'source' command. Note that we print the full trace all the - " way though the source command. - call s:RunDbgCmd(buf, 'step', ['line 1: func DoAThing()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ '->0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()']) - - call s:RunDbgCmd( buf, 'up' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ '->1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'up' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 function GlobalFunction[1]', - \ '->2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'up' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ '->3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ '->3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'down' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 function GlobalFunction[1]', - \ '->2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'down' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ '->1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'down' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ '->0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'down', [ 'frame is zero' ] ) - - " step until we have another meaningful trace - call s:RunDbgCmd(buf, 'step', ['line 5: func File2Function()']) - call s:RunDbgCmd(buf, 'step', ['line 9: call File2Function()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ '->0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 9: call File2Function()']) - - call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) - call s:RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 5 function GlobalFunction[1]', - \ ' 4 CallAFunction[1]', - \ ' 3 SourceAnotherFile[1]', - \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]', - \ ' 1 function File2Function[1]', - \ '->0 DoAThing', - \ 'line 1: echo "DoAThing"']) - - " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim - call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) - call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) - call s:RunDbgCmd(buf, 'step', ['line 10: End of sourced file']) - call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) - call s:RunDbgCmd(buf, 'step', ['line 2: call File2Function()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 1 function GlobalFunction[1]', - \ '->0 CallAFunction', - \ 'line 2: call File2Function()']) - - call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 2 function GlobalFunction[1]', - \ ' 1 CallAFunction[2]', - \ '->0 File2Function', - \ 'line 1: call DoAThing()']) - - call StopVimInTerminal(buf) -endfunc - -func Test_Backtrace_Autocmd() - CheckCWD - let file1 =<< trim END - func SourceAnotherFile() - source Xtest2.vim - endfunc - - func CallAFunction() - call SourceAnotherFile() - call File2Function() - endfunc - - func GlobalFunction() - call CallAFunction() - endfunc - - au User TestGlobalFunction :call GlobalFunction() | echo "Done" - END - call writefile(file1, 'Xtest1.vim', 'D') - - let file2 =<< trim END - func DoAThing() - echo "DoAThing" - endfunc - - func File2Function() - call DoAThing() - endfunc - - call File2Function() - END - call writefile(file2, 'Xtest2.vim', 'D') - - let buf = RunVimInTerminal('-S Xtest1.vim', {}) - - call s:RunDbgCmd(buf, - \ ':debug doautocmd User TestGlobalFunction', - \ ['cmd: doautocmd User TestGlobalFunction']) - call s:RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"']) - - " At this point the only thing in the stack is the autocommand - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ '->0 User Autocommands for "TestGlobalFunction"', - \ 'cmd: call GlobalFunction() | echo "Done"']) - - " And now we're back into the call stack - call s:RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 1 User Autocommands for "TestGlobalFunction"', - \ '->0 function GlobalFunction', - \ 'line 1: call CallAFunction()']) - - call s:RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()']) - call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) - - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 User Autocommands for "TestGlobalFunction"', - \ ' 2 function GlobalFunction[1]', - \ ' 1 CallAFunction[1]', - \ '->0 SourceAnotherFile', - \ 'line 1: source Xtest2.vim']) - - " Step into the 'source' command. Note that we print the full trace all the - " way though the source command. - call s:RunDbgCmd(buf, 'step', ['line 1: func DoAThing()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 4 User Autocommands for "TestGlobalFunction"', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ '->0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()']) - - call s:RunDbgCmd( buf, 'up' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 4 User Autocommands for "TestGlobalFunction"', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ '->1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'up' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 4 User Autocommands for "TestGlobalFunction"', - \ ' 3 function GlobalFunction[1]', - \ '->2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'up' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 4 User Autocommands for "TestGlobalFunction"', - \ '->3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'up' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ '->4 User Autocommands for "TestGlobalFunction"', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ '->4 User Autocommands for "TestGlobalFunction"', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'down' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 4 User Autocommands for "TestGlobalFunction"', - \ '->3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - - call s:RunDbgCmd( buf, 'down' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 4 User Autocommands for "TestGlobalFunction"', - \ ' 3 function GlobalFunction[1]', - \ '->2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'down' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 4 User Autocommands for "TestGlobalFunction"', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ '->1 SourceAnotherFile[1]', - \ ' 0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'down' ) - call s:RunDbgCmd( buf, 'backtrace', [ - \ '>backtrace', - \ ' 4 User Autocommands for "TestGlobalFunction"', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ '->0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 1: func DoAThing()' ] ) - - call s:RunDbgCmd( buf, 'down', [ 'frame is zero' ] ) - - " step until we have another meaningful trace - call s:RunDbgCmd(buf, 'step', ['line 5: func File2Function()']) - call s:RunDbgCmd(buf, 'step', ['line 9: call File2Function()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 4 User Autocommands for "TestGlobalFunction"', - \ ' 3 function GlobalFunction[1]', - \ ' 2 CallAFunction[1]', - \ ' 1 SourceAnotherFile[1]', - \ '->0 script ' .. getcwd() .. '/Xtest2.vim', - \ 'line 9: call File2Function()']) - - call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) - call s:RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 6 User Autocommands for "TestGlobalFunction"', - \ ' 5 function GlobalFunction[1]', - \ ' 4 CallAFunction[1]', - \ ' 3 SourceAnotherFile[1]', - \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]', - \ ' 1 function File2Function[1]', - \ '->0 DoAThing', - \ 'line 1: echo "DoAThing"']) - - " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim - call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) - call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) - call s:RunDbgCmd(buf, 'step', ['line 10: End of sourced file']) - call s:RunDbgCmd(buf, 'step', ['line 1: End of function']) - call s:RunDbgCmd(buf, 'step', ['line 2: call File2Function()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 2 User Autocommands for "TestGlobalFunction"', - \ ' 1 function GlobalFunction[1]', - \ '->0 CallAFunction', - \ 'line 2: call File2Function()']) - - call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 User Autocommands for "TestGlobalFunction"', - \ ' 2 function GlobalFunction[1]', - \ ' 1 CallAFunction[2]', - \ '->0 File2Function', - \ 'line 1: call DoAThing()']) - - - " Now unwind so that we get back to the original autocommand (and the second - " cmd echo "Done") - call s:RunDbgCmd(buf, 'finish', ['line 1: End of function']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 3 User Autocommands for "TestGlobalFunction"', - \ ' 2 function GlobalFunction[1]', - \ ' 1 CallAFunction[2]', - \ '->0 File2Function', - \ 'line 1: End of function']) - - call s:RunDbgCmd(buf, 'finish', ['line 2: End of function']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 2 User Autocommands for "TestGlobalFunction"', - \ ' 1 function GlobalFunction[1]', - \ '->0 CallAFunction', - \ 'line 2: End of function']) - - call s:RunDbgCmd(buf, 'finish', ['line 1: End of function']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 1 User Autocommands for "TestGlobalFunction"', - \ '->0 function GlobalFunction', - \ 'line 1: End of function']) - - call s:RunDbgCmd(buf, 'step', ['cmd: echo "Done"']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ '->0 User Autocommands for "TestGlobalFunction"', - \ 'cmd: echo "Done"']) - - call StopVimInTerminal(buf) -endfunc - -func Test_Backtrace_CmdLine() - CheckCWD - let file1 =<< trim END - func SourceAnotherFile() - source Xtest2.vim - endfunc - - func CallAFunction() - call SourceAnotherFile() - call File2Function() - endfunc - - func GlobalFunction() - call CallAFunction() - endfunc - - au User TestGlobalFunction :call GlobalFunction() | echo "Done" - END - call writefile(file1, 'Xtest1.vim', 'D') - - let file2 =<< trim END - func DoAThing() - echo "DoAThing" - endfunc - - func File2Function() - call DoAThing() - endfunc - - call File2Function() - END - call writefile(file2, 'Xtest2.vim', 'D') - - let buf = RunVimInTerminal( - \ '-S Xtest1.vim -c "debug call GlobalFunction()"', - \ {'wait_for_ruler': 0}) - - " Need to wait for the vim-in-terminal to be ready. - " With valgrind this can take quite long. - call s:CheckDbgOutput(buf, ['command line', - \ 'cmd: call GlobalFunction()'], #{msec: 5000}) - - " At this point the only thing in the stack is the cmdline - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ '->0 command line', - \ 'cmd: call GlobalFunction()']) - - " And now we're back into the call stack - call s:RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '>backtrace', - \ ' 1 command line', - \ '->0 function GlobalFunction', - \ 'line 1: call CallAFunction()']) - - call StopVimInTerminal(buf) -endfunc - -func Test_Backtrace_DefFunction() - CheckCWD - let file1 =<< trim END - vim9script - import './Xtest2.vim' as imp - - def SourceAnotherFile() - source Xtest2.vim - enddef - - def CallAFunction() - SourceAnotherFile() - imp.File2Function() - enddef - - def g:GlobalFunction() - var some = "some var" - CallAFunction() - enddef - - defcompile - END - call writefile(file1, 'Xtest1.vim', 'D') - - let file2 =<< trim END - vim9script - - def DoAThing(): number - var a = 100 * 2 - a += 3 - return a - enddef - - export def File2Function() - DoAThing() - enddef - - defcompile - File2Function() - END - call writefile(file2, 'Xtest2.vim', 'D') - - let buf = RunVimInTerminal('-S Xtest1.vim', {}) - - call s:RunDbgCmd(buf, - \ ':debug call GlobalFunction()', - \ ['cmd: call GlobalFunction()']) - - call s:RunDbgCmd(buf, 'step', ['line 1: var some = "some var"']) - call s:RunDbgCmd(buf, 'step', ['line 2: CallAFunction()']) - call s:RunDbgCmd(buf, 'echo some', ['some var']) - - call s:RunDbgCmd(buf, 'backtrace', [ - \ '\V>backtrace', - \ '\V->0 function GlobalFunction', - \ '\Vline 2: CallAFunction()', - \ ], - \ #{match: 'pattern'}) - - call s:RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()']) - call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) - " Repeated line, because we first are in the compiled function before the - " EXEC and then in do_cmdline() before the :source command. - call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) - call s:RunDbgCmd(buf, 'step', ['line 1: vim9script']) - call s:RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number']) - call s:RunDbgCmd(buf, 'step', ['line 9: export def File2Function()']) - call s:RunDbgCmd(buf, 'step', ['line 13: defcompile']) - call s:RunDbgCmd(buf, 'step', ['line 14: File2Function()']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '\V>backtrace', - \ '\V 3 function GlobalFunction[2]', - \ '\V 2 \.\*_CallAFunction[1]', - \ '\V 1 \.\*_SourceAnotherFile[1]', - \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim', - \ '\Vline 14: File2Function()'], - \ #{match: 'pattern'}) - - " Don't step into compiled functions... - call s:RunDbgCmd(buf, 'next', ['line 15: End of sourced file']) - call s:RunDbgCmd(buf, 'backtrace', [ - \ '\V>backtrace', - \ '\V 3 function GlobalFunction[2]', - \ '\V 2 \.\*_CallAFunction[1]', - \ '\V 1 \.\*_SourceAnotherFile[1]', - \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim', - \ '\Vline 15: End of sourced file'], - \ #{match: 'pattern'}) - - call StopVimInTerminal(buf) -endfunc - -func Test_DefFunction_expr() - CheckCWD - let file3 =<< trim END - vim9script - g:someVar = "foo" - def g:ChangeVar() - g:someVar = "bar" - echo "changed" - enddef - defcompile - END - call writefile(file3, 'Xtest3.vim', 'D') - let buf = RunVimInTerminal('-S Xtest3.vim', {}) - - call s:RunDbgCmd(buf, ':breakadd expr g:someVar') - call s:RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"']) - - call StopVimInTerminal(buf) -endfunc - -func Test_debug_def_and_legacy_function() - CheckCWD - let file =<< trim END - vim9script - def g:SomeFunc() - echo "here" - echo "and" - echo "there" - breakadd func 2 LocalFunc - LocalFunc() - enddef - - def LocalFunc() - echo "first" - echo "second" - breakadd func LegacyFunc - LegacyFunc() - enddef - - func LegacyFunc() - echo "legone" - echo "legtwo" - endfunc - - breakadd func 2 g:SomeFunc - END - call writefile(file, 'XtestDebug.vim', 'D') - - let buf = RunVimInTerminal('-S XtestDebug.vim', {}) - - call s:RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"']) - call s:RunDbgCmd(buf,'next', ['line 3: echo "there"']) - call s:RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc']) - - " continue, next breakpoint is in LocalFunc() - call s:RunDbgCmd(buf,'cont', ['line 2: echo "second"']) - - " continue, next breakpoint is in LegacyFunc() - call s:RunDbgCmd(buf,'cont', ['line 1: echo "legone"']) - - call s:RunDbgCmd(buf, 'cont') - - call StopVimInTerminal(buf) -endfunc - -func Test_debug_def_function() - CheckCWD - let file =<< trim END - vim9script - def g:Func() - var n: number - def Closure(): number - return n + 3 - enddef - n += Closure() - echo 'result: ' .. n - enddef - - def g:FuncWithArgs(text: string, nr: number, ...items: list) - echo text .. nr - for it in items - echo it - endfor - echo "done" - enddef - - def g:FuncWithDict() - var d = { - a: 1, - b: 2, - } - # comment - def Inner() - eval 1 + 2 - enddef - enddef - - def g:FuncComment() - # comment - echo "first" - .. "one" - # comment - echo "second" - enddef - - def g:FuncForLoop() - eval 1 + 2 - for i in [11, 22, 33] - eval i + 2 - endfor - echo "done" - enddef - - def g:FuncWithSplitLine() - eval 1 + 2 - | eval 2 + 3 - enddef - END - call writefile(file, 'Xtest.vim', 'D') - - let buf = RunVimInTerminal('-S Xtest.vim', {}) - - call s:RunDbgCmd(buf, - \ ':debug call Func()', - \ ['cmd: call Func()']) - call s:RunDbgCmd(buf, 'next', ['result: 3']) - call term_sendkeys(buf, "\r") - call s:RunDbgCmd(buf, 'cont') - - call s:RunDbgCmd(buf, - \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)', - \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)']) - call s:RunDbgCmd(buf, 'step', ['line 1: echo text .. nr']) - call s:RunDbgCmd(buf, 'echo text', ['asdf']) - call s:RunDbgCmd(buf, 'echo nr', ['42']) - call s:RunDbgCmd(buf, 'echo items', ['[1, 2, 3]']) - call s:RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items']) - call s:RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items']) - call s:RunDbgCmd(buf, 'echo it', ['0']) - call s:RunDbgCmd(buf, 'step', ['line 3: echo it']) - call s:RunDbgCmd(buf, 'echo it', ['1']) - call s:RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor']) - call s:RunDbgCmd(buf, 'step', ['line 2: for it in items']) - call s:RunDbgCmd(buf, 'echo it', ['1']) - call s:RunDbgCmd(buf, 'step', ['line 3: echo it']) - call s:RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor']) - call s:RunDbgCmd(buf, 'step', ['line 2: for it in items']) - call s:RunDbgCmd(buf, 'echo it', ['2']) - call s:RunDbgCmd(buf, 'step', ['line 3: echo it']) - call s:RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor']) - call s:RunDbgCmd(buf, 'step', ['line 2: for it in items']) - call s:RunDbgCmd(buf, 'step', ['line 5: echo "done"']) - call s:RunDbgCmd(buf, 'cont') - - call s:RunDbgCmd(buf, - \ ':debug call FuncWithDict()', - \ ['cmd: call FuncWithDict()']) - call s:RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }']) - call s:RunDbgCmd(buf, 'step', ['line 6: def Inner()']) - call s:RunDbgCmd(buf, 'cont') - - call s:RunDbgCmd(buf, ':breakadd func 1 FuncComment') - call s:RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"']) - call s:RunDbgCmd(buf, ':breakadd func 3 FuncComment') - call s:RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"']) - call s:RunDbgCmd(buf, 'cont') - - call s:RunDbgCmd(buf, ':breakadd func 2 FuncForLoop') - call s:RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]']) - call s:RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]']) - call s:RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2']) - call s:RunDbgCmd(buf, 'echo i', ['11']) - call s:RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor']) - call s:RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]']) - call s:RunDbgCmd(buf, 'next', ['line 3: eval i + 2']) - call s:RunDbgCmd(buf, 'echo i', ['22']) - - call s:RunDbgCmd(buf, 'breakdel *') - call s:RunDbgCmd(buf, 'cont') - - call s:RunDbgCmd(buf, ':breakadd func FuncWithSplitLine') - call s:RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3']) - - call s:RunDbgCmd(buf, 'cont') - call StopVimInTerminal(buf) -endfunc - -func Test_debug_def_function_with_lambda() - CheckCWD - let lines =<< trim END - vim9script - def g:Func() - var s = 'a' - ['b']->map((_, v) => s) - echo "done" - enddef - breakadd func 2 g:Func - END - call writefile(lines, 'XtestLambda.vim', 'D') - - let buf = RunVimInTerminal('-S XtestLambda.vim', {}) - - call s:RunDbgCmd(buf, - \ ':call g:Func()', - \ ['function Func', 'line 2: [''b'']->map((_, v) => s)']) - call s:RunDbgCmd(buf, - \ 'next', - \ ['function Func', 'line 3: echo "done"']) - - call s:RunDbgCmd(buf, 'cont') - call StopVimInTerminal(buf) -endfunc - -def Test_debug_backtrace_level() - CheckCWD - var lines =<< trim END - let s:file1_var = 'file1' - let g:global_var = 'global' - - func s:File1Func( arg ) - let s:file1_var .= a:arg - let local_var = s:file1_var .. ' test1' - let g:global_var .= local_var - source Xtest2.vim - endfunc - - call s:File1Func( 'arg1' ) - END - writefile(lines, 'Xtest1.vim', 'D') - - lines =<< trim END - let s:file2_var = 'file2' - - func s:File2Func( arg ) - let s:file2_var .= a:arg - let local_var = s:file2_var .. ' test2' - let g:global_var .= local_var - endfunc - - call s:File2Func( 'arg2' ) - END - writefile(lines, 'Xtest2.vim', 'D') - - var file1 = getcwd() .. '/Xtest1.vim' - var file2 = getcwd() .. '/Xtest2.vim' - - # set a breakpoint and source file1.vim - var buf = g:RunVimInTerminal( - '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim', - {wait_for_ruler: 0}) - - s:CheckDbgOutput(buf, [ - 'Breakpoint in "' .. file1 .. '" line 1', - 'Entering Debug mode. Type "cont" to continue.', - 'command line..script ' .. file1, - 'line 1: let s:file1_var = ''file1''' - ], {msec: 5000}) - - # step through the initial declarations - s:RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] ) - s:RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] ) - s:RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) - s:RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] ) - s:RunDbgCmd(buf, 'echo global_var', [ 'global' ] ) - - # step in to the first function - s:RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] ) - s:RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] ) - s:RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] ) - s:RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) - s:RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] ) - s:RunDbgCmd(buf, - 'echo global_var', - [ 'E121: Undefined variable: global_var' ] ) - s:RunDbgCmd(buf, - 'echo local_var', - [ 'E121: Undefined variable: local_var' ] ) - s:RunDbgCmd(buf, - 'echo l:local_var', - [ 'E121: Undefined variable: l:local_var' ] ) - - # backtrace up - s:RunDbgCmd(buf, 'backtrace', [ - '\V>backtrace', - '\V 2 command line', - '\V 1 script ' .. file1 .. '[11]', - '\V->0 function \.\*_File1Func', - '\Vline 1: let s:file1_var .= a:arg', - ], - { match: 'pattern' } ) - s:RunDbgCmd(buf, 'up', [ '>up' ] ) - - s:RunDbgCmd(buf, 'backtrace', [ - '\V>backtrace', - '\V 2 command line', - '\V->1 script ' .. file1 .. '[11]', - '\V 0 function \.\*_File1Func', - '\Vline 1: let s:file1_var .= a:arg', - ], - { match: 'pattern' } ) - - # Expression evaluation in the script frame (not the function frame) - # FIXME: Unexpected in this scope (a: should not be visible) - s:RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] ) - s:RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] ) - s:RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] ) - # FIXME: Unexpected in this scope (global should be found) - s:RunDbgCmd(buf, - 'echo global_var', - [ 'E121: Undefined variable: global_var' ] ) - s:RunDbgCmd(buf, - 'echo local_var', - [ 'E121: Undefined variable: local_var' ] ) - s:RunDbgCmd(buf, - 'echo l:local_var', - [ 'E121: Undefined variable: l:local_var' ] ) - - - # step while backtraced jumps to the latest frame - s:RunDbgCmd(buf, 'step', [ - 'line 2: let local_var = s:file1_var .. '' test1''' ] ) - s:RunDbgCmd(buf, 'backtrace', [ - '\V>backtrace', - '\V 2 command line', - '\V 1 script ' .. file1 .. '[11]', - '\V->0 function \.\*_File1Func', - '\Vline 2: let local_var = s:file1_var .. '' test1''', - ], - { match: 'pattern' } ) - - s:RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] ) - s:RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] ) - s:RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] ) - - s:RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] ) - s:RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] ) - s:RunDbgCmd(buf, 'backtrace', [ - '\V>backtrace', - '\V 3 command line', - '\V 2 script ' .. file1 .. '[11]', - '\V 1 function \.\*_File1Func[4]', - '\V->0 script ' .. file2, - '\Vline 1: let s:file2_var = ''file2''', - ], - { match: 'pattern' } ) - - # Expression evaluation in the script frame file2 (not the function frame) - s:RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] ) - s:RunDbgCmd(buf, - 'echo s:file1_var', - [ 'E121: Undefined variable: s:file1_var' ] ) - s:RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] ) - s:RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] ) - s:RunDbgCmd(buf, - 'echo local_var', - [ 'E121: Undefined variable: local_var' ] ) - s:RunDbgCmd(buf, - 'echo l:local_var', - [ 'E121: Undefined variable: l:local_var' ] ) - s:RunDbgCmd(buf, - 'echo s:file2_var', - [ 'E121: Undefined variable: s:file2_var' ] ) - - s:RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] ) - s:RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] ) - - # Up the stack to the other script context - s:RunDbgCmd(buf, 'up') - s:RunDbgCmd(buf, 'backtrace', [ - '\V>backtrace', - '\V 3 command line', - '\V 2 script ' .. file1 .. '[11]', - '\V->1 function \.\*_File1Func[4]', - '\V 0 script ' .. file2, - '\Vline 3: func s:File2Func( arg )', - ], - { match: 'pattern' } ) - # FIXME: Unexpected. Should see the a: and l: dicts from File1Func - s:RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] ) - s:RunDbgCmd(buf, - 'echo l:local_var', - [ 'E121: Undefined variable: l:local_var' ] ) - - s:RunDbgCmd(buf, 'up') - s:RunDbgCmd(buf, 'backtrace', [ - '\V>backtrace', - '\V 3 command line', - '\V->2 script ' .. file1 .. '[11]', - '\V 1 function \.\*_File1Func[4]', - '\V 0 script ' .. file2, - '\Vline 3: func s:File2Func( arg )', - ], - { match: 'pattern' } ) - - # FIXME: Unexpected (wrong script vars are used) - s:RunDbgCmd(buf, - 'echo s:file1_var', - [ 'E121: Undefined variable: s:file1_var' ] ) - s:RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] ) - - s:RunDbgCmd(buf, 'cont') - g:StopVimInTerminal(buf) -enddef - -" Test for setting a breakpoint on a :endif where the :if condition is false -" and then quit the script. This should generate an interrupt. -func Test_breakpt_endif_intr() - func F() - let g:Xpath ..= 'a' - if v:false - let g:Xpath ..= 'b' - endif - invalid_command - endfunc - - let g:Xpath = '' - breakadd func 4 F - try - let caught_intr = 0 - debuggreedy - call feedkeys(":call F()\quit\", "xt") - catch /^Vim:Interrupt$/ - call assert_match('\.F, line 4', v:throwpoint) - let caught_intr = 1 - endtry - 0debuggreedy - call assert_equal(1, caught_intr) - call assert_equal('a', g:Xpath) - breakdel * - delfunc F -endfunc - -" Test for setting a breakpoint on a :else where the :if condition is false -" and then quit the script. This should generate an interrupt. -func Test_breakpt_else_intr() - func F() - let g:Xpath ..= 'a' - if v:false - let g:Xpath ..= 'b' - else - invalid_command - endif - invalid_command - endfunc - - let g:Xpath = '' - breakadd func 4 F - try - let caught_intr = 0 - debuggreedy - call feedkeys(":call F()\quit\", "xt") - catch /^Vim:Interrupt$/ - call assert_match('\.F, line 4', v:throwpoint) - let caught_intr = 1 - endtry - 0debuggreedy - call assert_equal(1, caught_intr) - call assert_equal('a', g:Xpath) - breakdel * - delfunc F -endfunc - -" Test for setting a breakpoint on a :endwhile where the :while condition is -" false and then quit the script. This should generate an interrupt. -func Test_breakpt_endwhile_intr() - func F() - let g:Xpath ..= 'a' - while v:false - let g:Xpath ..= 'b' - endwhile - invalid_command - endfunc - - let g:Xpath = '' - breakadd func 4 F - try - let caught_intr = 0 - debuggreedy - call feedkeys(":call F()\quit\", "xt") - catch /^Vim:Interrupt$/ - call assert_match('\.F, line 4', v:throwpoint) - let caught_intr = 1 - endtry - 0debuggreedy - call assert_equal(1, caught_intr) - call assert_equal('a', g:Xpath) - breakdel * - delfunc F -endfunc - -" Test for setting a breakpoint on a script local function -func Test_breakpt_scriptlocal_func() - let g:Xpath = '' - func s:G() - let g:Xpath ..= 'a' - endfunc - - let funcname = expand("") .. "G" - exe "breakadd func 1 " .. funcname - debuggreedy - redir => output - call feedkeys(":call " .. funcname .. "()\c\", "xt") - redir END - 0debuggreedy - call assert_match('Breakpoint in "' .. funcname .. '" line 1', output) - call assert_equal('a', g:Xpath) - breakdel * - exe "delfunc " .. funcname -endfunc - -" vim: shiftwidth=2 sts=2 expandtab -- cgit 0.0.5-2-1-g0f52