diff options
author | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2021-04-07 17:58:04 -0400 |
---|---|---|
committer | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2021-04-08 07:28:57 -0400 |
commit | 1b40447df30bde28ede534b23bdcf40f24b4d71a (patch) | |
tree | fd9c1a41cd4d3d90bed05d906bc1f1924b6ded5e | |
parent | 69bab7e35d7e0d4d3ac9f09bcfe111a092a2720a (diff) | |
download | rneovim-1b40447df30bde28ede534b23bdcf40f24b4d71a.tar.gz rneovim-1b40447df30bde28ede534b23bdcf40f24b4d71a.tar.bz2 rneovim-1b40447df30bde28ede534b23bdcf40f24b4d71a.zip |
vim-patch:8.2.1304: debug backtrace isn't tested much
Problem: Debug backtrace isn't tested much.
Solution: Add more specific tests. (Ben Jackson, closes vim/vim#6540)
https://github.com/vim/vim/commit/6ca6ca48898750dd55cad13c88a9c1dfd7fdaad5
Port runtest.vim fix from patch v8.2.1305.
-rw-r--r-- | src/nvim/testdir/runtest.vim | 5 | ||||
-rw-r--r-- | src/nvim/testdir/test_debugger.vim | 453 |
2 files changed, 452 insertions, 6 deletions
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index 2d94b637e0..49993c03aa 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -13,6 +13,9 @@ " For csh: " setenv TEST_FILTER Test_channel " +" While working on a test you can make $TEST_NO_RETRY non-empty to not retry: +" export TEST_NO_RETRY=yes +" " To ignore failure for tests that are known to fail in a certain environment, " set $TEST_MAY_FAIL to a comma separated list of function names. E.g. for " sh/bash: @@ -413,9 +416,11 @@ for s:test in sort(s:tests) call RunTheTest(s:test) " Repeat a flaky test. Give up when: + " - $TEST_NO_RETRY is not empty " - it fails again with the same message " - it fails five times (with a different message) if len(v:errors) > 0 + \ && $TEST_NO_RETRY == '' \ && (index(s:flaky_tests, s:test) >= 0 \ || g:test_is_flaky) while 1 diff --git a/src/nvim/testdir/test_debugger.vim b/src/nvim/testdir/test_debugger.vim index 59d51b855b..e5d160aa62 100644 --- a/src/nvim/testdir/test_debugger.vim +++ b/src/nvim/testdir/test_debugger.vim @@ -2,6 +2,20 @@ source shared.vim source screendump.vim +source check.vim + +func CheckDbgOutput(buf, lines, options = {}) + " Verify the expected output + let lnum = 20 - len(a:lines) + for l in a:lines + if get(a:options, 'match', 'equal') ==# 'pattern' + call WaitForAssert({-> assert_match(l, term_getline(a:buf, lnum))}, 200) + else + call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, 200) + endif + let lnum += 1 + endfor +endfunc " Run a Vim debugger command " If the expected output argument is supplied, then check for it. @@ -10,12 +24,11 @@ func RunDbgCmd(buf, cmd, ...) call term_wait(a:buf) if a:0 != 0 - " Verify the expected output - let lnum = 20 - len(a:1) - for l in a:1 - call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}) - let lnum += 1 - endfor + let options = #{match: 'equal'} + if a:0 > 1 + call extend(options, a:2) + endif + call CheckDbgOutput(a:buf, a:1, options) endif endfunc @@ -317,6 +330,434 @@ func Test_Debugger() call delete('Xtest.vim') endfunc +func Test_Backtrace_Through_Source() + CheckRunVimInTerminal + + 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') + + let file2 =<< trim END + func DoAThing() + echo "DoAThing" + endfunc + + func File2Function() + call DoAThing() + endfunc + + call File2Function() + END + call writefile(file2, 'Xtest2.vim') + + let buf = RunVimInTerminal('-S Xtest1.vim', {}) + + call RunDbgCmd(buf, + \ ':debug call GlobalFunction()', + \ ['cmd: call GlobalFunction()']) + call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) + + call RunDbgCmd(buf, 'backtrace', ['>backtrace', + \ '->0 function GlobalFunction', + \ 'line 1: call CallAFunction()']) + + call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()']) + call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) + + call 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 RunDbgCmd(buf, 'step', ['line 1: func DoAThing()']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 3 function GlobalFunction[1]', + \ ' 2 CallAFunction[1]', + \ ' 1 SourceAnotherFile[1]', + \ '->0 script ' .. getcwd() .. '/Xtest2.vim', + \ 'line 1: func DoAThing()']) + + " step until we have another meaninfgul trace + call RunDbgCmd(buf, 'step', ['line 5: func File2Function()']) + call RunDbgCmd(buf, 'step', ['line 9: call File2Function()']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 3 function GlobalFunction[1]', + \ ' 2 CallAFunction[1]', + \ ' 1 SourceAnotherFile[1]', + \ '->0 script ' .. getcwd() .. '/Xtest2.vim', + \ 'line 9: call File2Function()']) + + call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) + call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"']) + call 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 RunDbgCmd(buf, 'step', ['line 1: End of function']) + call RunDbgCmd(buf, 'step', ['line 1: End of function']) + call RunDbgCmd(buf, 'step', ['line 10: End of sourced file']) + call RunDbgCmd(buf, 'step', ['line 1: End of function']) + call RunDbgCmd(buf, 'step', ['line 2: call File2Function()']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 1 function GlobalFunction[1]', + \ '->0 CallAFunction', + \ 'line 2: call File2Function()']) + + call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 2 function GlobalFunction[1]', + \ ' 1 CallAFunction[2]', + \ '->0 File2Function', + \ 'line 1: call DoAThing()']) + + call StopVimInTerminal(buf) + call delete('Xtest1.vim') + call delete('Xtest2.vim') +endfunc + +func Test_Backtrace_Autocmd() + CheckRunVimInTerminal + + 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') + + let file2 =<< trim END + func DoAThing() + echo "DoAThing" + endfunc + + func File2Function() + call DoAThing() + endfunc + + call File2Function() + END + call writefile(file2, 'Xtest2.vim') + + let buf = RunVimInTerminal('-S Xtest1.vim', {}) + + call RunDbgCmd(buf, + \ ':debug doautocmd User TestGlobalFunction', + \ ['cmd: doautocmd User TestGlobalFunction']) + call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"']) + + " At this point the ontly thing in the stack is the autocommand + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ '->0 User Autocommands for "TestGlobalFunction"', + \ 'cmd: call GlobalFunction() | echo "Done"']) + + " And now we're back into the call stack + call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 1 User Autocommands for "TestGlobalFunction"', + \ '->0 function GlobalFunction', + \ 'line 1: call CallAFunction()']) + + call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()']) + call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) + + call 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 RunDbgCmd(buf, 'step', ['line 1: func DoAThing()']) + call 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()']) + + " step until we have another meaninfgul trace + call RunDbgCmd(buf, 'step', ['line 5: func File2Function()']) + call RunDbgCmd(buf, 'step', ['line 9: call File2Function()']) + call 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 RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) + call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"']) + call 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 RunDbgCmd(buf, 'step', ['line 1: End of function']) + call RunDbgCmd(buf, 'step', ['line 1: End of function']) + call RunDbgCmd(buf, 'step', ['line 10: End of sourced file']) + call RunDbgCmd(buf, 'step', ['line 1: End of function']) + call RunDbgCmd(buf, 'step', ['line 2: call File2Function()']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 2 User Autocommands for "TestGlobalFunction"', + \ ' 1 function GlobalFunction[1]', + \ '->0 CallAFunction', + \ 'line 2: call File2Function()']) + + call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()']) + call 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 RunDbgCmd(buf, 'finish', ['line 1: End of function']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 3 User Autocommands for "TestGlobalFunction"', + \ ' 2 function GlobalFunction[1]', + \ ' 1 CallAFunction[2]', + \ '->0 File2Function', + \ 'line 1: End of function']) + + call RunDbgCmd(buf, 'finish', ['line 2: End of function']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 2 User Autocommands for "TestGlobalFunction"', + \ ' 1 function GlobalFunction[1]', + \ '->0 CallAFunction', + \ 'line 2: End of function']) + + call RunDbgCmd(buf, 'finish', ['line 1: End of function']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 1 User Autocommands for "TestGlobalFunction"', + \ '->0 function GlobalFunction', + \ 'line 1: End of function']) + + call RunDbgCmd(buf, 'step', ['cmd: echo "Done"']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ '->0 User Autocommands for "TestGlobalFunction"', + \ 'cmd: echo "Done"']) + + call StopVimInTerminal(buf) + call delete('Xtest1.vim') + call delete('Xtest2.vim') +endfunc + +func Test_Backtrace_CmdLine() + CheckRunVimInTerminal + + 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') + + let file2 =<< trim END + func DoAThing() + echo "DoAThing" + endfunc + + func File2Function() + call DoAThing() + endfunc + + call File2Function() + END + call writefile(file2, 'Xtest2.vim') + + 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 + call CheckDbgOutput(buf, ['command line', + \ 'cmd: call GlobalFunction()']) + + " At this point the ontly thing in the stack is the cmdline + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ '->0 command line', + \ 'cmd: call GlobalFunction()']) + + " And now we're back into the call stack + call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()']) + call RunDbgCmd(buf, 'backtrace', [ + \ '>backtrace', + \ ' 1 command line', + \ '->0 function GlobalFunction', + \ 'line 1: call CallAFunction()']) + + call StopVimInTerminal(buf) + call delete('Xtest1.vim') + call delete('Xtest2.vim') +endfunc + +func Test_Backtrace_DefFunction() + CheckRunVimInTerminal + + let file1 =<< trim END + vim9script + import File2Function from './Xtest2.vim' + + def SourceAnotherFile() + source Xtest2.vim + enddef + + def CallAFunction() + SourceAnotherFile() + File2Function() + enddef + + def g:GlobalFunction() + CallAFunction() + enddef + + defcompile + END + call writefile(file1, 'Xtest1.vim') + + let file2 =<< trim END + vim9script + + def DoAThing(): number + let a = 100 * 2 + a += 3 + return a + enddef + + export def File2Function() + DoAThing() + enddef + + defcompile + File2Function() + END + call writefile(file2, 'Xtest2.vim') + + let buf = RunVimInTerminal('-S Xtest1.vim', {}) + + call RunDbgCmd(buf, + \ ':debug call GlobalFunction()', + \ ['cmd: call GlobalFunction()']) + + " FIXME: Vim9 lines are not debugged! + call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim']) + + " But they do appear in the backtrace + call RunDbgCmd(buf, 'backtrace', [ + \ '\V>backtrace', + \ '\V 2 function GlobalFunction[1]', + \ '\V 1 <SNR>\.\*_CallAFunction[1]', + \ '\V->0 <SNR>\.\*_SourceAnotherFile', + \ '\Vline 1: source Xtest2.vim'], + \ #{match: 'pattern'}) + + + call RunDbgCmd(buf, 'step', ['line 1: vim9script']) + call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number']) + call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()']) + call RunDbgCmd(buf, 'step', ['line 9: def File2Function()']) + call RunDbgCmd(buf, 'step', ['line 13: defcompile']) + call RunDbgCmd(buf, 'step', ['line 14: File2Function()']) + call RunDbgCmd(buf, 'backtrace', [ + \ '\V>backtrace', + \ '\V 3 function GlobalFunction[1]', + \ '\V 2 <SNR>\.\*_CallAFunction[1]', + \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]', + \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim', + \ '\Vline 14: File2Function()'], + \ #{match: 'pattern'}) + + " Don't step into compiled functions... + call RunDbgCmd(buf, 'step', ['line 15: End of sourced file']) + call RunDbgCmd(buf, 'backtrace', [ + \ '\V>backtrace', + \ '\V 3 function GlobalFunction[1]', + \ '\V 2 <SNR>\.\*_CallAFunction[1]', + \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]', + \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim', + \ '\Vline 15: End of sourced file'], + \ #{match: 'pattern'}) + + + call StopVimInTerminal(buf) + call delete('Xtest1.vim') + call delete('Xtest2.vim') +endfunc + " 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() |