neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

test_plugin_termdebug.vim (14807B)


      1 " Test for the termdebug plugin
      2 
      3 source shared.vim
      4 source check.vim
      5 
      6 CheckUnix
      7 " CheckFeature terminal
      8 CheckExecutable gdb
      9 CheckExecutable gcc
     10 
     11 let g:GDB = exepath('gdb')
     12 if g:GDB->empty()
     13  throw 'Skipped: gdb is not found in $PATH'
     14 endif
     15 
     16 let g:GCC = exepath('gcc')
     17 if g:GCC->empty()
     18  throw 'Skipped: gcc is not found in $PATH'
     19 endif
     20 
     21 function s:generate_files(bin_name)
     22  let src_name = a:bin_name .. '.c'
     23  let lines =<< trim END
     24    #include <stdio.h>
     25    #include <stdlib.h>
     26 
     27    int isprime(int n)
     28    {
     29      if (n <= 1)
     30        return 0;
     31 
     32      for (int i = 2; i <= n / 2; i++)
     33        if (n % i == 0)
     34          return 0;
     35 
     36      return 1;
     37    }
     38 
     39    int main(int argc, char *argv[])
     40    {
     41      int n = 7;
     42 
     43      printf("%d is %s prime\n", n, isprime(n) ? "a" : "not a");
     44 
     45      return 0;
     46    }
     47  END
     48  call writefile(lines, src_name)
     49  call system($'{g:GCC} -g -o {a:bin_name} {src_name}')
     50 endfunction
     51 
     52 function s:cleanup_files(bin_name)
     53  call delete(a:bin_name)
     54  call delete(a:bin_name .. '.c')
     55 endfunction
     56 
     57 packadd termdebug
     58 
     59 func Test_termdebug_basic()
     60  let bin_name = 'XTD_basic'
     61  let src_name = bin_name .. '.c'
     62  call s:generate_files(bin_name)
     63 
     64  edit XTD_basic.c
     65  Termdebug ./XTD_basic
     66  call WaitForAssert({-> assert_equal(3, winnr('$'))})
     67  let gdb_buf = winbufnr(1)
     68  wincmd b
     69  Break 9
     70  call Nterm_wait(gdb_buf)
     71  redraw!
     72  call assert_equal([
     73        \ {'lnum': 9, 'id': 1014, 'name': 'debugBreakpoint1.0',
     74        \  'priority': 110, 'group': 'TermDebug'}],
     75        \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)
     76  Run
     77  call Nterm_wait(gdb_buf, 400)
     78  redraw!
     79  call WaitForAssert({-> assert_equal([
     80        \ {'lnum': 9, 'id': 12, 'name': 'debugPC', 'priority': 110,
     81        \  'group': 'TermDebug'},
     82        \ {'lnum': 9, 'id': 1014, 'name': 'debugBreakpoint1.0',
     83        \  'priority': 110, 'group': 'TermDebug'}],
     84        "\ sign_getplaced('', #{group: 'TermDebug'})[0].signs)})
     85        \ sign_getplaced('', #{group: 'TermDebug'})[0].signs->reverse())})
     86  Finish
     87  call Nterm_wait(gdb_buf)
     88  redraw!
     89  call WaitForAssert({-> assert_equal([
     90        \ {'lnum': 9, 'id': 1014, 'name': 'debugBreakpoint1.0',
     91        \  'priority': 110, 'group': 'TermDebug'},
     92        \ {'lnum': 20, 'id': 12, 'name': 'debugPC',
     93        \  'priority': 110, 'group': 'TermDebug'}],
     94        \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)})
     95  Continue
     96  call Nterm_wait(gdb_buf)
     97 
     98  let g:termdebug_config = {}
     99  let g:termdebug_config['signs'] = ['>1', '>2', '>3']
    100  let g:termdebug_config['sign'] = '>>'
    101  let g:termdebug_config['sign_decimal'] = 1
    102 
    103  let i = 2
    104  while i <= 258
    105    Break
    106    call Nterm_wait(gdb_buf)
    107    if i == 2
    108      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint2.0')[0].text, '>2')})
    109    endif
    110    if i == 3
    111      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint3.0')[0].text, '>3')})
    112    endif
    113    if i == 4
    114      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint4.0')[0].text, '>>')})
    115    endif
    116    if i == 5
    117      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint5.0')[0].text, '>>')})
    118      unlet g:termdebug_config['sign']
    119    endif
    120    if i == 6
    121      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint6.0')[0].text, '06')})
    122    endif
    123    if i == 10
    124      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint10.0')[0].text, '10')})
    125    endif
    126    if i == 99
    127      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint99.0')[0].text, '99')})
    128    endif
    129    if i == 100
    130      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint100.0')[0].text, '9+')})
    131    endif
    132    if i == 110
    133      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint110.0')[0].text, '9+')})
    134      unlet g:termdebug_config
    135    endif
    136    if i == 128
    137      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint128.0')[0].text, '80')})
    138    endif
    139    if i == 168
    140      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint168.0')[0].text, 'A8')})
    141    endif
    142    if i == 255
    143      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint255.0')[0].text, 'FF')})
    144    endif
    145    if i == 256
    146      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint256.0')[0].text, 'F+')})
    147    endif
    148    if i == 258
    149      call WaitForAssert({-> assert_equal(sign_getdefined('debugBreakpoint258.0')[0].text, 'F+')})
    150    endif
    151    let i += 1
    152  endwhile
    153 
    154  let cn = 0
    155  " 60 is approx spaceBuffer * 3
    156  if winwidth(0) <= 78 + 60
    157    Var
    158    call assert_equal(winnr('$'), winnr())
    159    call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]], winlayout())
    160    let cn += 1
    161    bw!
    162    Asm
    163    call assert_equal(winnr('$'), winnr())
    164    call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['leaf', 1000], ['leaf', 1003 + cn]]], winlayout())
    165    let cn += 1
    166    bw!
    167  endif
    168  set columns=160
    169  call Nterm_wait(gdb_buf)
    170  let winw = winwidth(0)
    171  Var
    172  if winwidth(0) < winw
    173    call assert_equal(winnr('$') - 1, winnr())
    174    call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]], winlayout())
    175    let cn += 1
    176    bw!
    177  endif
    178  let winw = winwidth(0)
    179  Asm
    180  if winwidth(0) < winw
    181    call assert_equal(winnr('$') - 1, winnr())
    182    call assert_equal(['col', [['leaf', 1002], ['leaf', 1001], ['row', [['leaf', 1003 + cn], ['leaf', 1000]]]]], winlayout())
    183    let cn += 1
    184    bw!
    185  endif
    186  set columns&
    187  call Nterm_wait(gdb_buf)
    188 
    189  wincmd t
    190  quit!
    191  redraw!
    192  call WaitForAssert({-> assert_equal(1, winnr('$'))})
    193  call assert_equal([], sign_getplaced('', #{group: 'TermDebug'})[0].signs)
    194 
    195  for use_prompt in [0, 1]
    196    let g:termdebug_config = {}
    197    let g:termdebug_config['use_prompt'] = use_prompt
    198    TermdebugCommand ./XTD_basic arg args
    199    call WaitForAssert({-> assert_equal(3, winnr('$'))})
    200    wincmd t
    201    quit!
    202    redraw!
    203    call WaitForAssert({-> assert_equal(1, winnr('$'))})
    204    unlet g:termdebug_config
    205  endfor
    206 
    207  call s:cleanup_files(bin_name)
    208  %bw!
    209 endfunc
    210 
    211 func Test_termdebug_tbreak()
    212  let g:test_is_flaky = 1
    213  let bin_name = 'XTD_tbreak'
    214  let src_name = bin_name .. '.c'
    215 
    216  eval s:generate_files(bin_name)
    217 
    218  execute 'edit ' .. src_name
    219  execute 'Termdebug ./' .. bin_name
    220 
    221  call WaitForAssert({-> assert_equal(3, winnr('$'))})
    222  let gdb_buf = winbufnr(1)
    223  wincmd b
    224 
    225  let bp_line = 22        " 'return' statement in main
    226  let temp_bp_line = 10   " 'if' statement in 'for' loop body
    227  execute "Tbreak " .. temp_bp_line
    228  execute "Break " .. bp_line
    229 
    230  call Nterm_wait(gdb_buf)
    231  redraw!
    232  " both temporary and normal breakpoint signs were displayed...
    233  call assert_equal([
    234        \ {'lnum': temp_bp_line, 'id': 1014, 'name': 'debugBreakpoint1.0',
    235        \  'priority': 110, 'group': 'TermDebug'},
    236        \ {'lnum': bp_line, 'id': 2014, 'name': 'debugBreakpoint2.0',
    237        \  'priority': 110, 'group': 'TermDebug'}],
    238        \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)
    239 
    240  Run
    241  call Nterm_wait(gdb_buf, 400)
    242  redraw!
    243  " debugPC sign is on the line where the temp. bp was set;
    244  " temp. bp sign was removed after hit;
    245  " normal bp sign is still present
    246  call WaitForAssert({-> assert_equal([
    247        \ {'lnum': temp_bp_line, 'id': 12, 'name': 'debugPC', 'priority': 110,
    248        \  'group': 'TermDebug'},
    249        \ {'lnum': bp_line, 'id': 2014, 'name': 'debugBreakpoint2.0',
    250        \  'priority': 110, 'group': 'TermDebug'}],
    251        \ sign_getplaced('', #{group: 'TermDebug'})[0].signs)})
    252 
    253  Continue
    254  call Nterm_wait(gdb_buf)
    255  redraw!
    256  " debugPC is on the normal breakpoint,
    257  " temp. bp on line 10 was only hit once
    258  call WaitForAssert({-> assert_equal([
    259        \ {'lnum': bp_line, 'id': 12, 'name': 'debugPC', 'priority': 110,
    260        \  'group': 'TermDebug'},
    261        \ {'lnum': bp_line, 'id': 2014, 'name': 'debugBreakpoint2.0',
    262        \  'priority': 110, 'group': 'TermDebug'}],
    263        "\ sign_getplaced('', #{group: 'TermDebug'})[0].signs)})
    264        \ sign_getplaced('', #{group: 'TermDebug'})[0].signs->reverse())})
    265 
    266  wincmd t
    267  quit!
    268  redraw!
    269  call WaitForAssert({-> assert_equal(1, winnr('$'))})
    270  call assert_equal([], sign_getplaced('', #{group: 'TermDebug'})[0].signs)
    271 
    272  eval s:cleanup_files(bin_name)
    273  %bw!
    274 endfunc
    275 
    276 func Test_termdebug_mapping()
    277  %bw!
    278  call assert_true(maparg('K', 'n', 0, 1)->empty())
    279  call assert_true(maparg('-', 'n', 0, 1)->empty())
    280  call assert_true(maparg('+', 'n', 0, 1)->empty())
    281  Termdebug
    282  call WaitForAssert({-> assert_equal(3, winnr('$'))})
    283  wincmd b
    284  call assert_false(maparg('K', 'n', 0, 1)->empty())
    285  call assert_false(maparg('-', 'n', 0, 1)->empty())
    286  call assert_false(maparg('+', 'n', 0, 1)->empty())
    287  call assert_false(maparg('K', 'n', 0, 1).buffer)
    288  call assert_false(maparg('-', 'n', 0, 1).buffer)
    289  call assert_false(maparg('+', 'n', 0, 1).buffer)
    290  call assert_equal(':Evaluate<CR>', maparg('K', 'n', 0, 1).rhs)
    291  wincmd t
    292  quit!
    293  redraw!
    294  call WaitForAssert({-> assert_equal(1, winnr('$'))})
    295  call assert_true(maparg('K', 'n', 0, 1)->empty())
    296  call assert_true(maparg('-', 'n', 0, 1)->empty())
    297  call assert_true(maparg('+', 'n', 0, 1)->empty())
    298 
    299  %bw!
    300  nnoremap K :echom "K"<cr>
    301  nnoremap - :echom "-"<cr>
    302  nnoremap + :echom "+"<cr>
    303  Termdebug
    304  call WaitForAssert({-> assert_equal(3, winnr('$'))})
    305  wincmd b
    306  call assert_false(maparg('K', 'n', 0, 1)->empty())
    307  call assert_false(maparg('-', 'n', 0, 1)->empty())
    308  call assert_false(maparg('+', 'n', 0, 1)->empty())
    309  call assert_false(maparg('K', 'n', 0, 1).buffer)
    310  call assert_false(maparg('-', 'n', 0, 1).buffer)
    311  call assert_false(maparg('+', 'n', 0, 1).buffer)
    312  call assert_equal(':Evaluate<CR>', maparg('K', 'n', 0, 1).rhs)
    313  wincmd t
    314  quit!
    315  redraw!
    316  call WaitForAssert({-> assert_equal(1, winnr('$'))})
    317  call assert_false(maparg('K', 'n', 0, 1)->empty())
    318  call assert_false(maparg('-', 'n', 0, 1)->empty())
    319  call assert_false(maparg('+', 'n', 0, 1)->empty())
    320  call assert_false(maparg('K', 'n', 0, 1).buffer)
    321  call assert_false(maparg('-', 'n', 0, 1).buffer)
    322  call assert_false(maparg('+', 'n', 0, 1).buffer)
    323  call assert_equal(':echom "K"<cr>', maparg('K', 'n', 0, 1).rhs)
    324 
    325  %bw!
    326 
    327  " -- Test that local-buffer mappings are restored in the correct buffers --
    328  " local mappings for foo
    329  file foo
    330  nnoremap <buffer> K :echom "bK"<cr>
    331  nnoremap <buffer> - :echom "b-"<cr>
    332  nnoremap <buffer> + :echom "b+"<cr>
    333 
    334  " no mappings for 'bar'
    335  enew
    336  file bar
    337 
    338  " Start termdebug from foo
    339  buffer foo
    340  Termdebug
    341  call WaitForAssert({-> assert_equal(3, winnr('$'))})
    342  wincmd b
    343  call assert_true(maparg('K', 'n', 0, 1).buffer)
    344  call assert_true(maparg('-', 'n', 0, 1).buffer)
    345  call assert_true(maparg('+', 'n', 0, 1).buffer)
    346  call assert_equal(maparg('K', 'n', 0, 1).rhs, ':echom "bK"<cr>')
    347 
    348  Source
    349  buffer bar
    350  call assert_false(maparg('K', 'n', 0, 1)->empty())
    351  call assert_false(maparg('-', 'n', 0, 1)->empty())
    352  call assert_false(maparg('+', 'n', 0, 1)->empty())
    353  call assert_true(maparg('K', 'n', 0, 1).buffer->empty())
    354  call assert_true(maparg('-', 'n', 0, 1).buffer->empty())
    355  call assert_true(maparg('+', 'n', 0, 1).buffer->empty())
    356  wincmd t
    357  quit!
    358  redraw!
    359  call WaitForAssert({-> assert_equal(1, winnr('$'))})
    360 
    361  " Termdebug session ended. Buffer 'bar' shall have no mappings
    362  call assert_true(bufname() ==# 'bar')
    363  call assert_false(maparg('K', 'n', 0, 1)->empty())
    364  call assert_false(maparg('-', 'n', 0, 1)->empty())
    365  call assert_false(maparg('+', 'n', 0, 1)->empty())
    366  call assert_true(maparg('K', 'n', 0, 1).buffer->empty())
    367  call assert_true(maparg('-', 'n', 0, 1).buffer->empty())
    368  call assert_true(maparg('+', 'n', 0, 1).buffer->empty())
    369 
    370  " Buffer 'foo' shall have the same mapping as before running the termdebug
    371  " session
    372  buffer foo
    373  call assert_true(bufname() ==# 'foo')
    374  call assert_true(maparg('K', 'n', 0, 1).buffer)
    375  call assert_true(maparg('-', 'n', 0, 1).buffer)
    376  call assert_true(maparg('+', 'n', 0, 1).buffer)
    377  call assert_equal(':echom "bK"<cr>', maparg('K', 'n', 0, 1).rhs)
    378 
    379  nunmap K
    380  nunmap +
    381  nunmap -
    382  %bw!
    383 endfunc
    384 
    385 func Test_termdebug_bufnames()
    386  " Test if user has filename/folders named gdb, Termdebug-gdb-console,
    387  " etc. in the current directory
    388  let g:termdebug_config = {}
    389  let g:termdebug_config['use_prompt'] = 1
    390  let filename = 'gdb'
    391  let replacement_filename = 'Termdebug-gdb-console'
    392 
    393  call writefile(['This', 'is', 'a', 'test'], filename, 'D')
    394  " Throw away the file once the test has done.
    395  Termdebug
    396  " Once termdebug has completed the startup you should have 3 windows on screen
    397  call WaitForAssert({-> assert_equal(3, winnr('$'))})
    398  " A file named filename already exists in the working directory,
    399  " hence you must call the newly created buffer differently
    400  call WaitForAssert({-> assert_false(bufexists(filename))})
    401  call WaitForAssert({-> assert_true(bufexists(replacement_filename))})
    402  quit!
    403  call WaitForAssert({-> assert_equal(1, winnr('$'))})
    404 
    405  " Check if error message is in :message
    406  let g:termdebug_config['disasm_window'] = 1
    407  let filename = 'Termdebug-asm-listing'
    408  call writefile(['This', 'is', 'a', 'test'], filename, 'D')
    409  " Check only the head of the error message
    410  let error_message = "You have a file/folder named '" .. filename .. "'"
    411  Termdebug
    412  " Once termdebug has completed the startup you should have 4 windows on screen
    413  call WaitForAssert({-> assert_equal(4, winnr('$'))})
    414  call WaitForAssert({-> assert_notequal(-1, stridx(execute('messages'), error_message))})
    415  quit!
    416  wincmd b
    417  wincmd q
    418  call WaitForAssert({-> assert_equal(1, winnr('$'))})
    419 
    420  unlet g:termdebug_config
    421 endfunc
    422 
    423 function Test_termdebug_save_restore_variables()
    424  " saved mousemodel
    425  "let &mousemodel=''
    426  let &mousemodel='extend'
    427 
    428  " saved keys
    429  nnoremap K :echo "hello world!"<cr>
    430  let expected_map_K = maparg('K', 'n', 0 , 1)
    431  nnoremap + :echo "hello plus!"<cr>
    432  let expected_map_plus = maparg('+', 'n', 0 , 1)
    433  let expected_map_minus = {}
    434 
    435  " saved &columns
    436  let expected_columns = &columns
    437 
    438  " We want termdebug to overwrite 'K' map but not '+' map.
    439  let g:termdebug_config = {}
    440  let g:termdebug_config['map_K'] = 1
    441 
    442  Termdebug
    443  call WaitForAssert({-> assert_equal(3, winnr('$'))})
    444  call WaitForAssert({-> assert_match(&mousemodel, 'popup_setpos')})
    445  wincmd t
    446  quit!
    447  call WaitForAssert({-> assert_equal(1, winnr('$'))})
    448 
    449  "call assert_true(empty(&mousemodel))
    450  call assert_equal(&mousemodel, 'extend')
    451 
    452  call assert_true(empty(expected_map_minus))
    453  call assert_equal(expected_map_K.rhs, maparg('K', 'n', 0, 1).rhs)
    454  call assert_equal(expected_map_plus.rhs, maparg('+', 'n', 0, 1).rhs)
    455 
    456  call assert_equal(expected_columns, &columns)
    457 
    458  nunmap K
    459  nunmap +
    460  unlet g:termdebug_config
    461 endfunction
    462 
    463 
    464 " vim: shiftwidth=2 sts=2 expandtab