blob: a99154a5af19c9ff30a341a260053b04f3a85aff [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
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02005source check.vim
Bram Moolenaar113bf062019-04-17 16:54:05 +02006
7" Run a Vim debugger command
8" If the expected output argument is supplied, then check for it.
9func RunDbgCmd(buf, cmd, ...)
10 call term_sendkeys(a:buf, a:cmd . "\r")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +020011 call TermWait(a:buf)
Bram Moolenaar113bf062019-04-17 16:54:05 +020012
13 if a:0 != 0
14 " Verify the expected output
15 let lnum = 20 - len(a:1)
16 for l in a:1
Bram Moolenaar1a47ae32019-12-29 23:04:25 +010017 call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, 200)
Bram Moolenaar113bf062019-04-17 16:54:05 +020018 let lnum += 1
19 endfor
20 endif
21endfunc
22
23" Debugger tests
24func Test_Debugger()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +020025 CheckRunVimInTerminal
Bram Moolenaar113bf062019-04-17 16:54:05 +020026
27 " Create a Vim script with some functions
Bram Moolenaare7eb9272019-06-24 00:58:07 +020028 let lines =<< trim END
29 func Foo()
30 let var1 = 1
31 let var2 = Bar(var1) + 9
32 return var2
33 endfunc
34 func Bar(var)
35 let var1 = 2 + a:var
36 let var2 = Bazz(var1) + 4
37 return var2
38 endfunc
39 func Bazz(var)
40 try
41 let var1 = 3 + a:var
42 let var3 = "another var"
43 let var3 = "value2"
44 catch
45 let var4 = "exception"
46 endtry
47 return var1
48 endfunc
49 END
50 call writefile(lines, 'Xtest.vim')
Bram Moolenaar113bf062019-04-17 16:54:05 +020051
52 " Start Vim in a terminal
53 let buf = RunVimInTerminal('-S Xtest.vim', {})
54
55 " Start the Vim debugger
Bram Moolenaarddd33082019-06-03 23:07:25 +020056 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020057
58 " Create a few stack frames by stepping through functions
Bram Moolenaarddd33082019-06-03 23:07:25 +020059 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
60 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
61 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
62 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
63 call RunDbgCmd(buf, 'step', ['line 1: try'])
64 call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
65 call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020066
67 " check backtrace
68 call RunDbgCmd(buf, 'backtrace', [
69 \ ' 2 function Foo[2]',
70 \ ' 1 Bar[2]',
71 \ '->0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020072 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020073
74 " Check variables in different stack frames
75 call RunDbgCmd(buf, 'echo var1', ['6'])
76
77 call RunDbgCmd(buf, 'up')
78 call RunDbgCmd(buf, 'back', [
79 \ ' 2 function Foo[2]',
80 \ '->1 Bar[2]',
81 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020082 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020083 call RunDbgCmd(buf, 'echo var1', ['3'])
84
85 call RunDbgCmd(buf, 'u')
86 call RunDbgCmd(buf, 'bt', [
87 \ '->2 function Foo[2]',
88 \ ' 1 Bar[2]',
89 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020090 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020091 call RunDbgCmd(buf, 'echo var1', ['1'])
92
93 " Undefined variables
94 call RunDbgCmd(buf, 'step')
95 call RunDbgCmd(buf, 'frame 2')
96 call RunDbgCmd(buf, 'echo var3', [
97 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020098 \ 'line 4:',
Bram Moolenaar113bf062019-04-17 16:54:05 +020099 \ 'E121: Undefined variable: var3'])
100
101 " var3 is defined in this level with some other value
102 call RunDbgCmd(buf, 'fr 0')
103 call RunDbgCmd(buf, 'echo var3', ['another var'])
104
105 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200106 call RunDbgCmd(buf, '')
107 call RunDbgCmd(buf, '')
108 call RunDbgCmd(buf, '')
109 call RunDbgCmd(buf, '')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200110 call RunDbgCmd(buf, 'step', [
111 \ 'function Foo[2]..Bar',
112 \ 'line 3: End of function'])
113 call RunDbgCmd(buf, 'up')
114
115 " Undefined var2
116 call RunDbgCmd(buf, 'echo var2', [
117 \ 'Error detected while processing function Foo[2]..Bar:',
118 \ 'line 3:',
119 \ 'E121: Undefined variable: var2'])
120
121 " Var2 is defined with 10
122 call RunDbgCmd(buf, 'down')
123 call RunDbgCmd(buf, 'echo var2', ['10'])
124
125 " Backtrace movements
126 call RunDbgCmd(buf, 'b', [
127 \ ' 1 function Foo[2]',
128 \ '->0 Bar',
129 \ 'line 3: End of function'])
130
131 " next command cannot go down, we are on bottom
132 call RunDbgCmd(buf, 'down', ['frame is zero'])
133 call RunDbgCmd(buf, 'up')
134
135 " next command cannot go up, we are on top
136 call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
137 call RunDbgCmd(buf, 'where', [
138 \ '->1 function Foo[2]',
139 \ ' 0 Bar',
140 \ 'line 3: End of function'])
141
142 " fil is not frame or finish, it is file
143 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
144
145 " relative backtrace movement
146 call RunDbgCmd(buf, 'fr -1')
147 call RunDbgCmd(buf, 'frame', [
148 \ ' 1 function Foo[2]',
149 \ '->0 Bar',
150 \ 'line 3: End of function'])
151
152 call RunDbgCmd(buf, 'fr +1')
153 call RunDbgCmd(buf, 'fram', [
154 \ '->1 function Foo[2]',
155 \ ' 0 Bar',
156 \ 'line 3: End of function'])
157
158 " go beyond limits does not crash
159 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
160 call RunDbgCmd(buf, 'fra', [
161 \ '->1 function Foo[2]',
162 \ ' 0 Bar',
163 \ 'line 3: End of function'])
164
165 call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
166 call RunDbgCmd(buf, 'fram', [
167 \ ' 1 function Foo[2]',
168 \ '->0 Bar',
169 \ 'line 3: End of function'])
170
171 " final result 19
172 call RunDbgCmd(buf, 'cont', ['19'])
173
174 " breakpoints tests
175
176 " Start a debug session, so that reading the last line from the terminal
177 " works properly.
178 call RunDbgCmd(buf, ':debug echo Foo()')
179
180 " No breakpoints
181 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
182
183 " Place some breakpoints
184 call RunDbgCmd(buf, 'breaka func Bar')
185 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
186 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
187 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
188 \ ' 2 func Bazz line 3'])
189
190 " Check whether the breakpoints are hit
191 call RunDbgCmd(buf, 'cont', [
192 \ 'Breakpoint in "Bar" line 1',
193 \ 'function Foo[2]..Bar',
194 \ 'line 1: let var1 = 2 + a:var'])
195 call RunDbgCmd(buf, 'cont', [
196 \ 'Breakpoint in "Bazz" line 3',
197 \ 'function Foo[2]..Bar[2]..Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200198 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200199
200 " Delete the breakpoints
201 call RunDbgCmd(buf, 'breakd 1')
202 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
203 call RunDbgCmd(buf, 'breakdel func 3 Bazz')
204 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
205
206 call RunDbgCmd(buf, 'cont')
207
208 " Make sure the breakpoints are removed
209 call RunDbgCmd(buf, ':echo Foo()', ['19'])
210
211 " Delete a non-existing breakpoint
212 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
213
214 " Expression breakpoint
215 call RunDbgCmd(buf, ':breakadd func 2 Bazz')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200216 call RunDbgCmd(buf, ':echo Bazz(1)', [
217 \ 'Entering Debug mode. Type "cont" to continue.',
218 \ 'function Bazz',
219 \ 'line 2: let var1 = 3 + a:var'])
220 call RunDbgCmd(buf, 'step')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200221 call RunDbgCmd(buf, 'step')
222 call RunDbgCmd(buf, 'breaka expr var3')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200223 call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
224 \ ' 4 expr var3'])
225 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200226 \ 'Oldval = "''another var''"',
227 \ 'Newval = "''value2''"',
228 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200229 \ 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200230
231 call RunDbgCmd(buf, 'breakdel *')
232 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
233
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200234 " Check for error cases
235 call RunDbgCmd(buf, 'breakadd abcd', [
236 \ 'Error detected while processing function Bazz:',
237 \ 'line 5:',
238 \ 'E475: Invalid argument: abcd'])
239 call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
240 call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
241 call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
242 call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
243 call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
244 call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
245 call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
246 call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
247 call RunDbgCmd(buf, 'breakd expr x', [
248 \ 'E121: Undefined variable: x',
249 \ 'E161: Breakpoint not found: expr x'])
250
Bram Moolenaar113bf062019-04-17 16:54:05 +0200251 " finish the current function
252 call RunDbgCmd(buf, 'finish', [
253 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200254 \ 'line 8: End of function'])
255 call RunDbgCmd(buf, 'cont')
256
257 " Test for :next
258 call RunDbgCmd(buf, ':debug echo Bar(1)')
259 call RunDbgCmd(buf, 'step')
260 call RunDbgCmd(buf, 'next')
261 call RunDbgCmd(buf, '', [
262 \ 'function Bar',
263 \ 'line 3: return var2'])
264 call RunDbgCmd(buf, 'c')
265
266 " Test for :interrupt
267 call RunDbgCmd(buf, ':debug echo Bazz(1)')
268 call RunDbgCmd(buf, 'step')
269 call RunDbgCmd(buf, 'step')
270 call RunDbgCmd(buf, 'interrupt', [
271 \ 'Exception thrown: Vim:Interrupt',
272 \ 'function Bazz',
273 \ 'line 5: catch'])
274 call RunDbgCmd(buf, 'c')
275
276 " Test for :quit
277 call RunDbgCmd(buf, ':debug echo Foo()')
278 call RunDbgCmd(buf, 'breakdel *')
279 call RunDbgCmd(buf, 'breakadd func 3 Foo')
280 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
281 call RunDbgCmd(buf, 'cont', [
282 \ 'Breakpoint in "Bazz" line 3',
283 \ 'function Foo[2]..Bar[2]..Bazz',
284 \ 'line 3: let var3 = "another var"'])
285 call RunDbgCmd(buf, 'quit', [
286 \ 'Breakpoint in "Foo" line 3',
287 \ 'function Foo',
288 \ 'line 3: return var2'])
289 call RunDbgCmd(buf, 'breakdel *')
290 call RunDbgCmd(buf, 'quit')
291 call RunDbgCmd(buf, 'enew! | only!')
292
293 call StopVimInTerminal(buf)
294
295 " Tests for :breakadd file and :breakadd here
296 " Breakpoints should be set before sourcing the file
297
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200298 let lines =<< trim END
299 let var1 = 10
300 let var2 = 20
301 let var3 = 30
302 let var4 = 40
303 END
304 call writefile(lines, 'Xtest.vim')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200305
306 " Start Vim in a terminal
307 let buf = RunVimInTerminal('Xtest.vim', {})
308 call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
309 call RunDbgCmd(buf, ':4 | breakadd here')
310 call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
311 call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200312 call RunDbgCmd(buf, 'cont')
313
314 call StopVimInTerminal(buf)
315
316 call delete('Xtest.vim')
317endfunc