blob: 8faf7ac06446f4791218eba7682d92f01e28fc56 [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
55 call RunDbgCmd(buf, ':debug echo Foo()')
56
57 " Create a few stack frames by stepping through functions
58 call RunDbgCmd(buf, 'step')
59 call RunDbgCmd(buf, 'step')
60 call RunDbgCmd(buf, 'step')
61 call RunDbgCmd(buf, 'step')
62 call RunDbgCmd(buf, 'step')
63 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020064 call RunDbgCmd(buf, 'step')
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