blob: 811717208e9e1a1480453a8172fa7d628ce971a1 [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()
Bram Moolenaar5d30ff12019-06-06 16:12:12 +020025 throw 'Skipped: cannot run Vim in a terminal window'
Bram Moolenaar113bf062019-04-17 16:54:05 +020026 endif
27
28 " Create a Vim script with some functions
Bram Moolenaare7eb9272019-06-24 00:58:07 +020029 let lines =<< trim END
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 try
42 let var1 = 3 + a:var
43 let var3 = "another var"
44 let var3 = "value2"
45 catch
46 let var4 = "exception"
47 endtry
48 return var1
49 endfunc
50 END
51 call writefile(lines, 'Xtest.vim')
Bram Moolenaar113bf062019-04-17 16:54:05 +020052
53 " Start Vim in a terminal
54 let buf = RunVimInTerminal('-S Xtest.vim', {})
55
56 " Start the Vim debugger
Bram Moolenaarddd33082019-06-03 23:07:25 +020057 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020058
59 " Create a few stack frames by stepping through functions
Bram Moolenaarddd33082019-06-03 23:07:25 +020060 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
61 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
62 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
63 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
64 call RunDbgCmd(buf, 'step', ['line 1: try'])
65 call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
66 call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020067
68 " check backtrace
69 call RunDbgCmd(buf, 'backtrace', [
70 \ ' 2 function Foo[2]',
71 \ ' 1 Bar[2]',
72 \ '->0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020073 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020074
75 " Check variables in different stack frames
76 call RunDbgCmd(buf, 'echo var1', ['6'])
77
78 call RunDbgCmd(buf, 'up')
79 call RunDbgCmd(buf, 'back', [
80 \ ' 2 function Foo[2]',
81 \ '->1 Bar[2]',
82 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020083 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020084 call RunDbgCmd(buf, 'echo var1', ['3'])
85
86 call RunDbgCmd(buf, 'u')
87 call RunDbgCmd(buf, 'bt', [
88 \ '->2 function Foo[2]',
89 \ ' 1 Bar[2]',
90 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020091 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020092 call RunDbgCmd(buf, 'echo var1', ['1'])
93
94 " Undefined variables
95 call RunDbgCmd(buf, 'step')
96 call RunDbgCmd(buf, 'frame 2')
97 call RunDbgCmd(buf, 'echo var3', [
98 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020099 \ 'line 4:',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200100 \ 'E121: Undefined variable: var3'])
101
102 " var3 is defined in this level with some other value
103 call RunDbgCmd(buf, 'fr 0')
104 call RunDbgCmd(buf, 'echo var3', ['another var'])
105
106 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200107 call RunDbgCmd(buf, '')
108 call RunDbgCmd(buf, '')
109 call RunDbgCmd(buf, '')
110 call RunDbgCmd(buf, '')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200111 call RunDbgCmd(buf, 'step', [
112 \ 'function Foo[2]..Bar',
113 \ 'line 3: End of function'])
114 call RunDbgCmd(buf, 'up')
115
116 " Undefined var2
117 call RunDbgCmd(buf, 'echo var2', [
118 \ 'Error detected while processing function Foo[2]..Bar:',
119 \ 'line 3:',
120 \ 'E121: Undefined variable: var2'])
121
122 " Var2 is defined with 10
123 call RunDbgCmd(buf, 'down')
124 call RunDbgCmd(buf, 'echo var2', ['10'])
125
126 " Backtrace movements
127 call RunDbgCmd(buf, 'b', [
128 \ ' 1 function Foo[2]',
129 \ '->0 Bar',
130 \ 'line 3: End of function'])
131
132 " next command cannot go down, we are on bottom
133 call RunDbgCmd(buf, 'down', ['frame is zero'])
134 call RunDbgCmd(buf, 'up')
135
136 " next command cannot go up, we are on top
137 call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
138 call RunDbgCmd(buf, 'where', [
139 \ '->1 function Foo[2]',
140 \ ' 0 Bar',
141 \ 'line 3: End of function'])
142
143 " fil is not frame or finish, it is file
144 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
145
146 " relative backtrace movement
147 call RunDbgCmd(buf, 'fr -1')
148 call RunDbgCmd(buf, 'frame', [
149 \ ' 1 function Foo[2]',
150 \ '->0 Bar',
151 \ 'line 3: End of function'])
152
153 call RunDbgCmd(buf, 'fr +1')
154 call RunDbgCmd(buf, 'fram', [
155 \ '->1 function Foo[2]',
156 \ ' 0 Bar',
157 \ 'line 3: End of function'])
158
159 " go beyond limits does not crash
160 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
161 call RunDbgCmd(buf, 'fra', [
162 \ '->1 function Foo[2]',
163 \ ' 0 Bar',
164 \ 'line 3: End of function'])
165
166 call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
167 call RunDbgCmd(buf, 'fram', [
168 \ ' 1 function Foo[2]',
169 \ '->0 Bar',
170 \ 'line 3: End of function'])
171
172 " final result 19
173 call RunDbgCmd(buf, 'cont', ['19'])
174
175 " breakpoints tests
176
177 " Start a debug session, so that reading the last line from the terminal
178 " works properly.
179 call RunDbgCmd(buf, ':debug echo Foo()')
180
181 " No breakpoints
182 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
183
184 " Place some breakpoints
185 call RunDbgCmd(buf, 'breaka func Bar')
186 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
187 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
188 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
189 \ ' 2 func Bazz line 3'])
190
191 " Check whether the breakpoints are hit
192 call RunDbgCmd(buf, 'cont', [
193 \ 'Breakpoint in "Bar" line 1',
194 \ 'function Foo[2]..Bar',
195 \ 'line 1: let var1 = 2 + a:var'])
196 call RunDbgCmd(buf, 'cont', [
197 \ 'Breakpoint in "Bazz" line 3',
198 \ 'function Foo[2]..Bar[2]..Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200199 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200200
201 " Delete the breakpoints
202 call RunDbgCmd(buf, 'breakd 1')
203 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
204 call RunDbgCmd(buf, 'breakdel func 3 Bazz')
205 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
206
207 call RunDbgCmd(buf, 'cont')
208
209 " Make sure the breakpoints are removed
210 call RunDbgCmd(buf, ':echo Foo()', ['19'])
211
212 " Delete a non-existing breakpoint
213 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
214
215 " Expression breakpoint
216 call RunDbgCmd(buf, ':breakadd func 2 Bazz')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200217 call RunDbgCmd(buf, ':echo Bazz(1)', [
218 \ 'Entering Debug mode. Type "cont" to continue.',
219 \ 'function Bazz',
220 \ 'line 2: let var1 = 3 + a:var'])
221 call RunDbgCmd(buf, 'step')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200222 call RunDbgCmd(buf, 'step')
223 call RunDbgCmd(buf, 'breaka expr var3')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200224 call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
225 \ ' 4 expr var3'])
226 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200227 \ 'Oldval = "''another var''"',
228 \ 'Newval = "''value2''"',
229 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200230 \ 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200231
232 call RunDbgCmd(buf, 'breakdel *')
233 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
234
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200235 " Check for error cases
236 call RunDbgCmd(buf, 'breakadd abcd', [
237 \ 'Error detected while processing function Bazz:',
238 \ 'line 5:',
239 \ 'E475: Invalid argument: abcd'])
240 call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
241 call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
242 call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
243 call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
244 call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
245 call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
246 call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
247 call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
248 call RunDbgCmd(buf, 'breakd expr x', [
249 \ 'E121: Undefined variable: x',
250 \ 'E161: Breakpoint not found: expr x'])
251
Bram Moolenaar113bf062019-04-17 16:54:05 +0200252 " finish the current function
253 call RunDbgCmd(buf, 'finish', [
254 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200255 \ 'line 8: End of function'])
256 call RunDbgCmd(buf, 'cont')
257
258 " Test for :next
259 call RunDbgCmd(buf, ':debug echo Bar(1)')
260 call RunDbgCmd(buf, 'step')
261 call RunDbgCmd(buf, 'next')
262 call RunDbgCmd(buf, '', [
263 \ 'function Bar',
264 \ 'line 3: return var2'])
265 call RunDbgCmd(buf, 'c')
266
267 " Test for :interrupt
268 call RunDbgCmd(buf, ':debug echo Bazz(1)')
269 call RunDbgCmd(buf, 'step')
270 call RunDbgCmd(buf, 'step')
271 call RunDbgCmd(buf, 'interrupt', [
272 \ 'Exception thrown: Vim:Interrupt',
273 \ 'function Bazz',
274 \ 'line 5: catch'])
275 call RunDbgCmd(buf, 'c')
276
277 " Test for :quit
278 call RunDbgCmd(buf, ':debug echo Foo()')
279 call RunDbgCmd(buf, 'breakdel *')
280 call RunDbgCmd(buf, 'breakadd func 3 Foo')
281 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
282 call RunDbgCmd(buf, 'cont', [
283 \ 'Breakpoint in "Bazz" line 3',
284 \ 'function Foo[2]..Bar[2]..Bazz',
285 \ 'line 3: let var3 = "another var"'])
286 call RunDbgCmd(buf, 'quit', [
287 \ 'Breakpoint in "Foo" line 3',
288 \ 'function Foo',
289 \ 'line 3: return var2'])
290 call RunDbgCmd(buf, 'breakdel *')
291 call RunDbgCmd(buf, 'quit')
292 call RunDbgCmd(buf, 'enew! | only!')
293
294 call StopVimInTerminal(buf)
295
296 " Tests for :breakadd file and :breakadd here
297 " Breakpoints should be set before sourcing the file
298
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200299 let lines =<< trim END
300 let var1 = 10
301 let var2 = 20
302 let var3 = 30
303 let var4 = 40
304 END
305 call writefile(lines, 'Xtest.vim')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200306
307 " Start Vim in a terminal
308 let buf = RunVimInTerminal('Xtest.vim', {})
309 call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
310 call RunDbgCmd(buf, ':4 | breakadd here')
311 call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
312 call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200313 call RunDbgCmd(buf, 'cont')
314
315 call StopVimInTerminal(buf)
316
317 call delete('Xtest.vim')
318endfunc