test and doc updates for conditional breakpoints
use a better description of hit condition and describe the options dict.
This commit is contained in:
parent
e153b9536e
commit
77dc400077
5 changed files with 218 additions and 9 deletions
37
README.md
37
README.md
|
|
@ -517,7 +517,7 @@ let g:vimspector_enable_mappings = 'HUMAN'
|
|||
| `F4` | Restart debugging with the same configuration. | `vimspector#Restart()` |
|
||||
| `F6` | Pause debugee. | `vimspector#Pause()` |
|
||||
| `F9` | Toggle line breakpoint on the current line. | `vimspector#ToggleBreakpoint()` |
|
||||
| `<leader>F9` | Toggle conditional line breakpoint on the current line. | `vimspector#ToggleBreakpoint( {condition, hit condition } )` |
|
||||
| `<leader>F9` | Toggle conditional line breakpoint on the current line. | `vimspector#ToggleBreakpoint( { trigger expr, hit count expr } )` |
|
||||
| `F8` | Add a function breakpoint for the expression under cursor | `vimspector#AddFunctionBreakpoint( '<cexpr>' )` |
|
||||
| `F10` | Step Over | `vimspector#StepOver()` |
|
||||
| `F11` | Step Into | `vimspector#StepInto()` |
|
||||
|
|
@ -530,6 +530,8 @@ let g:vimspector_enable_mappings = 'HUMAN'
|
|||
* Create `vimspector.json`. See [below](#supported-languages).
|
||||
* `:call vimspector#Launch()` and select a configuration.
|
||||
|
||||

|
||||
|
||||
### Launch with options
|
||||
|
||||
To launch a specific debug configuration, or specify [replacement
|
||||
|
|
@ -562,16 +564,35 @@ debugger](#java---partially-supported)
|
|||
|
||||
## Breakpoints
|
||||
|
||||
* Use `vimspector#ToggleBreakpoint([ { 'condition': '<condition>' } ])`
|
||||
* Use `vimspector#ToggleBreakpoint([ { 'condition': '<condition expr>' } ])`
|
||||
to set/disable/delete a line breakpoint, with optional condition.
|
||||
* Use `vimspector#AddFunctionBreakpoint( '<name>' [, { 'condition': '<condition>' } ] )`
|
||||
* Use `vimspector#AddFunctionBreakpoint( '<name>' [, { 'condition': '<condition expr>' } ] )`
|
||||
to add a function breakpoint with optional condition.
|
||||
|
||||
Both of these functions take a single optional argument which is a dictionary of
|
||||
options. The dictionary can have the following keys:
|
||||
|
||||
* `condition`: An optional expression evaluated to deterimie if the breakpoint
|
||||
should fire. Not supported by all debug adapters. For example, to break when
|
||||
`abc` is `10`, enter something like `abc == 10`, depending on the language.
|
||||
* `hitCondition`: An optional expression evaluated to determine a number of
|
||||
times the breakpoint should be ignored. Should (probablty?) not be used in
|
||||
combination with `condition`. Not supported by all debug adapters. For
|
||||
example, to break on the 3rd time hitting this line, enter `3`.
|
||||
|
||||
In both cases, the expression is evaluated by the debugger, so should be in
|
||||
whatever dialect the debugger understands when evaluating expressions.
|
||||
|
||||
When using the `<leader><F9>` mapping, the user is prompted to enter these
|
||||
expressions in a command line (with history).
|
||||
|
||||
## Stepping
|
||||
|
||||
* Step in/out, finish, continue, pause etc. using the WinBar.
|
||||
* Step in/out, finish, continue, pause etc. using the WinBar, or mappings.
|
||||
* If you really want to, the API is `vimspector#StepInto()` etc.
|
||||
|
||||

|
||||
|
||||
## Variables and scopes
|
||||
|
||||
* Current scope shows values of locals.
|
||||
|
|
@ -579,6 +600,8 @@ debugger](#java---partially-supported)
|
|||
* When changing the stack frame the locals window updates.
|
||||
* While paused, hover to see values
|
||||
|
||||

|
||||
|
||||
## Watches
|
||||
|
||||
The watches window is a prompt buffer, where that's available. Enter insert mode
|
||||
|
|
@ -591,11 +614,15 @@ to add a new watch expression.
|
|||
* Expand result with `<CR>`.
|
||||
* Delete with `<DEL>`.
|
||||
|
||||

|
||||
|
||||
## Stack Traces
|
||||
|
||||
* In the threads window, use `<CR>` to expand/collapse.
|
||||
* Use `<CR>` on a stack frame to jump to it.
|
||||
|
||||

|
||||
|
||||
## Program Output
|
||||
|
||||
* In the outputs window use the WinBar to select the output channel.
|
||||
|
|
@ -604,6 +631,8 @@ to add a new watch expression.
|
|||
* The debugee prints to the stdout channel.
|
||||
* Other channels may be useful for debugging.
|
||||
|
||||

|
||||
|
||||
### Console
|
||||
|
||||
The console window is a prompt buffer, where that's available, and can be used
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ nnoremap <Plug>VimspectorToggleBreakpoint
|
|||
\ :<c-u>call vimspector#ToggleBreakpoint()<CR>
|
||||
nnoremap <Plug>VimspectorToggleConditionalBreakpoint
|
||||
\ :<c-u>call vimspector#ToggleBreakpoint(
|
||||
\ { 'condition': input( 'Enter condition: ' ),
|
||||
\ 'hitCondition': input( 'Enter hit condition: ' ) }
|
||||
\ { 'condition': input( 'Enter condition expression: ' ),
|
||||
\ 'hitCondition': input( 'Enter hit count expression: ' ) }
|
||||
\ )<CR>
|
||||
nnoremap <Plug>VimspectorAddFunctionBreakpoint
|
||||
\ :<c-u>call vimspector#AddFunctionBreakpoint( expand( '<cexpr>' ) )<CR>
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ class VariablesView( object ):
|
|||
if result_str is None:
|
||||
result_str = 'null'
|
||||
|
||||
line = '{0}{1} Result: {2} '.format( ' ' * indent, icon, result_str )
|
||||
line = '{0}{1} Result: {2}'.format( ' ' * indent, icon, result_str )
|
||||
line = utils.AppendToBuffer( self._watch.win.buffer, line.split( '\n' ) )
|
||||
self._watch.lines[ line ] = result
|
||||
|
||||
|
|
|
|||
|
|
@ -295,3 +295,158 @@ function! Test_Insert_Code_Above_Breakpoint()
|
|||
call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 26 )
|
||||
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_Conditional_Line_Breakpoint()
|
||||
let g:vimspector_enable_mappings = 'HUMAN'
|
||||
endfunction
|
||||
|
||||
function! Test_Conditional_Line_Breakpoint()
|
||||
lcd testdata/cpp/simple
|
||||
edit simple.cpp
|
||||
call setpos( '.', [ 0, 16, 1 ] )
|
||||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 16, 1 )
|
||||
call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 16 )
|
||||
|
||||
" Add the conditional breakpoint
|
||||
call feedkeys( "\\\<F9>argc==0\<CR>\<CR>", 'xt' )
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
|
||||
\ 16,
|
||||
\ 'vimspectorBPCond' )
|
||||
|
||||
" Disable the breakpoint
|
||||
call feedkeys( "\<F9>", 'xt' )
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorBP',
|
||||
\ 16,
|
||||
\ 'vimspectorBPDisabled' )
|
||||
|
||||
" Delete the breakpoint
|
||||
call feedkeys( "\<F9>", 'xt' )
|
||||
call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 16 )
|
||||
|
||||
" Add breakpoint using API:
|
||||
" - on line 16 condition which doesn't match
|
||||
" - then an unconditional one on line 9, unconditional
|
||||
" - then on line 17, condition which matches
|
||||
call vimspector#ToggleBreakpoint( { 'condition': 'argc == 0' } )
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorBP',
|
||||
\ 16,
|
||||
\ 'vimspectorBPCond' )
|
||||
call setpos( '.', [ 0, 9, 1 ] )
|
||||
call vimspector#ToggleBreakpoint()
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorBP',
|
||||
\ 9,
|
||||
\ 'vimspectorBP' )
|
||||
|
||||
call setpos( '.', [ 0, 17, 1 ] )
|
||||
call vimspector#ToggleBreakpoint( { 'condition': 'argc == 1' } )
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorBP',
|
||||
\ 17,
|
||||
\ 'vimspectorBPCond' )
|
||||
|
||||
call setpos( '.', [ 0, 1, 1 ] )
|
||||
|
||||
" Start debugging
|
||||
call vimspector#Continue()
|
||||
" break on main
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 )
|
||||
|
||||
" Ignore non-matching on line 16, break on line 9
|
||||
call vimspector#Continue()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 9, 1 )
|
||||
|
||||
" Condition matches on line 17
|
||||
call vimspector#Continue()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 17, 1 )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
|
||||
lcd -
|
||||
%bwipeout!
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_Conditional_Line_Breakpoint_Hit()
|
||||
let g:vimspector_enable_mappings = 'HUMAN'
|
||||
endfunction
|
||||
|
||||
function! Test_Conditional_Line_Breakpoint_Hit()
|
||||
let fn = '../support/test/python/simple_python/main.py'
|
||||
exe 'edit' fn
|
||||
call setpos( '.', [ 0, 14, 1 ] )
|
||||
|
||||
" Add the conditional breakpoint (3 times)
|
||||
call feedkeys( "\\\<F9>\<CR>3\<CR>", 'xt' )
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorBP',
|
||||
\ 14,
|
||||
\ 'vimspectorBPCond' )
|
||||
|
||||
call vimspector#LaunchWithSettings( { 'configuration': 'run' } )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 14, 1 )
|
||||
|
||||
" difficult to check if we really did run 3 times, so just use the watch
|
||||
" window (also, tests the watch window!)
|
||||
call vimspector#AddWatch( 'i' )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( [ ' - Result: 2' ],
|
||||
\ getbufline( 'vimspector.Watches', '$' ) )
|
||||
\ } )
|
||||
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipeout!
|
||||
endfunction
|
||||
|
||||
function! Test_Function_Breakpoint()
|
||||
lcd testdata/cpp/simple
|
||||
edit simple.cpp
|
||||
call vimspector#AddFunctionBreakpoint( 'foo' )
|
||||
call vimspector#Launch()
|
||||
" break on main
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 )
|
||||
call vimspector#Continue()
|
||||
" break on func
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 9, 1 )
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipeout!
|
||||
endfunction
|
||||
|
||||
function! Test_Function_Breakpoint_Condition()
|
||||
lcd testdata/cpp/simple
|
||||
edit simple.cpp
|
||||
call vimspector#AddFunctionBreakpoint( 'foo', { 'condition': '1' } )
|
||||
call vimspector#Launch()
|
||||
" break on main
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 )
|
||||
call vimspector#Continue()
|
||||
" break on func
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 9, 1 )
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipeout!
|
||||
endfunction
|
||||
|
||||
" Can't find an adapter that supports conditional function breakpoints which are
|
||||
" probably pretty niche anyway
|
||||
"
|
||||
" function! Test_Function_Breakpoint_Condition_False()
|
||||
" lcd testdata/cpp/simple
|
||||
" edit simple.cpp
|
||||
"
|
||||
" call vimspector#AddFunctionBreakpoint( 'foo', { 'condition': '0' } )
|
||||
" call setpos( '.', [ 0, 17, 1 ] )
|
||||
" call vimspector#ToggleBreakpoint()
|
||||
" call vimspector#Launch()
|
||||
" " break on main
|
||||
" call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 )
|
||||
" call vimspector#Continue()
|
||||
"
|
||||
" " doesn't break in func, break on line 17
|
||||
" call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 17, 1 )
|
||||
" call vimspector#test#setup#Reset()
|
||||
" %bwipeout!
|
||||
" throw "xfail cpptools doesn't seem to honour conditions on function bps"
|
||||
" endfunction
|
||||
|
|
|
|||
|
|
@ -32,11 +32,12 @@
|
|||
" call ch_log( ",,,message..." )
|
||||
" Then view it in 'debuglog'
|
||||
|
||||
" Let a test take up to 1 minute
|
||||
" Let a test take up to 1 minute, unless debugging
|
||||
let s:single_test_timeout = 60000
|
||||
|
||||
" Restrict the runtimepath to the exact minimum needed for testing
|
||||
set runtimepath=$PWD/lib,$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after
|
||||
let &rtp = getcwd() . '/lib'
|
||||
set runtimepath+=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after
|
||||
if has('packages')
|
||||
let &packpath = &runtimepath
|
||||
endif
|
||||
|
|
@ -70,6 +71,10 @@ func s:TestFailed()
|
|||
endfunc
|
||||
|
||||
func! Abort( timer_id )
|
||||
if exists( '&debugfunc' ) && &debugfunc != ''
|
||||
return
|
||||
endif
|
||||
|
||||
call assert_report( 'Test timed out!!!' )
|
||||
qa!
|
||||
endfunc
|
||||
|
|
@ -152,6 +157,26 @@ func RunTheTest(test)
|
|||
\ 'SKIPPED ' . a:test
|
||||
\ . ': '
|
||||
\ . substitute(v:exception, '^\S*\s\+', '', ''))
|
||||
catch /^\cxfail/
|
||||
if len( v:errors ) == 0
|
||||
call add(v:errors,
|
||||
\ 'Expected failure but no error in ' . a:test
|
||||
\ . ': '
|
||||
\ . v:exception
|
||||
\ . ' @ '
|
||||
\ . g:testpath
|
||||
\ . ':'
|
||||
\ . v:throwpoint)
|
||||
|
||||
call s:TestFailed()
|
||||
else
|
||||
let v:errors = []
|
||||
call add(s:messages, ' XFAIL' )
|
||||
call add(s:skipped,
|
||||
\ 'XFAIL ' . a:test
|
||||
\ . ': '
|
||||
\ . substitute(v:exception, '^\S*\s\+', '', ''))
|
||||
endif
|
||||
catch
|
||||
call add(v:errors,
|
||||
\ 'Caught exception in ' . a:test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue