blob: 659c7a81d552e36990791e0090e07ce7a03062be [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 Moolenaar18dc3552020-11-22 14:24:00 +010020" "options" argument can contain:
21" 'msec' - time to wait for a match
22" 'match' - "pattern" to use "lines" as pattern instead of text
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020023func CheckDbgOutput(buf, lines, options = {})
24 " Verify the expected output
25 let lnum = 20 - len(a:lines)
Bram Moolenaar18dc3552020-11-22 14:24:00 +010026 let msec = get(a:options, 'msec', 1000)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020027 for l in a:lines
28 if get(a:options, 'match', 'equal') ==# 'pattern'
Bram Moolenaar18dc3552020-11-22 14:24:00 +010029 call WaitForAssert({-> assert_match(l, term_getline(a:buf, lnum))}, msec)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020030 else
Bram Moolenaar18dc3552020-11-22 14:24:00 +010031 call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, msec)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020032 endif
33 let lnum += 1
34 endfor
35endfunc
36
Bram Moolenaar113bf062019-04-17 16:54:05 +020037" Run a Vim debugger command
38" If the expected output argument is supplied, then check for it.
39func RunDbgCmd(buf, cmd, ...)
40 call term_sendkeys(a:buf, a:cmd . "\r")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +020041 call TermWait(a:buf)
Bram Moolenaar113bf062019-04-17 16:54:05 +020042
43 if a:0 != 0
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020044 let options = #{match: 'equal'}
45 if a:0 > 1
46 call extend(options, a:2)
47 endif
48 call CheckDbgOutput(a:buf, a:1, options)
Bram Moolenaar113bf062019-04-17 16:54:05 +020049 endif
50endfunc
51
52" Debugger tests
53func Test_Debugger()
Bram Moolenaar113bf062019-04-17 16:54:05 +020054 " Create a Vim script with some functions
Bram Moolenaare7eb9272019-06-24 00:58:07 +020055 let lines =<< trim END
56 func Foo()
57 let var1 = 1
58 let var2 = Bar(var1) + 9
59 return var2
60 endfunc
61 func Bar(var)
62 let var1 = 2 + a:var
63 let var2 = Bazz(var1) + 4
64 return var2
65 endfunc
66 func Bazz(var)
67 try
68 let var1 = 3 + a:var
69 let var3 = "another var"
70 let var3 = "value2"
71 catch
72 let var4 = "exception"
73 endtry
74 return var1
75 endfunc
76 END
77 call writefile(lines, 'Xtest.vim')
Bram Moolenaar113bf062019-04-17 16:54:05 +020078
79 " Start Vim in a terminal
80 let buf = RunVimInTerminal('-S Xtest.vim', {})
81
82 " Start the Vim debugger
Bram Moolenaarddd33082019-06-03 23:07:25 +020083 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020084
85 " Create a few stack frames by stepping through functions
Bram Moolenaarddd33082019-06-03 23:07:25 +020086 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
87 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
88 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
89 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
90 call RunDbgCmd(buf, 'step', ['line 1: try'])
91 call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
92 call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020093
94 " check backtrace
95 call RunDbgCmd(buf, 'backtrace', [
96 \ ' 2 function Foo[2]',
97 \ ' 1 Bar[2]',
98 \ '->0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020099 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200100
101 " Check variables in different stack frames
102 call RunDbgCmd(buf, 'echo var1', ['6'])
103
104 call RunDbgCmd(buf, 'up')
105 call RunDbgCmd(buf, 'back', [
106 \ ' 2 function Foo[2]',
107 \ '->1 Bar[2]',
108 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200109 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200110 call RunDbgCmd(buf, 'echo var1', ['3'])
111
112 call RunDbgCmd(buf, 'u')
113 call RunDbgCmd(buf, 'bt', [
114 \ '->2 function Foo[2]',
115 \ ' 1 Bar[2]',
116 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200117 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200118 call RunDbgCmd(buf, 'echo var1', ['1'])
119
120 " Undefined variables
121 call RunDbgCmd(buf, 'step')
122 call RunDbgCmd(buf, 'frame 2')
123 call RunDbgCmd(buf, 'echo var3', [
124 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200125 \ 'line 4:',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200126 \ 'E121: Undefined variable: var3'])
127
128 " var3 is defined in this level with some other value
129 call RunDbgCmd(buf, 'fr 0')
130 call RunDbgCmd(buf, 'echo var3', ['another var'])
131
132 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200133 call RunDbgCmd(buf, '')
134 call RunDbgCmd(buf, '')
135 call RunDbgCmd(buf, '')
136 call RunDbgCmd(buf, '')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200137 call RunDbgCmd(buf, 'step', [
138 \ 'function Foo[2]..Bar',
139 \ 'line 3: End of function'])
140 call RunDbgCmd(buf, 'up')
141
142 " Undefined var2
143 call RunDbgCmd(buf, 'echo var2', [
144 \ 'Error detected while processing function Foo[2]..Bar:',
145 \ 'line 3:',
146 \ 'E121: Undefined variable: var2'])
147
148 " Var2 is defined with 10
149 call RunDbgCmd(buf, 'down')
150 call RunDbgCmd(buf, 'echo var2', ['10'])
151
152 " Backtrace movements
153 call RunDbgCmd(buf, 'b', [
154 \ ' 1 function Foo[2]',
155 \ '->0 Bar',
156 \ 'line 3: End of function'])
157
158 " next command cannot go down, we are on bottom
159 call RunDbgCmd(buf, 'down', ['frame is zero'])
160 call RunDbgCmd(buf, 'up')
161
162 " next command cannot go up, we are on top
163 call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
164 call RunDbgCmd(buf, 'where', [
165 \ '->1 function Foo[2]',
166 \ ' 0 Bar',
167 \ 'line 3: End of function'])
168
169 " fil is not frame or finish, it is file
170 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
171
172 " relative backtrace movement
173 call RunDbgCmd(buf, 'fr -1')
174 call RunDbgCmd(buf, 'frame', [
175 \ ' 1 function Foo[2]',
176 \ '->0 Bar',
177 \ 'line 3: End of function'])
178
179 call RunDbgCmd(buf, 'fr +1')
180 call RunDbgCmd(buf, 'fram', [
181 \ '->1 function Foo[2]',
182 \ ' 0 Bar',
183 \ 'line 3: End of function'])
184
185 " go beyond limits does not crash
186 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
187 call RunDbgCmd(buf, 'fra', [
188 \ '->1 function Foo[2]',
189 \ ' 0 Bar',
190 \ 'line 3: End of function'])
191
192 call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
193 call RunDbgCmd(buf, 'fram', [
194 \ ' 1 function Foo[2]',
195 \ '->0 Bar',
196 \ 'line 3: End of function'])
197
198 " final result 19
199 call RunDbgCmd(buf, 'cont', ['19'])
200
201 " breakpoints tests
202
203 " Start a debug session, so that reading the last line from the terminal
204 " works properly.
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100205 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200206
207 " No breakpoints
208 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
209
210 " Place some breakpoints
211 call RunDbgCmd(buf, 'breaka func Bar')
212 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
213 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
214 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
215 \ ' 2 func Bazz line 3'])
216
217 " Check whether the breakpoints are hit
218 call RunDbgCmd(buf, 'cont', [
219 \ 'Breakpoint in "Bar" line 1',
220 \ 'function Foo[2]..Bar',
221 \ 'line 1: let var1 = 2 + a:var'])
222 call RunDbgCmd(buf, 'cont', [
223 \ 'Breakpoint in "Bazz" line 3',
224 \ 'function Foo[2]..Bar[2]..Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200225 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200226
227 " Delete the breakpoints
228 call RunDbgCmd(buf, 'breakd 1')
229 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
230 call RunDbgCmd(buf, 'breakdel func 3 Bazz')
231 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
232
233 call RunDbgCmd(buf, 'cont')
234
235 " Make sure the breakpoints are removed
236 call RunDbgCmd(buf, ':echo Foo()', ['19'])
237
238 " Delete a non-existing breakpoint
239 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
240
241 " Expression breakpoint
242 call RunDbgCmd(buf, ':breakadd func 2 Bazz')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200243 call RunDbgCmd(buf, ':echo Bazz(1)', [
244 \ 'Entering Debug mode. Type "cont" to continue.',
245 \ 'function Bazz',
246 \ 'line 2: let var1 = 3 + a:var'])
247 call RunDbgCmd(buf, 'step')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200248 call RunDbgCmd(buf, 'step')
249 call RunDbgCmd(buf, 'breaka expr var3')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200250 call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
251 \ ' 4 expr var3'])
252 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200253 \ 'Oldval = "''another var''"',
254 \ 'Newval = "''value2''"',
255 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200256 \ 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200257
258 call RunDbgCmd(buf, 'breakdel *')
259 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
260
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200261 " Check for error cases
262 call RunDbgCmd(buf, 'breakadd abcd', [
263 \ 'Error detected while processing function Bazz:',
264 \ 'line 5:',
265 \ 'E475: Invalid argument: abcd'])
266 call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
267 call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
268 call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
269 call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
270 call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
271 call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
272 call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
273 call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
Bram Moolenaar0325d392021-09-09 12:34:19 +0200274 call RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x'])
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200275
Bram Moolenaar113bf062019-04-17 16:54:05 +0200276 " finish the current function
277 call RunDbgCmd(buf, 'finish', [
278 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200279 \ 'line 8: End of function'])
280 call RunDbgCmd(buf, 'cont')
281
282 " Test for :next
283 call RunDbgCmd(buf, ':debug echo Bar(1)')
284 call RunDbgCmd(buf, 'step')
285 call RunDbgCmd(buf, 'next')
286 call RunDbgCmd(buf, '', [
287 \ 'function Bar',
288 \ 'line 3: return var2'])
289 call RunDbgCmd(buf, 'c')
290
291 " Test for :interrupt
292 call RunDbgCmd(buf, ':debug echo Bazz(1)')
293 call RunDbgCmd(buf, 'step')
294 call RunDbgCmd(buf, 'step')
295 call RunDbgCmd(buf, 'interrupt', [
296 \ 'Exception thrown: Vim:Interrupt',
297 \ 'function Bazz',
298 \ 'line 5: catch'])
299 call RunDbgCmd(buf, 'c')
300
301 " Test for :quit
302 call RunDbgCmd(buf, ':debug echo Foo()')
303 call RunDbgCmd(buf, 'breakdel *')
304 call RunDbgCmd(buf, 'breakadd func 3 Foo')
305 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
306 call RunDbgCmd(buf, 'cont', [
307 \ 'Breakpoint in "Bazz" line 3',
308 \ 'function Foo[2]..Bar[2]..Bazz',
309 \ 'line 3: let var3 = "another var"'])
310 call RunDbgCmd(buf, 'quit', [
311 \ 'Breakpoint in "Foo" line 3',
312 \ 'function Foo',
313 \ 'line 3: return var2'])
314 call RunDbgCmd(buf, 'breakdel *')
315 call RunDbgCmd(buf, 'quit')
316 call RunDbgCmd(buf, 'enew! | only!')
317
318 call StopVimInTerminal(buf)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200319endfunc
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200320
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200321func Test_Debugger_breakadd()
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200322 " Tests for :breakadd file and :breakadd here
323 " Breakpoints should be set before sourcing the file
324
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200325 let lines =<< trim END
326 let var1 = 10
327 let var2 = 20
328 let var3 = 30
329 let var4 = 40
330 END
331 call writefile(lines, 'Xtest.vim')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200332
333 " Start Vim in a terminal
334 let buf = RunVimInTerminal('Xtest.vim', {})
335 call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
336 call RunDbgCmd(buf, ':4 | breakadd here')
337 call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
338 call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200339 call RunDbgCmd(buf, 'cont')
340
341 call StopVimInTerminal(buf)
342
343 call delete('Xtest.vim')
Bram Moolenaar16c62322020-08-13 19:20:04 +0200344 %bw!
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200345
Bram Moolenaar16c62322020-08-13 19:20:04 +0200346 call assert_fails('breakadd here', 'E32:')
Bram Moolenaar531be472020-09-23 22:38:05 +0200347 call assert_fails('breakadd file Xtest.vim /\)/', 'E55:')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200348endfunc
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200349
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200350def Test_Debugger_breakadd_expr()
351 var lines =<< trim END
352 vim9script
353 func g:EarlyFunc()
354 endfunc
355 breakadd expr DoesNotExist()
356 func g:LaterFunc()
357 endfunc
358 breakdel *
359 END
360 writefile(lines, 'Xtest.vim')
361
362 # Start Vim in a terminal
363 var buf = RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
364 call TermWait(buf)
365
366 # Despite the failure the functions are defined
367 RunDbgCmd(buf, ':function g:EarlyFunc',
368 ['function EarlyFunc()', 'endfunction'], {match: 'pattern'})
369 RunDbgCmd(buf, ':function g:LaterFunc',
370 ['function LaterFunc()', 'endfunction'], {match: 'pattern'})
371
372 call StopVimInTerminal(buf)
373 call delete('Xtest.vim')
374enddef
375
Bram Moolenaar112bed02021-11-23 22:16:34 +0000376def Test_Debugger_break_at_return()
377 var lines =<< trim END
378 vim9script
379 def g:GetNum(): number
380 return 1
381 + 2
382 + 3
383 enddef
384 breakadd func GetNum
385 END
386 writefile(lines, 'Xtest.vim')
387
388 # Start Vim in a terminal
389 var buf = RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
390 call TermWait(buf)
391
392 RunDbgCmd(buf, ':call GetNum()',
393 ['line 1: return 1 + 2 + 3'], {match: 'pattern'})
394
395 call StopVimInTerminal(buf)
396 call delete('Xtest.vim')
397enddef
398
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200399func Test_Backtrace_Through_Source()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200400 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200401 let file1 =<< trim END
402 func SourceAnotherFile()
403 source Xtest2.vim
404 endfunc
405
406 func CallAFunction()
407 call SourceAnotherFile()
408 call File2Function()
409 endfunc
410
411 func GlobalFunction()
412 call CallAFunction()
413 endfunc
414 END
415 call writefile(file1, 'Xtest1.vim')
416
417 let file2 =<< trim END
418 func DoAThing()
419 echo "DoAThing"
420 endfunc
421
422 func File2Function()
423 call DoAThing()
424 endfunc
425
426 call File2Function()
427 END
428 call writefile(file2, 'Xtest2.vim')
429
430 let buf = RunVimInTerminal('-S Xtest1.vim', {})
431
432 call RunDbgCmd(buf,
433 \ ':debug call GlobalFunction()',
434 \ ['cmd: call GlobalFunction()'])
435 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
436
437 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
438 \ '->0 function GlobalFunction',
439 \ 'line 1: call CallAFunction()'])
440
441 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
442 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
443
444 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
445 \ ' 2 function GlobalFunction[1]',
446 \ ' 1 CallAFunction[1]',
447 \ '->0 SourceAnotherFile',
448 \ 'line 1: source Xtest2.vim'])
449
450 " Step into the 'source' command. Note that we print the full trace all the
451 " way though the source command.
452 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
453 call RunDbgCmd(buf, 'backtrace', [
454 \ '>backtrace',
455 \ ' 3 function GlobalFunction[1]',
456 \ ' 2 CallAFunction[1]',
457 \ ' 1 SourceAnotherFile[1]',
458 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
459 \ 'line 1: func DoAThing()'])
460
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200461 call RunDbgCmd( buf, 'up' )
462 call RunDbgCmd( buf, 'backtrace', [
463 \ '>backtrace',
464 \ ' 3 function GlobalFunction[1]',
465 \ ' 2 CallAFunction[1]',
466 \ '->1 SourceAnotherFile[1]',
467 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
468 \ 'line 1: func DoAThing()' ] )
469
470 call RunDbgCmd( buf, 'up' )
471 call RunDbgCmd( buf, 'backtrace', [
472 \ '>backtrace',
473 \ ' 3 function GlobalFunction[1]',
474 \ '->2 CallAFunction[1]',
475 \ ' 1 SourceAnotherFile[1]',
476 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
477 \ 'line 1: func DoAThing()' ] )
478
479 call RunDbgCmd( buf, 'up' )
480 call RunDbgCmd( buf, 'backtrace', [
481 \ '>backtrace',
482 \ '->3 function GlobalFunction[1]',
483 \ ' 2 CallAFunction[1]',
484 \ ' 1 SourceAnotherFile[1]',
485 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
486 \ 'line 1: func DoAThing()' ] )
487
488 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
489 call RunDbgCmd( buf, 'backtrace', [
490 \ '>backtrace',
491 \ '->3 function GlobalFunction[1]',
492 \ ' 2 CallAFunction[1]',
493 \ ' 1 SourceAnotherFile[1]',
494 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
495 \ 'line 1: func DoAThing()' ] )
496
497 call RunDbgCmd( buf, 'down' )
498 call RunDbgCmd( buf, 'backtrace', [
499 \ '>backtrace',
500 \ ' 3 function GlobalFunction[1]',
501 \ '->2 CallAFunction[1]',
502 \ ' 1 SourceAnotherFile[1]',
503 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
504 \ 'line 1: func DoAThing()' ] )
505
506 call RunDbgCmd( buf, 'down' )
507 call RunDbgCmd( buf, 'backtrace', [
508 \ '>backtrace',
509 \ ' 3 function GlobalFunction[1]',
510 \ ' 2 CallAFunction[1]',
511 \ '->1 SourceAnotherFile[1]',
512 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
513 \ 'line 1: func DoAThing()' ] )
514
515 call RunDbgCmd( buf, 'down' )
516 call RunDbgCmd( buf, 'backtrace', [
517 \ '>backtrace',
518 \ ' 3 function GlobalFunction[1]',
519 \ ' 2 CallAFunction[1]',
520 \ ' 1 SourceAnotherFile[1]',
521 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
522 \ 'line 1: func DoAThing()' ] )
523
524 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
525
Dominique Pelle923dce22021-11-21 11:36:04 +0000526 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200527 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
528 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
529 call RunDbgCmd(buf, 'backtrace', [
530 \ '>backtrace',
531 \ ' 3 function GlobalFunction[1]',
532 \ ' 2 CallAFunction[1]',
533 \ ' 1 SourceAnotherFile[1]',
534 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
535 \ 'line 9: call File2Function()'])
536
537 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
538 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
539 call RunDbgCmd(buf, 'backtrace', [
540 \ '>backtrace',
541 \ ' 5 function GlobalFunction[1]',
542 \ ' 4 CallAFunction[1]',
543 \ ' 3 SourceAnotherFile[1]',
544 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
545 \ ' 1 function File2Function[1]',
546 \ '->0 DoAThing',
547 \ 'line 1: echo "DoAThing"'])
548
549 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
550 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
551 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
552 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
553 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
554 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
555 call RunDbgCmd(buf, 'backtrace', [
556 \ '>backtrace',
557 \ ' 1 function GlobalFunction[1]',
558 \ '->0 CallAFunction',
559 \ 'line 2: call File2Function()'])
560
561 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
562 call RunDbgCmd(buf, 'backtrace', [
563 \ '>backtrace',
564 \ ' 2 function GlobalFunction[1]',
565 \ ' 1 CallAFunction[2]',
566 \ '->0 File2Function',
567 \ 'line 1: call DoAThing()'])
568
569 call StopVimInTerminal(buf)
570 call delete('Xtest1.vim')
571 call delete('Xtest2.vim')
572endfunc
573
574func Test_Backtrace_Autocmd()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200575 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200576 let file1 =<< trim END
577 func SourceAnotherFile()
578 source Xtest2.vim
579 endfunc
580
581 func CallAFunction()
582 call SourceAnotherFile()
583 call File2Function()
584 endfunc
585
586 func GlobalFunction()
587 call CallAFunction()
588 endfunc
589
590 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
591 END
592 call writefile(file1, 'Xtest1.vim')
593
594 let file2 =<< trim END
595 func DoAThing()
596 echo "DoAThing"
597 endfunc
598
599 func File2Function()
600 call DoAThing()
601 endfunc
602
603 call File2Function()
604 END
605 call writefile(file2, 'Xtest2.vim')
606
607 let buf = RunVimInTerminal('-S Xtest1.vim', {})
608
609 call RunDbgCmd(buf,
610 \ ':debug doautocmd User TestGlobalFunction',
611 \ ['cmd: doautocmd User TestGlobalFunction'])
612 call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
613
Dominique Pelle923dce22021-11-21 11:36:04 +0000614 " At this point the only thing in the stack is the autocommand
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200615 call RunDbgCmd(buf, 'backtrace', [
616 \ '>backtrace',
617 \ '->0 User Autocommands for "TestGlobalFunction"',
618 \ 'cmd: call GlobalFunction() | echo "Done"'])
619
620 " And now we're back into the call stack
621 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
622 call RunDbgCmd(buf, 'backtrace', [
623 \ '>backtrace',
624 \ ' 1 User Autocommands for "TestGlobalFunction"',
625 \ '->0 function GlobalFunction',
626 \ 'line 1: call CallAFunction()'])
627
628 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
629 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
630
631 call RunDbgCmd(buf, 'backtrace', [
632 \ '>backtrace',
633 \ ' 3 User Autocommands for "TestGlobalFunction"',
634 \ ' 2 function GlobalFunction[1]',
635 \ ' 1 CallAFunction[1]',
636 \ '->0 SourceAnotherFile',
637 \ 'line 1: source Xtest2.vim'])
638
639 " Step into the 'source' command. Note that we print the full trace all the
640 " way though the source command.
641 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
642 call RunDbgCmd(buf, 'backtrace', [
643 \ '>backtrace',
644 \ ' 4 User Autocommands for "TestGlobalFunction"',
645 \ ' 3 function GlobalFunction[1]',
646 \ ' 2 CallAFunction[1]',
647 \ ' 1 SourceAnotherFile[1]',
648 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
649 \ 'line 1: func DoAThing()'])
650
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200651 call RunDbgCmd( buf, 'up' )
652 call RunDbgCmd( buf, 'backtrace', [
653 \ '>backtrace',
654 \ ' 4 User Autocommands for "TestGlobalFunction"',
655 \ ' 3 function GlobalFunction[1]',
656 \ ' 2 CallAFunction[1]',
657 \ '->1 SourceAnotherFile[1]',
658 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
659 \ 'line 1: func DoAThing()' ] )
660
661 call RunDbgCmd( buf, 'up' )
662 call RunDbgCmd( buf, 'backtrace', [
663 \ '>backtrace',
664 \ ' 4 User Autocommands for "TestGlobalFunction"',
665 \ ' 3 function GlobalFunction[1]',
666 \ '->2 CallAFunction[1]',
667 \ ' 1 SourceAnotherFile[1]',
668 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
669 \ 'line 1: func DoAThing()' ] )
670
671 call RunDbgCmd( buf, 'up' )
672 call RunDbgCmd( buf, 'backtrace', [
673 \ '>backtrace',
674 \ ' 4 User Autocommands for "TestGlobalFunction"',
675 \ '->3 function GlobalFunction[1]',
676 \ ' 2 CallAFunction[1]',
677 \ ' 1 SourceAnotherFile[1]',
678 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
679 \ 'line 1: func DoAThing()' ] )
680
681 call RunDbgCmd( buf, 'up' )
682 call RunDbgCmd( buf, 'backtrace', [
683 \ '>backtrace',
684 \ '->4 User Autocommands for "TestGlobalFunction"',
685 \ ' 3 function GlobalFunction[1]',
686 \ ' 2 CallAFunction[1]',
687 \ ' 1 SourceAnotherFile[1]',
688 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
689 \ 'line 1: func DoAThing()' ] )
690
691 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] )
692 call RunDbgCmd( buf, 'backtrace', [
693 \ '>backtrace',
694 \ '->4 User Autocommands for "TestGlobalFunction"',
695 \ ' 3 function GlobalFunction[1]',
696 \ ' 2 CallAFunction[1]',
697 \ ' 1 SourceAnotherFile[1]',
698 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
699 \ 'line 1: func DoAThing()' ] )
700
701 call RunDbgCmd( buf, 'down' )
702 call RunDbgCmd( buf, 'backtrace', [
703 \ '>backtrace',
704 \ ' 4 User Autocommands for "TestGlobalFunction"',
705 \ '->3 function GlobalFunction[1]',
706 \ ' 2 CallAFunction[1]',
707 \ ' 1 SourceAnotherFile[1]',
708 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
709 \ 'line 1: func DoAThing()' ] )
710
711
712 call RunDbgCmd( buf, 'down' )
713 call RunDbgCmd( buf, 'backtrace', [
714 \ '>backtrace',
715 \ ' 4 User Autocommands for "TestGlobalFunction"',
716 \ ' 3 function GlobalFunction[1]',
717 \ '->2 CallAFunction[1]',
718 \ ' 1 SourceAnotherFile[1]',
719 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
720 \ 'line 1: func DoAThing()' ] )
721
722 call RunDbgCmd( buf, 'down' )
723 call RunDbgCmd( buf, 'backtrace', [
724 \ '>backtrace',
725 \ ' 4 User Autocommands for "TestGlobalFunction"',
726 \ ' 3 function GlobalFunction[1]',
727 \ ' 2 CallAFunction[1]',
728 \ '->1 SourceAnotherFile[1]',
729 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
730 \ 'line 1: func DoAThing()' ] )
731
732 call RunDbgCmd( buf, 'down' )
733 call RunDbgCmd( buf, 'backtrace', [
734 \ '>backtrace',
735 \ ' 4 User Autocommands for "TestGlobalFunction"',
736 \ ' 3 function GlobalFunction[1]',
737 \ ' 2 CallAFunction[1]',
738 \ ' 1 SourceAnotherFile[1]',
739 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
740 \ 'line 1: func DoAThing()' ] )
741
742 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
743
Dominique Pelle923dce22021-11-21 11:36:04 +0000744 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200745 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
746 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
747 call RunDbgCmd(buf, 'backtrace', [
748 \ '>backtrace',
749 \ ' 4 User Autocommands for "TestGlobalFunction"',
750 \ ' 3 function GlobalFunction[1]',
751 \ ' 2 CallAFunction[1]',
752 \ ' 1 SourceAnotherFile[1]',
753 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
754 \ 'line 9: call File2Function()'])
755
756 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
757 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
758 call RunDbgCmd(buf, 'backtrace', [
759 \ '>backtrace',
760 \ ' 6 User Autocommands for "TestGlobalFunction"',
761 \ ' 5 function GlobalFunction[1]',
762 \ ' 4 CallAFunction[1]',
763 \ ' 3 SourceAnotherFile[1]',
764 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
765 \ ' 1 function File2Function[1]',
766 \ '->0 DoAThing',
767 \ 'line 1: echo "DoAThing"'])
768
769 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
770 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
771 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
772 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
773 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
774 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
775 call RunDbgCmd(buf, 'backtrace', [
776 \ '>backtrace',
777 \ ' 2 User Autocommands for "TestGlobalFunction"',
778 \ ' 1 function GlobalFunction[1]',
779 \ '->0 CallAFunction',
780 \ 'line 2: call File2Function()'])
781
782 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
783 call RunDbgCmd(buf, 'backtrace', [
784 \ '>backtrace',
785 \ ' 3 User Autocommands for "TestGlobalFunction"',
786 \ ' 2 function GlobalFunction[1]',
787 \ ' 1 CallAFunction[2]',
788 \ '->0 File2Function',
789 \ 'line 1: call DoAThing()'])
790
791
792 " Now unwind so that we get back to the original autocommand (and the second
793 " cmd echo "Done")
794 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
795 call RunDbgCmd(buf, 'backtrace', [
796 \ '>backtrace',
797 \ ' 3 User Autocommands for "TestGlobalFunction"',
798 \ ' 2 function GlobalFunction[1]',
799 \ ' 1 CallAFunction[2]',
800 \ '->0 File2Function',
801 \ 'line 1: End of function'])
802
803 call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
804 call RunDbgCmd(buf, 'backtrace', [
805 \ '>backtrace',
806 \ ' 2 User Autocommands for "TestGlobalFunction"',
807 \ ' 1 function GlobalFunction[1]',
808 \ '->0 CallAFunction',
809 \ 'line 2: End of function'])
810
811 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
812 call RunDbgCmd(buf, 'backtrace', [
813 \ '>backtrace',
814 \ ' 1 User Autocommands for "TestGlobalFunction"',
815 \ '->0 function GlobalFunction',
816 \ 'line 1: End of function'])
817
818 call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
819 call RunDbgCmd(buf, 'backtrace', [
820 \ '>backtrace',
821 \ '->0 User Autocommands for "TestGlobalFunction"',
822 \ 'cmd: echo "Done"'])
823
824 call StopVimInTerminal(buf)
825 call delete('Xtest1.vim')
826 call delete('Xtest2.vim')
827endfunc
828
829func Test_Backtrace_CmdLine()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200830 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200831 let file1 =<< trim END
832 func SourceAnotherFile()
833 source Xtest2.vim
834 endfunc
835
836 func CallAFunction()
837 call SourceAnotherFile()
838 call File2Function()
839 endfunc
840
841 func GlobalFunction()
842 call CallAFunction()
843 endfunc
844
845 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
846 END
847 call writefile(file1, 'Xtest1.vim')
848
849 let file2 =<< trim END
850 func DoAThing()
851 echo "DoAThing"
852 endfunc
853
854 func File2Function()
855 call DoAThing()
856 endfunc
857
858 call File2Function()
859 END
860 call writefile(file2, 'Xtest2.vim')
861
862 let buf = RunVimInTerminal(
863 \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
864 \ {'wait_for_ruler': 0})
865
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100866 " Need to wait for the vim-in-terminal to be ready.
867 " With valgrind this can take quite long.
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200868 call CheckDbgOutput(buf, ['command line',
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100869 \ 'cmd: call GlobalFunction()'], #{msec: 5000})
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200870
Dominique Pelle923dce22021-11-21 11:36:04 +0000871 " At this point the only thing in the stack is the cmdline
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200872 call RunDbgCmd(buf, 'backtrace', [
873 \ '>backtrace',
874 \ '->0 command line',
875 \ 'cmd: call GlobalFunction()'])
876
877 " And now we're back into the call stack
878 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
879 call RunDbgCmd(buf, 'backtrace', [
880 \ '>backtrace',
881 \ ' 1 command line',
882 \ '->0 function GlobalFunction',
883 \ 'line 1: call CallAFunction()'])
884
885 call StopVimInTerminal(buf)
886 call delete('Xtest1.vim')
887 call delete('Xtest2.vim')
888endfunc
889
890func Test_Backtrace_DefFunction()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200891 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200892 let file1 =<< trim END
893 vim9script
894 import File2Function from './Xtest2.vim'
895
896 def SourceAnotherFile()
897 source Xtest2.vim
898 enddef
899
900 def CallAFunction()
901 SourceAnotherFile()
902 File2Function()
903 enddef
904
905 def g:GlobalFunction()
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200906 var some = "some var"
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200907 CallAFunction()
908 enddef
909
910 defcompile
911 END
912 call writefile(file1, 'Xtest1.vim')
913
914 let file2 =<< trim END
915 vim9script
916
917 def DoAThing(): number
Bram Moolenaar1bdae402020-10-03 14:14:56 +0200918 var a = 100 * 2
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200919 a += 3
920 return a
921 enddef
922
923 export def File2Function()
924 DoAThing()
925 enddef
926
927 defcompile
928 File2Function()
929 END
930 call writefile(file2, 'Xtest2.vim')
931
932 let buf = RunVimInTerminal('-S Xtest1.vim', {})
933
934 call RunDbgCmd(buf,
935 \ ':debug call GlobalFunction()',
936 \ ['cmd: call GlobalFunction()'])
937
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200938 call RunDbgCmd(buf, 'step', ['line 1: var some = "some var"'])
939 call RunDbgCmd(buf, 'step', ['line 2: CallAFunction()'])
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200940 call RunDbgCmd(buf, 'echo some', ['some var'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200941
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200942 call RunDbgCmd(buf, 'backtrace', [
943 \ '\V>backtrace',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200944 \ '\V->0 function GlobalFunction',
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200945 \ '\Vline 2: CallAFunction()',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200946 \ ],
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200947 \ #{match: 'pattern'})
948
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200949 call RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()'])
950 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Dominique Pelleaf4a61a2021-12-27 17:21:41 +0000951 " Repeated line, because we first are in the compiled function before the
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200952 " EXEC and then in do_cmdline() before the :source command.
Bram Moolenaare99d4222021-06-13 14:01:26 +0200953 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200954 call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
955 call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
956 call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
957 call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
958 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
959 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
960 call RunDbgCmd(buf, 'backtrace', [
961 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200962 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200963 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
964 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
965 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
966 \ '\Vline 14: File2Function()'],
967 \ #{match: 'pattern'})
968
969 " Don't step into compiled functions...
Bram Moolenaare99d4222021-06-13 14:01:26 +0200970 call RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200971 call RunDbgCmd(buf, 'backtrace', [
972 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200973 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200974 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
975 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
976 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
977 \ '\Vline 15: End of sourced file'],
978 \ #{match: 'pattern'})
979
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200980 call StopVimInTerminal(buf)
981 call delete('Xtest1.vim')
982 call delete('Xtest2.vim')
983endfunc
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200984
Bram Moolenaar26a44842021-09-02 18:49:06 +0200985func Test_DefFunction_expr()
986 CheckCWD
987 let file3 =<< trim END
988 vim9script
989 g:someVar = "foo"
990 def g:ChangeVar()
991 g:someVar = "bar"
992 echo "changed"
993 enddef
994 defcompile
995 END
996 call writefile(file3, 'Xtest3.vim')
997 let buf = RunVimInTerminal('-S Xtest3.vim', {})
998
999 call RunDbgCmd(buf, ':breakadd expr g:someVar')
1000 call RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"'])
1001
1002 call StopVimInTerminal(buf)
1003 call delete('Xtest3.vim')
1004endfunc
1005
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001006func Test_debug_def_and_legacy_function()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001007 CheckCWD
1008 let file =<< trim END
1009 vim9script
1010 def g:SomeFunc()
1011 echo "here"
1012 echo "and"
1013 echo "there"
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001014 breakadd func 2 LocalFunc
1015 LocalFunc()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001016 enddef
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001017
1018 def LocalFunc()
1019 echo "first"
1020 echo "second"
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001021 breakadd func LegacyFunc
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001022 LegacyFunc()
1023 enddef
1024
1025 func LegacyFunc()
1026 echo "legone"
1027 echo "legtwo"
1028 endfunc
1029
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001030 breakadd func 2 g:SomeFunc
1031 END
1032 call writefile(file, 'XtestDebug.vim')
1033
1034 let buf = RunVimInTerminal('-S XtestDebug.vim', {})
1035
1036 call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
1037 call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001038 call RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc'])
1039
1040 " continue, next breakpoint is in LocalFunc()
1041 call RunDbgCmd(buf,'cont', ['line 2: echo "second"'])
1042
1043 " continue, next breakpoint is in LegacyFunc()
1044 call RunDbgCmd(buf,'cont', ['line 1: echo "legone"'])
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001045
1046 call RunDbgCmd(buf, 'cont')
1047
1048 call StopVimInTerminal(buf)
Dominique Pelle6c72fd52021-07-04 12:30:06 +02001049 call delete('XtestDebug.vim')
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001050endfunc
1051
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001052func Test_debug_def_function()
1053 CheckCWD
1054 let file =<< trim END
1055 vim9script
1056 def g:Func()
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001057 var n: number
1058 def Closure(): number
1059 return n + 3
1060 enddef
1061 n += Closure()
1062 echo 'result: ' .. n
1063 enddef
1064
1065 def g:FuncWithArgs(text: string, nr: number, ...items: list<number>)
1066 echo text .. nr
1067 for it in items
1068 echo it
1069 endfor
1070 echo "done"
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001071 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001072
1073 def g:FuncWithDict()
1074 var d = {
1075 a: 1,
1076 b: 2,
1077 }
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001078 # comment
1079 def Inner()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001080 eval 1 + 2
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001081 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001082 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001083
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001084 def g:FuncComment()
1085 # comment
1086 echo "first"
1087 .. "one"
1088 # comment
1089 echo "second"
1090 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001091
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001092 def g:FuncForLoop()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001093 eval 1 + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001094 for i in [11, 22, 33]
Bram Moolenaar31e21762021-07-10 20:43:59 +02001095 eval i + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001096 endfor
1097 echo "done"
1098 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001099
1100 def g:FuncWithSplitLine()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001101 eval 1 + 2
1102 | eval 2 + 3
Bram Moolenaar303215d2021-07-07 20:10:43 +02001103 enddef
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001104 END
1105 call writefile(file, 'Xtest.vim')
1106
1107 let buf = RunVimInTerminal('-S Xtest.vim', {})
1108
1109 call RunDbgCmd(buf,
1110 \ ':debug call Func()',
1111 \ ['cmd: call Func()'])
1112 call RunDbgCmd(buf, 'next', ['result: 3'])
1113 call term_sendkeys(buf, "\r")
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001114 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001115
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001116 call RunDbgCmd(buf,
1117 \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
1118 \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001119 call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001120 call RunDbgCmd(buf, 'echo text', ['asdf'])
1121 call RunDbgCmd(buf, 'echo nr', ['42'])
1122 call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001123 call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
1124 call RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items'])
1125 call RunDbgCmd(buf, 'echo it', ['0'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001126 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001127 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001128 call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
1129 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001130 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001131 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1132 call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
1133 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001134 call RunDbgCmd(buf, 'echo it', ['2'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001135 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1136 call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001137 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001138 call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
1139 call RunDbgCmd(buf, 'cont')
1140
1141 call RunDbgCmd(buf,
1142 \ ':debug call FuncWithDict()',
1143 \ ['cmd: call FuncWithDict()'])
1144 call RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }'])
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001145 call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001146 call RunDbgCmd(buf, 'cont')
1147
1148 call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
1149 call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
1150 call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
1151 call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001152 call RunDbgCmd(buf, 'cont')
1153
1154 call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001155 call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1156 call RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]'])
Bram Moolenaar31e21762021-07-10 20:43:59 +02001157 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001158 call RunDbgCmd(buf, 'echo i', ['11'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001159 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
1160 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001161 call RunDbgCmd(buf, 'next', ['line 3: eval i + 2'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001162 call RunDbgCmd(buf, 'echo i', ['22'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001163
Bram Moolenaar303215d2021-07-07 20:10:43 +02001164 call RunDbgCmd(buf, 'breakdel *')
1165 call RunDbgCmd(buf, 'cont')
1166
1167 call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
Bram Moolenaar31e21762021-07-10 20:43:59 +02001168 call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
Bram Moolenaar303215d2021-07-07 20:10:43 +02001169
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001170 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001171 call StopVimInTerminal(buf)
1172 call delete('Xtest.vim')
1173endfunc
1174
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001175func Test_debug_def_function_with_lambda()
1176 CheckCWD
1177 let lines =<< trim END
1178 vim9script
1179 def g:Func()
1180 var s = 'a'
1181 ['b']->map((_, v) => s)
1182 echo "done"
1183 enddef
1184 breakadd func 2 g:Func
1185 END
1186 call writefile(lines, 'XtestLambda.vim')
1187
1188 let buf = RunVimInTerminal('-S XtestLambda.vim', {})
1189
1190 call RunDbgCmd(buf,
1191 \ ':call g:Func()',
1192 \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
1193 call RunDbgCmd(buf,
1194 \ 'next',
1195 \ ['function Func', 'line 3: echo "done"'])
1196
1197 call RunDbgCmd(buf, 'cont')
1198 call StopVimInTerminal(buf)
1199 call delete('XtestLambda.vim')
1200endfunc
1201
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001202func Test_debug_backtrace_level()
1203 CheckCWD
1204 let lines =<< trim END
1205 let s:file1_var = 'file1'
1206 let g:global_var = 'global'
1207
1208 func s:File1Func( arg )
1209 let s:file1_var .= a:arg
1210 let local_var = s:file1_var .. ' test1'
1211 let g:global_var .= local_var
1212 source Xtest2.vim
1213 endfunc
1214
1215 call s:File1Func( 'arg1' )
1216 END
1217 call writefile(lines, 'Xtest1.vim')
1218
1219 let lines =<< trim END
1220 let s:file2_var = 'file2'
1221
1222 func s:File2Func( arg )
1223 let s:file2_var .= a:arg
1224 let local_var = s:file2_var .. ' test2'
1225 let g:global_var .= local_var
1226 endfunc
1227
1228 call s:File2Func( 'arg2' )
1229 END
1230 call writefile(lines, 'Xtest2.vim')
1231
1232 let file1 = getcwd() .. '/Xtest1.vim'
1233 let file2 = getcwd() .. '/Xtest2.vim'
1234
1235 " set a breakpoint and source file1.vim
1236 let buf = RunVimInTerminal(
1237 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001238 \ #{wait_for_ruler: 0})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001239
1240 call CheckDbgOutput(buf, [
1241 \ 'Breakpoint in "' .. file1 .. '" line 1',
1242 \ 'Entering Debug mode. Type "cont" to continue.',
1243 \ 'command line..script ' .. file1,
1244 \ 'line 1: let s:file1_var = ''file1'''
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001245 \ ], #{msec: 5000})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001246
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01001247 " step through the initial declarations
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001248 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1249 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1250 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1251 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1252 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
1253
1254 " step in to the first function
1255 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1256 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1257 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1258 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1259 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1260 call RunDbgCmd(buf,
1261 \'echo global_var',
1262 \[ 'E121: Undefined variable: global_var' ] )
1263 call RunDbgCmd(buf,
1264 \'echo local_var',
1265 \[ 'E121: Undefined variable: local_var' ] )
1266 call RunDbgCmd(buf,
1267 \'echo l:local_var',
1268 \[ 'E121: Undefined variable: l:local_var' ] )
1269
1270 " backtrace up
1271 call RunDbgCmd(buf, 'backtrace', [
1272 \ '\V>backtrace',
1273 \ '\V 2 command line',
1274 \ '\V 1 script ' .. file1 .. '[11]',
1275 \ '\V->0 function <SNR>\.\*_File1Func',
1276 \ '\Vline 1: let s:file1_var .= a:arg',
1277 \ ],
1278 \ #{ match: 'pattern' } )
1279 call RunDbgCmd(buf, 'up', [ '>up' ] )
1280
1281 call RunDbgCmd(buf, 'backtrace', [
1282 \ '\V>backtrace',
1283 \ '\V 2 command line',
1284 \ '\V->1 script ' .. file1 .. '[11]',
1285 \ '\V 0 function <SNR>\.\*_File1Func',
1286 \ '\Vline 1: let s:file1_var .= a:arg',
1287 \ ],
1288 \ #{ match: 'pattern' } )
1289
1290 " Expression evaluation in the script frame (not the function frame)
Dominique Pelle923dce22021-11-21 11:36:04 +00001291 " FIXME: Unexpected in this scope (a: should not be visible)
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001292 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1293 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1294 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1295 " FIXME: Unexpected in this scope (global should be found)
1296 call RunDbgCmd(buf,
1297 \'echo global_var',
1298 \[ 'E121: Undefined variable: global_var' ] )
1299 call RunDbgCmd(buf,
1300 \'echo local_var',
1301 \[ 'E121: Undefined variable: local_var' ] )
1302 call RunDbgCmd(buf,
1303 \'echo l:local_var',
1304 \[ 'E121: Undefined variable: l:local_var' ] )
1305
1306
1307 " step while backtraced jumps to the latest frame
1308 call RunDbgCmd(buf, 'step', [
1309 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1310 call RunDbgCmd(buf, 'backtrace', [
1311 \ '\V>backtrace',
1312 \ '\V 2 command line',
1313 \ '\V 1 script ' .. file1 .. '[11]',
1314 \ '\V->0 function <SNR>\.\*_File1Func',
1315 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1316 \ ],
1317 \ #{ match: 'pattern' } )
1318
1319 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1320 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1321 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1322
1323 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1324 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1325 call RunDbgCmd(buf, 'backtrace', [
1326 \ '\V>backtrace',
1327 \ '\V 3 command line',
1328 \ '\V 2 script ' .. file1 .. '[11]',
1329 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1330 \ '\V->0 script ' .. file2,
1331 \ '\Vline 1: let s:file2_var = ''file2''',
1332 \ ],
1333 \ #{ match: 'pattern' } )
1334
1335 " Expression evaluation in the script frame file2 (not the function frame)
1336 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1337 call RunDbgCmd(buf,
1338 \ 'echo s:file1_var',
1339 \ [ 'E121: Undefined variable: s:file1_var' ] )
1340 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1341 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1342 call RunDbgCmd(buf,
1343 \'echo local_var',
1344 \[ 'E121: Undefined variable: local_var' ] )
1345 call RunDbgCmd(buf,
1346 \'echo l:local_var',
1347 \[ 'E121: Undefined variable: l:local_var' ] )
1348 call RunDbgCmd(buf,
1349 \ 'echo s:file2_var',
1350 \ [ 'E121: Undefined variable: s:file2_var' ] )
1351
1352 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1353 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1354
1355 " Up the stack to the other script context
1356 call RunDbgCmd(buf, 'up')
1357 call RunDbgCmd(buf, 'backtrace', [
1358 \ '\V>backtrace',
1359 \ '\V 3 command line',
1360 \ '\V 2 script ' .. file1 .. '[11]',
1361 \ '\V->1 function <SNR>\.\*_File1Func[4]',
1362 \ '\V 0 script ' .. file2,
1363 \ '\Vline 3: func s:File2Func( arg )',
1364 \ ],
1365 \ #{ match: 'pattern' } )
1366 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1367 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1368 call RunDbgCmd(buf,
1369 \ 'echo l:local_var',
1370 \ [ 'E121: Undefined variable: l:local_var' ] )
1371
1372 call RunDbgCmd(buf, 'up')
1373 call RunDbgCmd(buf, 'backtrace', [
1374 \ '\V>backtrace',
1375 \ '\V 3 command line',
1376 \ '\V->2 script ' .. file1 .. '[11]',
1377 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1378 \ '\V 0 script ' .. file2,
1379 \ '\Vline 3: func s:File2Func( arg )',
1380 \ ],
1381 \ #{ match: 'pattern' } )
1382
1383 " FIXME: Unexpected (wrong script vars are used)
1384 call RunDbgCmd(buf,
1385 \ 'echo s:file1_var',
1386 \ [ 'E121: Undefined variable: s:file1_var' ] )
1387 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1388
Bram Moolenaare99d4222021-06-13 14:01:26 +02001389 call RunDbgCmd(buf, 'cont')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001390 call StopVimInTerminal(buf)
1391 call delete('Xtest1.vim')
1392 call delete('Xtest2.vim')
1393endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001394
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001395" Test for setting a breakpoint on a :endif where the :if condition is false
1396" and then quit the script. This should generate an interrupt.
1397func Test_breakpt_endif_intr()
1398 func F()
1399 let g:Xpath ..= 'a'
1400 if v:false
1401 let g:Xpath ..= 'b'
1402 endif
1403 invalid_command
1404 endfunc
1405
1406 let g:Xpath = ''
1407 breakadd func 4 F
1408 try
1409 let caught_intr = 0
1410 debuggreedy
1411 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001412 catch /^Vim:Interrupt$/
1413 call assert_match('\.F, line 4', v:throwpoint)
1414 let caught_intr = 1
1415 endtry
1416 0debuggreedy
1417 call assert_equal(1, caught_intr)
1418 call assert_equal('a', g:Xpath)
1419 breakdel *
1420 delfunc F
1421endfunc
1422
1423" Test for setting a breakpoint on a :else where the :if condition is false
1424" and then quit the script. This should generate an interrupt.
1425func Test_breakpt_else_intr()
1426 func F()
1427 let g:Xpath ..= 'a'
1428 if v:false
1429 let g:Xpath ..= 'b'
1430 else
1431 invalid_command
1432 endif
1433 invalid_command
1434 endfunc
1435
1436 let g:Xpath = ''
1437 breakadd func 4 F
1438 try
1439 let caught_intr = 0
1440 debuggreedy
1441 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001442 catch /^Vim:Interrupt$/
1443 call assert_match('\.F, line 4', v:throwpoint)
1444 let caught_intr = 1
1445 endtry
1446 0debuggreedy
1447 call assert_equal(1, caught_intr)
1448 call assert_equal('a', g:Xpath)
1449 breakdel *
1450 delfunc F
1451endfunc
1452
1453" Test for setting a breakpoint on a :endwhile where the :while condition is
1454" false and then quit the script. This should generate an interrupt.
1455func Test_breakpt_endwhile_intr()
1456 func F()
1457 let g:Xpath ..= 'a'
1458 while v:false
1459 let g:Xpath ..= 'b'
1460 endwhile
1461 invalid_command
1462 endfunc
1463
1464 let g:Xpath = ''
1465 breakadd func 4 F
1466 try
1467 let caught_intr = 0
1468 debuggreedy
1469 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001470 catch /^Vim:Interrupt$/
1471 call assert_match('\.F, line 4', v:throwpoint)
1472 let caught_intr = 1
1473 endtry
1474 0debuggreedy
1475 call assert_equal(1, caught_intr)
1476 call assert_equal('a', g:Xpath)
1477 breakdel *
1478 delfunc F
1479endfunc
1480
Bram Moolenaar16c62322020-08-13 19:20:04 +02001481" Test for setting a breakpoint on a script local function
1482func Test_breakpt_scriptlocal_func()
1483 let g:Xpath = ''
1484 func s:G()
1485 let g:Xpath ..= 'a'
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001486 endfunc
1487
Bram Moolenaar16c62322020-08-13 19:20:04 +02001488 let funcname = expand("<SID>") .. "G"
1489 exe "breakadd func 1 " .. funcname
1490 debuggreedy
1491 redir => output
1492 call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
1493 redir END
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001494 0debuggreedy
Bram Moolenaar16c62322020-08-13 19:20:04 +02001495 call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001496 call assert_equal('a', g:Xpath)
1497 breakdel *
Bram Moolenaar16c62322020-08-13 19:20:04 +02001498 exe "delfunc " .. funcname
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001499endfunc
1500
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001501" vim: shiftwidth=2 sts=2 expandtab