1" Tests for the Vim script debug commands 2 3source shared.vim 4source screendump.vim 5 6" Run a Vim debugger command 7" If the expected output argument is supplied, then check for it. 8func RunDbgCmd(buf, cmd, ...) 9 call term_sendkeys(a:buf, a:cmd . "\r") 10 call term_wait(a:buf) 11 12 if a:0 != 0 13 " Verify the expected output 14 let lnum = 20 - len(a:1) 15 for l in a:1 16 call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}) 17 let lnum += 1 18 endfor 19 endif 20endfunc 21 22" Debugger tests 23func Test_Debugger() 24 if !CanRunVimInTerminal() 25 return 26 endif 27 28 " Create a Vim script with some functions 29 call writefile([ 30 \ 'func Foo()', 31 \ ' let var1 = 1', 32 \ ' let var2 = Bar(var1) + 9', 33 \ ' return var2', 34 \ 'endfunc', 35 \ 'func Bar(var)', 36 \ ' let var1 = 2 + a:var', 37 \ ' let var2 = Bazz(var1) + 4', 38 \ ' return var2', 39 \ 'endfunc', 40 \ 'func Bazz(var)', 41 \ ' let var1 = 3 + a:var', 42 \ ' let var3 = "another var"', 43 \ ' let var3 = "value2"', 44 \ ' let var3 = "value3"', 45 \ ' return var1', 46 \ 'endfunc'], 'Xtest.vim') 47 48 " Start Vim in a terminal 49 let buf = RunVimInTerminal('-S Xtest.vim', {}) 50 51 " Start the Vim debugger 52 call RunDbgCmd(buf, ':debug echo Foo()') 53 54 " Create a few stack frames by stepping through functions 55 call RunDbgCmd(buf, 'step') 56 call RunDbgCmd(buf, 'step') 57 call RunDbgCmd(buf, 'step') 58 call RunDbgCmd(buf, 'step') 59 call RunDbgCmd(buf, 'step') 60 call RunDbgCmd(buf, 'step') 61 62 " check backtrace 63 call RunDbgCmd(buf, 'backtrace', [ 64 \ ' 2 function Foo[2]', 65 \ ' 1 Bar[2]', 66 \ '->0 Bazz', 67 \ 'line 2: let var3 = "another var"']) 68 69 " Check variables in different stack frames 70 call RunDbgCmd(buf, 'echo var1', ['6']) 71 72 call RunDbgCmd(buf, 'up') 73 call RunDbgCmd(buf, 'back', [ 74 \ ' 2 function Foo[2]', 75 \ '->1 Bar[2]', 76 \ ' 0 Bazz', 77 \ 'line 2: let var3 = "another var"']) 78 call RunDbgCmd(buf, 'echo var1', ['3']) 79 80 call RunDbgCmd(buf, 'u') 81 call RunDbgCmd(buf, 'bt', [ 82 \ '->2 function Foo[2]', 83 \ ' 1 Bar[2]', 84 \ ' 0 Bazz', 85 \ 'line 2: let var3 = "another var"']) 86 call RunDbgCmd(buf, 'echo var1', ['1']) 87 88 " Undefined variables 89 call RunDbgCmd(buf, 'step') 90 call RunDbgCmd(buf, 'frame 2') 91 call RunDbgCmd(buf, 'echo var3', [ 92 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:', 93 \ 'line 3:', 94 \ 'E121: Undefined variable: var3']) 95 96 " var3 is defined in this level with some other value 97 call RunDbgCmd(buf, 'fr 0') 98 call RunDbgCmd(buf, 'echo var3', ['another var']) 99 100 call RunDbgCmd(buf, 'step') 101 call RunDbgCmd(buf, 'step') 102 call RunDbgCmd(buf, 'step') 103 call RunDbgCmd(buf, 'step') 104 call RunDbgCmd(buf, 'step', [ 105 \ 'function Foo[2]..Bar', 106 \ 'line 3: End of function']) 107 call RunDbgCmd(buf, 'up') 108 109 " Undefined var2 110 call RunDbgCmd(buf, 'echo var2', [ 111 \ 'Error detected while processing function Foo[2]..Bar:', 112 \ 'line 3:', 113 \ 'E121: Undefined variable: var2']) 114 115 " Var2 is defined with 10 116 call RunDbgCmd(buf, 'down') 117 call RunDbgCmd(buf, 'echo var2', ['10']) 118 119 " Backtrace movements 120 call RunDbgCmd(buf, 'b', [ 121 \ ' 1 function Foo[2]', 122 \ '->0 Bar', 123 \ 'line 3: End of function']) 124 125 " next command cannot go down, we are on bottom 126 call RunDbgCmd(buf, 'down', ['frame is zero']) 127 call RunDbgCmd(buf, 'up') 128 129 " next command cannot go up, we are on top 130 call RunDbgCmd(buf, 'up', ['frame at highest level: 1']) 131 call RunDbgCmd(buf, 'where', [ 132 \ '->1 function Foo[2]', 133 \ ' 0 Bar', 134 \ 'line 3: End of function']) 135 136 " fil is not frame or finish, it is file 137 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--']) 138 139 " relative backtrace movement 140 call RunDbgCmd(buf, 'fr -1') 141 call RunDbgCmd(buf, 'frame', [ 142 \ ' 1 function Foo[2]', 143 \ '->0 Bar', 144 \ 'line 3: End of function']) 145 146 call RunDbgCmd(buf, 'fr +1') 147 call RunDbgCmd(buf, 'fram', [ 148 \ '->1 function Foo[2]', 149 \ ' 0 Bar', 150 \ 'line 3: End of function']) 151 152 " go beyond limits does not crash 153 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1']) 154 call RunDbgCmd(buf, 'fra', [ 155 \ '->1 function Foo[2]', 156 \ ' 0 Bar', 157 \ 'line 3: End of function']) 158 159 call RunDbgCmd(buf, 'frame -40', ['frame is zero']) 160 call RunDbgCmd(buf, 'fram', [ 161 \ ' 1 function Foo[2]', 162 \ '->0 Bar', 163 \ 'line 3: End of function']) 164 165 " final result 19 166 call RunDbgCmd(buf, 'cont', ['19']) 167 168 " breakpoints tests 169 170 " Start a debug session, so that reading the last line from the terminal 171 " works properly. 172 call RunDbgCmd(buf, ':debug echo Foo()') 173 174 " No breakpoints 175 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) 176 177 " Place some breakpoints 178 call RunDbgCmd(buf, 'breaka func Bar') 179 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1']) 180 call RunDbgCmd(buf, 'breakadd func 3 Bazz') 181 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1', 182 \ ' 2 func Bazz line 3']) 183 184 " Check whether the breakpoints are hit 185 call RunDbgCmd(buf, 'cont', [ 186 \ 'Breakpoint in "Bar" line 1', 187 \ 'function Foo[2]..Bar', 188 \ 'line 1: let var1 = 2 + a:var']) 189 call RunDbgCmd(buf, 'cont', [ 190 \ 'Breakpoint in "Bazz" line 3', 191 \ 'function Foo[2]..Bar[2]..Bazz', 192 \ 'line 3: let var3 = "value2"']) 193 194 " Delete the breakpoints 195 call RunDbgCmd(buf, 'breakd 1') 196 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3']) 197 call RunDbgCmd(buf, 'breakdel func 3 Bazz') 198 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) 199 200 call RunDbgCmd(buf, 'cont') 201 202 " Make sure the breakpoints are removed 203 call RunDbgCmd(buf, ':echo Foo()', ['19']) 204 205 " Delete a non-existing breakpoint 206 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2']) 207 208 " Expression breakpoint 209 call RunDbgCmd(buf, ':breakadd func 2 Bazz') 210 call RunDbgCmd(buf, ':echo Bazz(1)') 211 call RunDbgCmd(buf, 'step') 212 call RunDbgCmd(buf, 'breaka expr var3') 213 call RunDbgCmd(buf, 'breakl', [' 4 expr var3']) 214 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 4', 215 \ 'Oldval = "''another var''"', 216 \ 'Newval = "''value2''"', 217 \ 'function Bazz', 218 \ 'line 4: let var3 = "value3"']) 219 220 call RunDbgCmd(buf, 'breakdel *') 221 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined']) 222 223 " finish the current function 224 call RunDbgCmd(buf, 'finish', [ 225 \ 'function Bazz', 226 \ 'line 5: End of function']) 227 call RunDbgCmd(buf, 'cont') 228 229 call StopVimInTerminal(buf) 230 231 call delete('Xtest.vim') 232endfunc 233