byebug 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +3 -11
  4. data/Rakefile +10 -3
  5. data/bin/byebug +16 -2
  6. data/byebug.gemspec +1 -0
  7. data/ext/byebug/byebug.c +0 -54
  8. data/ext/byebug/byebug.h +3 -4
  9. data/ext/byebug/extconf.rb +1 -1
  10. data/lib/byebug.rb +15 -42
  11. data/lib/byebug/command.rb +12 -28
  12. data/lib/byebug/commands/breakpoints.rb +2 -0
  13. data/lib/byebug/commands/catchpoint.rb +1 -1
  14. data/lib/byebug/commands/condition.rb +1 -0
  15. data/lib/byebug/commands/display.rb +6 -0
  16. data/lib/byebug/commands/frame.rb +10 -3
  17. data/lib/byebug/commands/info.rb +5 -3
  18. data/lib/byebug/commands/reload.rb +1 -0
  19. data/lib/byebug/commands/set.rb +5 -1
  20. data/lib/byebug/commands/threads.rb +5 -4
  21. data/lib/byebug/commands/trace.rb +5 -5
  22. data/lib/byebug/context.rb +3 -3
  23. data/lib/byebug/interface.rb +3 -187
  24. data/lib/byebug/interfaces/local_interface.rb +88 -0
  25. data/lib/byebug/interfaces/remote_interface.rb +55 -0
  26. data/lib/byebug/interfaces/script_interface.rb +45 -0
  27. data/lib/byebug/processor.rb +15 -13
  28. data/lib/byebug/version.rb +1 -1
  29. data/test/breakpoints_test.rb +23 -25
  30. data/test/conditions_test.rb +6 -8
  31. data/test/continue_test.rb +4 -6
  32. data/test/debugger_alias_test.rb +5 -0
  33. data/test/display_test.rb +9 -11
  34. data/test/edit_test.rb +0 -2
  35. data/test/eval_test.rb +1 -3
  36. data/test/finish_test.rb +12 -12
  37. data/test/frame_test.rb +38 -40
  38. data/test/help_test.rb +1 -3
  39. data/test/info_test.rb +12 -14
  40. data/test/kill_test.rb +0 -2
  41. data/test/list_test.rb +1 -3
  42. data/test/method_test.rb +0 -2
  43. data/test/post_mortem_test.rb +77 -96
  44. data/test/quit_test.rb +0 -2
  45. data/test/reload_test.rb +0 -2
  46. data/test/repl_test.rb +3 -5
  47. data/test/restart_test.rb +0 -2
  48. data/test/save_test.rb +1 -3
  49. data/test/set_test.rb +3 -5
  50. data/test/show_test.rb +0 -2
  51. data/test/source_test.rb +0 -2
  52. data/test/stepping_test.rb +17 -19
  53. data/test/support/test_dsl.rb +21 -13
  54. data/test/test_helper.rb +23 -1
  55. data/test/thread_test.rb +19 -21
  56. data/test/trace_test.rb +12 -14
  57. data/test/variables_test.rb +6 -6
  58. metadata +22 -3
@@ -0,0 +1,45 @@
1
+ module Byebug
2
+ class ScriptInterface < Interface
3
+ attr_accessor :command_queue, :history_length, :history_save, :histfile
4
+ attr_accessor :restart_file
5
+
6
+ def initialize(file, out, verbose=false)
7
+ super()
8
+ @command_queue = []
9
+ @file = file.respond_to?(:gets) ? file : open(file)
10
+ @out = out
11
+ @verbose = verbose
12
+ @history_save = false
13
+ @history_length = 256
14
+ @histfile = ''
15
+ end
16
+
17
+ def finalize
18
+ end
19
+
20
+ def read_command(prompt)
21
+ while result = @file.gets
22
+ puts "# #{result}" if @verbose
23
+ next if result =~ /^\s*#/
24
+ next if result.strip.empty?
25
+ return result.chomp
26
+ end
27
+ end
28
+
29
+ def readline_support?
30
+ false
31
+ end
32
+
33
+ def confirm(prompt)
34
+ 'y'
35
+ end
36
+
37
+ def print(*args)
38
+ @out.printf(*args)
39
+ end
40
+
41
+ def close
42
+ @file.close
43
+ end
44
+ end
45
+ end
@@ -58,7 +58,7 @@ module Byebug
58
58
 
59
59
  def self.protect(mname)
60
60
  alias_method "__#{mname}", mname
61
- module_eval %{
61
+ module_eval <<-END, __FILE__, __LINE__+1
62
62
  def #{mname}(*args)
63
63
  @mutex.synchronize do
64
64
  return unless @interface
@@ -72,7 +72,7 @@ module Byebug
72
72
  print "INTERNAL ERROR!!! #\{$!\}\n" rescue nil
73
73
  print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n") rescue nil
74
74
  end
75
- }
75
+ END
76
76
  end
77
77
 
78
78
  def at_breakpoint(context, breakpoint)
@@ -87,7 +87,6 @@ module Byebug
87
87
  file = CommandProcessor.canonic_file(context.frame_file(0))
88
88
  line = context.frame_line(0)
89
89
  print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class
90
- print_backtrace
91
90
  end
92
91
  protect :at_catchpoint
93
92
 
@@ -129,24 +128,22 @@ module Byebug
129
128
  # @return List of commands acceptable to run bound to the current state
130
129
  #
131
130
  def always_run(context, file, line, run_level)
132
- event_cmds = Command.commands.select{|cmd| cmd.event }
131
+ cmds = Command.commands
133
132
 
134
133
  # Remove some commands in post-mortem
135
- event_cmds = event_cmds.find_all do |cmd|
136
- cmd.allow_in_post_mortem
137
- end if context.dead?
134
+ cmds = cmds.find_all { |cmd| cmd.allow_in_post_mortem } if context.dead?
138
135
 
139
- state = State.new(event_cmds, context, @display, file, @interface, line)
136
+ state = State.new(cmds, context, @display, file, @interface, line)
140
137
 
141
138
  # Change default when in irb or code included in command line
142
139
  Command.settings[:autolist] = 0 if ['(irb)', '-e'].include?(file)
143
140
 
144
141
  # Bind commands to the current state.
145
- commands = event_cmds.map{|cmd| cmd.new(state)}
142
+ commands = cmds.map { |cmd| cmd.new(state) }
143
+
144
+ commands.select { |cmd| cmd.class.always_run >= run_level }
145
+ .each { |cmd| cmd.execute }
146
146
 
147
- commands.select do |cmd|
148
- cmd.class.always_run >= run_level
149
- end.each {|cmd| cmd.execute}
150
147
  return state, commands
151
148
  end
152
149
 
@@ -175,7 +172,12 @@ module Byebug
175
172
  #
176
173
  def process_commands(context, file, line)
177
174
  state, commands = always_run(context, file, line, 1)
178
- $state = Command.settings[:testing] ? state : nil
175
+
176
+ if Command.settings[:testing]
177
+ Thread.current.thread_variable_set('state', state)
178
+ else
179
+ Thread.current.thread_variable_set('state', nil)
180
+ end
179
181
 
180
182
  preloop(commands, context)
181
183
  print state.location if Command.settings[:autolist] == 0
@@ -1,3 +1,3 @@
1
1
  module Byebug
2
- VERSION = '2.3.1'
2
+ VERSION = '2.4.0'
3
3
  end
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class BreakpointExample
4
2
  def self.a(num)
5
3
  4
@@ -93,12 +91,12 @@ class TestBreakpoints < TestDsl::TestCase
93
91
  describe 'stopping at breakpoint' do
94
92
  it 'must stop at the correct line' do
95
93
  enter 'break 5', 'cont'
96
- debug_file('breakpoint') { $state.line.must_equal 5 }
94
+ debug_file('breakpoint') { state.line.must_equal 5 }
97
95
  end
98
96
 
99
97
  it 'must stop at the correct file' do
100
98
  enter 'break 5', 'cont'
101
- debug_file('breakpoint') { $state.file.must_equal @tst_file }
99
+ debug_file('breakpoint') { state.file.must_equal @tst_file }
102
100
  end
103
101
 
104
102
  describe 'show a message' do
@@ -151,14 +149,14 @@ class TestBreakpoints < TestDsl::TestCase
151
149
 
152
150
  describe 'set breakpoint in a file' do
153
151
  describe 'successfully' do
154
- before { enter "break #{__FILE__}:5", 'cont' }
152
+ before { enter "break #{__FILE__}:3", 'cont' }
155
153
 
156
154
  it 'must stop at the correct line' do
157
- debug_file('breakpoint') { $state.line.must_equal 5 }
155
+ debug_file('breakpoint') { state.line.must_equal 3 }
158
156
  end
159
157
 
160
158
  it 'must stop at the correct file' do
161
- debug_file('breakpoint') { $state.file.must_equal __FILE__ }
159
+ debug_file('breakpoint') { state.file.must_equal __FILE__ }
162
160
  end
163
161
  end
164
162
 
@@ -184,11 +182,11 @@ class TestBreakpoints < TestDsl::TestCase
184
182
  before { enter 'break BreakpointExample#b', 'cont' }
185
183
 
186
184
  it 'must stop at the correct line' do
187
- debug_file('breakpoint') { $state.line.must_equal 7 }
185
+ debug_file('breakpoint') { state.line.must_equal 5 }
188
186
  end
189
187
 
190
188
  it 'must stop at the correct file' do
191
- debug_file('breakpoint') { $state.file.must_equal __FILE__ }
189
+ debug_file('breakpoint') { state.file.must_equal __FILE__ }
192
190
  end
193
191
  end
194
192
 
@@ -196,11 +194,11 @@ class TestBreakpoints < TestDsl::TestCase
196
194
  before { enter 'break BreakpointExample.a', 'cont' }
197
195
 
198
196
  it 'must stop at the correct line' do
199
- debug_file('breakpoint') { $state.line.must_equal 4 }
197
+ debug_file('breakpoint') { state.line.must_equal 2 }
200
198
  end
201
199
 
202
200
  it 'must stop at the correct file' do
203
- debug_file('breakpoint') { $state.file.must_equal __FILE__ }
201
+ debug_file('breakpoint') { state.file.must_equal __FILE__ }
204
202
  end
205
203
  end
206
204
 
@@ -240,7 +238,7 @@ class TestBreakpoints < TestDsl::TestCase
240
238
 
241
239
  it 'must not stop on the disabled breakpoint' do
242
240
  enter 'cont'
243
- debug_file('breakpoint') { $state.line.must_equal 6 }
241
+ debug_file('breakpoint') { state.line.must_equal 6 }
244
242
  end
245
243
  end
246
244
 
@@ -259,7 +257,7 @@ class TestBreakpoints < TestDsl::TestCase
259
257
  enter 'cont'
260
258
  debug_file('breakpoint')
261
259
  # Obscure assert to check for program termination
262
- $state.proceed.must_equal true
260
+ state.proceed.must_equal true
263
261
  end
264
262
  end
265
263
 
@@ -313,7 +311,7 @@ class TestBreakpoints < TestDsl::TestCase
313
311
 
314
312
  it 'must stop on the enabled breakpoint' do
315
313
  enter 'cont'
316
- debug_file('breakpoint') { $state.line.must_equal 5 }
314
+ debug_file('breakpoint') { state.line.must_equal 5 }
317
315
  end
318
316
  end
319
317
 
@@ -330,12 +328,12 @@ class TestBreakpoints < TestDsl::TestCase
330
328
 
331
329
  it 'must stop on the first breakpoint' do
332
330
  enter 'cont'
333
- debug_file('breakpoint') { $state.line.must_equal 5 }
331
+ debug_file('breakpoint') { state.line.must_equal 5 }
334
332
  end
335
333
 
336
334
  it 'must stop on the last breakpoint' do
337
335
  enter 'cont', 'cont'
338
- debug_file('breakpoint') { $state.line.must_equal 6 }
336
+ debug_file('breakpoint') { state.line.must_equal 6 }
339
337
  end
340
338
  end
341
339
 
@@ -351,7 +349,7 @@ class TestBreakpoints < TestDsl::TestCase
351
349
 
352
350
  it 'must stop only on the enabled breakpoint' do
353
351
  enter 'cont'
354
- debug_file('breakpoint') { $state.line.must_equal 6 }
352
+ debug_file('breakpoint') { state.line.must_equal 6 }
355
353
  end
356
354
  end
357
355
  end
@@ -377,24 +375,24 @@ class TestBreakpoints < TestDsl::TestCase
377
375
 
378
376
  it 'must not stop on the disabled breakpoint' do
379
377
  enter 'cont'
380
- debug_file('breakpoint') { $state.line.must_equal 6 }
378
+ debug_file('breakpoint') { state.line.must_equal 6 }
381
379
  end
382
380
  end
383
381
 
384
382
  describe 'Conditional breakpoints' do
385
383
  it 'must stop if the condition is true' do
386
384
  enter 'break 5 if z == 5', 'break 6', 'cont'
387
- debug_file('breakpoint') { $state.line.must_equal 5 }
385
+ debug_file('breakpoint') { state.line.must_equal 5 }
388
386
  end
389
387
 
390
388
  it 'must skip if the condition is false' do
391
389
  enter 'break 5 if z == 3', 'break 6', 'cont'
392
- debug_file('breakpoint') { $state.line.must_equal 6 }
390
+ debug_file('breakpoint') { state.line.must_equal 6 }
393
391
  end
394
392
 
395
393
  it 'must show an error when conditional syntax is wrong' do
396
394
  enter 'break 5 ifa z == 3', 'break 6', 'cont'
397
- debug_file('breakpoint') { $state.line.must_equal 6 }
395
+ debug_file('breakpoint') { state.line.must_equal 6 }
398
396
  check_error_includes \
399
397
  'Expecting "if" in breakpoint condition; got: ifa z == 3.'
400
398
  end
@@ -419,13 +417,13 @@ class TestBreakpoints < TestDsl::TestCase
419
417
 
420
418
  it 'must show an error if no file or line is specified' do
421
419
  enter 'break ifa z == 3', 'break 6', 'cont'
422
- debug_file('breakpoint') { $state.line.must_equal 6 }
420
+ debug_file('breakpoint') { state.line.must_equal 6 }
423
421
  check_error_includes 'Invalid breakpoint location: ifa z == 3.'
424
422
  end
425
423
 
426
424
  it 'must show an error if expression syntax is invalid' do
427
425
  enter 'break if z -=) 3', 'break 6', 'cont'
428
- debug_file('breakpoint') { $state.line.must_equal 6 }
426
+ debug_file('breakpoint') { state.line.must_equal 6 }
429
427
  check_error_includes \
430
428
  'Expression "z -=) 3" syntactically incorrect; breakpoint disabled.'
431
429
  end
@@ -434,13 +432,13 @@ class TestBreakpoints < TestDsl::TestCase
434
432
  describe 'Stopping through `byebug` keyword' do
435
433
  describe 'when not the last instruction of a method' do
436
434
  it 'must stop in the next line' do
437
- debug_file('breakpoint') { $state.line.must_equal 4 }
435
+ debug_file('breakpoint') { state.line.must_equal 4 }
438
436
  end
439
437
  end
440
438
 
441
439
  describe 'when last instruction of a method' do
442
440
  it 'must stop right before returning from the frame' do
443
- debug_file('breakpoint_deep') { $state.line.must_equal 27 }
441
+ debug_file('breakpoint_deep') { state.line.must_equal 25 }
444
442
  end
445
443
  end
446
444
  end
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class TestConditions < TestDsl::TestCase
4
2
 
5
3
  describe 'setting condition' do
@@ -14,11 +12,11 @@ class TestConditions < TestDsl::TestCase
14
12
  end
15
13
 
16
14
  it 'must stop at the breakpoint if condition is true' do
17
- debug_file('conditions') { $state.line.must_equal 3 }
15
+ debug_file('conditions') { state.line.must_equal 3 }
18
16
  end
19
17
 
20
18
  it 'must work with full command name too' do
21
- debug_file('conditions') { $state.line.must_equal 3 }
19
+ debug_file('conditions') { state.line.must_equal 3 }
22
20
  end
23
21
  end
24
22
 
@@ -27,7 +25,7 @@ class TestConditions < TestDsl::TestCase
27
25
 
28
26
  it 'must not stop at the breakpoint if condition is false' do
29
27
  enter ->{ "cond #{Byebug.breakpoints.first.id} b == 3" }, 'cont'
30
- debug_file('conditions') { $state.line.must_equal 4 }
28
+ debug_file('conditions') { state.line.must_equal 4 }
31
29
  end
32
30
 
33
31
  it 'must assign expression to breakpoint in spite of incorrect syntax' do
@@ -38,7 +36,7 @@ class TestConditions < TestDsl::TestCase
38
36
 
39
37
  it 'must ignore the condition if when incorrect syntax' do
40
38
  enter ->{ "cond #{Byebug.breakpoints.first.id} b ==" }, 'cont'
41
- debug_file('conditions') { $state.line.must_equal 4 }
39
+ debug_file('conditions') { state.line.must_equal 4 }
42
40
  end
43
41
  end
44
42
  end
@@ -52,7 +50,7 @@ class TestConditions < TestDsl::TestCase
52
50
  end
53
51
 
54
52
  it 'must unconditionally stop on the breakpoint' do
55
- debug_file('conditions') { $state.line.must_equal 3 }
53
+ debug_file('conditions') { state.line.must_equal 3 }
56
54
  end
57
55
  end
58
56
 
@@ -65,7 +63,7 @@ class TestConditions < TestDsl::TestCase
65
63
 
66
64
  it 'must not set breakpoint condition if breakpoint id is incorrect' do
67
65
  enter 'break 3', 'cond 8 b == 3', 'cont'
68
- debug_file('conditions') { $state.line.must_equal 3 }
66
+ debug_file('conditions') { state.line.must_equal 3 }
69
67
  end
70
68
  end
71
69
  end
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class ContinueExample
4
2
  def self.a(num)
5
3
  num + 4
@@ -11,24 +9,24 @@ class TestContinue < TestDsl::TestCase
11
9
  describe "successful" do
12
10
  it "must continue up to breakpoint if no line specified" do
13
11
  enter 'break 4', 'continue'
14
- debug_file('continue') { $state.line.must_equal 4 }
12
+ debug_file('continue') { state.line.must_equal 4 }
15
13
  end
16
14
 
17
15
  it "must work in abbreviated mode too" do
18
16
  enter 'break 4', 'cont'
19
- debug_file('continue') { $state.line.must_equal 4 }
17
+ debug_file('continue') { state.line.must_equal 4 }
20
18
  end
21
19
 
22
20
  it "must continue up to specified line" do
23
21
  enter 'cont 4'
24
- debug_file('continue') { $state.line.must_equal 4 }
22
+ debug_file('continue') { state.line.must_equal 4 }
25
23
  end
26
24
  end
27
25
 
28
26
  describe "unsuccessful" do
29
27
  it "must ignore the command if specified line is not valid" do
30
28
  enter 'cont 123'
31
- debug_file('continue') { $state.line.must_equal 3 }
29
+ debug_file('continue') { state.line.must_equal 3 }
32
30
  end
33
31
 
34
32
  it "must show error if specified line is not valid" do
@@ -0,0 +1,5 @@
1
+ class TestDebuggerAlias < MiniTest::Spec
2
+ it 'aliases "debugger" to "byebug"' do
3
+ Kernel.method(:debugger).must_equal(Kernel.method(:byebug))
4
+ end
5
+ end
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class TestDisplay < TestDsl::TestCase
4
2
 
5
3
  it 'must show expressions' do
@@ -16,7 +14,7 @@ class TestDisplay < TestDsl::TestCase
16
14
 
17
15
  it 'must save displayed expressions' do
18
16
  enter 'display d + 1'
19
- debug_file('display') { $state.display.must_equal [[true, 'd + 1']] }
17
+ debug_file('display') { state.display.must_equal [[true, 'd + 1']] }
20
18
  end
21
19
 
22
20
  it 'displays all expressions available' do
@@ -46,8 +44,8 @@ class TestDisplay < TestDsl::TestCase
46
44
  end
47
45
 
48
46
  it 'must set all expressions saved to "false"' do
49
- debug_file('display') {
50
- $state.display.must_equal [[false, 'abc'], [false, 'd']] }
47
+ debug_file('display') { state.display.must_equal [[false, 'abc'],
48
+ [false, 'd']] }
51
49
  end
52
50
 
53
51
  it 'must not show any output' do
@@ -60,8 +58,8 @@ class TestDisplay < TestDsl::TestCase
60
58
  let(:confirm_response) { 'n' }
61
59
 
62
60
  it 'must set all expressions saved to "false"' do
63
- debug_file('display') {
64
- $state.display.must_equal [[true, 'abc'], [true, 'd']] }
61
+ debug_file('display') { state.display.must_equal [[true, 'abc'],
62
+ [true, 'd']] }
65
63
  end
66
64
 
67
65
  it 'must not show any output' do
@@ -80,8 +78,8 @@ class TestDisplay < TestDsl::TestCase
80
78
  end
81
79
 
82
80
  it 'must set inactive positions' do
83
- debug_file('display') {
84
- $state.display.must_equal [[nil, 'abc'], [true, 'd']] }
81
+ debug_file('display') { state.display.must_equal [[nil, 'abc'],
82
+ [true, 'd']] }
85
83
  end
86
84
 
87
85
  it 'must display only the active position' do
@@ -99,7 +97,7 @@ class TestDisplay < TestDsl::TestCase
99
97
  describe 'disable' do
100
98
  it 'must disable a position' do
101
99
  enter 'display d', 'disable display 1'
102
- debug_file('display') { $state.display.must_equal [[false, 'd']] }
100
+ debug_file('display') { state.display.must_equal [[false, 'd']] }
103
101
  end
104
102
 
105
103
  it 'must show an error if no displays are set' do
@@ -120,7 +118,7 @@ class TestDisplay < TestDsl::TestCase
120
118
  describe 'enable' do
121
119
  it 'must enable a position' do
122
120
  enter 'display d', 'disable display 1', 'enable display 1'
123
- debug_file('display') { $state.display.must_equal [[true, 'd']] }
121
+ debug_file('display') { state.display.must_equal [[true, 'd']] }
124
122
  end
125
123
  end
126
124
  end