byebug 3.1.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -2
  3. data/CHANGELOG.md +15 -0
  4. data/GUIDE.md +17 -35
  5. data/Gemfile +8 -5
  6. data/LICENSE +1 -1
  7. data/README.md +10 -22
  8. data/Rakefile +1 -1
  9. data/ext/byebug/byebug.c +3 -2
  10. data/lib/byebug.rb +3 -38
  11. data/lib/byebug/commands/break.rb +83 -0
  12. data/lib/byebug/commands/catchpoint.rb +0 -1
  13. data/lib/byebug/commands/condition.rb +10 -6
  14. data/lib/byebug/commands/continue.rb +3 -6
  15. data/lib/byebug/commands/delete.rb +38 -0
  16. data/lib/byebug/commands/edit.rb +0 -2
  17. data/lib/byebug/commands/enable.rb +7 -8
  18. data/lib/byebug/commands/finish.rb +0 -2
  19. data/lib/byebug/commands/frame.rb +13 -15
  20. data/lib/byebug/commands/help.rb +1 -3
  21. data/lib/byebug/commands/history.rb +3 -3
  22. data/lib/byebug/commands/info.rb +4 -13
  23. data/lib/byebug/commands/interrupt.rb +25 -0
  24. data/lib/byebug/commands/kill.rb +0 -2
  25. data/lib/byebug/commands/list.rb +2 -4
  26. data/lib/byebug/commands/method.rb +2 -8
  27. data/lib/byebug/commands/quit.rb +0 -2
  28. data/lib/byebug/commands/reload.rb +2 -15
  29. data/lib/byebug/commands/repl.rb +0 -3
  30. data/lib/byebug/commands/{control.rb → restart.rb} +2 -26
  31. data/lib/byebug/commands/save.rb +0 -1
  32. data/lib/byebug/commands/set.rb +4 -7
  33. data/lib/byebug/commands/show.rb +0 -3
  34. data/lib/byebug/commands/source.rb +0 -3
  35. data/lib/byebug/commands/stepping.rb +3 -4
  36. data/lib/byebug/commands/trace.rb +0 -1
  37. data/lib/byebug/commands/variables.rb +3 -4
  38. data/lib/byebug/context.rb +0 -1
  39. data/lib/byebug/helper.rb +23 -0
  40. data/lib/byebug/interfaces/script_interface.rb +1 -1
  41. data/lib/byebug/processors/command_processor.rb +9 -9
  42. data/lib/byebug/remote.rb +2 -2
  43. data/lib/byebug/setting.rb +3 -1
  44. data/lib/byebug/settings/autoeval.rb +3 -1
  45. data/lib/byebug/settings/autoirb.rb +3 -1
  46. data/lib/byebug/settings/autolist.rb +3 -1
  47. data/lib/byebug/settings/autoreload.rb +1 -3
  48. data/lib/byebug/settings/autosave.rb +1 -3
  49. data/lib/byebug/settings/callstyle.rb +2 -4
  50. data/lib/byebug/settings/fullpath.rb +1 -3
  51. data/lib/byebug/settings/histfile.rb +1 -3
  52. data/lib/byebug/settings/histsize.rb +0 -4
  53. data/lib/byebug/settings/listsize.rb +1 -3
  54. data/lib/byebug/settings/post_mortem.rb +14 -1
  55. data/lib/byebug/settings/width.rb +1 -17
  56. data/lib/byebug/version.rb +1 -1
  57. data/test/break_test.rb +376 -0
  58. data/test/condition_test.rb +82 -0
  59. data/test/continue_test.rb +27 -30
  60. data/test/debugger_alias_test.rb +4 -4
  61. data/test/delete_test.rb +26 -0
  62. data/test/display_test.rb +80 -102
  63. data/test/edit_test.rb +28 -31
  64. data/test/eval_test.rb +50 -80
  65. data/test/finish_test.rb +23 -23
  66. data/test/frame_test.rb +172 -186
  67. data/test/help_test.rb +27 -37
  68. data/test/history_test.rb +32 -41
  69. data/test/info_test.rb +198 -230
  70. data/test/interrupt_test.rb +17 -36
  71. data/test/irb_test.rb +47 -0
  72. data/test/kill_test.rb +19 -19
  73. data/test/list_test.rb +126 -133
  74. data/test/method_test.rb +21 -54
  75. data/test/post_mortem_test.rb +44 -46
  76. data/test/pry_test.rb +42 -0
  77. data/test/quit_test.rb +17 -15
  78. data/test/reload_test.rb +23 -28
  79. data/test/restart_test.rb +35 -63
  80. data/test/save_test.rb +46 -62
  81. data/test/set_test.rb +93 -144
  82. data/test/show_test.rb +50 -71
  83. data/test/source_test.rb +23 -26
  84. data/test/stepping_test.rb +125 -153
  85. data/test/support/matchers.rb +1 -6
  86. data/test/support/test_interface.rb +1 -1
  87. data/test/support/{test_dsl.rb → utils.rb} +17 -64
  88. data/test/test_helper.rb +25 -7
  89. data/test/thread_test.rb +101 -89
  90. data/test/trace_test.rb +48 -85
  91. data/test/variables_test.rb +43 -80
  92. metadata +18 -13
  93. data/lib/byebug/commands/breakpoints.rb +0 -137
  94. data/lib/byebug/commands/skip.rb +0 -30
  95. data/test/breakpoints_test.rb +0 -474
  96. data/test/conditions_test.rb +0 -82
  97. data/test/repl_test.rb +0 -75
@@ -1,3 +1,3 @@
1
1
  module Byebug
2
- VERSION = '3.1.2'
2
+ VERSION = '3.2.0'
3
3
  end
@@ -0,0 +1,376 @@
1
+ module Byebug
2
+ class BreakExample
3
+ def self.a(num)
4
+ 4
5
+ end
6
+
7
+ def b
8
+ 3
9
+ end
10
+ end
11
+
12
+ class BreakTestCase < TestCase
13
+ def setup
14
+ @example = -> do
15
+ y = 3
16
+ # A comment
17
+ byebug
18
+ z = 5
19
+ BreakExample.new.b
20
+ BreakExample.a(y+z)
21
+ end
22
+
23
+ super
24
+ end
25
+
26
+ def test_setting_breakpoint_sets_correct_fields
27
+ enter 'break 19'
28
+
29
+ debug_proc(@example) do
30
+ assert_equal 19, first_brkpt.pos
31
+ assert_equal __FILE__, first_brkpt.source
32
+ assert_equal nil, first_brkpt.expr
33
+ assert_equal 0, first_brkpt.hit_count
34
+ assert_equal 0, first_brkpt.hit_value
35
+ assert_equal true, first_brkpt.enabled?
36
+ end
37
+ end
38
+
39
+ def test_setting_breakpoint_using_shortcut_properly_adds_the_breakpoint
40
+ enter 'break 19'
41
+ debug_proc(@example) { assert_equal 1, Byebug.breakpoints.size }
42
+ end
43
+
44
+ def test_setting_breakpoint_to_nonexistent_line_does_not_create_breakpoint
45
+ enter 'break 1000'
46
+ debug_proc(@example) { assert_empty Byebug.breakpoints }
47
+ end
48
+
49
+ def test_setting_breakpoint_to_nonexistent_file_does_not_create_breakpoint
50
+ enter 'break asf:324'
51
+ debug_proc(@example) { assert_empty Byebug.breakpoints }
52
+ check_error_includes 'No file named asf'
53
+ end
54
+
55
+ def test_setting_breakpoint_to_invalid_line_does_not_create_breakpoint
56
+ enter 'break 6'
57
+ debug_proc(@example) { assert_empty Byebug.breakpoints }
58
+ end
59
+
60
+ def test_stops_at_the_correct_place_when_a_breakpoint_is_set
61
+ enter 'break 19', 'cont'
62
+ debug_proc(@example) do
63
+ assert_equal 19, state.line
64
+ assert_equal __FILE__, state.file
65
+ end
66
+ end
67
+
68
+ def test_setting_breakpoint_to_an_instance_method_stops_at_correct_place
69
+ enter 'break BreakExample#b', 'cont'
70
+
71
+ debug_proc(@example) do
72
+ assert_equal 7, state.line
73
+ assert_equal __FILE__, state.file
74
+ end
75
+ end
76
+
77
+ def test_setting_breakpoint_to_a_class_method_stops_at_correct_place
78
+ enter 'break BreakExample.a', 'cont'
79
+
80
+ debug_proc(@example) do
81
+ assert_equal 3, state.line
82
+ assert_equal __FILE__, state.file
83
+ end
84
+ end
85
+
86
+ def test_setting_breakpoint_to_nonexistent_class_does_not_create_breakpoint
87
+ enter 'break B.a'
88
+
89
+ debug_proc(@example)
90
+ check_error_includes 'Unknown class B'
91
+ end
92
+
93
+ def test_setting_breakpoint_to_nonexistent_class_shows_error_message
94
+ enter 'break B.a'
95
+
96
+ debug_proc(@example)
97
+ check_error_includes 'Unknown class B'
98
+ end
99
+
100
+ def test_setting_breakpoint_to_invalid_location_does_not_create_breakpoint
101
+ enter 'break foo'
102
+
103
+ debug_proc(@example) { assert_empty Byebug.breakpoints }
104
+ end
105
+
106
+ def test_setting_breakpoint_to_invalid_location_shows_error_message
107
+ enter 'break foo'
108
+
109
+ debug_proc(@example)
110
+ check_error_includes 'Invalid breakpoint location: foo'
111
+ end
112
+
113
+ def test_breaking_w_byebug_keywork_stops_at_the_next_line
114
+ debug_proc(@example) { assert_equal 18, state.line }
115
+ end
116
+
117
+ class BreakDeepExample
118
+ def a
119
+ z = 2
120
+ b(z)
121
+ end
122
+
123
+ def b(num)
124
+ v2 = 5 if 1 == num ; [1,2,v2].map { |a| a.to_f }
125
+ c
126
+ end
127
+
128
+ def c
129
+ z = 4
130
+ z += 5
131
+ byebug
132
+ end
133
+ end
134
+
135
+ def test_breaking_w_byebug_keywork_stops_at_frame_end_when_last_instruction
136
+ @deep_example = lambda do
137
+ ex = BreakDeepExample.new.a
138
+ 2.times do
139
+ ex = ex ? ex : 1
140
+ end
141
+ end
142
+
143
+ debug_proc(@deep_example) { assert_equal 132, state.line }
144
+ end
145
+
146
+ def test_disabling_breakpoints_with_short_syntax_sets_enabled_to_false
147
+ enter 'break 19', 'break 20', -> { "disable #{first_brkpt.id}" }
148
+
149
+ debug_proc(@example) { assert_equal false, first_brkpt.enabled? }
150
+ end
151
+
152
+ def test_disabling_breakpoints_with_short_syntax_properly_ignores_them
153
+ enter 'break 19', 'break 20', -> { "disable #{first_brkpt.id}" } , 'cont'
154
+
155
+ debug_proc(@example) { assert_equal 20, state.line }
156
+ end
157
+
158
+ def test_disabling_breakpoints_with_full_syntax_sets_enabled_to_false
159
+ enter 'b 19', 'b 20', -> { "disable breakpoints #{first_brkpt.id}" }
160
+
161
+ debug_proc(@example) { assert_equal false, first_brkpt.enabled? }
162
+ end
163
+
164
+ def test_disabling_breakpoints_with_full_syntax_properly_ignores_them
165
+ enter 'b 19', 'b 20', -> { "disable breakpoints #{first_brkpt.id}" },
166
+ 'cont'
167
+
168
+ debug_proc(@example) { assert_equal 20, state.line }
169
+ end
170
+
171
+ def test_disabling_all_breakpoints_sets_all_enabled_flags_to_false
172
+ enter 'break 19', 'break 20', 'disable breakpoints'
173
+
174
+ debug_proc(@example) do
175
+ assert_equal false, first_brkpt.enabled?
176
+ assert_equal false, last_brkpt.enabled?
177
+ end
178
+ end
179
+
180
+ def test_disabling_all_breakpoints_ignores_all_breakpoints
181
+ enter 'break 19', 'break 20', 'disable breakpoints', 'cont'
182
+
183
+ debug_proc(@example)
184
+ assert_equal true, state.proceed # Obscure assert to check termination
185
+ end
186
+
187
+ def test_disabling_breakpoints_shows_an_error_in_syntax_is_incorrect
188
+ enter 'disable'
189
+
190
+ debug_proc(@example)
191
+ check_error_includes \
192
+ '"disable" must be followed by "display", "breakpoints" or breakpoint ids'
193
+ end
194
+
195
+ def test_disabling_breakpoints_shows_an_error_if_no_breakpoints_are_set
196
+ enter 'disable 1'
197
+
198
+ debug_proc(@example)
199
+ check_error_includes 'No breakpoints have been set'
200
+ end
201
+
202
+ def test_disabling_breakpoints_shows_an_error_if_non_numeric_arg_is_provided
203
+ enter 'break 5', 'disable foo'
204
+
205
+ debug_proc(@example)
206
+ check_output_includes \
207
+ '"disable breakpoints" argument "foo" needs to be a number'
208
+ end
209
+
210
+ def test_enabling_breakpoints_with_short_syntax_sets_enabled_to_true
211
+ enter 'b 19', 'b 20', 'disable breakpoints',
212
+ -> { "enable #{first_brkpt.id}" }
213
+
214
+ debug_proc(@example) { assert_equal true, first_brkpt.enabled? }
215
+ end
216
+
217
+ def test_enabling_breakpoints_with_short_syntax_stops_at_enabled_breakpoint
218
+ enter 'break 19', 'break 20', 'disable breakpoints',
219
+ -> { "enable #{first_brkpt.id}" }, 'cont'
220
+
221
+ debug_proc(@example) { assert_equal 19, state.line }
222
+ end
223
+
224
+ def test_enabling_all_breakpoints_sets_all_enabled_flags_to_true
225
+ enter 'break 19', 'break 20', 'disable breakpoints', 'enable breakpoints'
226
+
227
+ debug_proc(@example) do
228
+ assert_equal true, first_brkpt.enabled?
229
+ assert_equal true, last_brkpt.enabled?
230
+ end
231
+ end
232
+
233
+ def test_enabling_all_breakpoints_stops_at_first_breakpoint
234
+ enter 'b 19', 'b 20', 'disable breakpoints', 'enable breakpoints', 'cont'
235
+
236
+ debug_proc(@example) { assert_equal 19, state.line }
237
+ end
238
+
239
+ def test_enabling_all_breakpoints_stops_at_last_breakpoint
240
+ enter 'break 19', 'break 20', 'disable breakpoints',
241
+ 'enable breakpoints', 'cont', 'cont'
242
+
243
+ debug_proc(@example) { assert_equal 20, state.line }
244
+ end
245
+
246
+ def test_enabling_breakpoints_with_full_syntax_sets_enabled_to_false
247
+ enter 'break 19', 'break 20', 'disable breakpoints',
248
+ -> { "enable breakpoints #{last_brkpt.id}" }
249
+
250
+ debug_proc(@example) { assert_equal false, first_brkpt.enabled? }
251
+ end
252
+
253
+ def test_enabling_breakpoints_with_full_syntax_stops_at_enabled_breakpoint
254
+ enter 'break 19', 'break 20', 'disable breakpoints',
255
+ -> { "enable breakpoints #{last_brkpt.id}" }, 'cont'
256
+
257
+ debug_proc(@example) { assert_equal 20, state.line }
258
+ end
259
+
260
+ def test_enabling_breakpoints_shows_an_error_in_syntax_is_incorrect
261
+ enter 'enable'
262
+
263
+ debug_proc(@example)
264
+ check_error_includes \
265
+ '"enable" must be followed by "display", "breakpoints" or breakpoint ids'
266
+ end
267
+
268
+ def test_conditional_breakpoint_stops_if_condition_is_true
269
+ enter 'break 19 if z == 5', 'break 20', 'cont'
270
+ debug_proc(@example) { assert_equal 19, state.line }
271
+ end
272
+
273
+ def test_conditional_breakpoint_is_ignored_if_condition_is_false
274
+ enter 'break 19 if z == 3', 'break 20', 'cont'
275
+ debug_proc(@example) { assert_equal 20, state.line }
276
+ end
277
+
278
+ def test_setting_conditional_breakpoint_shows_error_if_syntax_wrong
279
+ enter 'break 19 ifa z == 3', 'break 20', 'cont'
280
+ debug_proc(@example) { assert_equal 20, state.line }
281
+ check_error_includes \
282
+ 'Expecting "if" in breakpoint condition, got: ifa z == 3'
283
+ end
284
+
285
+ def test_setting_conditional_breakpoint_shows_error_if_no_breakpoint_id
286
+ enter 'break if z == 3', 'break 20', 'cont'
287
+ debug_proc(@example) { assert_equal 20, state.line }
288
+ check_error_includes 'Invalid breakpoint location: if z == 3'
289
+ end
290
+
291
+ def test_setting_conditional_breakpoint_using_wrong_expression_ignores_it
292
+ enter 'break if z -=) 3', 'break 20', 'cont'
293
+ debug_proc(@example) { assert_equal 20, state.line }
294
+ end
295
+
296
+ def test_shows_info_about_setting_breakpoints_when_using_just_break
297
+ enter 'break', 'cont'
298
+ debug_proc(@example)
299
+ check_output_includes(/b\[reak\] file:line \[if expr\]/)
300
+ end
301
+ end
302
+
303
+ module FilenameTests
304
+ def test_setting_breakpoint_prints_confirmation_message
305
+ enter 'break 19'
306
+ debug_proc(@example) { @id = first_brkpt.id }
307
+ check_output_includes "Created breakpoint #{@id} at #{@filename}:19"
308
+ end
309
+
310
+ def test_setting_breakpoint_to_nonexistent_line_shows_an_error
311
+ enter 'break 1000'
312
+ debug_proc(@example)
313
+ n = %x{wc -l #{__FILE__}}.split.first.to_i
314
+ check_error_includes "There are only #{n} lines in file #{@filename}"
315
+ end
316
+
317
+ def test_setting_breakpoint_to_invalid_line_shows_an_error
318
+ enter 'break 6'
319
+ debug_proc(@example)
320
+ check_error_includes \
321
+ "Line 6 is not a valid breakpoint in file #{@filename}"
322
+ end
323
+ end
324
+
325
+ class BreakTestCaseBasename < BreakTestCase
326
+ def setup
327
+ @filename = File.basename(__FILE__)
328
+ super
329
+ enter 'set basename'
330
+ end
331
+
332
+ include FilenameTests
333
+ end
334
+
335
+ class BreakTestCaseNobasename < BreakTestCase
336
+ def setup
337
+ @filename = __FILE__
338
+ super
339
+ enter 'set nobasename'
340
+ end
341
+
342
+ include FilenameTests
343
+ end
344
+
345
+ class BreakTestCaseAutoreload < BreakTestCase
346
+ def setup
347
+ super
348
+ enter 'set autoreload'
349
+ end
350
+
351
+ def test_setting_breakpoint_with_autoreload_uses_new_source
352
+ enter -> do
353
+ change_line_in_file(__FILE__, 19, '')
354
+ 'break 19'
355
+ end
356
+ debug_proc(@example) { assert_empty Byebug.breakpoints }
357
+ change_line_in_file(__FILE__,19, ' BreakExample.new.b')
358
+ end
359
+ end
360
+
361
+ class BreakTestCaseNoAutoreload < BreakTestCase
362
+ def setup
363
+ super
364
+ enter 'set noautoreload'
365
+ end
366
+
367
+ def test_setting_breakpoint_with_autoreload_uses_new_source
368
+ enter -> do
369
+ change_line_in_file(__FILE__, 19, '')
370
+ 'break 19'
371
+ end
372
+ debug_proc(@example) { assert_equal 1, Byebug.breakpoints.size }
373
+ change_line_in_file(__FILE__,19, ' BreakExample.new.b')
374
+ end
375
+ end
376
+ end
@@ -0,0 +1,82 @@
1
+ module Byebug
2
+ class ConditionTestCase < TestCase
3
+ def setup
4
+ @example = -> do
5
+ byebug
6
+ b = 5
7
+ c = b + 5
8
+ c = Object.new
9
+ end
10
+
11
+ super
12
+ end
13
+
14
+ def test_setting_condition_w_short_syntax_assigns_expression_to_breakpoint
15
+ enter 'break 7', -> { "cond #{first_brkpt.id} b == 5" }
16
+
17
+ debug_proc(@example) { assert_equal 'b == 5', first_brkpt.expr }
18
+ end
19
+
20
+ def test_setting_condition_w_full_syntax_assigns_expression_to_breakpoint
21
+ enter 'break 7', -> { "condition #{first_brkpt.id} b == 5" }
22
+
23
+ debug_proc(@example) { assert_equal 'b == 5', first_brkpt.expr }
24
+ end
25
+
26
+ def test_setting_condition_w_wrong_syntax_does_not_enable_breakpoint
27
+ enter 'break 7', -> { "disable #{first_brkpt.id}" },
28
+ -> { "cond #{first_brkpt.id} b ==" }
29
+
30
+ debug_proc(@example) { assert_equal false, first_brkpt.enabled? }
31
+ end
32
+
33
+ def test_setting_condition_w_wrong_syntax_shows_error
34
+ enter 'break 7', -> { "disable #{first_brkpt.id}" },
35
+ -> { "cond #{first_brkpt.id} b ==" }
36
+
37
+ debug_proc(@example)
38
+ check_error_includes \
39
+ 'Incorrect expression "b ==", breakpoint not changed'
40
+ end
41
+
42
+ def test_execution_stops_when_condition_is_true
43
+ enter 'break 7', -> { "cond #{first_brkpt.id} b == 5" }, 'cont'
44
+
45
+ debug_proc(@example) { assert_equal 7, state.line }
46
+ end
47
+
48
+ def test_execution_does_not_stop_when_condition_is_false
49
+ enter 'b 7', 'b 8', -> { "cond #{first_brkpt.id} b == 3" }, 'cont'
50
+
51
+ debug_proc(@example) { assert_equal 8, state.line }
52
+ end
53
+
54
+ def test_conditions_with_wrong_syntax_are_ignored
55
+ enter 'break 7', 'break 8', -> { "cond #{first_brkpt.id} b ==" }, 'cont'
56
+
57
+ debug_proc(@example) { assert_equal 7, state.line }
58
+ end
59
+
60
+ def test_empty_condition_means_removing_any_conditions
61
+ enter 'b 7 if b == 3', 'b 8', -> { "cond #{first_brkpt.id}" }, 'cont'
62
+
63
+ debug_proc(@example) do
64
+ assert_nil first_brkpt.expr
65
+ assert_equal 7, state.line
66
+ end
67
+ end
68
+
69
+ def test_shows_error_if_there_are_no_breakpoints
70
+ enter 'cond 1 true'
71
+
72
+ debug_proc(@example)
73
+ check_error_includes 'No breakpoints have been set'
74
+ end
75
+
76
+ def test_shows_error_if_breakpoint_id_is_incorrect
77
+ enter 'break 7', 'cond 8 b == 3', 'cont'
78
+
79
+ debug_proc(@example) { assert_equal 7, state.line }
80
+ end
81
+ end
82
+ end