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.
Files changed (133) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +8 -0
  3. data/AUTHORS +10 -0
  4. data/CHANGELOG.md +2 -0
  5. data/CONTRIBUTING.md +1 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +20 -0
  8. data/README.md +5 -0
  9. data/Rakefile +28 -0
  10. data/bin/byebug +395 -0
  11. data/byebug.gemspec +29 -0
  12. data/doc/hanoi.rb +35 -0
  13. data/doc/primes.rb +28 -0
  14. data/doc/rdebug-emacs.texi +1030 -0
  15. data/doc/test-tri2.rb +18 -0
  16. data/doc/tri3.rb +8 -0
  17. data/doc/triangle.rb +12 -0
  18. data/ext/byebug/breakpoint.c +476 -0
  19. data/ext/byebug/byebug.c +512 -0
  20. data/ext/byebug/byebug.h +131 -0
  21. data/ext/byebug/context.c +424 -0
  22. data/ext/byebug/extconf.rb +21 -0
  23. data/ext/byebug/locker.c +53 -0
  24. data/lib/byebug.rb +404 -0
  25. data/lib/byebug/command.rb +232 -0
  26. data/lib/byebug/commands/breakpoints.rb +153 -0
  27. data/lib/byebug/commands/catchpoint.rb +56 -0
  28. data/lib/byebug/commands/condition.rb +49 -0
  29. data/lib/byebug/commands/continue.rb +38 -0
  30. data/lib/byebug/commands/control.rb +110 -0
  31. data/lib/byebug/commands/display.rb +122 -0
  32. data/lib/byebug/commands/edit.rb +48 -0
  33. data/lib/byebug/commands/enable.rb +202 -0
  34. data/lib/byebug/commands/eval.rb +176 -0
  35. data/lib/byebug/commands/finish.rb +43 -0
  36. data/lib/byebug/commands/frame.rb +303 -0
  37. data/lib/byebug/commands/help.rb +56 -0
  38. data/lib/byebug/commands/info.rb +462 -0
  39. data/lib/byebug/commands/irb.rb +123 -0
  40. data/lib/byebug/commands/jump.rb +66 -0
  41. data/lib/byebug/commands/kill.rb +51 -0
  42. data/lib/byebug/commands/list.rb +94 -0
  43. data/lib/byebug/commands/method.rb +84 -0
  44. data/lib/byebug/commands/quit.rb +39 -0
  45. data/lib/byebug/commands/reload.rb +40 -0
  46. data/lib/byebug/commands/save.rb +90 -0
  47. data/lib/byebug/commands/set.rb +210 -0
  48. data/lib/byebug/commands/show.rb +246 -0
  49. data/lib/byebug/commands/skip.rb +35 -0
  50. data/lib/byebug/commands/source.rb +36 -0
  51. data/lib/byebug/commands/stepping.rb +83 -0
  52. data/lib/byebug/commands/threads.rb +189 -0
  53. data/lib/byebug/commands/tmate.rb +36 -0
  54. data/lib/byebug/commands/trace.rb +56 -0
  55. data/lib/byebug/commands/variables.rb +199 -0
  56. data/lib/byebug/context.rb +58 -0
  57. data/lib/byebug/helper.rb +69 -0
  58. data/lib/byebug/interface.rb +223 -0
  59. data/lib/byebug/processor.rb +468 -0
  60. data/lib/byebug/version.rb +3 -0
  61. data/man/rdebug.1 +241 -0
  62. data/test/breakpoints_test.rb +357 -0
  63. data/test/conditions_test.rb +77 -0
  64. data/test/continue_test.rb +44 -0
  65. data/test/display_test.rb +141 -0
  66. data/test/edit_test.rb +56 -0
  67. data/test/eval_test.rb +92 -0
  68. data/test/examples/breakpoint1.rb +15 -0
  69. data/test/examples/breakpoint2.rb +7 -0
  70. data/test/examples/conditions.rb +4 -0
  71. data/test/examples/continue.rb +4 -0
  72. data/test/examples/display.rb +5 -0
  73. data/test/examples/edit.rb +3 -0
  74. data/test/examples/edit2.rb +3 -0
  75. data/test/examples/eval.rb +4 -0
  76. data/test/examples/finish.rb +20 -0
  77. data/test/examples/frame.rb +20 -0
  78. data/test/examples/frame_threads.rb +31 -0
  79. data/test/examples/help.rb +2 -0
  80. data/test/examples/info.rb +38 -0
  81. data/test/examples/info2.rb +3 -0
  82. data/test/examples/info_threads.rb +48 -0
  83. data/test/examples/irb.rb +6 -0
  84. data/test/examples/jump.rb +14 -0
  85. data/test/examples/kill.rb +2 -0
  86. data/test/examples/list.rb +12 -0
  87. data/test/examples/method.rb +15 -0
  88. data/test/examples/post_mortem.rb +19 -0
  89. data/test/examples/quit.rb +2 -0
  90. data/test/examples/reload.rb +6 -0
  91. data/test/examples/restart.rb +6 -0
  92. data/test/examples/save.rb +3 -0
  93. data/test/examples/set.rb +3 -0
  94. data/test/examples/set_annotate.rb +12 -0
  95. data/test/examples/settings.rb +1 -0
  96. data/test/examples/show.rb +2 -0
  97. data/test/examples/source.rb +3 -0
  98. data/test/examples/stepping.rb +21 -0
  99. data/test/examples/thread.rb +32 -0
  100. data/test/examples/tmate.rb +10 -0
  101. data/test/examples/trace.rb +7 -0
  102. data/test/examples/trace_threads.rb +20 -0
  103. data/test/examples/variables.rb +26 -0
  104. data/test/finish_test.rb +48 -0
  105. data/test/frame_test.rb +143 -0
  106. data/test/help_test.rb +50 -0
  107. data/test/info_test.rb +313 -0
  108. data/test/irb_test.rb +81 -0
  109. data/test/jump_test.rb +70 -0
  110. data/test/kill_test.rb +48 -0
  111. data/test/list_test.rb +145 -0
  112. data/test/method_test.rb +70 -0
  113. data/test/post_mortem_test.rb +27 -0
  114. data/test/quit_test.rb +56 -0
  115. data/test/reload_test.rb +44 -0
  116. data/test/restart_test.rb +164 -0
  117. data/test/save_test.rb +92 -0
  118. data/test/set_test.rb +177 -0
  119. data/test/show_test.rb +293 -0
  120. data/test/source_test.rb +45 -0
  121. data/test/stepping_test.rb +130 -0
  122. data/test/support/breakpoint.rb +13 -0
  123. data/test/support/context.rb +14 -0
  124. data/test/support/matchers.rb +67 -0
  125. data/test/support/mocha_extensions.rb +72 -0
  126. data/test/support/processor.rb +7 -0
  127. data/test/support/test_dsl.rb +206 -0
  128. data/test/support/test_interface.rb +68 -0
  129. data/test/test_helper.rb +10 -0
  130. data/test/tmate_test.rb +44 -0
  131. data/test/trace_test.rb +159 -0
  132. data/test/variables_test.rb +119 -0
  133. metadata +265 -0
@@ -0,0 +1,3 @@
1
+ module Byebug
2
+ VERSION = '0.0.1'
3
+ end
@@ -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