blob: 4c3d6721f1f2cfe6ca4261cd4baa6c0efb8e31fb [file] [log] [blame]
Bram Moolenaar113bf062019-04-17 16:54:05 +02001" 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)',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020041 \ ' try',
42 \ ' let var1 = 3 + a:var',
43 \ ' let var3 = "another var"',
44 \ ' let var3 = "value2"',
45 \ ' catch',
46 \ ' let var4 = "exception"',
47 \ ' endtry',
Bram Moolenaar113bf062019-04-17 16:54:05 +020048 \ ' return var1',
49 \ 'endfunc'], 'Xtest.vim')
50
51 " Start Vim in a terminal
52 let buf = RunVimInTerminal('-S Xtest.vim', {})
53
54 " Start the Vim debugger
Bram Moolenaarddd33082019-06-03 23:07:25 +020055 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020056
57 " Create a few stack frames by stepping through functions
Bram Moolenaarddd33082019-06-03 23:07:25 +020058 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
59 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
60 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
61 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
62 call RunDbgCmd(buf, 'step', ['line 1: try'])
63 call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
64 call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020065
66 " check backtrace
67 call RunDbgCmd(buf, 'backtrace', [
68 \ ' 2 function Foo[2]',
69 \ ' 1 Bar[2]',
70 \ '->0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020071 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020072
73 " Check variables in different stack frames
74 call RunDbgCmd(buf, 'echo var1', ['6'])
75
76 call RunDbgCmd(buf, 'up')
77 call RunDbgCmd(buf, 'back', [
78 \ ' 2 function Foo[2]',
79 \ '->1 Bar[2]',
80 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020081 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020082 call RunDbgCmd(buf, 'echo var1', ['3'])
83
84 call RunDbgCmd(buf, 'u')
85 call RunDbgCmd(buf, 'bt', [
86 \ '->2 function Foo[2]',
87 \ ' 1 Bar[2]',
88 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020089 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020090 call RunDbgCmd(buf, 'echo var1', ['1'])
91
92 " Undefined variables
93 call RunDbgCmd(buf, 'step')
94 call RunDbgCmd(buf, 'frame 2')
95 call RunDbgCmd(buf, 'echo var3', [
96 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020097 \ 'line 4:',
Bram Moolenaar113bf062019-04-17 16:54:05 +020098 \ 'E121: Undefined variable: var3'])
99
100 " var3 is defined in this level with some other value
101 call RunDbgCmd(buf, 'fr 0')
102 call RunDbgCmd(buf, 'echo var3', ['another var'])
103
104 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200105 call RunDbgCmd(buf, '')
106 call RunDbgCmd(buf, '')
107 call RunDbgCmd(buf, '')
108 call RunDbgCmd(buf, '')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200109 call RunDbgCmd(buf, 'step', [
110 \ 'function Foo[2]..Bar',
111 \ 'line 3: End of function'])
112 call RunDbgCmd(buf, 'up')
113
114 " Undefined var2
115 call RunDbgCmd(buf, 'echo var2', [
116 \ 'Error detected while processing function Foo[2]..Bar:',
117 \ 'line 3:',
118 \ 'E121: Undefined variable: var2'])
119
120 " Var2 is defined with 10
121 call RunDbgCmd(buf, 'down')
122 call RunDbgCmd(buf, 'echo var2', ['10'])
123
124 " Backtrace movements
125 call RunDbgCmd(buf, 'b', [
126 \ ' 1 function Foo[2]',
127 \ '->0 Bar',
128 \ 'line 3: End of function'])
129
130 " next command cannot go down, we are on bottom
131 call RunDbgCmd(buf, 'down', ['frame is zero'])
132 call RunDbgCmd(buf, 'up')
133
134 " next command cannot go up, we are on top
135 call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
136 call RunDbgCmd(buf, 'where', [
137 \ '->1 function Foo[2]',
138 \ ' 0 Bar',
139 \ 'line 3: End of function'])
140
141 " fil is not frame or finish, it is file
142 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
143
144 " relative backtrace movement
145 call RunDbgCmd(buf, 'fr -1')
146 call RunDbgCmd(buf, 'frame', [
147 \ ' 1 function Foo[2]',
148 \ '->0 Bar',
149 \ 'line 3: End of function'])
150
151 call RunDbgCmd(buf, 'fr +1')
152 call RunDbgCmd(buf, 'fram', [
153 \ '->1 function Foo[2]',
154 \ ' 0 Bar',
155 \ 'line 3: End of function'])
156
157 " go beyond limits does not crash
158 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
159 call RunDbgCmd(buf, 'fra', [
160 \ '->1 function Foo[2]',
161 \ ' 0 Bar',
162 \ 'line 3: End of function'])
163
164 call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
165 call RunDbgCmd(buf, 'fram', [
166 \ ' 1 function Foo[2]',
167 \ '->0 Bar',
168 \ 'line 3: End of function'])
169
170 " final result 19
171 call RunDbgCmd(buf, 'cont', ['19'])
172
173 " breakpoints tests
174
175 " Start a debug session, so that reading the last line from the terminal
176 " works properly.
177 call RunDbgCmd(buf, ':debug echo Foo()')
178
179 " No breakpoints
180 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
181
182 " Place some breakpoints
183 call RunDbgCmd(buf, 'breaka func Bar')
184 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
185 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
186 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
187 \ ' 2 func Bazz line 3'])
188
189 " Check whether the breakpoints are hit
190 call RunDbgCmd(buf, 'cont', [
191 \ 'Breakpoint in "Bar" line 1',
192 \ 'function Foo[2]..Bar',
193 \ 'line 1: let var1 = 2 + a:var'])
194 call RunDbgCmd(buf, 'cont', [
195 \ 'Breakpoint in "Bazz" line 3',
196 \ 'function Foo[2]..Bar[2]..Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200197 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200198
199 " Delete the breakpoints
200 call RunDbgCmd(buf, 'breakd 1')
201 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
202 call RunDbgCmd(buf, 'breakdel func 3 Bazz')
203 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
204
205 call RunDbgCmd(buf, 'cont')
206
207 " Make sure the breakpoints are removed
208 call RunDbgCmd(buf, ':echo Foo()', ['19'])
209
210 " Delete a non-existing breakpoint
211 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
212
213 " Expression breakpoint
214 call RunDbgCmd(buf, ':breakadd func 2 Bazz')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200215 call RunDbgCmd(buf, ':echo Bazz(1)', [
216 \ 'Entering Debug mode. Type "cont" to continue.',
217 \ 'function Bazz',
218 \ 'line 2: let var1 = 3 + a:var'])
219 call RunDbgCmd(buf, 'step')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200220 call RunDbgCmd(buf, 'step')
221 call RunDbgCmd(buf, 'breaka expr var3')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200222 call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
223 \ ' 4 expr var3'])
224 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200225 \ 'Oldval = "''another var''"',
226 \ 'Newval = "''value2''"',
227 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200228 \ 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200229
230 call RunDbgCmd(buf, 'breakdel *')
231 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
232
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200233 " Check for error cases
234 call RunDbgCmd(buf, 'breakadd abcd', [
235 \ 'Error detected while processing function Bazz:',
236 \ 'line 5:',
237 \ 'E475: Invalid argument: abcd'])
238 call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
239 call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
240 call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
241 call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
242 call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
243 call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
244 call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
245 call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
246 call RunDbgCmd(buf, 'breakd expr x', [
247 \ 'E121: Undefined variable: x',
248 \ 'E161: Breakpoint not found: expr x'])
249
Bram Moolenaar113bf062019-04-17 16:54:05 +0200250 " finish the current function
251 call RunDbgCmd(buf, 'finish', [
252 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200253 \ 'line 8: End of function'])
254 call RunDbgCmd(buf, 'cont')
255
256 " Test for :next
257 call RunDbgCmd(buf, ':debug echo Bar(1)')
258 call RunDbgCmd(buf, 'step')
259 call RunDbgCmd(buf, 'next')
260 call RunDbgCmd(buf, '', [
261 \ 'function Bar',
262 \ 'line 3: return var2'])
263 call RunDbgCmd(buf, 'c')
264
265 " Test for :interrupt
266 call RunDbgCmd(buf, ':debug echo Bazz(1)')
267 call RunDbgCmd(buf, 'step')
268 call RunDbgCmd(buf, 'step')
269 call RunDbgCmd(buf, 'interrupt', [
270 \ 'Exception thrown: Vim:Interrupt',
271 \ 'function Bazz',
272 \ 'line 5: catch'])
273 call RunDbgCmd(buf, 'c')
274
275 " Test for :quit
276 call RunDbgCmd(buf, ':debug echo Foo()')
277 call RunDbgCmd(buf, 'breakdel *')
278 call RunDbgCmd(buf, 'breakadd func 3 Foo')
279 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
280 call RunDbgCmd(buf, 'cont', [
281 \ 'Breakpoint in "Bazz" line 3',
282 \ 'function Foo[2]..Bar[2]..Bazz',
283 \ 'line 3: let var3 = "another var"'])
284 call RunDbgCmd(buf, 'quit', [
285 \ 'Breakpoint in "Foo" line 3',
286 \ 'function Foo',
287 \ 'line 3: return var2'])
288 call RunDbgCmd(buf, 'breakdel *')
289 call RunDbgCmd(buf, 'quit')
290 call RunDbgCmd(buf, 'enew! | only!')
291
292 call StopVimInTerminal(buf)
293
294 " Tests for :breakadd file and :breakadd here
295 " Breakpoints should be set before sourcing the file
296
297 call writefile([
298 \ 'let var1 = 10',
299 \ 'let var2 = 20',
300 \ 'let var3 = 30',
301 \ 'let var4 = 40'], 'Xtest.vim')
302
303 " Start Vim in a terminal
304 let buf = RunVimInTerminal('Xtest.vim', {})
305 call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
306 call RunDbgCmd(buf, ':4 | breakadd here')
307 call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
308 call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200309 call RunDbgCmd(buf, 'cont')
310
311 call StopVimInTerminal(buf)
312
313 call delete('Xtest.vim')
314endfunc