byebug 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +10 -0
- data/.travis.yml +8 -0
- data/AUTHORS +10 -0
- data/CHANGELOG.md +2 -0
- data/CONTRIBUTING.md +1 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +5 -0
- data/Rakefile +28 -0
- data/bin/byebug +395 -0
- data/byebug.gemspec +29 -0
- data/doc/hanoi.rb +35 -0
- data/doc/primes.rb +28 -0
- data/doc/rdebug-emacs.texi +1030 -0
- data/doc/test-tri2.rb +18 -0
- data/doc/tri3.rb +8 -0
- data/doc/triangle.rb +12 -0
- data/ext/byebug/breakpoint.c +476 -0
- data/ext/byebug/byebug.c +512 -0
- data/ext/byebug/byebug.h +131 -0
- data/ext/byebug/context.c +424 -0
- data/ext/byebug/extconf.rb +21 -0
- data/ext/byebug/locker.c +53 -0
- data/lib/byebug.rb +404 -0
- data/lib/byebug/command.rb +232 -0
- data/lib/byebug/commands/breakpoints.rb +153 -0
- data/lib/byebug/commands/catchpoint.rb +56 -0
- data/lib/byebug/commands/condition.rb +49 -0
- data/lib/byebug/commands/continue.rb +38 -0
- data/lib/byebug/commands/control.rb +110 -0
- data/lib/byebug/commands/display.rb +122 -0
- data/lib/byebug/commands/edit.rb +48 -0
- data/lib/byebug/commands/enable.rb +202 -0
- data/lib/byebug/commands/eval.rb +176 -0
- data/lib/byebug/commands/finish.rb +43 -0
- data/lib/byebug/commands/frame.rb +303 -0
- data/lib/byebug/commands/help.rb +56 -0
- data/lib/byebug/commands/info.rb +462 -0
- data/lib/byebug/commands/irb.rb +123 -0
- data/lib/byebug/commands/jump.rb +66 -0
- data/lib/byebug/commands/kill.rb +51 -0
- data/lib/byebug/commands/list.rb +94 -0
- data/lib/byebug/commands/method.rb +84 -0
- data/lib/byebug/commands/quit.rb +39 -0
- data/lib/byebug/commands/reload.rb +40 -0
- data/lib/byebug/commands/save.rb +90 -0
- data/lib/byebug/commands/set.rb +210 -0
- data/lib/byebug/commands/show.rb +246 -0
- data/lib/byebug/commands/skip.rb +35 -0
- data/lib/byebug/commands/source.rb +36 -0
- data/lib/byebug/commands/stepping.rb +83 -0
- data/lib/byebug/commands/threads.rb +189 -0
- data/lib/byebug/commands/tmate.rb +36 -0
- data/lib/byebug/commands/trace.rb +56 -0
- data/lib/byebug/commands/variables.rb +199 -0
- data/lib/byebug/context.rb +58 -0
- data/lib/byebug/helper.rb +69 -0
- data/lib/byebug/interface.rb +223 -0
- data/lib/byebug/processor.rb +468 -0
- data/lib/byebug/version.rb +3 -0
- data/man/rdebug.1 +241 -0
- data/test/breakpoints_test.rb +357 -0
- data/test/conditions_test.rb +77 -0
- data/test/continue_test.rb +44 -0
- data/test/display_test.rb +141 -0
- data/test/edit_test.rb +56 -0
- data/test/eval_test.rb +92 -0
- data/test/examples/breakpoint1.rb +15 -0
- data/test/examples/breakpoint2.rb +7 -0
- data/test/examples/conditions.rb +4 -0
- data/test/examples/continue.rb +4 -0
- data/test/examples/display.rb +5 -0
- data/test/examples/edit.rb +3 -0
- data/test/examples/edit2.rb +3 -0
- data/test/examples/eval.rb +4 -0
- data/test/examples/finish.rb +20 -0
- data/test/examples/frame.rb +20 -0
- data/test/examples/frame_threads.rb +31 -0
- data/test/examples/help.rb +2 -0
- data/test/examples/info.rb +38 -0
- data/test/examples/info2.rb +3 -0
- data/test/examples/info_threads.rb +48 -0
- data/test/examples/irb.rb +6 -0
- data/test/examples/jump.rb +14 -0
- data/test/examples/kill.rb +2 -0
- data/test/examples/list.rb +12 -0
- data/test/examples/method.rb +15 -0
- data/test/examples/post_mortem.rb +19 -0
- data/test/examples/quit.rb +2 -0
- data/test/examples/reload.rb +6 -0
- data/test/examples/restart.rb +6 -0
- data/test/examples/save.rb +3 -0
- data/test/examples/set.rb +3 -0
- data/test/examples/set_annotate.rb +12 -0
- data/test/examples/settings.rb +1 -0
- data/test/examples/show.rb +2 -0
- data/test/examples/source.rb +3 -0
- data/test/examples/stepping.rb +21 -0
- data/test/examples/thread.rb +32 -0
- data/test/examples/tmate.rb +10 -0
- data/test/examples/trace.rb +7 -0
- data/test/examples/trace_threads.rb +20 -0
- data/test/examples/variables.rb +26 -0
- data/test/finish_test.rb +48 -0
- data/test/frame_test.rb +143 -0
- data/test/help_test.rb +50 -0
- data/test/info_test.rb +313 -0
- data/test/irb_test.rb +81 -0
- data/test/jump_test.rb +70 -0
- data/test/kill_test.rb +48 -0
- data/test/list_test.rb +145 -0
- data/test/method_test.rb +70 -0
- data/test/post_mortem_test.rb +27 -0
- data/test/quit_test.rb +56 -0
- data/test/reload_test.rb +44 -0
- data/test/restart_test.rb +164 -0
- data/test/save_test.rb +92 -0
- data/test/set_test.rb +177 -0
- data/test/show_test.rb +293 -0
- data/test/source_test.rb +45 -0
- data/test/stepping_test.rb +130 -0
- data/test/support/breakpoint.rb +13 -0
- data/test/support/context.rb +14 -0
- data/test/support/matchers.rb +67 -0
- data/test/support/mocha_extensions.rb +72 -0
- data/test/support/processor.rb +7 -0
- data/test/support/test_dsl.rb +206 -0
- data/test/support/test_interface.rb +68 -0
- data/test/test_helper.rb +10 -0
- data/test/tmate_test.rb +44 -0
- data/test/trace_test.rb +159 -0
- data/test/variables_test.rb +119 -0
- metadata +265 -0
data/man/rdebug.1
ADDED
@@ -0,0 +1,241 @@
|
|
1
|
+
.\" $Id: rdebug.1 516 2007-12-31 05:55:24Z rockyb $
|
2
|
+
.TH rdebug 1
|
3
|
+
.SH NAME
|
4
|
+
rdebug \- Fast Ruby byebug
|
5
|
+
.SH SYNOPSIS
|
6
|
+
.B rdebug
|
7
|
+
[byebug-options]
|
8
|
+
rdebug
|
9
|
+
[script-options...]
|
10
|
+
.SH "DESCRIPTION"
|
11
|
+
This manual page documents briefly the
|
12
|
+
.BR rdebug
|
13
|
+
command.
|
14
|
+
.PP
|
15
|
+
.B rdebug
|
16
|
+
is a fast implementation of the standard Ruby byebug debug.rb. It
|
17
|
+
is implemented by utilizing a Ruby C API hook, allows for remote
|
18
|
+
debugging and can be used as the Ruby byebug backend interface for a
|
19
|
+
development environment.
|
20
|
+
.PP
|
21
|
+
The commands generally follow gdb's command set unless there's good
|
22
|
+
reason not to.
|
23
|
+
|
24
|
+
.PP
|
25
|
+
rdebug can do four main kinds of things (plus other things in support of
|
26
|
+
these) to help you catch bugs in the act:
|
27
|
+
|
28
|
+
.TP
|
29
|
+
\ \ \ \(bu
|
30
|
+
Start or restart your Ruby script, specifying arguments that might
|
31
|
+
affect its behavior.
|
32
|
+
|
33
|
+
.TP
|
34
|
+
\ \ \ \(bu
|
35
|
+
Make your program stop at various points possibly determined by
|
36
|
+
specified conditions.
|
37
|
+
|
38
|
+
.TP
|
39
|
+
\ \ \ \(bu
|
40
|
+
Examine what has happened when your program has stopped.
|
41
|
+
|
42
|
+
.TP
|
43
|
+
\ \ \ \(bu
|
44
|
+
Change things in your program, so you can experiment with correcting the
|
45
|
+
effects of one bug and go on to learn about another.
|
46
|
+
.PP
|
47
|
+
|
48
|
+
Here are some of the most frequently-needed commands:
|
49
|
+
.TP
|
50
|
+
.B break \fR[\|\fIfile\fB:\fIline\fR\fR|\fIclass.method\fR] \fR[if \fIexpr\fR]
|
51
|
+
\&
|
52
|
+
Set a breakpoint at \c
|
53
|
+
.I class.method\c
|
54
|
+
\& or at the specified file and line.
|
55
|
+
.TP
|
56
|
+
.B continue \fR[\fIline\fR]
|
57
|
+
Continue running your program (after stopping, e.g. at a
|
58
|
+
breakpoint). If a line is given a one-time breakpoint is set there.
|
59
|
+
.TP
|
60
|
+
.B delete \fR[\fIbreakpoint-numbers\fR]
|
61
|
+
\&
|
62
|
+
Delete breakpoints by number. If no number is given delete all breakpoints.
|
63
|
+
.TP
|
64
|
+
.B down \fR[\|\fIcount\fR\|]
|
65
|
+
Move down one block frame. If count is given move up that many frames. A negative number
|
66
|
+
goes the other direction and is like the up command
|
67
|
+
.TP
|
68
|
+
.B finish
|
69
|
+
Run until the completion of the current function or method.
|
70
|
+
.TP
|
71
|
+
.BI frame " frame-number"
|
72
|
+
Set the stack frame to \fIframe-number\fR for purposes of examinine local variables. For positioning relative to the current frame, use
|
73
|
+
.B up
|
74
|
+
or
|
75
|
+
.B down. A negative number starts counting from the other end.
|
76
|
+
.TP
|
77
|
+
.B help \fR[\|\fIname\fR\|]
|
78
|
+
Show information about rdebug command \c
|
79
|
+
.I name\c
|
80
|
+
\&, or general information
|
81
|
+
about using rdebug.
|
82
|
+
.TP
|
83
|
+
.B info \fR[\|\fIname\fR\|]
|
84
|
+
Get the various information usually about the debugged program.
|
85
|
+
.TP
|
86
|
+
.B irb \fIcommand\fR
|
87
|
+
Run an interactive ruby shell (irb) using the current environment.
|
88
|
+
.TP
|
89
|
+
.B list \fR[\|\fIfile\fB:\fIline\fR|\fIfunction]
|
90
|
+
type the text of the program in the vicinity of where it is presently stopped
|
91
|
+
or at the specified function or file and line.
|
92
|
+
.TP
|
93
|
+
.B next \fR[\|\fIcount\fR\|]
|
94
|
+
Execute next program line(s) (after stopping); step \c
|
95
|
+
.I over\c
|
96
|
+
\& any
|
97
|
+
function calls in the line.
|
98
|
+
.TP
|
99
|
+
.BI pp " expr"\c
|
100
|
+
\&
|
101
|
+
Pretty print the value of an expression.
|
102
|
+
.TP
|
103
|
+
.BI print " expr"\c
|
104
|
+
\&
|
105
|
+
Display the value of an expression.
|
106
|
+
.TP
|
107
|
+
.BI ps " expr"\c
|
108
|
+
\&
|
109
|
+
Print an array as a columized sorted list.
|
110
|
+
.TP
|
111
|
+
.B quit
|
112
|
+
Exit from the byebug.
|
113
|
+
.TP
|
114
|
+
.B run \fR[\|\fIarglist\fR\|]
|
115
|
+
(Re)start your program (with \c
|
116
|
+
.I arglist\c
|
117
|
+
\&, if specified). If you want the byebug to get reloaded, use
|
118
|
+
.B restart
|
119
|
+
instead.
|
120
|
+
.TP
|
121
|
+
.B set
|
122
|
+
Modify parts of the byebug environment.
|
123
|
+
.TP
|
124
|
+
.B show
|
125
|
+
See the byebug environment settings
|
126
|
+
.TP
|
127
|
+
.BI source " filename"\c
|
128
|
+
\&
|
129
|
+
Read and execute the lines in file \fIfilename\fR as a series of byebug
|
130
|
+
commands.
|
131
|
+
.TP
|
132
|
+
.B step \fR[\|\fIcount\fR\|]
|
133
|
+
Execute next program line(s) (after stopping); step \c
|
134
|
+
.I into\c
|
135
|
+
\& any
|
136
|
+
function calls in the line.
|
137
|
+
.TP
|
138
|
+
.B up \fR[\|\fIcount\fR\|]
|
139
|
+
Move up one block frame. If count is given move up that many frames. A negative number
|
140
|
+
goes the other direction and is like the down command
|
141
|
+
.TP
|
142
|
+
.B where \fR[\|\fIcount\fR\|]
|
143
|
+
Display all or \fIcount\fR items of the program stack.
|
144
|
+
.PP
|
145
|
+
For full details on rdebug, see \c
|
146
|
+
https://github.com/cldwalker/byebug
|
147
|
+
.SH OPTIONS
|
148
|
+
.PP
|
149
|
+
.TP 10
|
150
|
+
.TP
|
151
|
+
.B \-A | \-\-annotate LEVEL
|
152
|
+
Set gdb-style annotation to LEVEL, a number. Additional information is output
|
153
|
+
automatically when program state is changed. This can be used by
|
154
|
+
front-ends such as GNU Emacs to post this updated information without
|
155
|
+
having to poll for it.
|
156
|
+
.TP
|
157
|
+
.B \-\-client
|
158
|
+
Connect to a remote byebug. Used with another rdebug invocation using \-\-server.
|
159
|
+
See also \-\-host and \-\-cport options
|
160
|
+
.TP
|
161
|
+
.B \-\-cport=PORT
|
162
|
+
Port used for control commands.
|
163
|
+
.TP
|
164
|
+
.B \-d | \-\-debug
|
165
|
+
Set $DEBUG true.
|
166
|
+
.TP
|
167
|
+
.B \-\-emacs
|
168
|
+
Activates full GNU Emacs mode. Is the equivalent of setting the
|
169
|
+
options \-\-emacs\-basic, \-\-annotate=3, \-\-no-stop, \-\-no\-control
|
170
|
+
and \-\-post\-mortem.
|
171
|
+
.TP
|
172
|
+
.B \-\-emacs-basic
|
173
|
+
Activates GNU Emacs mode. Byebug prompts are prefaced with two octal
|
174
|
+
032 characters.
|
175
|
+
.TP
|
176
|
+
.B \-h | \-\-host=HOST
|
177
|
+
Host name used for remote debugging.
|
178
|
+
.TP
|
179
|
+
.B \-I | \-\-include PATH
|
180
|
+
Add PATH to $LOAD_PATH
|
181
|
+
.TP
|
182
|
+
.B \-m | \-\-post-mortem
|
183
|
+
Activate post-mortem mode.
|
184
|
+
.TP
|
185
|
+
.B \-\-no-control
|
186
|
+
Do not automatically start control thread.
|
187
|
+
.TP
|
188
|
+
.B \-\-no\-stop
|
189
|
+
Do not stop when script is loaded.
|
190
|
+
.TP
|
191
|
+
.B \-p | \-\-port=PORT
|
192
|
+
Host name used for remote debugging.
|
193
|
+
.TP
|
194
|
+
.B \-r | \-\-require SCRIPT
|
195
|
+
Require the library, before executing your script.
|
196
|
+
.TP
|
197
|
+
.B \-\-script FILE
|
198
|
+
Name of the script file to run.
|
199
|
+
.TP
|
200
|
+
.B \-x | \-\-trace
|
201
|
+
Show lines before executing them.
|
202
|
+
.TP
|
203
|
+
.B \-\-no\-quit
|
204
|
+
Do not quit when script terminates. Instead rerun the program.
|
205
|
+
.TP
|
206
|
+
.B \-\-version
|
207
|
+
Show the version number and exit.
|
208
|
+
.TP
|
209
|
+
.B \-\-verbose
|
210
|
+
Turn on verbose mode.
|
211
|
+
.TP
|
212
|
+
.B \-\-v
|
213
|
+
Print the version number, then turn on verbose mode if a script name
|
214
|
+
is given. If no script name is given just exit after printing the
|
215
|
+
version number.
|
216
|
+
.TP
|
217
|
+
.B \-\-nx
|
218
|
+
Don't execute commands found in any initialization files, e.g. .rdebugrc.
|
219
|
+
.TP
|
220
|
+
.B \-\-keep-frame-binding
|
221
|
+
Keep frame bindings.
|
222
|
+
.TP
|
223
|
+
.B \-\-script=FILE
|
224
|
+
Name of the script file to run
|
225
|
+
.B \-s | \-\-server
|
226
|
+
Listen for remote connections. Another rdebug session accesses using the \-\-client option.
|
227
|
+
See also the \-\-host, \-\-port and
|
228
|
+
\-\-cport options
|
229
|
+
.TP
|
230
|
+
.B \-w | \-\-wait
|
231
|
+
Wait for a client connection, implies -s option.
|
232
|
+
.TP
|
233
|
+
.B \-\-help
|
234
|
+
Show invocation help and exit.
|
235
|
+
.PD
|
236
|
+
.SH "SEE ALSO"
|
237
|
+
.Sp
|
238
|
+
https://github.com/cldwalker/byebug
|
239
|
+
.SH AUTHOR
|
240
|
+
rdebug was written by Kent Siblev. This manual page was written by
|
241
|
+
Rocky Bernstein <rocky@gnu.org>
|
@@ -0,0 +1,357 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
describe "Breakpoints" do
|
4
|
+
include TestDsl
|
5
|
+
|
6
|
+
describe "setting breakpoint in the current file" do
|
7
|
+
before { enter 'break 10' }
|
8
|
+
subject { breakpoint }
|
9
|
+
|
10
|
+
def check_subject(field, value)
|
11
|
+
debug_file("breakpoint1") { subject.send(field).must_equal value }
|
12
|
+
end
|
13
|
+
|
14
|
+
it("must have correct pos") { check_subject(:pos, 10) }
|
15
|
+
it("must have correct source") { check_subject(:source, fullpath("breakpoint1")) }
|
16
|
+
it("must have correct expression") { check_subject(:expr, nil) }
|
17
|
+
it("must have correct hit count") { check_subject(:hit_count, 0) }
|
18
|
+
it("must have correct hit value") { check_subject(:hit_value, 0) }
|
19
|
+
it("must be enabled") { check_subject(:enabled?, true) }
|
20
|
+
it("must return right response") do
|
21
|
+
id = nil
|
22
|
+
debug_file('breakpoint1') { id = subject.id }
|
23
|
+
check_output_includes "Breakpoint #{id} file #{fullpath('breakpoint1')}, line 10"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "using shortcut for the command" do
|
28
|
+
before { enter 'b 10' }
|
29
|
+
it "must set a breakpoint" do
|
30
|
+
debug_file("breakpoint1") { Byebug.breakpoints.size.must_equal 1 }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "setting breakpoint to unexistent line" do
|
35
|
+
before { enter 'break 100' }
|
36
|
+
|
37
|
+
it "must not create a breakpoint" do
|
38
|
+
debug_file("breakpoint1") { Byebug.breakpoints.must_be_empty }
|
39
|
+
end
|
40
|
+
|
41
|
+
it "must show an error" do
|
42
|
+
debug_file("breakpoint1")
|
43
|
+
check_output_includes "There are only #{LineCache.size(fullpath('breakpoint1'))} lines in file \"breakpoint1.rb\".", interface.error_queue
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
describe "setting breakpoint to incorrect line" do
|
49
|
+
before { enter 'break 11' }
|
50
|
+
|
51
|
+
it "must not create a breakpoint" do
|
52
|
+
debug_file("breakpoint1") { Byebug.breakpoints.must_be_empty }
|
53
|
+
end
|
54
|
+
|
55
|
+
it "must show an error" do
|
56
|
+
debug_file("breakpoint1")
|
57
|
+
check_output_includes 'Line 11 is not a stopping point in file "breakpoint1.rb".', interface.error_queue
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "stopping at breakpoint" do
|
62
|
+
it "must stop at the correct line" do
|
63
|
+
enter 'break 14', 'cont'
|
64
|
+
debug_file("breakpoint1") { state.line.must_equal 14 }
|
65
|
+
end
|
66
|
+
|
67
|
+
it "must stop at the correct file" do
|
68
|
+
enter 'break 14', 'cont'
|
69
|
+
debug_file("breakpoint1") { state.file.must_equal fullpath("breakpoint1") }
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "show a message" do
|
73
|
+
temporary_change_hash_value(Byebug::Command.settings, :basename, false)
|
74
|
+
|
75
|
+
it "must show a message with full filename" do
|
76
|
+
enter 'break 14', 'cont'
|
77
|
+
debug_file("breakpoint1")
|
78
|
+
check_output_includes "Breakpoint 1 at #{fullpath('breakpoint1')}:14"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "must show a message with basename" do
|
82
|
+
enter 'set basename', 'break 14', 'cont'
|
83
|
+
debug_file("breakpoint1")
|
84
|
+
check_output_includes "Breakpoint 1 at breakpoint1.rb:14"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
describe "reloading source on change" do
|
91
|
+
temporary_change_hash_value(Byebug::Command.settings, :reload_source_on_change, false)
|
92
|
+
|
93
|
+
it "must not reload source if autoreload is not set" do
|
94
|
+
enter(
|
95
|
+
'set noautoreload',
|
96
|
+
->{change_line_in_file(fullpath('breakpoint1'), 14, ''); 'break 14'},
|
97
|
+
->{change_line_in_file(fullpath('breakpoint1'), 14, 'c = a + b'); 'cont'}
|
98
|
+
)
|
99
|
+
debug_file "breakpoint1"
|
100
|
+
check_output_includes "Breakpoint 1 at #{fullpath('breakpoint1')}:14"
|
101
|
+
end
|
102
|
+
|
103
|
+
it "must reload source if autoreload is set" do
|
104
|
+
enter(
|
105
|
+
'set autoreload',
|
106
|
+
->{change_line_in_file(fullpath('breakpoint1'), 14, ''); 'break 14'},
|
107
|
+
# Setting second breakpoint just to reload the source code after rolling the file changes back
|
108
|
+
->{change_line_in_file(fullpath('breakpoint1'), 14, 'c = a + b'); 'break 15'}, 'cont'
|
109
|
+
)
|
110
|
+
debug_file "breakpoint1"
|
111
|
+
check_output_includes "Line 14 is not a stopping point in file \"breakpoint1.rb\".", interface.error_queue
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "set breakpoint in a file" do
|
116
|
+
describe "successfully" do
|
117
|
+
before do
|
118
|
+
enter "break #{fullpath('breakpoint2')}:3", 'cont'
|
119
|
+
end
|
120
|
+
|
121
|
+
it "must stop at the correct line" do
|
122
|
+
debug_file("breakpoint1") { state.line.must_equal 3 }
|
123
|
+
end
|
124
|
+
|
125
|
+
it "must stop at the correct file" do
|
126
|
+
debug_file("breakpoint1") { state.file.must_equal fullpath("breakpoint2") }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "when setting breakpoint to unexisted file" do
|
131
|
+
before do
|
132
|
+
enter "break asf:324"
|
133
|
+
debug_file("breakpoint1")
|
134
|
+
end
|
135
|
+
it "must show an error" do
|
136
|
+
check_output_includes "No source file named asf", interface.error_queue
|
137
|
+
end
|
138
|
+
|
139
|
+
it "must ask about setting breakpoint anyway" do
|
140
|
+
check_output_includes "Set breakpoint anyway? (y/n)", interface.confirm_queue
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "set breakpoint to a method" do
|
146
|
+
describe "set breakpoint to an instance method" do
|
147
|
+
before do
|
148
|
+
enter 'break A#b', 'cont'
|
149
|
+
end
|
150
|
+
|
151
|
+
it "must stop at the correct line" do
|
152
|
+
debug_file("breakpoint1") { state.line.must_equal 5 }
|
153
|
+
end
|
154
|
+
|
155
|
+
it "must stop at the correct file" do
|
156
|
+
debug_file("breakpoint1") { state.file.must_equal fullpath("breakpoint1") }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "set breakpoint to a class method" do
|
161
|
+
before do
|
162
|
+
enter 'break A.a', 'cont'
|
163
|
+
end
|
164
|
+
|
165
|
+
it "must stop at the correct line" do
|
166
|
+
debug_file("breakpoint1") { state.line.must_equal 2 }
|
167
|
+
end
|
168
|
+
|
169
|
+
it "must stop at the correct file" do
|
170
|
+
debug_file("breakpoint1") { state.file.must_equal fullpath("breakpoint1") }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "set breakpoint to unexisted class" do
|
175
|
+
it "must show an error" do
|
176
|
+
enter "break B.a"
|
177
|
+
debug_file("breakpoint1")
|
178
|
+
check_output_includes "Unknown class B.", interface.error_queue
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
describe "set breakpoint to an invalid location" do
|
185
|
+
before { enter "break foo" }
|
186
|
+
|
187
|
+
it "must not create a breakpoint" do
|
188
|
+
debug_file("breakpoint1") { Byebug.breakpoints.must_be_empty }
|
189
|
+
end
|
190
|
+
|
191
|
+
it "must show an error" do
|
192
|
+
debug_file("breakpoint1")
|
193
|
+
check_output_includes 'Invalid breakpoint location: foo.', interface.error_queue
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
describe "disabling a breakpoint" do
|
199
|
+
describe "successfully" do
|
200
|
+
before { enter "break 14" }
|
201
|
+
|
202
|
+
describe "short syntax" do
|
203
|
+
before { enter ->{"disable #{breakpoint.id}"}, "break 15" }
|
204
|
+
it "must have a breakpoint with #enabled? returning false" do
|
205
|
+
debug_file("breakpoint1") { breakpoint.enabled?.must_equal false }
|
206
|
+
end
|
207
|
+
|
208
|
+
it "must not stop on the disabled breakpoint" do
|
209
|
+
enter "cont"
|
210
|
+
debug_file("breakpoint1") { state.line.must_equal 15 }
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "full syntax" do
|
215
|
+
before { enter ->{"disable breakpoints #{breakpoint.id}"}, "break 15" }
|
216
|
+
it "must have a breakpoint with #enabled? returning false" do
|
217
|
+
debug_file("breakpoint1") { breakpoint.enabled?.must_equal false }
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe "errors" do
|
223
|
+
it "must show an error if syntax is incorrect" do
|
224
|
+
enter "disable"
|
225
|
+
debug_file("breakpoint1")
|
226
|
+
check_output_includes(
|
227
|
+
'"disable" must be followed "display", "breakpoints" or breakpoint numbers.',
|
228
|
+
interface.error_queue
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "must show an error if no breakpoints is set" do
|
233
|
+
enter "disable 1"
|
234
|
+
debug_file("breakpoint1")
|
235
|
+
check_output_includes 'No breakpoints have been set.', interface.error_queue
|
236
|
+
end
|
237
|
+
|
238
|
+
it "must show an error if not a number is provided as an argument to 'disable' command" do
|
239
|
+
enter "break 14", "disable foo"
|
240
|
+
debug_file("breakpoint1")
|
241
|
+
check_output_includes "Disable breakpoints argument 'foo' needs to be a number."
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "enabling a breakpoint" do
|
247
|
+
describe "successfully" do
|
248
|
+
before { enter "break 14" }
|
249
|
+
describe "short syntax" do
|
250
|
+
before { enter ->{"enable #{breakpoint.id}"}, "break 15" }
|
251
|
+
|
252
|
+
it "must have a breakpoint with #enabled? returning true" do
|
253
|
+
debug_file("breakpoint1") { breakpoint.enabled?.must_equal true }
|
254
|
+
end
|
255
|
+
|
256
|
+
it "must stop on the enabled breakpoint" do
|
257
|
+
enter "cont"
|
258
|
+
debug_file("breakpoint1") { state.line.must_equal 14 }
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe "full syntax" do
|
263
|
+
before { enter ->{"enable breakpoints #{breakpoint.id}"}, "break 15" }
|
264
|
+
|
265
|
+
it "must have a breakpoint with #enabled? returning true" do
|
266
|
+
debug_file("breakpoint1") { breakpoint.enabled?.must_equal true }
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
describe "errors" do
|
272
|
+
it "must show an error if syntax is incorrect" do
|
273
|
+
enter "enable"
|
274
|
+
debug_file("breakpoint1")
|
275
|
+
check_output_includes(
|
276
|
+
'"enable" must be followed "display", "breakpoints" or breakpoint numbers.',
|
277
|
+
interface.error_queue
|
278
|
+
)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
describe "deleting a breakpoint" do
|
284
|
+
before { enter "break 14", ->{"delete #{breakpoint.id}"}, "break 15" }
|
285
|
+
|
286
|
+
it "must have only one breakpoint" do
|
287
|
+
debug_file("breakpoint1") { Byebug.breakpoints.size.must_equal 1 }
|
288
|
+
end
|
289
|
+
|
290
|
+
it "must not stop on the disabled breakpoint" do
|
291
|
+
enter "cont"
|
292
|
+
debug_file("breakpoint1") { state.line.must_equal 15 }
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe "Conditional breakpoints" do
|
297
|
+
it "must stop if the condition is true" do
|
298
|
+
enter "break 14 if b == 5", "break 15", "cont"
|
299
|
+
debug_file("breakpoint1") { state.line.must_equal 14 }
|
300
|
+
end
|
301
|
+
|
302
|
+
it "must skip if the condition is false" do
|
303
|
+
enter "break 14 if b == 3", "break 15", "cont"
|
304
|
+
debug_file("breakpoint1") { state.line.must_equal 15 }
|
305
|
+
end
|
306
|
+
|
307
|
+
it "must show an error when conditional syntax is wrong" do
|
308
|
+
enter "break 14 ifa b == 3", "break 15", "cont"
|
309
|
+
debug_file("breakpoint1") { state.line.must_equal 15 }
|
310
|
+
check_output_includes "Expecting 'if' in breakpoint condition; got: ifa b == 3.", interface.error_queue
|
311
|
+
end
|
312
|
+
|
313
|
+
describe "enabling with wrong conditional syntax" do
|
314
|
+
before do
|
315
|
+
enter(
|
316
|
+
"break 14",
|
317
|
+
->{"disable #{breakpoint.id}"},
|
318
|
+
->{"cond #{breakpoint.id} b -=( 3"},
|
319
|
+
->{"enable #{breakpoint.id}"}
|
320
|
+
)
|
321
|
+
end
|
322
|
+
|
323
|
+
it "must not enable a breakpoint" do
|
324
|
+
debug_file("breakpoint1") { breakpoint.enabled?.must_equal false }
|
325
|
+
end
|
326
|
+
|
327
|
+
it "must show an error" do
|
328
|
+
debug_file("breakpoint1")
|
329
|
+
check_output_includes(
|
330
|
+
'Expression "b -=( 3" syntactically incorrect; breakpoint remains disabled.',
|
331
|
+
interface.error_queue
|
332
|
+
)
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
it "must show an error if no file or line is specified" do
|
337
|
+
enter "break ifa b == 3", "break 15", "cont"
|
338
|
+
debug_file("breakpoint1") { state.line.must_equal 15 }
|
339
|
+
check_output_includes "Invalid breakpoint location: ifa b == 3.", interface.error_queue
|
340
|
+
end
|
341
|
+
|
342
|
+
it "must show an error if expression syntax is invalid" do
|
343
|
+
enter "break if b -=) 3", "break 15", "cont"
|
344
|
+
debug_file("breakpoint1") { state.line.must_equal 15 }
|
345
|
+
check_output_includes 'Expression "b -=) 3" syntactically incorrect; breakpoint disabled.', interface.error_queue
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
describe "Post Mortem" do
|
350
|
+
it "must be able to set breakpoints in post-mortem mode" do
|
351
|
+
skip("No post morten mode for now")
|
352
|
+
#enter 'cont', 'break 12', 'cont'
|
353
|
+
#debug_file("post_mortem") { state.line.must_equal 12 }
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|