blob: 6f01917ed4483da385629a4ea8fc5f4dbb876865 [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'])
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200951 " Repeated line, because we fist are in the compiled function before the
952 " 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 Moolenaar4cea5362021-06-16 22:24:40 +02001123 call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001124 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001125 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1126 call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
1127 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001128 call RunDbgCmd(buf, 'echo it', ['2'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001129 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1130 call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
1131 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001132 call RunDbgCmd(buf, 'echo it', ['3'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001133 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1134 call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
1135 call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
1136 call RunDbgCmd(buf, 'cont')
1137
1138 call RunDbgCmd(buf,
1139 \ ':debug call FuncWithDict()',
1140 \ ['cmd: call FuncWithDict()'])
1141 call RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }'])
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001142 call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001143 call RunDbgCmd(buf, 'cont')
1144
1145 call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
1146 call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
1147 call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
1148 call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001149 call RunDbgCmd(buf, 'cont')
1150
1151 call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
1152 call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1153 call RunDbgCmd(buf, 'echo i', ['11'])
Bram Moolenaar31e21762021-07-10 20:43:59 +02001154 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001155 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
1156 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1157 call RunDbgCmd(buf, 'echo i', ['22'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001158
Bram Moolenaar303215d2021-07-07 20:10:43 +02001159 call RunDbgCmd(buf, 'breakdel *')
1160 call RunDbgCmd(buf, 'cont')
1161
1162 call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
Bram Moolenaar31e21762021-07-10 20:43:59 +02001163 call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
Bram Moolenaar303215d2021-07-07 20:10:43 +02001164
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001165 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001166 call StopVimInTerminal(buf)
1167 call delete('Xtest.vim')
1168endfunc
1169
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001170func Test_debug_def_function_with_lambda()
1171 CheckCWD
1172 let lines =<< trim END
1173 vim9script
1174 def g:Func()
1175 var s = 'a'
1176 ['b']->map((_, v) => s)
1177 echo "done"
1178 enddef
1179 breakadd func 2 g:Func
1180 END
1181 call writefile(lines, 'XtestLambda.vim')
1182
1183 let buf = RunVimInTerminal('-S XtestLambda.vim', {})
1184
1185 call RunDbgCmd(buf,
1186 \ ':call g:Func()',
1187 \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
1188 call RunDbgCmd(buf,
1189 \ 'next',
1190 \ ['function Func', 'line 3: echo "done"'])
1191
1192 call RunDbgCmd(buf, 'cont')
1193 call StopVimInTerminal(buf)
1194 call delete('XtestLambda.vim')
1195endfunc
1196
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001197func Test_debug_backtrace_level()
1198 CheckCWD
1199 let lines =<< trim END
1200 let s:file1_var = 'file1'
1201 let g:global_var = 'global'
1202
1203 func s:File1Func( arg )
1204 let s:file1_var .= a:arg
1205 let local_var = s:file1_var .. ' test1'
1206 let g:global_var .= local_var
1207 source Xtest2.vim
1208 endfunc
1209
1210 call s:File1Func( 'arg1' )
1211 END
1212 call writefile(lines, 'Xtest1.vim')
1213
1214 let lines =<< trim END
1215 let s:file2_var = 'file2'
1216
1217 func s:File2Func( arg )
1218 let s:file2_var .= a:arg
1219 let local_var = s:file2_var .. ' test2'
1220 let g:global_var .= local_var
1221 endfunc
1222
1223 call s:File2Func( 'arg2' )
1224 END
1225 call writefile(lines, 'Xtest2.vim')
1226
1227 let file1 = getcwd() .. '/Xtest1.vim'
1228 let file2 = getcwd() .. '/Xtest2.vim'
1229
1230 " set a breakpoint and source file1.vim
1231 let buf = RunVimInTerminal(
1232 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001233 \ #{wait_for_ruler: 0})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001234
1235 call CheckDbgOutput(buf, [
1236 \ 'Breakpoint in "' .. file1 .. '" line 1',
1237 \ 'Entering Debug mode. Type "cont" to continue.',
1238 \ 'command line..script ' .. file1,
1239 \ 'line 1: let s:file1_var = ''file1'''
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001240 \ ], #{msec: 5000})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001241
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01001242 " step through the initial declarations
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001243 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1244 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1245 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1246 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1247 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
1248
1249 " step in to the first function
1250 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1251 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1252 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1253 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1254 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1255 call RunDbgCmd(buf,
1256 \'echo global_var',
1257 \[ 'E121: Undefined variable: global_var' ] )
1258 call RunDbgCmd(buf,
1259 \'echo local_var',
1260 \[ 'E121: Undefined variable: local_var' ] )
1261 call RunDbgCmd(buf,
1262 \'echo l:local_var',
1263 \[ 'E121: Undefined variable: l:local_var' ] )
1264
1265 " backtrace up
1266 call RunDbgCmd(buf, 'backtrace', [
1267 \ '\V>backtrace',
1268 \ '\V 2 command line',
1269 \ '\V 1 script ' .. file1 .. '[11]',
1270 \ '\V->0 function <SNR>\.\*_File1Func',
1271 \ '\Vline 1: let s:file1_var .= a:arg',
1272 \ ],
1273 \ #{ match: 'pattern' } )
1274 call RunDbgCmd(buf, 'up', [ '>up' ] )
1275
1276 call RunDbgCmd(buf, 'backtrace', [
1277 \ '\V>backtrace',
1278 \ '\V 2 command line',
1279 \ '\V->1 script ' .. file1 .. '[11]',
1280 \ '\V 0 function <SNR>\.\*_File1Func',
1281 \ '\Vline 1: let s:file1_var .= a:arg',
1282 \ ],
1283 \ #{ match: 'pattern' } )
1284
1285 " Expression evaluation in the script frame (not the function frame)
Dominique Pelle923dce22021-11-21 11:36:04 +00001286 " FIXME: Unexpected in this scope (a: should not be visible)
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001287 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1288 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1289 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1290 " FIXME: Unexpected in this scope (global should be found)
1291 call RunDbgCmd(buf,
1292 \'echo global_var',
1293 \[ 'E121: Undefined variable: global_var' ] )
1294 call RunDbgCmd(buf,
1295 \'echo local_var',
1296 \[ 'E121: Undefined variable: local_var' ] )
1297 call RunDbgCmd(buf,
1298 \'echo l:local_var',
1299 \[ 'E121: Undefined variable: l:local_var' ] )
1300
1301
1302 " step while backtraced jumps to the latest frame
1303 call RunDbgCmd(buf, 'step', [
1304 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1305 call RunDbgCmd(buf, 'backtrace', [
1306 \ '\V>backtrace',
1307 \ '\V 2 command line',
1308 \ '\V 1 script ' .. file1 .. '[11]',
1309 \ '\V->0 function <SNR>\.\*_File1Func',
1310 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1311 \ ],
1312 \ #{ match: 'pattern' } )
1313
1314 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1315 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1316 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1317
1318 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1319 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1320 call RunDbgCmd(buf, 'backtrace', [
1321 \ '\V>backtrace',
1322 \ '\V 3 command line',
1323 \ '\V 2 script ' .. file1 .. '[11]',
1324 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1325 \ '\V->0 script ' .. file2,
1326 \ '\Vline 1: let s:file2_var = ''file2''',
1327 \ ],
1328 \ #{ match: 'pattern' } )
1329
1330 " Expression evaluation in the script frame file2 (not the function frame)
1331 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1332 call RunDbgCmd(buf,
1333 \ 'echo s:file1_var',
1334 \ [ 'E121: Undefined variable: s:file1_var' ] )
1335 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1336 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1337 call RunDbgCmd(buf,
1338 \'echo local_var',
1339 \[ 'E121: Undefined variable: local_var' ] )
1340 call RunDbgCmd(buf,
1341 \'echo l:local_var',
1342 \[ 'E121: Undefined variable: l:local_var' ] )
1343 call RunDbgCmd(buf,
1344 \ 'echo s:file2_var',
1345 \ [ 'E121: Undefined variable: s:file2_var' ] )
1346
1347 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1348 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1349
1350 " Up the stack to the other script context
1351 call RunDbgCmd(buf, 'up')
1352 call RunDbgCmd(buf, 'backtrace', [
1353 \ '\V>backtrace',
1354 \ '\V 3 command line',
1355 \ '\V 2 script ' .. file1 .. '[11]',
1356 \ '\V->1 function <SNR>\.\*_File1Func[4]',
1357 \ '\V 0 script ' .. file2,
1358 \ '\Vline 3: func s:File2Func( arg )',
1359 \ ],
1360 \ #{ match: 'pattern' } )
1361 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1362 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1363 call RunDbgCmd(buf,
1364 \ 'echo l:local_var',
1365 \ [ 'E121: Undefined variable: l:local_var' ] )
1366
1367 call RunDbgCmd(buf, 'up')
1368 call RunDbgCmd(buf, 'backtrace', [
1369 \ '\V>backtrace',
1370 \ '\V 3 command line',
1371 \ '\V->2 script ' .. file1 .. '[11]',
1372 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1373 \ '\V 0 script ' .. file2,
1374 \ '\Vline 3: func s:File2Func( arg )',
1375 \ ],
1376 \ #{ match: 'pattern' } )
1377
1378 " FIXME: Unexpected (wrong script vars are used)
1379 call RunDbgCmd(buf,
1380 \ 'echo s:file1_var',
1381 \ [ 'E121: Undefined variable: s:file1_var' ] )
1382 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1383
Bram Moolenaare99d4222021-06-13 14:01:26 +02001384 call RunDbgCmd(buf, 'cont')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001385 call StopVimInTerminal(buf)
1386 call delete('Xtest1.vim')
1387 call delete('Xtest2.vim')
1388endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001389
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001390" Test for setting a breakpoint on a :endif where the :if condition is false
1391" and then quit the script. This should generate an interrupt.
1392func Test_breakpt_endif_intr()
1393 func F()
1394 let g:Xpath ..= 'a'
1395 if v:false
1396 let g:Xpath ..= 'b'
1397 endif
1398 invalid_command
1399 endfunc
1400
1401 let g:Xpath = ''
1402 breakadd func 4 F
1403 try
1404 let caught_intr = 0
1405 debuggreedy
1406 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001407 catch /^Vim:Interrupt$/
1408 call assert_match('\.F, line 4', v:throwpoint)
1409 let caught_intr = 1
1410 endtry
1411 0debuggreedy
1412 call assert_equal(1, caught_intr)
1413 call assert_equal('a', g:Xpath)
1414 breakdel *
1415 delfunc F
1416endfunc
1417
1418" Test for setting a breakpoint on a :else where the :if condition is false
1419" and then quit the script. This should generate an interrupt.
1420func Test_breakpt_else_intr()
1421 func F()
1422 let g:Xpath ..= 'a'
1423 if v:false
1424 let g:Xpath ..= 'b'
1425 else
1426 invalid_command
1427 endif
1428 invalid_command
1429 endfunc
1430
1431 let g:Xpath = ''
1432 breakadd func 4 F
1433 try
1434 let caught_intr = 0
1435 debuggreedy
1436 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001437 catch /^Vim:Interrupt$/
1438 call assert_match('\.F, line 4', v:throwpoint)
1439 let caught_intr = 1
1440 endtry
1441 0debuggreedy
1442 call assert_equal(1, caught_intr)
1443 call assert_equal('a', g:Xpath)
1444 breakdel *
1445 delfunc F
1446endfunc
1447
1448" Test for setting a breakpoint on a :endwhile where the :while condition is
1449" false and then quit the script. This should generate an interrupt.
1450func Test_breakpt_endwhile_intr()
1451 func F()
1452 let g:Xpath ..= 'a'
1453 while v:false
1454 let g:Xpath ..= 'b'
1455 endwhile
1456 invalid_command
1457 endfunc
1458
1459 let g:Xpath = ''
1460 breakadd func 4 F
1461 try
1462 let caught_intr = 0
1463 debuggreedy
1464 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001465 catch /^Vim:Interrupt$/
1466 call assert_match('\.F, line 4', v:throwpoint)
1467 let caught_intr = 1
1468 endtry
1469 0debuggreedy
1470 call assert_equal(1, caught_intr)
1471 call assert_equal('a', g:Xpath)
1472 breakdel *
1473 delfunc F
1474endfunc
1475
Bram Moolenaar16c62322020-08-13 19:20:04 +02001476" Test for setting a breakpoint on a script local function
1477func Test_breakpt_scriptlocal_func()
1478 let g:Xpath = ''
1479 func s:G()
1480 let g:Xpath ..= 'a'
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001481 endfunc
1482
Bram Moolenaar16c62322020-08-13 19:20:04 +02001483 let funcname = expand("<SID>") .. "G"
1484 exe "breakadd func 1 " .. funcname
1485 debuggreedy
1486 redir => output
1487 call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
1488 redir END
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001489 0debuggreedy
Bram Moolenaar16c62322020-08-13 19:20:04 +02001490 call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001491 call assert_equal('a', g:Xpath)
1492 breakdel *
Bram Moolenaar16c62322020-08-13 19:20:04 +02001493 exe "delfunc " .. funcname
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001494endfunc
1495
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001496" vim: shiftwidth=2 sts=2 expandtab