blob: 27826429ea1166c4db9d9017c48854f2f1d63702 [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
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02007CheckRunVimInTerminal
8
9func CheckCWD()
10 " Check that the longer lines don't wrap due to the length of the script name
11 " in cwd
12 let script_len = len( getcwd() .. '/Xtest1.vim' )
13 let longest_line = len( 'Breakpoint in "" line 1' )
14 if script_len > ( 75 - longest_line )
15 throw 'Skipped: Your CWD has too many characters'
16 endif
17endfunc
18command! -nargs=0 -bar CheckCWD call CheckCWD()
19
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020020func CheckDbgOutput(buf, lines, options = {})
21 " Verify the expected output
22 let lnum = 20 - len(a:lines)
23 for l in a:lines
24 if get(a:options, 'match', 'equal') ==# 'pattern'
25 call WaitForAssert({-> assert_match(l, term_getline(a:buf, lnum))}, 200)
26 else
27 call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, 200)
28 endif
29 let lnum += 1
30 endfor
31endfunc
32
Bram Moolenaar113bf062019-04-17 16:54:05 +020033" Run a Vim debugger command
34" If the expected output argument is supplied, then check for it.
35func RunDbgCmd(buf, cmd, ...)
36 call term_sendkeys(a:buf, a:cmd . "\r")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +020037 call TermWait(a:buf)
Bram Moolenaar113bf062019-04-17 16:54:05 +020038
39 if a:0 != 0
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020040 let options = #{match: 'equal'}
41 if a:0 > 1
42 call extend(options, a:2)
43 endif
44 call CheckDbgOutput(a:buf, a:1, options)
Bram Moolenaar113bf062019-04-17 16:54:05 +020045 endif
46endfunc
47
48" Debugger tests
49func Test_Debugger()
Bram Moolenaar113bf062019-04-17 16:54:05 +020050 " Create a Vim script with some functions
Bram Moolenaare7eb9272019-06-24 00:58:07 +020051 let lines =<< trim END
52 func Foo()
53 let var1 = 1
54 let var2 = Bar(var1) + 9
55 return var2
56 endfunc
57 func Bar(var)
58 let var1 = 2 + a:var
59 let var2 = Bazz(var1) + 4
60 return var2
61 endfunc
62 func Bazz(var)
63 try
64 let var1 = 3 + a:var
65 let var3 = "another var"
66 let var3 = "value2"
67 catch
68 let var4 = "exception"
69 endtry
70 return var1
71 endfunc
72 END
73 call writefile(lines, 'Xtest.vim')
Bram Moolenaar113bf062019-04-17 16:54:05 +020074
75 " Start Vim in a terminal
76 let buf = RunVimInTerminal('-S Xtest.vim', {})
77
78 " Start the Vim debugger
Bram Moolenaarddd33082019-06-03 23:07:25 +020079 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020080
81 " Create a few stack frames by stepping through functions
Bram Moolenaarddd33082019-06-03 23:07:25 +020082 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
83 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
84 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
85 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
86 call RunDbgCmd(buf, 'step', ['line 1: try'])
87 call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
88 call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020089
90 " check backtrace
91 call RunDbgCmd(buf, 'backtrace', [
92 \ ' 2 function Foo[2]',
93 \ ' 1 Bar[2]',
94 \ '->0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020095 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020096
97 " Check variables in different stack frames
98 call RunDbgCmd(buf, 'echo var1', ['6'])
99
100 call RunDbgCmd(buf, 'up')
101 call RunDbgCmd(buf, 'back', [
102 \ ' 2 function Foo[2]',
103 \ '->1 Bar[2]',
104 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200105 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200106 call RunDbgCmd(buf, 'echo var1', ['3'])
107
108 call RunDbgCmd(buf, 'u')
109 call RunDbgCmd(buf, 'bt', [
110 \ '->2 function Foo[2]',
111 \ ' 1 Bar[2]',
112 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200113 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200114 call RunDbgCmd(buf, 'echo var1', ['1'])
115
116 " Undefined variables
117 call RunDbgCmd(buf, 'step')
118 call RunDbgCmd(buf, 'frame 2')
119 call RunDbgCmd(buf, 'echo var3', [
120 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200121 \ 'line 4:',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200122 \ 'E121: Undefined variable: var3'])
123
124 " var3 is defined in this level with some other value
125 call RunDbgCmd(buf, 'fr 0')
126 call RunDbgCmd(buf, 'echo var3', ['another var'])
127
128 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200129 call RunDbgCmd(buf, '')
130 call RunDbgCmd(buf, '')
131 call RunDbgCmd(buf, '')
132 call RunDbgCmd(buf, '')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200133 call RunDbgCmd(buf, 'step', [
134 \ 'function Foo[2]..Bar',
135 \ 'line 3: End of function'])
136 call RunDbgCmd(buf, 'up')
137
138 " Undefined var2
139 call RunDbgCmd(buf, 'echo var2', [
140 \ 'Error detected while processing function Foo[2]..Bar:',
141 \ 'line 3:',
142 \ 'E121: Undefined variable: var2'])
143
144 " Var2 is defined with 10
145 call RunDbgCmd(buf, 'down')
146 call RunDbgCmd(buf, 'echo var2', ['10'])
147
148 " Backtrace movements
149 call RunDbgCmd(buf, 'b', [
150 \ ' 1 function Foo[2]',
151 \ '->0 Bar',
152 \ 'line 3: End of function'])
153
154 " next command cannot go down, we are on bottom
155 call RunDbgCmd(buf, 'down', ['frame is zero'])
156 call RunDbgCmd(buf, 'up')
157
158 " next command cannot go up, we are on top
159 call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
160 call RunDbgCmd(buf, 'where', [
161 \ '->1 function Foo[2]',
162 \ ' 0 Bar',
163 \ 'line 3: End of function'])
164
165 " fil is not frame or finish, it is file
166 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
167
168 " relative backtrace movement
169 call RunDbgCmd(buf, 'fr -1')
170 call RunDbgCmd(buf, 'frame', [
171 \ ' 1 function Foo[2]',
172 \ '->0 Bar',
173 \ 'line 3: End of function'])
174
175 call RunDbgCmd(buf, 'fr +1')
176 call RunDbgCmd(buf, 'fram', [
177 \ '->1 function Foo[2]',
178 \ ' 0 Bar',
179 \ 'line 3: End of function'])
180
181 " go beyond limits does not crash
182 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
183 call RunDbgCmd(buf, 'fra', [
184 \ '->1 function Foo[2]',
185 \ ' 0 Bar',
186 \ 'line 3: End of function'])
187
188 call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
189 call RunDbgCmd(buf, 'fram', [
190 \ ' 1 function Foo[2]',
191 \ '->0 Bar',
192 \ 'line 3: End of function'])
193
194 " final result 19
195 call RunDbgCmd(buf, 'cont', ['19'])
196
197 " breakpoints tests
198
199 " Start a debug session, so that reading the last line from the terminal
200 " works properly.
201 call RunDbgCmd(buf, ':debug echo Foo()')
202
203 " No breakpoints
204 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
205
206 " Place some breakpoints
207 call RunDbgCmd(buf, 'breaka func Bar')
208 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
209 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
210 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
211 \ ' 2 func Bazz line 3'])
212
213 " Check whether the breakpoints are hit
214 call RunDbgCmd(buf, 'cont', [
215 \ 'Breakpoint in "Bar" line 1',
216 \ 'function Foo[2]..Bar',
217 \ 'line 1: let var1 = 2 + a:var'])
218 call RunDbgCmd(buf, 'cont', [
219 \ 'Breakpoint in "Bazz" line 3',
220 \ 'function Foo[2]..Bar[2]..Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200221 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200222
223 " Delete the breakpoints
224 call RunDbgCmd(buf, 'breakd 1')
225 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
226 call RunDbgCmd(buf, 'breakdel func 3 Bazz')
227 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
228
229 call RunDbgCmd(buf, 'cont')
230
231 " Make sure the breakpoints are removed
232 call RunDbgCmd(buf, ':echo Foo()', ['19'])
233
234 " Delete a non-existing breakpoint
235 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
236
237 " Expression breakpoint
238 call RunDbgCmd(buf, ':breakadd func 2 Bazz')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200239 call RunDbgCmd(buf, ':echo Bazz(1)', [
240 \ 'Entering Debug mode. Type "cont" to continue.',
241 \ 'function Bazz',
242 \ 'line 2: let var1 = 3 + a:var'])
243 call RunDbgCmd(buf, 'step')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200244 call RunDbgCmd(buf, 'step')
245 call RunDbgCmd(buf, 'breaka expr var3')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200246 call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
247 \ ' 4 expr var3'])
248 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200249 \ 'Oldval = "''another var''"',
250 \ 'Newval = "''value2''"',
251 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200252 \ 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200253
254 call RunDbgCmd(buf, 'breakdel *')
255 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
256
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200257 " Check for error cases
258 call RunDbgCmd(buf, 'breakadd abcd', [
259 \ 'Error detected while processing function Bazz:',
260 \ 'line 5:',
261 \ 'E475: Invalid argument: abcd'])
262 call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
263 call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
264 call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
265 call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
266 call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
267 call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
268 call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
269 call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
270 call RunDbgCmd(buf, 'breakd expr x', [
271 \ 'E121: Undefined variable: x',
272 \ 'E161: Breakpoint not found: expr x'])
273
Bram Moolenaar113bf062019-04-17 16:54:05 +0200274 " finish the current function
275 call RunDbgCmd(buf, 'finish', [
276 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200277 \ 'line 8: End of function'])
278 call RunDbgCmd(buf, 'cont')
279
280 " Test for :next
281 call RunDbgCmd(buf, ':debug echo Bar(1)')
282 call RunDbgCmd(buf, 'step')
283 call RunDbgCmd(buf, 'next')
284 call RunDbgCmd(buf, '', [
285 \ 'function Bar',
286 \ 'line 3: return var2'])
287 call RunDbgCmd(buf, 'c')
288
289 " Test for :interrupt
290 call RunDbgCmd(buf, ':debug echo Bazz(1)')
291 call RunDbgCmd(buf, 'step')
292 call RunDbgCmd(buf, 'step')
293 call RunDbgCmd(buf, 'interrupt', [
294 \ 'Exception thrown: Vim:Interrupt',
295 \ 'function Bazz',
296 \ 'line 5: catch'])
297 call RunDbgCmd(buf, 'c')
298
299 " Test for :quit
300 call RunDbgCmd(buf, ':debug echo Foo()')
301 call RunDbgCmd(buf, 'breakdel *')
302 call RunDbgCmd(buf, 'breakadd func 3 Foo')
303 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
304 call RunDbgCmd(buf, 'cont', [
305 \ 'Breakpoint in "Bazz" line 3',
306 \ 'function Foo[2]..Bar[2]..Bazz',
307 \ 'line 3: let var3 = "another var"'])
308 call RunDbgCmd(buf, 'quit', [
309 \ 'Breakpoint in "Foo" line 3',
310 \ 'function Foo',
311 \ 'line 3: return var2'])
312 call RunDbgCmd(buf, 'breakdel *')
313 call RunDbgCmd(buf, 'quit')
314 call RunDbgCmd(buf, 'enew! | only!')
315
316 call StopVimInTerminal(buf)
317
318 " Tests for :breakadd file and :breakadd here
319 " Breakpoints should be set before sourcing the file
320
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200321 let lines =<< trim END
322 let var1 = 10
323 let var2 = 20
324 let var3 = 30
325 let var4 = 40
326 END
327 call writefile(lines, 'Xtest.vim')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200328
329 " Start Vim in a terminal
330 let buf = RunVimInTerminal('Xtest.vim', {})
331 call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
332 call RunDbgCmd(buf, ':4 | breakadd here')
333 call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
334 call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200335 call RunDbgCmd(buf, 'cont')
336
337 call StopVimInTerminal(buf)
338
339 call delete('Xtest.vim')
340endfunc
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200341
342func Test_Backtrace_Through_Source()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200343 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200344 let file1 =<< trim END
345 func SourceAnotherFile()
346 source Xtest2.vim
347 endfunc
348
349 func CallAFunction()
350 call SourceAnotherFile()
351 call File2Function()
352 endfunc
353
354 func GlobalFunction()
355 call CallAFunction()
356 endfunc
357 END
358 call writefile(file1, 'Xtest1.vim')
359
360 let file2 =<< trim END
361 func DoAThing()
362 echo "DoAThing"
363 endfunc
364
365 func File2Function()
366 call DoAThing()
367 endfunc
368
369 call File2Function()
370 END
371 call writefile(file2, 'Xtest2.vim')
372
373 let buf = RunVimInTerminal('-S Xtest1.vim', {})
374
375 call RunDbgCmd(buf,
376 \ ':debug call GlobalFunction()',
377 \ ['cmd: call GlobalFunction()'])
378 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
379
380 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
381 \ '->0 function GlobalFunction',
382 \ 'line 1: call CallAFunction()'])
383
384 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
385 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
386
387 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
388 \ ' 2 function GlobalFunction[1]',
389 \ ' 1 CallAFunction[1]',
390 \ '->0 SourceAnotherFile',
391 \ 'line 1: source Xtest2.vim'])
392
393 " Step into the 'source' command. Note that we print the full trace all the
394 " way though the source command.
395 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
396 call RunDbgCmd(buf, 'backtrace', [
397 \ '>backtrace',
398 \ ' 3 function GlobalFunction[1]',
399 \ ' 2 CallAFunction[1]',
400 \ ' 1 SourceAnotherFile[1]',
401 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
402 \ 'line 1: func DoAThing()'])
403
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200404 call RunDbgCmd( buf, 'up' )
405 call RunDbgCmd( buf, 'backtrace', [
406 \ '>backtrace',
407 \ ' 3 function GlobalFunction[1]',
408 \ ' 2 CallAFunction[1]',
409 \ '->1 SourceAnotherFile[1]',
410 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
411 \ 'line 1: func DoAThing()' ] )
412
413 call RunDbgCmd( buf, 'up' )
414 call RunDbgCmd( buf, 'backtrace', [
415 \ '>backtrace',
416 \ ' 3 function GlobalFunction[1]',
417 \ '->2 CallAFunction[1]',
418 \ ' 1 SourceAnotherFile[1]',
419 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
420 \ 'line 1: func DoAThing()' ] )
421
422 call RunDbgCmd( buf, 'up' )
423 call RunDbgCmd( buf, 'backtrace', [
424 \ '>backtrace',
425 \ '->3 function GlobalFunction[1]',
426 \ ' 2 CallAFunction[1]',
427 \ ' 1 SourceAnotherFile[1]',
428 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
429 \ 'line 1: func DoAThing()' ] )
430
431 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
432 call RunDbgCmd( buf, 'backtrace', [
433 \ '>backtrace',
434 \ '->3 function GlobalFunction[1]',
435 \ ' 2 CallAFunction[1]',
436 \ ' 1 SourceAnotherFile[1]',
437 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
438 \ 'line 1: func DoAThing()' ] )
439
440 call RunDbgCmd( buf, 'down' )
441 call RunDbgCmd( buf, 'backtrace', [
442 \ '>backtrace',
443 \ ' 3 function GlobalFunction[1]',
444 \ '->2 CallAFunction[1]',
445 \ ' 1 SourceAnotherFile[1]',
446 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
447 \ 'line 1: func DoAThing()' ] )
448
449 call RunDbgCmd( buf, 'down' )
450 call RunDbgCmd( buf, 'backtrace', [
451 \ '>backtrace',
452 \ ' 3 function GlobalFunction[1]',
453 \ ' 2 CallAFunction[1]',
454 \ '->1 SourceAnotherFile[1]',
455 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
456 \ 'line 1: func DoAThing()' ] )
457
458 call RunDbgCmd( buf, 'down' )
459 call RunDbgCmd( buf, 'backtrace', [
460 \ '>backtrace',
461 \ ' 3 function GlobalFunction[1]',
462 \ ' 2 CallAFunction[1]',
463 \ ' 1 SourceAnotherFile[1]',
464 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
465 \ 'line 1: func DoAThing()' ] )
466
467 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
468
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200469 " step until we have another meaninfgul trace
470 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
471 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
472 call RunDbgCmd(buf, 'backtrace', [
473 \ '>backtrace',
474 \ ' 3 function GlobalFunction[1]',
475 \ ' 2 CallAFunction[1]',
476 \ ' 1 SourceAnotherFile[1]',
477 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
478 \ 'line 9: call File2Function()'])
479
480 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
481 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
482 call RunDbgCmd(buf, 'backtrace', [
483 \ '>backtrace',
484 \ ' 5 function GlobalFunction[1]',
485 \ ' 4 CallAFunction[1]',
486 \ ' 3 SourceAnotherFile[1]',
487 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
488 \ ' 1 function File2Function[1]',
489 \ '->0 DoAThing',
490 \ 'line 1: echo "DoAThing"'])
491
492 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
493 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
494 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
495 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
496 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
497 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
498 call RunDbgCmd(buf, 'backtrace', [
499 \ '>backtrace',
500 \ ' 1 function GlobalFunction[1]',
501 \ '->0 CallAFunction',
502 \ 'line 2: call File2Function()'])
503
504 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
505 call RunDbgCmd(buf, 'backtrace', [
506 \ '>backtrace',
507 \ ' 2 function GlobalFunction[1]',
508 \ ' 1 CallAFunction[2]',
509 \ '->0 File2Function',
510 \ 'line 1: call DoAThing()'])
511
512 call StopVimInTerminal(buf)
513 call delete('Xtest1.vim')
514 call delete('Xtest2.vim')
515endfunc
516
517func Test_Backtrace_Autocmd()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200518 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200519 let file1 =<< trim END
520 func SourceAnotherFile()
521 source Xtest2.vim
522 endfunc
523
524 func CallAFunction()
525 call SourceAnotherFile()
526 call File2Function()
527 endfunc
528
529 func GlobalFunction()
530 call CallAFunction()
531 endfunc
532
533 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
534 END
535 call writefile(file1, 'Xtest1.vim')
536
537 let file2 =<< trim END
538 func DoAThing()
539 echo "DoAThing"
540 endfunc
541
542 func File2Function()
543 call DoAThing()
544 endfunc
545
546 call File2Function()
547 END
548 call writefile(file2, 'Xtest2.vim')
549
550 let buf = RunVimInTerminal('-S Xtest1.vim', {})
551
552 call RunDbgCmd(buf,
553 \ ':debug doautocmd User TestGlobalFunction',
554 \ ['cmd: doautocmd User TestGlobalFunction'])
555 call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
556
557 " At this point the ontly thing in the stack is the autocommand
558 call RunDbgCmd(buf, 'backtrace', [
559 \ '>backtrace',
560 \ '->0 User Autocommands for "TestGlobalFunction"',
561 \ 'cmd: call GlobalFunction() | echo "Done"'])
562
563 " And now we're back into the call stack
564 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
565 call RunDbgCmd(buf, 'backtrace', [
566 \ '>backtrace',
567 \ ' 1 User Autocommands for "TestGlobalFunction"',
568 \ '->0 function GlobalFunction',
569 \ 'line 1: call CallAFunction()'])
570
571 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
572 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
573
574 call RunDbgCmd(buf, 'backtrace', [
575 \ '>backtrace',
576 \ ' 3 User Autocommands for "TestGlobalFunction"',
577 \ ' 2 function GlobalFunction[1]',
578 \ ' 1 CallAFunction[1]',
579 \ '->0 SourceAnotherFile',
580 \ 'line 1: source Xtest2.vim'])
581
582 " Step into the 'source' command. Note that we print the full trace all the
583 " way though the source command.
584 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
585 call RunDbgCmd(buf, 'backtrace', [
586 \ '>backtrace',
587 \ ' 4 User Autocommands for "TestGlobalFunction"',
588 \ ' 3 function GlobalFunction[1]',
589 \ ' 2 CallAFunction[1]',
590 \ ' 1 SourceAnotherFile[1]',
591 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
592 \ 'line 1: func DoAThing()'])
593
594 " step until we have another meaninfgul trace
595 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
596 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
597 call RunDbgCmd(buf, 'backtrace', [
598 \ '>backtrace',
599 \ ' 4 User Autocommands for "TestGlobalFunction"',
600 \ ' 3 function GlobalFunction[1]',
601 \ ' 2 CallAFunction[1]',
602 \ ' 1 SourceAnotherFile[1]',
603 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
604 \ 'line 9: call File2Function()'])
605
606 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
607 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
608 call RunDbgCmd(buf, 'backtrace', [
609 \ '>backtrace',
610 \ ' 6 User Autocommands for "TestGlobalFunction"',
611 \ ' 5 function GlobalFunction[1]',
612 \ ' 4 CallAFunction[1]',
613 \ ' 3 SourceAnotherFile[1]',
614 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
615 \ ' 1 function File2Function[1]',
616 \ '->0 DoAThing',
617 \ 'line 1: echo "DoAThing"'])
618
619 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
620 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
621 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
622 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
623 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
624 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
625 call RunDbgCmd(buf, 'backtrace', [
626 \ '>backtrace',
627 \ ' 2 User Autocommands for "TestGlobalFunction"',
628 \ ' 1 function GlobalFunction[1]',
629 \ '->0 CallAFunction',
630 \ 'line 2: call File2Function()'])
631
632 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
633 call RunDbgCmd(buf, 'backtrace', [
634 \ '>backtrace',
635 \ ' 3 User Autocommands for "TestGlobalFunction"',
636 \ ' 2 function GlobalFunction[1]',
637 \ ' 1 CallAFunction[2]',
638 \ '->0 File2Function',
639 \ 'line 1: call DoAThing()'])
640
641
642 " Now unwind so that we get back to the original autocommand (and the second
643 " cmd echo "Done")
644 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
645 call RunDbgCmd(buf, 'backtrace', [
646 \ '>backtrace',
647 \ ' 3 User Autocommands for "TestGlobalFunction"',
648 \ ' 2 function GlobalFunction[1]',
649 \ ' 1 CallAFunction[2]',
650 \ '->0 File2Function',
651 \ 'line 1: End of function'])
652
653 call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
654 call RunDbgCmd(buf, 'backtrace', [
655 \ '>backtrace',
656 \ ' 2 User Autocommands for "TestGlobalFunction"',
657 \ ' 1 function GlobalFunction[1]',
658 \ '->0 CallAFunction',
659 \ 'line 2: End of function'])
660
661 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
662 call RunDbgCmd(buf, 'backtrace', [
663 \ '>backtrace',
664 \ ' 1 User Autocommands for "TestGlobalFunction"',
665 \ '->0 function GlobalFunction',
666 \ 'line 1: End of function'])
667
668 call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
669 call RunDbgCmd(buf, 'backtrace', [
670 \ '>backtrace',
671 \ '->0 User Autocommands for "TestGlobalFunction"',
672 \ 'cmd: echo "Done"'])
673
674 call StopVimInTerminal(buf)
675 call delete('Xtest1.vim')
676 call delete('Xtest2.vim')
677endfunc
678
679func Test_Backtrace_CmdLine()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200680 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200681 let file1 =<< trim END
682 func SourceAnotherFile()
683 source Xtest2.vim
684 endfunc
685
686 func CallAFunction()
687 call SourceAnotherFile()
688 call File2Function()
689 endfunc
690
691 func GlobalFunction()
692 call CallAFunction()
693 endfunc
694
695 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
696 END
697 call writefile(file1, 'Xtest1.vim')
698
699 let file2 =<< trim END
700 func DoAThing()
701 echo "DoAThing"
702 endfunc
703
704 func File2Function()
705 call DoAThing()
706 endfunc
707
708 call File2Function()
709 END
710 call writefile(file2, 'Xtest2.vim')
711
712 let buf = RunVimInTerminal(
713 \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
714 \ {'wait_for_ruler': 0})
715
716 " Need to wait for the vim-in-terminal to be ready
717 call CheckDbgOutput(buf, ['command line',
718 \ 'cmd: call GlobalFunction()'])
719
720 " At this point the ontly thing in the stack is the cmdline
721 call RunDbgCmd(buf, 'backtrace', [
722 \ '>backtrace',
723 \ '->0 command line',
724 \ 'cmd: call GlobalFunction()'])
725
726 " And now we're back into the call stack
727 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
728 call RunDbgCmd(buf, 'backtrace', [
729 \ '>backtrace',
730 \ ' 1 command line',
731 \ '->0 function GlobalFunction',
732 \ 'line 1: call CallAFunction()'])
733
734 call StopVimInTerminal(buf)
735 call delete('Xtest1.vim')
736 call delete('Xtest2.vim')
737endfunc
738
739func Test_Backtrace_DefFunction()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200740 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200741 let file1 =<< trim END
742 vim9script
743 import File2Function from './Xtest2.vim'
744
745 def SourceAnotherFile()
746 source Xtest2.vim
747 enddef
748
749 def CallAFunction()
750 SourceAnotherFile()
751 File2Function()
752 enddef
753
754 def g:GlobalFunction()
755 CallAFunction()
756 enddef
757
758 defcompile
759 END
760 call writefile(file1, 'Xtest1.vim')
761
762 let file2 =<< trim END
763 vim9script
764
765 def DoAThing(): number
766 let a = 100 * 2
767 a += 3
768 return a
769 enddef
770
771 export def File2Function()
772 DoAThing()
773 enddef
774
775 defcompile
776 File2Function()
777 END
778 call writefile(file2, 'Xtest2.vim')
779
780 let buf = RunVimInTerminal('-S Xtest1.vim', {})
781
782 call RunDbgCmd(buf,
783 \ ':debug call GlobalFunction()',
784 \ ['cmd: call GlobalFunction()'])
785
786 " FIXME: Vim9 lines are not debugged!
787 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
788
789 " But they do appear in the backtrace
790 call RunDbgCmd(buf, 'backtrace', [
791 \ '\V>backtrace',
792 \ '\V 2 function GlobalFunction[1]',
793 \ '\V 1 <SNR>\.\*_CallAFunction[1]',
794 \ '\V->0 <SNR>\.\*_SourceAnotherFile',
795 \ '\Vline 1: source Xtest2.vim'],
796 \ #{match: 'pattern'})
797
798
799 call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
800 call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
801 call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
802 call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
803 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
804 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
805 call RunDbgCmd(buf, 'backtrace', [
806 \ '\V>backtrace',
807 \ '\V 3 function GlobalFunction[1]',
808 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
809 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
810 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
811 \ '\Vline 14: File2Function()'],
812 \ #{match: 'pattern'})
813
814 " Don't step into compiled functions...
815 call RunDbgCmd(buf, 'step', ['line 15: End of sourced file'])
816 call RunDbgCmd(buf, 'backtrace', [
817 \ '\V>backtrace',
818 \ '\V 3 function GlobalFunction[1]',
819 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
820 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
821 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
822 \ '\Vline 15: End of sourced file'],
823 \ #{match: 'pattern'})
824
825
826 call StopVimInTerminal(buf)
827 call delete('Xtest1.vim')
828 call delete('Xtest2.vim')
829endfunc
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200830
831func Test_debug_backtrace_level()
832 CheckCWD
833 let lines =<< trim END
834 let s:file1_var = 'file1'
835 let g:global_var = 'global'
836
837 func s:File1Func( arg )
838 let s:file1_var .= a:arg
839 let local_var = s:file1_var .. ' test1'
840 let g:global_var .= local_var
841 source Xtest2.vim
842 endfunc
843
844 call s:File1Func( 'arg1' )
845 END
846 call writefile(lines, 'Xtest1.vim')
847
848 let lines =<< trim END
849 let s:file2_var = 'file2'
850
851 func s:File2Func( arg )
852 let s:file2_var .= a:arg
853 let local_var = s:file2_var .. ' test2'
854 let g:global_var .= local_var
855 endfunc
856
857 call s:File2Func( 'arg2' )
858 END
859 call writefile(lines, 'Xtest2.vim')
860
861 let file1 = getcwd() .. '/Xtest1.vim'
862 let file2 = getcwd() .. '/Xtest2.vim'
863
864 " set a breakpoint and source file1.vim
865 let buf = RunVimInTerminal(
866 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
867 \ #{ wait_for_ruler: 0 } )
868
869 call CheckDbgOutput(buf, [
870 \ 'Breakpoint in "' .. file1 .. '" line 1',
871 \ 'Entering Debug mode. Type "cont" to continue.',
872 \ 'command line..script ' .. file1,
873 \ 'line 1: let s:file1_var = ''file1'''
874 \ ])
875
876 " step throught the initial declarations
877 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
878 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
879 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
880 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
881 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
882
883 " step in to the first function
884 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
885 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
886 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
887 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
888 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
889 call RunDbgCmd(buf,
890 \'echo global_var',
891 \[ 'E121: Undefined variable: global_var' ] )
892 call RunDbgCmd(buf,
893 \'echo local_var',
894 \[ 'E121: Undefined variable: local_var' ] )
895 call RunDbgCmd(buf,
896 \'echo l:local_var',
897 \[ 'E121: Undefined variable: l:local_var' ] )
898
899 " backtrace up
900 call RunDbgCmd(buf, 'backtrace', [
901 \ '\V>backtrace',
902 \ '\V 2 command line',
903 \ '\V 1 script ' .. file1 .. '[11]',
904 \ '\V->0 function <SNR>\.\*_File1Func',
905 \ '\Vline 1: let s:file1_var .= a:arg',
906 \ ],
907 \ #{ match: 'pattern' } )
908 call RunDbgCmd(buf, 'up', [ '>up' ] )
909
910 call RunDbgCmd(buf, 'backtrace', [
911 \ '\V>backtrace',
912 \ '\V 2 command line',
913 \ '\V->1 script ' .. file1 .. '[11]',
914 \ '\V 0 function <SNR>\.\*_File1Func',
915 \ '\Vline 1: let s:file1_var .= a:arg',
916 \ ],
917 \ #{ match: 'pattern' } )
918
919 " Expression evaluation in the script frame (not the function frame)
920 " FIXME: Unexpected in this scope (a: should not be visibnle)
921 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
922 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
923 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
924 " FIXME: Unexpected in this scope (global should be found)
925 call RunDbgCmd(buf,
926 \'echo global_var',
927 \[ 'E121: Undefined variable: global_var' ] )
928 call RunDbgCmd(buf,
929 \'echo local_var',
930 \[ 'E121: Undefined variable: local_var' ] )
931 call RunDbgCmd(buf,
932 \'echo l:local_var',
933 \[ 'E121: Undefined variable: l:local_var' ] )
934
935
936 " step while backtraced jumps to the latest frame
937 call RunDbgCmd(buf, 'step', [
938 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
939 call RunDbgCmd(buf, 'backtrace', [
940 \ '\V>backtrace',
941 \ '\V 2 command line',
942 \ '\V 1 script ' .. file1 .. '[11]',
943 \ '\V->0 function <SNR>\.\*_File1Func',
944 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
945 \ ],
946 \ #{ match: 'pattern' } )
947
948 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
949 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
950 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
951
952 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
953 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
954 call RunDbgCmd(buf, 'backtrace', [
955 \ '\V>backtrace',
956 \ '\V 3 command line',
957 \ '\V 2 script ' .. file1 .. '[11]',
958 \ '\V 1 function <SNR>\.\*_File1Func[4]',
959 \ '\V->0 script ' .. file2,
960 \ '\Vline 1: let s:file2_var = ''file2''',
961 \ ],
962 \ #{ match: 'pattern' } )
963
964 " Expression evaluation in the script frame file2 (not the function frame)
965 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
966 call RunDbgCmd(buf,
967 \ 'echo s:file1_var',
968 \ [ 'E121: Undefined variable: s:file1_var' ] )
969 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
970 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
971 call RunDbgCmd(buf,
972 \'echo local_var',
973 \[ 'E121: Undefined variable: local_var' ] )
974 call RunDbgCmd(buf,
975 \'echo l:local_var',
976 \[ 'E121: Undefined variable: l:local_var' ] )
977 call RunDbgCmd(buf,
978 \ 'echo s:file2_var',
979 \ [ 'E121: Undefined variable: s:file2_var' ] )
980
981 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
982 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
983
984 " Up the stack to the other script context
985 call RunDbgCmd(buf, 'up')
986 call RunDbgCmd(buf, 'backtrace', [
987 \ '\V>backtrace',
988 \ '\V 3 command line',
989 \ '\V 2 script ' .. file1 .. '[11]',
990 \ '\V->1 function <SNR>\.\*_File1Func[4]',
991 \ '\V 0 script ' .. file2,
992 \ '\Vline 3: func s:File2Func( arg )',
993 \ ],
994 \ #{ match: 'pattern' } )
995 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
996 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
997 call RunDbgCmd(buf,
998 \ 'echo l:local_var',
999 \ [ 'E121: Undefined variable: l:local_var' ] )
1000
1001 call RunDbgCmd(buf, 'up')
1002 call RunDbgCmd(buf, 'backtrace', [
1003 \ '\V>backtrace',
1004 \ '\V 3 command line',
1005 \ '\V->2 script ' .. file1 .. '[11]',
1006 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1007 \ '\V 0 script ' .. file2,
1008 \ '\Vline 3: func s:File2Func( arg )',
1009 \ ],
1010 \ #{ match: 'pattern' } )
1011
1012 " FIXME: Unexpected (wrong script vars are used)
1013 call RunDbgCmd(buf,
1014 \ 'echo s:file1_var',
1015 \ [ 'E121: Undefined variable: s:file1_var' ] )
1016 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1017
1018 call StopVimInTerminal(buf)
1019 call delete('Xtest1.vim')
1020 call delete('Xtest2.vim')
1021endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001022
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001023" Test for setting a breakpoint on a :endif where the :if condition is false
1024" and then quit the script. This should generate an interrupt.
1025func Test_breakpt_endif_intr()
1026 func F()
1027 let g:Xpath ..= 'a'
1028 if v:false
1029 let g:Xpath ..= 'b'
1030 endif
1031 invalid_command
1032 endfunc
1033
1034 let g:Xpath = ''
1035 breakadd func 4 F
1036 try
1037 let caught_intr = 0
1038 debuggreedy
1039 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
1040 call F()
1041 catch /^Vim:Interrupt$/
1042 call assert_match('\.F, line 4', v:throwpoint)
1043 let caught_intr = 1
1044 endtry
1045 0debuggreedy
1046 call assert_equal(1, caught_intr)
1047 call assert_equal('a', g:Xpath)
1048 breakdel *
1049 delfunc F
1050endfunc
1051
1052" Test for setting a breakpoint on a :else where the :if condition is false
1053" and then quit the script. This should generate an interrupt.
1054func Test_breakpt_else_intr()
1055 func F()
1056 let g:Xpath ..= 'a'
1057 if v:false
1058 let g:Xpath ..= 'b'
1059 else
1060 invalid_command
1061 endif
1062 invalid_command
1063 endfunc
1064
1065 let g:Xpath = ''
1066 breakadd func 4 F
1067 try
1068 let caught_intr = 0
1069 debuggreedy
1070 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
1071 call F()
1072 catch /^Vim:Interrupt$/
1073 call assert_match('\.F, line 4', v:throwpoint)
1074 let caught_intr = 1
1075 endtry
1076 0debuggreedy
1077 call assert_equal(1, caught_intr)
1078 call assert_equal('a', g:Xpath)
1079 breakdel *
1080 delfunc F
1081endfunc
1082
1083" Test for setting a breakpoint on a :endwhile where the :while condition is
1084" false and then quit the script. This should generate an interrupt.
1085func Test_breakpt_endwhile_intr()
1086 func F()
1087 let g:Xpath ..= 'a'
1088 while v:false
1089 let g:Xpath ..= 'b'
1090 endwhile
1091 invalid_command
1092 endfunc
1093
1094 let g:Xpath = ''
1095 breakadd func 4 F
1096 try
1097 let caught_intr = 0
1098 debuggreedy
1099 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
1100 call F()
1101 catch /^Vim:Interrupt$/
1102 call assert_match('\.F, line 4', v:throwpoint)
1103 let caught_intr = 1
1104 endtry
1105 0debuggreedy
1106 call assert_equal(1, caught_intr)
1107 call assert_equal('a', g:Xpath)
1108 breakdel *
1109 delfunc F
1110endfunc
1111
1112" Test for setting a breakpoint on an :endtry where an exception is pending to
1113" be processed and then quit the script. This should generate an interrupt and
1114" the thrown exception should be ignored.
1115func Test_breakpt_endtry_intr()
1116 func F()
1117 try
1118 let g:Xpath ..= 'a'
1119 throw "abc"
1120 endtry
1121 invalid_command
1122 endfunc
1123
1124 let g:Xpath = ''
1125 breakadd func 4 F
1126 try
1127 let caught_intr = 0
1128 let caught_abc = 0
1129 debuggreedy
1130 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
1131 call F()
1132 catch /abc/
1133 let caught_abc = 1
1134 catch /^Vim:Interrupt$/
1135 call assert_match('\.F, line 4', v:throwpoint)
1136 let caught_intr = 1
1137 endtry
1138 0debuggreedy
1139 call assert_equal(1, caught_intr)
1140 call assert_equal(0, caught_abc)
1141 call assert_equal('a', g:Xpath)
1142 breakdel *
1143 delfunc F
1144endfunc
1145
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001146" vim: shiftwidth=2 sts=2 expandtab