byebug 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +4 -0
  2. data/.travis.yml +0 -5
  3. data/CHANGELOG.md +6 -0
  4. data/Gemfile +1 -1
  5. data/LICENSE +23 -20
  6. data/byebug.gemspec +5 -5
  7. data/ext/byebug/breakpoint.c +102 -134
  8. data/ext/byebug/byebug.c +110 -64
  9. data/ext/byebug/byebug.h +2 -3
  10. data/ext/byebug/context.c +72 -39
  11. data/lib/byebug.rb +34 -38
  12. data/lib/byebug/command.rb +19 -24
  13. data/lib/byebug/commands/breakpoints.rb +11 -12
  14. data/lib/byebug/commands/catchpoint.rb +1 -1
  15. data/lib/byebug/commands/control.rb +2 -4
  16. data/lib/byebug/commands/finish.rb +1 -1
  17. data/lib/byebug/commands/frame.rb +15 -17
  18. data/lib/byebug/commands/info.rb +29 -28
  19. data/lib/byebug/commands/irb.rb +23 -21
  20. data/lib/byebug/commands/method.rb +4 -4
  21. data/lib/byebug/commands/reload.rb +8 -6
  22. data/lib/byebug/commands/set.rb +27 -23
  23. data/lib/byebug/commands/show.rb +6 -4
  24. data/lib/byebug/commands/stepping.rb +2 -2
  25. data/lib/byebug/commands/threads.rb +10 -10
  26. data/lib/byebug/commands/trace.rb +13 -14
  27. data/lib/byebug/commands/variables.rb +14 -12
  28. data/lib/byebug/context.rb +2 -15
  29. data/lib/byebug/interface.rb +5 -0
  30. data/lib/byebug/processor.rb +59 -64
  31. data/lib/byebug/version.rb +2 -1
  32. data/old_doc/Makefile +20 -0
  33. data/{man/rdebug.1 → old_doc/byebug.1} +5 -5
  34. data/old_doc/byebug.html +6178 -0
  35. data/old_doc/byebug.texi +3775 -0
  36. data/{doc → old_doc}/hanoi.rb +0 -0
  37. data/{doc → old_doc}/primes.rb +0 -0
  38. data/{doc → old_doc}/test-tri2.rb +0 -0
  39. data/{doc → old_doc}/tri3.rb +0 -0
  40. data/{doc → old_doc}/triangle.rb +0 -0
  41. data/test/breakpoints_test.rb +96 -60
  42. data/test/conditions_test.rb +15 -12
  43. data/test/examples/info.rb +5 -5
  44. data/test/examples/stepping.rb +1 -1
  45. data/test/frame_test.rb +40 -39
  46. data/test/info_test.rb +105 -96
  47. data/test/irb_test.rb +66 -61
  48. data/test/jump_test.rb +18 -9
  49. data/test/list_test.rb +114 -107
  50. data/test/restart_test.rb +51 -58
  51. data/test/save_test.rb +8 -7
  52. data/test/set_test.rb +8 -11
  53. data/test/show_test.rb +3 -5
  54. data/test/stepping_test.rb +43 -53
  55. data/test/support/context.rb +1 -0
  56. data/test/support/processor.rb +10 -4
  57. data/test/support/test_dsl.rb +46 -18
  58. data/test/support/test_interface.rb +8 -5
  59. data/test/test_helper.rb +2 -2
  60. data/test/trace_test.rb +123 -124
  61. metadata +39 -17
  62. data/AUTHORS +0 -10
  63. data/doc/rdebug-emacs.texi +0 -1030
@@ -35,10 +35,7 @@ describe "Frame Command" do
35
35
 
36
36
  it "must print current stack frame when without arguments" do
37
37
  enter 'break A.d', 'cont', 'up', 'frame'
38
- debug_file('frame') { check_output_includes "#0", "A::d" }
39
- # XXX: Deal with arguments
40
- #check_output_includes "#0 ", "A.d(e#String)"
41
- #check_output_includes "#0 ", "A.d"
38
+ debug_file('frame') { check_output_includes "#0", "A.d(e#String)" }
42
39
  end
43
40
 
44
41
  it "must set frame to the first one" do
@@ -54,89 +51,93 @@ describe "Frame Command" do
54
51
  it "must not set frame if the frame number is too low" do
55
52
  enter 'break 16', 'cont', 'down'
56
53
  debug_file('frame') { state.line.must_equal 16 }
57
- check_output_includes "Adjusting would put us beyond the newest (innermost) frame.", interface.error_queue
54
+ check_output_includes \
55
+ "Adjusting would put us beyond the newest (innermost) frame.",
56
+ interface.error_queue
58
57
  end
59
58
 
60
59
  it "must not set frame if the frame number is too high" do
61
60
  enter 'break 16', 'cont', 'up 100'
62
61
  debug_file('frame') { state.line.must_equal 16 }
63
- check_output_includes "Adjusting would put us beyond the oldest (initial) frame.", interface.error_queue
62
+ check_output_includes \
63
+ "Adjusting would put us beyond the oldest (initial) frame.",
64
+ interface.error_queue
64
65
  end
65
66
 
66
67
  describe "full path settings" do
67
- temporary_change_hash_value(Byebug::Command.settings, :full_path, false)
68
-
69
68
  def short_path(fullpath)
70
69
  separator = File::ALT_SEPARATOR || File::SEPARATOR
71
70
  "...#{separator}" + fullpath.split(separator)[-3..-1].join(separator)
72
71
  end
73
72
 
73
+ before do
74
+ Byebug::Command.settings[:callstyle] = :last
75
+ end
76
+
74
77
  it "must display current backtrace with full path = true" do
75
78
  enter 'set fullpath', 'break 16', 'cont', 'where'
76
- debug_file('frame')
77
- check_output_includes(
79
+ debug_file 'frame'
80
+ check_output_includes \
78
81
  "-->", "#0", "A.d(e#String)", "at line #{fullpath('frame')}:16",
79
82
  "#1", "A.c", "at line #{fullpath('frame')}:12"
80
- )
81
83
  end
82
84
 
83
85
  it "must display current backtrace with full path = false" do
84
86
  enter 'set nofullpath', 'break 16', 'cont', 'where'
85
- debug_file('frame')
86
- check_output_includes(
87
+ debug_file 'frame'
88
+ check_output_includes \
87
89
  "-->", "#0", "A.d(e#String)", "at line #{short_path(fullpath('frame'))}:16",
88
90
  "#1", "A.c", "at line #{short_path(fullpath('frame'))}:12"
89
- )
90
91
  end
91
92
  end
92
93
 
93
- describe "display backtrace with callstyle" do
94
- temporary_change_hash_value(Byebug::Command.settings, :callstyle, :last)
95
-
96
- it "must display current backtrace" do
94
+ describe "callstyles" do
95
+ it "displays current backtrace with callstyle 'last'" do
97
96
  enter 'set callstyle last', 'break 16', 'cont', 'where'
98
- debug_file('frame')
99
- check_output_includes(
97
+ debug_file 'frame'
98
+ check_output_includes \
100
99
  "-->", "#0", "A.d(e#String)", "at line #{fullpath('frame')}:16",
101
100
  "#1", "A.c", "at line #{fullpath('frame')}:12",
102
101
  "#2", "A.b", "at line #{fullpath('frame')}:8",
103
102
  "#3", "A.a", "at line #{fullpath('frame')}:5"
104
- )
105
103
  end
106
104
 
107
- it "must display current backtrace" do
108
- enter 'set callstyle short', 'break 25', 'cont', 'where'
109
- debug_file('frame')
110
- check_output_includes(
105
+ it "displays current backtrace with callstyle 'short'" do
106
+ enter 'set callstyle short', 'break 16', 'cont', 'where'
107
+ debug_file 'frame'
108
+ check_output_includes \
111
109
  "-->", "#0", "d(e)", "at line #{fullpath('frame')}:16",
112
110
  "#1", "c", "at line #{fullpath('frame')}:12",
113
111
  "#2", "b", "at line #{fullpath('frame')}:8",
114
112
  "#3", "a", "at line #{fullpath('frame')}:5"
115
- )
116
113
  end
117
114
 
118
- # NOTE: We also have support of 'tracked' callstyle in the code,
119
- # but for some reason it is not set by the 'set' command
120
- it "must not set 'tracked' callstyle" do
115
+ it "displays current backtrace with callstyle 'tracked'" do
116
+ skip("XXX: Style supported but not working....")
121
117
  enter 'set callstyle tracked'
122
- debug_file('frame')
123
- check_output_includes "Invalid call style tracked. Should be one of: 'short' or 'last'."
118
+ debug_file 'frame'
119
+ check_output_includes \
120
+ "Invalid call style tracked. Should be one of: 'shast'."
124
121
  Byebug::Command.settings[:callstyle].must_equal :last
125
122
  end
126
123
  end
127
124
 
128
- it "must change frame in another thread"
129
- it "must not change frame in another thread if specified thread doesn't exist"
125
+ it "must change to frame in another thread" do
126
+ skip("No threads supported")
127
+ end
128
+
129
+ it "must not change to frame in another thread if thread doesn't exist" do
130
+ skip("No threads supported")
131
+ end
130
132
 
131
133
  describe "Post Mortem" do
132
- # TODO: This test fails with "Segmentation fault". Probably need to fix it somehow, or forbid this
133
- # command in the post mortem mode. Seems like state.context.frame_file and state.context.frame_line
134
- # cause that.
134
+ # TODO: This test fails with "Segmentation fault". Probably need to fix it
135
+ # somehow, or forbid this command in the post mortem mode. Seems like
136
+ # state.context.frame_file and state.context.frame_line cause that.
135
137
  it "must work in post-mortem mode" do
136
138
  skip("No post morten mode for now")
137
- #enter 'cont', "frame"
138
- #debug_file "post_mortem"
139
- #pi
139
+ enter 'cont', "frame"
140
+ debug_file "post_mortem"
140
141
  end
141
142
  end
142
143
 
@@ -8,10 +8,9 @@ describe "Info Command" do
8
8
  temporary_change_hash_value(Byebug::InfoCommand.settings, :width, 15)
9
9
 
10
10
  it "must show info about all args" do
11
- skip ("XXX: How to handle args in the new API?")
12
- #enter 'break 3', 'cont', 'info args'
13
- #debug_file 'info'
14
- #check_output_includes 'a = "aaaaaaa...', 'b = "b"'
11
+ enter 'break 3', 'cont', 'info args'
12
+ debug_file 'info'
13
+ check_output_includes 'a = "aaaaaaa...', 'b = "b"'
15
14
  end
16
15
  end
17
16
 
@@ -19,15 +18,14 @@ describe "Info Command" do
19
18
  it "must show info about all breakpoints" do
20
19
  enter 'break 7', 'break 9 if a == b', 'info breakpoints'
21
20
  debug_file 'info'
22
- check_output_includes(
23
- "Num Enb What",
24
- /\d+ y at #{fullpath('info')}:7/,
25
- /\d+ y at #{fullpath('info')}:9 if a == b/
26
- )
21
+ check_output_includes "Num Enb What",
22
+ /\d+ y at #{fullpath('info')}:7/,
23
+ /\d+ y at #{fullpath('info')}:9 if a == b/
27
24
  end
28
25
 
29
26
  it "must show info about specific breakpoint" do
30
- enter 'break 7', 'break 9', ->{"info breakpoints #{breakpoint.id}"}
27
+ enter 'break 7', 'break 9',
28
+ ->{"info breakpoints #{Byebug.breakpoints.first.id}"}
31
29
  debug_file 'info'
32
30
  check_output_includes "Num Enb What", /\d+ y at #{fullpath('info')}:7/
33
31
  check_output_doesnt_include /\d+ y at #{fullpath('info')}:9/
@@ -42,13 +40,16 @@ describe "Info Command" do
42
40
  it "must show an error if no breakpoints are found" do
43
41
  enter 'break 7', 'info breakpoints 123'
44
42
  debug_file 'info'
45
- check_output_includes "No breakpoints found among list given.", interface.error_queue
43
+ check_output_includes "No breakpoints found among list given.",
44
+ interface.error_queue
46
45
  end
47
46
 
48
47
  it "must show hit count" do
49
48
  enter 'break 9', 'cont', 'info breakpoints'
50
49
  debug_file 'info'
51
- check_output_includes /\d+ y at #{fullpath('info')}:9/, "breakpoint already hit 1 time"
50
+ check_output_includes /\d+ y at #{fullpath('info')}:9/
51
+ check_output_includes /\d+ y at #{fullpath('info')}:9/,
52
+ "breakpoint already hit 1 time"
52
53
  end
53
54
  end
54
55
 
@@ -56,12 +57,10 @@ describe "Info Command" do
56
57
  it "must show all display expressions" do
57
58
  enter 'display 3 + 3', 'display a + b', 'info display'
58
59
  debug_file 'info'
59
- check_output_includes(
60
- "Auto-display expressions now in effect:",
61
- "Num Enb Expression",
62
- "1: y 3 + 3",
63
- "2: y a + b"
64
- )
60
+ check_output_includes "Auto-display expressions now in effect:",
61
+ "Num Enb Expression",
62
+ "1: y 3 + 3",
63
+ "2: y a + b"
65
64
  end
66
65
 
67
66
  it "must show a message if there are no display expressions created" do
@@ -88,7 +87,8 @@ describe "Info Command" do
88
87
  it "must show explicitly loaded files" do
89
88
  enter 'info files stat'
90
89
  debug_file 'info'
91
- check_output_includes "File #{fullpath('info')}", LineCache.stat(fullpath('info')).mtime.to_s
90
+ check_output_includes "File #{fullpath('info')}",
91
+ LineCache.stat(fullpath('info')).mtime.to_s
92
92
  end
93
93
  end
94
94
 
@@ -99,7 +99,8 @@ describe "Info Command" do
99
99
  let(:mtime) { LineCache.stat(file).mtime.to_s }
100
100
  let(:sha1) { LineCache.sha1(file) }
101
101
  let(:breakpoint_line_numbers) do
102
- columnize(LineCache.trace_line_numbers(file).to_a.sort, Byebug::InfoCommand.settings[:width])
102
+ columnize(LineCache.trace_line_numbers(file).to_a.sort,
103
+ Byebug::InfoCommand.settings[:width])
103
104
  end
104
105
 
105
106
  it "must show basic info about the file" do
@@ -133,17 +134,18 @@ describe "Info Command" do
133
134
  it "must show breakpoints in the file" do
134
135
  enter 'break 5', 'break 7', "info file #{file} breakpoints"
135
136
  debug_file 'info'
136
- check_output_includes(
137
- filename, "breakpoint line numbers:", breakpoint_line_numbers,
138
- /Breakpoint \d+ at #{file}:5/, /Breakpoint \d+ at #{file}:7/
139
- )
137
+ check_output_includes /Created breakpoint \d+ at #{file}:5/,
138
+ /Created breakpoint \d+ at #{file}:7/,
139
+ filename,
140
+ "breakpoint line numbers:", breakpoint_line_numbers
140
141
  check_output_doesnt_include lines, mtime, sha1
141
142
  end
142
143
 
143
144
  it "must show all info about the file" do
144
145
  enter "info file #{file} all"
145
146
  debug_file 'info'
146
- check_output_includes filename, lines, breakpoint_line_numbers, mtime, sha1
147
+ check_output_includes \
148
+ filename, lines, breakpoint_line_numbers, mtime, sha1
147
149
  end
148
150
 
149
151
  it "must not show info about the file if the file is not loaded" do
@@ -175,33 +177,36 @@ describe "Info Command" do
175
177
  end
176
178
  end
177
179
 
178
- # describe "Locals info" do
179
- # it "must show the current local variables" do
180
- # temporary_change_hash_value(Byebug::InfoCommand.settings, :width, 12) do
181
- # enter 'break 21', 'cont', 'info locals'
182
- # debug_file 'info'
183
- # check_output_includes 'a = "1111...', 'b = 2'
184
- # end
185
- # end
186
-
187
- # it "must fail if the local variable doesn't respond to #to_s or to #inspect" do
188
- # enter 'break 26', 'cont', 'info locals'
189
- # debug_file 'info'
190
- # check_output_includes "*Error in evaluation*"
191
- # end
192
- # end
180
+ describe "Locals info" do
181
+ it "must show the current local variables" do
182
+ temporary_change_hash_value(Byebug::InfoCommand.settings, :width, 12) do
183
+ enter 'break 21', 'cont', 'info locals'
184
+ debug_file 'info'
185
+ check_output_includes 'a = "1111...', 'b = 2'
186
+ end
187
+ end
188
+
189
+ it "must fail if the local variable doesn't respond to #to_s or to #inspect" do
190
+ enter 'break 26', 'cont', 'info locals'
191
+ debug_file 'info'
192
+ check_output_includes "*Error in evaluation*"
193
+ end
194
+ end
193
195
 
194
196
  describe "Program info" do
195
197
  it "must show the initial stop reason" do
196
198
  enter 'info program'
197
199
  debug_file 'info'
198
- check_output_includes "It stopped after stepping, next'ing or initial start."
200
+ check_output_includes \
201
+ "It stopped after stepping, next'ing or initial start."
199
202
  end
200
203
 
201
204
  it "must show the step stop reason" do
202
205
  enter 'step', 'info program'
203
206
  debug_file 'info'
204
- check_output_includes "Program stopped.", "It stopped after stepping, next'ing or initial start."
207
+ check_output_includes \
208
+ "Program stopped.",
209
+ "It stopped after stepping, next'ing or initial start."
205
210
  end
206
211
 
207
212
  it "must show the breakpoint stop reason" do
@@ -213,7 +218,8 @@ describe "Info Command" do
213
218
  it "must show the catchpoint stop reason"
214
219
 
215
220
  it "must show the unknown stop reason" do
216
- enter 'break 7', 'cont', ->{context.stubs(:stop_reason).returns("blabla"); 'info program'}
221
+ enter 'break 7', 'cont',
222
+ ->{context.stubs(:stop_reason).returns("blabla"); 'info program'}
217
223
  debug_file 'info'
218
224
  check_output_includes "Program stopped.", "unknown reason: blabla"
219
225
  end
@@ -222,76 +228,79 @@ describe "Info Command" do
222
228
  end
223
229
 
224
230
  describe "Stack info" do
231
+ before do
232
+ Byebug::InfoCommand.settings[:full_path] = true
233
+ end
225
234
  it "must show stack info" do
226
235
  enter 'break 20', 'cont', 'info stack'
227
236
  debug_file 'info'
228
- check_output_includes(
237
+ check_output_includes \
229
238
  "-->", "#0", "A.a", "at line #{fullpath('info')}:20",
230
- "#1", "at line #{fullpath('info')}:30"
231
- )
239
+ "#1", "A.b", "at line #{fullpath('info')}:30",
240
+ "#2", "at line #{fullpath('info')}:36"
232
241
  end
233
242
  end
234
243
 
235
- # describe "Thread info" do
236
- # it "must show threads info when without args" # TODO: Unreliable due to race conditions, need to fix to be reliable
237
- # # enter 'break 48', 'cont', 'info threads'
238
- # # debug_file 'info'
239
- # # check_output_includes /#<Thread:\S+ run>/, /#<Thread:\S+ run>/
240
- # # end
241
- #
242
- # it "must show thread info" do
243
- # thread_number = nil
244
- # enter ->{thread_number = context.thnum; "info thread #{context.thnum}"}
245
- # debug_file 'info'
246
- # check_output_includes "+", thread_number.to_s, /#<Thread:\S+ run>/
247
- # end
248
- #
249
- # it "must show verbose thread info" do # TODO: Unreliable due to race conditions, need to fix to be reliable
250
- # enter 'break 20', 'cont', ->{"info thread #{context.thnum} verbose"}
251
- # debug_file 'info'
252
- # check_output_includes /#<Thread:\S+ run>/, "#0", "A.a", "at line #{fullpath('info')}:20"
253
- # end
254
- #
255
- # it "must show error when unknown parameter is used" do
256
- # enter ->{"info thread #{context.thnum} blabla"}
257
- # debug_file 'info'
258
- # check_output_includes "'terse' or 'verbose' expected. Got 'blabla'", interface.error_queue
259
- # end
260
- # end
244
+ describe "Thread info" do
245
+ it "must show threads info when without args" do
246
+ skip("XXX: Unreliable due to race conditions, needs fix to be reliable")
247
+ enter 'break 48', 'cont', 'info threads'
248
+ debug_file 'info'
249
+ check_output_includes /#<Thread:\S+ run>/, /#<Thread:\S+ run>/
250
+ end
251
+
252
+ it "must show thread info" do
253
+ skip("No thread support")
254
+ thread_number = nil
255
+ enter ->{thread_number = context.thnum; "info thread #{context.thnum}"}
256
+ debug_file 'info'
257
+ check_output_includes "+", thread_number.to_s, /#<Thread:\S+ run>/
258
+ end
259
+
260
+ it "must show verbose thread info" do
261
+ skip("XXX: Unreliable due to race conditions, needs fix to be reliable")
262
+ enter 'break 20', 'cont', ->{"info thread #{context.thnum} verbose"}
263
+ debug_file 'info'
264
+ check_output_includes /#<Thread:\S+ run>/, "#0", "A.a",
265
+ "at line #{fullpath('info')}:20"
266
+ end
267
+
268
+ it "must show error when unknown parameter is used" do
269
+ skip("No thread support")
270
+ enter ->{"info thread #{context.thnum} blabla"}
271
+ debug_file 'info'
272
+ check_output_includes "'terse' or 'verbose' expected. Got 'blabla'",
273
+ interface.error_queue
274
+ end
275
+ end
261
276
 
262
277
  describe "Global Variables info" do
263
278
  it "must show global variables" do
264
- skip("XXX: handle global variables, XXX: Fix warning in test")
265
- #enter 'info global_variables'
266
- #debug_file 'info'
267
- #check_output_includes "$$ = #{Process.pid}"
279
+ enter 'info global_variables'
280
+ debug_file 'info'
281
+ check_output_includes "$$ = #{Process.pid}"
268
282
  end
269
283
  end
270
284
 
271
285
  describe "Variables info" do
272
286
  it "must show all variables" do
273
- temporary_change_hash_value(Byebug::InfoCommand.settings, :width, 30) do
274
- enter 'break 21', 'cont', 'info variables'
275
- debug_file 'info'
276
- check_output_includes(
277
- 'a = "1111111111111111111111...',
278
- "b = 2",
279
- /self = #<A:\S+.../,
280
- '@bla = "blabla"',
281
- '@foo = "bar"'
282
- )
283
- end
287
+ Byebug::InfoCommand.settings[:width] = 30
288
+ enter 'break 21', 'cont', 'info variables'
289
+ debug_file 'info'
290
+ check_output_includes 'a = "1111111111111111111111...',
291
+ 'b = 2',
292
+ /self = #<A:\S+.../,
293
+ '@bla = "blabla"',
294
+ '@foo = "bar"'
284
295
  end
285
296
 
286
297
  it "must fail if the variable doesn't respond to #to_s or to #inspect" do
287
298
  enter 'break 26', 'cont', 'info variables'
288
299
  debug_file 'info'
289
- check_output_includes(
290
- 'a = *Error in evaluation*',
291
- /self = #<A:\S+.../,
292
- '@bla = "blabla"',
293
- '@foo = "bar"'
294
- )
300
+ check_output_includes 'a = *Error in evaluation*',
301
+ /self = #<A:\S+.../,
302
+ '@bla = "blabla"',
303
+ '@foo = "bar"'
295
304
  end
296
305
 
297
306
  it "must handle printf strings correctly" do
@@ -304,9 +313,9 @@ describe "Info Command" do
304
313
  describe "Post Mortem" do
305
314
  it "must work in post-mortem mode" do
306
315
  skip("No post morten mode for now")
307
- #enter 'cont', 'info line'
308
- #debug_file "post_mortem"
309
- #check_output_includes "Line 8 of \"#{fullpath('post_mortem')}\""
316
+ enter 'cont', 'info line'
317
+ debug_file "post_mortem"
318
+ check_output_includes "Line 8 of \"#{fullpath('post_mortem')}\""
310
319
  end
311
320
  end
312
321