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
@@ -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"