byebug 2.3.1 → 2.4.0

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 (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
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class TestQuit < TestDsl::TestCase
4
2
  it 'must quit if user confirmed' do
5
3
  Byebug::QuitCommand.any_instance.expects(:exit!)
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class TestReload < TestDsl::TestCase
4
2
 
5
3
  describe 'autoreloading' do
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class TestRepl < TestDsl::TestCase
4
2
 
5
3
  describe 'Irb Command' do
@@ -13,19 +11,19 @@ class TestRepl < TestDsl::TestCase
13
11
  it 'must support next command' do
14
12
  irb.stubs(:eval_input).throws(:IRB_EXIT, :next)
15
13
  enter 'irb'
16
- debug_file('repl') { $state.line.must_equal 3 }
14
+ debug_file('repl') { state.line.must_equal 3 }
17
15
  end
18
16
 
19
17
  it 'must support step command' do
20
18
  irb.stubs(:eval_input).throws(:IRB_EXIT, :step)
21
19
  enter 'irb'
22
- debug_file('repl') { $state.line.must_equal 3 }
20
+ debug_file('repl') { state.line.must_equal 3 }
23
21
  end
24
22
 
25
23
  it 'must support cont command' do
26
24
  irb.stubs(:eval_input).throws(:IRB_EXIT, :cont)
27
25
  enter 'break 4', 'irb'
28
- debug_file('repl') { $state.line.must_equal 4 }
26
+ debug_file('repl') { state.line.must_equal 4 }
29
27
  end
30
28
 
31
29
  describe 'autoirb' do
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class RestartExample
4
2
  def concat_args(a, b, c)
5
3
  a.to_s + b.to_s + c.to_s
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class TestSave < TestDsl::TestCase
4
2
 
5
3
  describe 'successful saving' do
@@ -11,7 +9,7 @@ class TestSave < TestDsl::TestCase
11
9
  debug_file 'save'
12
10
  end
13
11
  after do
14
- FileUtils.rm(file_name)
12
+ File.delete(file_name)
15
13
  end
16
14
 
17
15
  it 'must save usual breakpoints' do
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class TestSet < TestDsl::TestCase
4
2
 
5
3
  describe 'setting to on' do
@@ -69,14 +67,14 @@ class TestSet < TestDsl::TestCase
69
67
  end
70
68
 
71
69
  describe 'testing' do
72
- describe '$state' do
70
+ describe 'state' do
73
71
  describe 'when setting "testing" to on' do
74
72
  temporary_change_hash Byebug.settings, :testing, false
75
73
 
76
74
  it 'must get set' do
77
75
  enter 'set testing', 'break 3', 'cont'
78
76
  debug_file('set') {
79
- $state.must_be_kind_of Byebug::CommandProcessor::State }
77
+ state.must_be_kind_of Byebug::CommandProcessor::State }
80
78
  end
81
79
  end
82
80
 
@@ -85,7 +83,7 @@ class TestSet < TestDsl::TestCase
85
83
 
86
84
  it 'must get unset' do
87
85
  enter 'set notesting', 'break 3', 'cont'
88
- debug_file('set') { $state.must_be_nil }
86
+ debug_file('set') { state.must_be_nil }
89
87
  end
90
88
  end
91
89
  end
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class TestShow < TestDsl::TestCase
4
2
  describe 'args' do
5
3
  temporary_change_hash Byebug.settings, :argv, %w{foo bar}
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class TestSource < TestDsl::TestCase
4
2
  let(:filename) { 'source_example.txt' }
5
3
 
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class SteppingExample
4
2
  def self.a(num)
5
3
  num += 2
@@ -21,21 +19,21 @@ class TestStepping < TestDsl::TestCase
21
19
  describe 'Next Command' do
22
20
 
23
21
  describe 'method call behaviour' do
24
- before { enter "break #{__FILE__}:10", 'cont' }
22
+ before { enter "break #{__FILE__}:8", 'cont' }
25
23
 
26
24
  it 'must leave on the same line by default' do
27
25
  enter 'next'
28
- debug_file('stepping') { $state.line.must_equal 10 }
26
+ debug_file('stepping') { state.line.must_equal 8 }
29
27
  end
30
28
 
31
29
  it 'must go to the next line if forced by "plus" sign' do
32
30
  enter 'next+'
33
- debug_file('stepping') { $state.line.must_equal 11 }
31
+ debug_file('stepping') { state.line.must_equal 9 }
34
32
  end
35
33
 
36
34
  it 'must leave on the same line if forced by "minus" sign' do
37
35
  enter 'next-'
38
- debug_file('stepping') { $state.line.must_equal 10 }
36
+ debug_file('stepping') { state.line.must_equal 8 }
39
37
  end
40
38
 
41
39
  describe 'when forcestep is set' do
@@ -43,17 +41,17 @@ class TestStepping < TestDsl::TestCase
43
41
 
44
42
  it 'must go to the next line' do
45
43
  enter 'next'
46
- debug_file('stepping') { $state.line.must_equal 11 }
44
+ debug_file('stepping') { state.line.must_equal 9 }
47
45
  end
48
46
 
49
47
  it 'must go to the next line (by shortcut)' do
50
48
  enter 'n'
51
- debug_file('stepping') { $state.line.must_equal 11 }
49
+ debug_file('stepping') { state.line.must_equal 9 }
52
50
  end
53
51
 
54
52
  it 'must go the specified number of lines forward by default' do
55
53
  enter 'next 2'
56
- debug_file('stepping') { $state.line.must_equal 4 }
54
+ debug_file('stepping') { state.line.must_equal 4 }
57
55
  end
58
56
 
59
57
  it 'must inform when not staying in the same frame' do
@@ -66,7 +64,7 @@ class TestStepping < TestDsl::TestCase
66
64
 
67
65
  it 'must ignore it if "minus" is specified' do
68
66
  enter 'next-'
69
- debug_file('stepping') { $state.line.must_equal 10 }
67
+ debug_file('stepping') { state.line.must_equal 8 }
70
68
  end
71
69
  end
72
70
  end
@@ -76,7 +74,7 @@ class TestStepping < TestDsl::TestCase
76
74
 
77
75
  it 'must step over blocks' do
78
76
  enter 'next'
79
- debug_file('stepping') { $state.line.must_equal 8 }
77
+ debug_file('stepping') { state.line.must_equal 8 }
80
78
  end
81
79
  end
82
80
  end
@@ -84,21 +82,21 @@ class TestStepping < TestDsl::TestCase
84
82
  describe 'Step Command' do
85
83
 
86
84
  describe 'method call behaviour' do
87
- before { enter "break #{__FILE__}:10", 'cont' }
85
+ before { enter "break #{__FILE__}:8", 'cont' }
88
86
 
89
87
  it 'must leave on the same line if forced by a setting' do
90
88
  enter 'step'
91
- debug_file('stepping') { $state.line.must_equal 10 }
89
+ debug_file('stepping') { state.line.must_equal 8 }
92
90
  end
93
91
 
94
92
  it 'must go to the step line if forced to do that by "plus" sign' do
95
93
  enter 'step+'
96
- debug_file('stepping') { $state.line.must_equal 11 }
94
+ debug_file('stepping') { state.line.must_equal 9 }
97
95
  end
98
96
 
99
97
  it 'must leave on the same line if forced to do that by "minus" sign' do
100
98
  enter 'step-'
101
- debug_file('stepping') { $state.line.must_equal 10 }
99
+ debug_file('stepping') { state.line.must_equal 8 }
102
100
  end
103
101
 
104
102
  describe 'when forcestep is set' do
@@ -106,17 +104,17 @@ class TestStepping < TestDsl::TestCase
106
104
 
107
105
  it 'must go to the step line if forced by a setting' do
108
106
  enter 'step'
109
- debug_file('stepping') { $state.line.must_equal 11 }
107
+ debug_file('stepping') { state.line.must_equal 9 }
110
108
  end
111
109
 
112
110
  it 'must go to the next line if forced by a setting (by shortcut)' do
113
111
  enter 's'
114
- debug_file('stepping') { $state.line.must_equal 11 }
112
+ debug_file('stepping') { state.line.must_equal 9 }
115
113
  end
116
114
 
117
115
  it 'must go the specified number of lines forward by default' do
118
116
  enter 'step 2'
119
- debug_file('stepping') { $state.line.must_equal 15 }
117
+ debug_file('stepping') { state.line.must_equal 13 }
120
118
  end
121
119
  end
122
120
  end
@@ -126,7 +124,7 @@ class TestStepping < TestDsl::TestCase
126
124
 
127
125
  it 'must step into blocks' do
128
126
  enter 'step'
129
- debug_file('stepping') { $state.line.must_equal 5 }
127
+ debug_file('stepping') { state.line.must_equal 5 }
130
128
  end
131
129
  end
132
130
  end
@@ -6,6 +6,7 @@ module TestDsl
6
6
  def setup
7
7
  Byebug.handler = Byebug::CommandProcessor.new(TestInterface.new)
8
8
  Byebug.tracing = false
9
+ Byebug.breakpoints.clear if Byebug.breakpoints
9
10
  end
10
11
 
11
12
  def self.temporary_change_hash hash, key, value
@@ -79,20 +80,19 @@ module TestDsl
79
80
  #
80
81
  # Runs byebug with the provided basename for a file.
81
82
  #
82
- # The file should be placed in the test/examples dir. You also can specify a
83
- # block, which will be executed when Processor extracts all the commands from
84
- # the input queue. You can use that for making asserts on the current test. If
85
- # you specified the block and it never was executed, the test will fail.
83
+ # You also can specify a block, which will be executed when Processor extracts
84
+ # all the commands from the input queue. You can use that for making asserts
85
+ # on the current test. If you specified the block and it never was executed,
86
+ # the test will fail.
86
87
  #
87
88
  # Usage:
88
- # debug "ex1" # ex1 should be placed in test/examples/ex1.rb
89
+ # debug_file '/path/to/ex1.rb'
89
90
  #
90
91
  # enter 'b 4', 'cont'
91
- # debug("ex1") { $state.line.must_equal 4 }
92
+ # debug_file('/path/to/ex2.rb') { state.line.must_equal 4 }
92
93
  #
93
- def debug_file(filename, &block)
94
+ def debug_file(filename, options = {}, &block)
94
95
  is_test_block_called = false
95
- debug_completed = false
96
96
  exception = nil
97
97
  Byebug.stubs(:run_init_script)
98
98
  if block
@@ -105,15 +105,19 @@ module TestDsl
105
105
  block.call
106
106
  rescue Exception => e
107
107
  exception = e
108
- raise e
109
108
  end
110
109
  end
111
110
  end
112
- Byebug.start do
111
+ begin
113
112
  load fullpath(filename)
114
- debug_completed = true
113
+ rescue Exception => e
114
+ if options[:rescue]
115
+ interface.test_block.call if interface.test_block
116
+ else
117
+ raise e
118
+ end
115
119
  end
116
- flunk "Debug block was not completed" unless debug_completed
120
+
117
121
  flunk "Test block was provided, but not called" if block && !is_test_block_called
118
122
  raise exception if exception
119
123
  end
@@ -153,8 +157,12 @@ module TestDsl
153
157
  Byebug.handler.interface
154
158
  end
155
159
 
160
+ def state
161
+ Thread.current.thread_variable_get('state')
162
+ end
163
+
156
164
  def context
157
- $state.context
165
+ state.context
158
166
  end
159
167
 
160
168
  def force_set_const(klass, const, value)
@@ -1,4 +1,5 @@
1
- require 'minitest/autorun'
1
+ require 'minitest'
2
+ require 'minitest/spec'
2
3
  require 'pathname'
3
4
  require 'mocha/setup'
4
5
  require 'byebug'
@@ -15,3 +16,24 @@ end
15
16
  # Init globals to avoid warnings
16
17
  $bla = nil
17
18
  $binding = binding # this is from irb...
19
+
20
+ # Load the test files from the command line.
21
+ argv = ARGV.select do |argument|
22
+ case argument
23
+ when /^-/ then
24
+ argument
25
+ when /\*/ then
26
+ Dir.glob('test/*_test.rb').each do |file|
27
+ require File.expand_path file
28
+ end
29
+ false
30
+ else
31
+ require File.expand_path argument
32
+ false
33
+ end
34
+ end
35
+
36
+ ARGV.replace argv
37
+
38
+ # Run the tests
39
+ Minitest.run
@@ -1,5 +1,3 @@
1
- require_relative 'test_helper'
2
-
3
1
  class ThreadExample
4
2
  def initialize
5
3
  Thread.main[:should_break] = false
@@ -34,20 +32,20 @@ class TestThread < TestDsl::TestCase
34
32
  describe 'list' do
35
33
  it 'must show current thread by "plus" sign' do
36
34
  thnum = nil
37
- enter "break #{__FILE__}:9", 'cont', 'thread list', release
35
+ enter "break #{__FILE__}:7", 'cont', 'thread list', release
38
36
  debug_file('thread') { thnum = Byebug.contexts.first.thnum }
39
- check_output_includes(/\+ #{thnum} #<Thread:\S+ run>\t#{__FILE__}:9/)
37
+ check_output_includes(/\+ #{thnum} #<Thread:\S+ run>\t#{__FILE__}:7/)
40
38
  end
41
39
 
42
40
  it 'must work with shortcut' do
43
41
  thnum = nil
44
- enter "break #{__FILE__}:9", 'cont', 'th list', release
42
+ enter "break #{__FILE__}:7", 'cont', 'th list', release
45
43
  debug_file('thread') { thnum = Byebug.contexts.first.thnum }
46
- check_output_includes(/\+ #{thnum} #<Thread:\S+ run>\t#{__FILE__}:9/)
44
+ check_output_includes(/\+ #{thnum} #<Thread:\S+ run>\t#{__FILE__}:7/)
47
45
  end
48
46
 
49
47
  it 'must show 3 available threads' do
50
- enter "break #{__FILE__}:22", 'cont', 'thread list', release
48
+ enter "break #{__FILE__}:20", 'cont', 'thread list', release
51
49
  debug_file 'thread'
52
50
  check_output_includes(/(\+)?\d+ #<Thread:\S+ (sleep|run)>/,
53
51
  /(\+)?\d+ #<Thread:\S+ (sleep|run)>/,
@@ -58,28 +56,28 @@ class TestThread < TestDsl::TestCase
58
56
  describe 'stop' do
59
57
  it 'must mark thread as suspended' do
60
58
  thnum = nil
61
- enter "break #{__FILE__}:22", 'cont',
59
+ enter "break #{__FILE__}:20", 'cont',
62
60
  ->{ "thread stop #{Byebug.contexts.last.thnum}" }, release
63
61
  debug_file('thread') { thnum = Byebug.contexts.last.thnum }
64
62
  check_output_includes(/\$ #{thnum} #<Thread:/)
65
63
  end
66
64
 
67
65
  it 'must actually suspend thread execution' do
68
- enter "break #{__FILE__}:22", 'cont', 'trace on',
66
+ enter "break #{__FILE__}:20", 'cont', 'trace on',
69
67
  ->{ "thread stop #{Byebug.contexts.last.thnum}" }, release
70
68
  debug_file('thread')
71
- check_output_doesnt_include(/Tracing: #{__FILE__}:17/,
72
- /Tracing: #{__FILE__}:18/)
69
+ check_output_doesnt_include(/Tracing: #{__FILE__}:15/,
70
+ /Tracing: #{__FILE__}:16/)
73
71
  end
74
72
 
75
73
  it 'must show error message if thread number is not specified' do
76
- enter "break #{__FILE__}:9", 'cont', 'thread stop', release
74
+ enter "break #{__FILE__}:7", 'cont', 'thread stop', release
77
75
  debug_file 'thread'
78
76
  check_error_includes '"thread stop" needs a thread number'
79
77
  end
80
78
 
81
79
  it 'must show error message when trying to stop current thread' do
82
- enter "break #{__FILE__}:9", 'cont',
80
+ enter "break #{__FILE__}:7", 'cont',
83
81
  ->{"thread stop #{Byebug.contexts.first.thnum}"}, release
84
82
  debug_file 'thread'
85
83
  check_error_includes "It's the current thread"
@@ -89,7 +87,7 @@ class TestThread < TestDsl::TestCase
89
87
  describe 'resume' do
90
88
  it 'must mark remove thread from the suspended state' do
91
89
  thnum = nil
92
- enter "break #{__FILE__}:22", 'cont',
90
+ enter "break #{__FILE__}:20", 'cont',
93
91
  -> { thnum = Byebug.contexts.last.thnum ; "thread stop #{thnum}" },
94
92
  -> { "thread resume #{thnum}" }, release
95
93
  debug_file('thread') { Byebug.contexts.last.suspended?.must_equal false }
@@ -97,20 +95,20 @@ class TestThread < TestDsl::TestCase
97
95
  end
98
96
 
99
97
  it 'must show error message if thread number is not specified' do
100
- enter "break #{__FILE__}:9", 'cont', 'thread resume', release
98
+ enter "break #{__FILE__}:7", 'cont', 'thread resume', release
101
99
  debug_file 'thread'
102
100
  check_error_includes '"thread resume" needs a thread number'
103
101
  end
104
102
 
105
103
  it 'must show error message when trying to resume current thread' do
106
- enter "break #{__FILE__}:9", 'cont',
104
+ enter "break #{__FILE__}:7", 'cont',
107
105
  ->{ "thread resume #{Byebug.contexts.first.thnum}" }, release
108
106
  debug_file 'thread'
109
107
  check_error_includes "It's the current thread"
110
108
  end
111
109
 
112
110
  it 'must show error message if it is not stopped' do
113
- enter "break #{__FILE__}:22", 'cont',
111
+ enter "break #{__FILE__}:20", 'cont',
114
112
  ->{ "thread resume #{Byebug.contexts.last.thnum}" }, release
115
113
  debug_file 'thread'
116
114
  check_error_includes 'Already running'
@@ -119,19 +117,19 @@ class TestThread < TestDsl::TestCase
119
117
 
120
118
  describe 'switch' do
121
119
  it 'must switch to another thread' do
122
- enter "break #{__FILE__}:22", 'cont',
120
+ enter "break #{__FILE__}:20", 'cont',
123
121
  ->{ "thread switch #{Byebug.contexts.last.thnum}" }, release
124
- debug_file('thread') { $state.line.must_equal 17 }
122
+ debug_file('thread') { assert_equal state.line, 15 }
125
123
  end
126
124
 
127
125
  it 'must show error message if thread number is not specified' do
128
- enter "break #{__FILE__}:9", 'cont', 'thread switch', release
126
+ enter "break #{__FILE__}:7", 'cont', 'thread switch', release
129
127
  debug_file 'thread'
130
128
  check_error_includes '"thread switch" needs a thread number'
131
129
  end
132
130
 
133
131
  it 'must show error message when trying to switch current thread' do
134
- enter "break #{__FILE__}:9", 'cont',
132
+ enter "break #{__FILE__}:7", 'cont',
135
133
  ->{ "thread switch #{Byebug.contexts.first.thnum}" }, release
136
134
  debug_file 'thread'
137
135
  check_error_includes "It's the current thread"