byebug 1.8.2 → 2.0.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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/GUIDE.md +14 -22
  4. data/README.md +69 -6
  5. data/bin/byebug +3 -20
  6. data/ext/byebug/breakpoint.c +185 -101
  7. data/ext/byebug/byebug.c +393 -214
  8. data/ext/byebug/byebug.h +34 -15
  9. data/ext/byebug/context.c +327 -102
  10. data/ext/byebug/extconf.rb +1 -1
  11. data/ext/byebug/locker.c +54 -0
  12. data/ext/byebug/threads.c +113 -0
  13. data/lib/byebug.rb +19 -58
  14. data/lib/byebug/command.rb +18 -19
  15. data/lib/byebug/commands/breakpoints.rb +1 -4
  16. data/lib/byebug/commands/catchpoint.rb +1 -1
  17. data/lib/byebug/commands/condition.rb +1 -1
  18. data/lib/byebug/commands/control.rb +2 -3
  19. data/lib/byebug/commands/display.rb +2 -7
  20. data/lib/byebug/commands/edit.rb +1 -1
  21. data/lib/byebug/commands/enable.rb +12 -12
  22. data/lib/byebug/commands/eval.rb +4 -4
  23. data/lib/byebug/commands/finish.rb +1 -1
  24. data/lib/byebug/commands/frame.rb +12 -8
  25. data/lib/byebug/commands/info.rb +20 -52
  26. data/lib/byebug/commands/kill.rb +1 -5
  27. data/lib/byebug/commands/list.rb +2 -1
  28. data/lib/byebug/commands/quit.rb +1 -1
  29. data/lib/byebug/commands/repl.rb +2 -2
  30. data/lib/byebug/commands/save.rb +1 -1
  31. data/lib/byebug/commands/set.rb +84 -90
  32. data/lib/byebug/commands/show.rb +44 -53
  33. data/lib/byebug/commands/skip.rb +1 -1
  34. data/lib/byebug/commands/stepping.rb +5 -4
  35. data/lib/byebug/commands/threads.rb +202 -0
  36. data/lib/byebug/commands/trace.rb +1 -1
  37. data/lib/byebug/helper.rb +3 -3
  38. data/lib/byebug/interface.rb +2 -20
  39. data/lib/byebug/processor.rb +21 -100
  40. data/lib/byebug/remote.rb +3 -3
  41. data/lib/byebug/version.rb +1 -1
  42. data/old_doc/byebug.1 +0 -6
  43. data/old_doc/byebug.texi +29 -46
  44. data/test/breakpoints_test.rb +44 -65
  45. data/test/conditions_test.rb +0 -9
  46. data/test/continue_test.rb +2 -2
  47. data/test/display_test.rb +4 -23
  48. data/test/edit_test.rb +2 -16
  49. data/test/eval_test.rb +4 -13
  50. data/test/examples/thread.rb +32 -0
  51. data/test/finish_test.rb +1 -13
  52. data/test/frame_test.rb +5 -12
  53. data/test/help_test.rb +2 -12
  54. data/test/info_test.rb +8 -18
  55. data/test/kill_test.rb +1 -10
  56. data/test/list_test.rb +5 -14
  57. data/test/method_test.rb +1 -10
  58. data/test/post_mortem_test.rb +247 -14
  59. data/test/quit_test.rb +0 -9
  60. data/test/reload_test.rb +1 -15
  61. data/test/repl_test.rb +1 -9
  62. data/test/restart_test.rb +3 -18
  63. data/test/save_test.rb +1 -13
  64. data/test/set_test.rb +35 -32
  65. data/test/show_test.rb +8 -27
  66. data/test/source_test.rb +1 -8
  67. data/test/stepping_test.rb +65 -96
  68. data/test/support/test_dsl.rb +12 -17
  69. data/test/test_helper.rb +1 -1
  70. data/test/thread_test.rb +106 -0
  71. data/test/trace_test.rb +5 -17
  72. data/test/variables_test.rb +1 -10
  73. metadata +9 -7
  74. data/lib/byebug/commands/jump.rb +0 -52
  75. data/test/jump_test.rb +0 -77
  76. data/test/support/context.rb +0 -15
@@ -1,18 +1,8 @@
1
1
  require_relative 'test_helper'
2
2
 
3
3
  class TestShow < TestDsl::TestCase
4
-
5
- describe 'annotate' do
6
- it 'must show annotate setting' do
7
- enter 'show annotate'
8
- debug_file 'show'
9
- Byebug.annotate.must_equal 0
10
- check_output_includes 'Annotation level is 0'
11
- end
12
- end
13
-
14
4
  describe 'args' do
15
- temporary_change_hash Byebug::Command.settings, :argv, %w{foo bar}
5
+ temporary_change_hash Byebug.settings, :argv, %w{foo bar}
16
6
 
17
7
  describe 'default behaviour' do
18
8
  it 'must show args' do
@@ -109,11 +99,11 @@ class TestShow < TestDsl::TestCase
109
99
  end
110
100
  end
111
101
 
112
- describe 'linetrace+' do
102
+ describe 'linetrace_plus' do
113
103
  it 'must show default value' do
114
- enter 'show linetrace+'
104
+ enter 'show linetrace_plus'
115
105
  debug_file 'show'
116
- check_output_includes 'line tracing style is every line.'
106
+ check_output_includes 'line tracing style is different consecutive lines.'
117
107
  end
118
108
  end
119
109
 
@@ -125,9 +115,9 @@ class TestShow < TestDsl::TestCase
125
115
  end
126
116
  end
127
117
 
128
- describe 'trace' do
129
- it 'must show trace' do
130
- enter 'show trace'
118
+ describe 'stack_trace_on_error' do
119
+ it 'must show stack_trace_on_error' do
120
+ enter 'show stack_trace_on_error'
131
121
  debug_file 'show'
132
122
  check_output_includes 'Displaying stack trace is off.'
133
123
  end
@@ -137,7 +127,7 @@ class TestShow < TestDsl::TestCase
137
127
  it 'must show version' do
138
128
  enter 'show version'
139
129
  debug_file 'show'
140
- check_output_includes "byebug #{Byebug::VERSION}"
130
+ check_output_includes "Byebug #{Byebug::VERSION}"
141
131
  end
142
132
  end
143
133
 
@@ -274,13 +264,4 @@ class TestShow < TestDsl::TestCase
274
264
  check_output_includes /List of "show" subcommands:/
275
265
  end
276
266
  end
277
-
278
- describe 'Post Mortem' do
279
- it 'must work in post-mortem mode' do
280
- enter 'cont', 'show autolist'
281
- debug_file 'post_mortem'
282
- check_output_includes 'autolist is on.'
283
- end
284
- end
285
-
286
267
  end
@@ -28,7 +28,7 @@ class TestSource < TestDsl::TestCase
28
28
  it 'must show an error if file is not found' do
29
29
  enter 'source blabla'
30
30
  debug_file 'source'
31
- check_output_includes /File ".*blabla" not found/, interface.error_queue
31
+ check_error_includes /File ".*blabla" not found/
32
32
  end
33
33
 
34
34
  describe 'Help' do
@@ -39,11 +39,4 @@ class TestSource < TestDsl::TestCase
39
39
  "source FILE\texecutes a file containing byebug commands"
40
40
  end
41
41
  end
42
-
43
- describe 'Post Mortem' do
44
- it 'must work in post-mortem mode' do
45
- enter 'cont', "so #{filename}"
46
- debug_file('post_mortem') { Byebug.breakpoints[0].pos.must_equal 3 }
47
- end
48
- end
49
42
  end
@@ -4,137 +4,106 @@ class TestStepping < TestDsl::TestCase
4
4
 
5
5
  describe 'Next Command' do
6
6
 
7
- describe 'Usual mode' do
7
+ describe 'method call behaviour' do
8
+ before { enter 'break 10', 'cont' }
8
9
 
9
- describe 'method call behaviour' do
10
- before { enter 'break 10', 'cont' }
10
+ it 'must leave on the same line by default' do
11
+ enter 'next'
12
+ debug_file('stepping') { $state.line.must_equal 10 }
13
+ end
11
14
 
12
- it 'must leave on the same line by default' do
13
- enter 'next'
14
- debug_file('stepping') { $state.line.must_equal 10 }
15
- end
15
+ it 'must go to the next line if forced by "plus" sign' do
16
+ enter 'next+'
17
+ debug_file('stepping') { $state.line.must_equal 11 }
18
+ end
16
19
 
17
- it 'must go to the next line if forced by "plus" sign' do
18
- enter 'next+'
20
+ it 'must leave on the same line if forced by "minus" sign' do
21
+ enter 'next-'
22
+ debug_file('stepping') { $state.line.must_equal 10 }
23
+ end
24
+
25
+ describe 'when forcestep is set' do
26
+ temporary_change_hash Byebug.settings, :forcestep, true
27
+
28
+ it 'must go to the next line' do
29
+ enter 'next'
19
30
  debug_file('stepping') { $state.line.must_equal 11 }
20
31
  end
21
32
 
22
- it 'must leave on the same line if forced by "minus" sign' do
23
- enter 'next-'
24
- debug_file('stepping') { $state.line.must_equal 10 }
33
+ it 'must go to the next line (by shortcut)' do
34
+ enter 'n'
35
+ debug_file('stepping') { $state.line.must_equal 11 }
25
36
  end
26
37
 
27
- describe 'when force_stepping is set' do
28
- temporary_change_hash Byebug::Command.settings, :force_stepping, true
29
-
30
- it 'must go to the next line' do
31
- enter 'next'
32
- debug_file('stepping') { $state.line.must_equal 11 }
33
- end
34
-
35
- it 'must go to the next line (by shortcut)' do
36
- enter 'n'
37
- debug_file('stepping') { $state.line.must_equal 11 }
38
- end
39
-
40
- it 'must go the specified number of lines forward by default' do
41
- enter 'next 2'
42
- debug_file('stepping') { $state.line.must_equal 21 }
43
- end
44
-
45
- it 'must ignore it if "minus" is specified' do
46
- enter 'next-'
47
- debug_file('stepping') { $state.line.must_equal 10 }
48
- end
38
+ it 'must go the specified number of lines forward by default' do
39
+ enter 'next 2'
40
+ debug_file('stepping') { $state.line.must_equal 21 }
49
41
  end
50
- end
51
42
 
52
- describe 'block behaviour' do
53
- before { enter 'break 21', 'cont' }
54
-
55
- it 'must step over blocks' do
56
- enter 'next'
57
- debug_file('stepping') { $state.line.must_equal 25 }
43
+ it 'must ignore it if "minus" is specified' do
44
+ enter 'next-'
45
+ debug_file('stepping') { $state.line.must_equal 10 }
58
46
  end
59
47
  end
60
-
61
48
  end
62
49
 
63
- describe 'Post Mortem' do
64
- temporary_change_hash Byebug::Command.settings, :autoeval, false
50
+ describe 'block behaviour' do
51
+ before { enter 'break 21', 'cont' }
65
52
 
66
- it 'must not work in post-mortem mode' do
67
- enter 'cont', 'next'
68
- debug_file 'post_mortem'
69
- check_output_includes \
70
- 'Unknown command: "next". Try "help".', interface.error_queue
53
+ it 'must step over blocks' do
54
+ enter 'next'
55
+ debug_file('stepping') { $state.line.must_equal 25 }
71
56
  end
72
57
  end
73
-
74
58
  end
75
59
 
76
60
  describe 'Step Command' do
77
61
 
78
- describe 'Usual mode' do
79
-
80
- describe 'method call behaviour' do
81
- before { enter 'break 10', 'cont' }
82
-
83
- it 'must leave on the same line if forced by a setting' do
84
- enter 'step'
85
- debug_file('stepping') { $state.line.must_equal 10 }
86
- end
62
+ describe 'method call behaviour' do
63
+ before { enter 'break 10', 'cont' }
87
64
 
88
- it 'must go to the step line if forced to do that by "plus" sign' do
89
- enter 'step+'
90
- debug_file('stepping') { $state.line.must_equal 11 }
91
- end
92
-
93
- it 'must leave on the same line if forced to do that by "minus" sign' do
94
- enter 'step-'
95
- debug_file('stepping') { $state.line.must_equal 10 }
96
- end
65
+ it 'must leave on the same line if forced by a setting' do
66
+ enter 'step'
67
+ debug_file('stepping') { $state.line.must_equal 10 }
68
+ end
97
69
 
98
- describe 'when force_stepping is set' do
99
- temporary_change_hash Byebug::Command.settings, :force_stepping, true
70
+ it 'must go to the step line if forced to do that by "plus" sign' do
71
+ enter 'step+'
72
+ debug_file('stepping') { $state.line.must_equal 11 }
73
+ end
100
74
 
101
- it 'must go to the step line if forced by a setting' do
102
- enter 'step'
103
- debug_file('stepping') { $state.line.must_equal 11 }
104
- end
75
+ it 'must leave on the same line if forced to do that by "minus" sign' do
76
+ enter 'step-'
77
+ debug_file('stepping') { $state.line.must_equal 10 }
78
+ end
105
79
 
106
- it 'must go to the next line if forced by a setting (by shortcut)' do
107
- enter 's'
108
- debug_file('stepping') { $state.line.must_equal 11 }
109
- end
80
+ describe 'when forcestep is set' do
81
+ temporary_change_hash Byebug.settings, :forcestep, true
110
82
 
111
- it 'must go the specified number of lines forward by default' do
112
- enter 'step 2'
113
- debug_file('stepping') { $state.line.must_equal 15 }
114
- end
83
+ it 'must go to the step line if forced by a setting' do
84
+ enter 'step'
85
+ debug_file('stepping') { $state.line.must_equal 11 }
115
86
  end
116
- end
117
87
 
118
- describe 'block behaviour' do
119
- before { enter 'break 21', 'cont' }
88
+ it 'must go to the next line if forced by a setting (by shortcut)' do
89
+ enter 's'
90
+ debug_file('stepping') { $state.line.must_equal 11 }
91
+ end
120
92
 
121
- it 'must step into blocks' do
122
- enter 'step'
123
- debug_file('stepping') { $state.line.must_equal 22 }
93
+ it 'must go the specified number of lines forward by default' do
94
+ enter 'step 2'
95
+ debug_file('stepping') { $state.line.must_equal 15 }
124
96
  end
125
97
  end
126
98
  end
127
99
 
128
- describe 'Post Mortem' do
129
- temporary_change_hash Byebug::Command.settings, :autoeval, false
100
+ describe 'block behaviour' do
101
+ before { enter 'break 21', 'cont' }
130
102
 
131
- it 'must not work in post-mortem mode' do
132
- enter 'cont', 'step'
133
- debug_file 'post_mortem'
134
- check_output_includes \
135
- 'Unknown command: "step". Try "help".', interface.error_queue
103
+ it 'must step into blocks' do
104
+ enter 'step'
105
+ debug_file('stepping') { $state.line.must_equal 22 }
136
106
  end
137
107
  end
138
108
  end
139
-
140
109
  end
@@ -4,8 +4,8 @@ module TestDsl
4
4
  include TestDsl
5
5
 
6
6
  def setup
7
- Byebug.interface = TestInterface.new
8
- Byebug.handler.display.clear
7
+ Byebug.handler = Byebug::CommandProcessor.new(TestInterface.new)
8
+ Byebug.tracing = false
9
9
  end
10
10
 
11
11
  def self.temporary_change_hash hash, key, value
@@ -42,14 +42,14 @@ module TestDsl
42
42
  end
43
43
  end
44
44
 
45
- ##
45
+ #
46
46
  # Expand fullpath of a given example file
47
47
  #
48
48
  def fullpath(filename)
49
49
  (Pathname.new(__FILE__) + "../../examples/#{filename}.rb").cleanpath.to_s
50
50
  end
51
51
 
52
- ##
52
+ #
53
53
  # Adds commands to the input queue, so they will be later retrieved by
54
54
  # Processor, i.e., it emulates user's input.
55
55
  #
@@ -68,7 +68,7 @@ module TestDsl
68
68
  interface.input_queue.concat(messages)
69
69
  end
70
70
 
71
- ##
71
+ #
72
72
  # Runs byebug with the provided basename for a file.
73
73
  #
74
74
  # The file should be placed in the test/examples dir. You also can specify a
@@ -85,20 +85,11 @@ module TestDsl
85
85
  def debug_file(filename, &block)
86
86
  is_test_block_called = false
87
87
  debug_completed = false
88
- exception = nil
89
88
  Byebug.stubs(:run_init_script)
90
89
  if block
91
90
  interface.test_block= lambda do
92
91
  is_test_block_called = true
93
- # We need to store exception and reraise it after completing debugging,
94
- # because Byebug will swallow any exceptions, so e.g. our failed
95
- # assertions will be ignored
96
- begin
97
- block.call
98
- rescue Exception => e
99
- exception = e
100
- raise e
101
- end
92
+ block.call
102
93
  end
103
94
  end
104
95
  Byebug.start do
@@ -107,10 +98,9 @@ module TestDsl
107
98
  end
108
99
  flunk "Debug block was not completed" unless debug_completed
109
100
  flunk "Test block was provided, but not called" if block && !is_test_block_called
110
- raise exception if exception
111
101
  end
112
102
 
113
- ##
103
+ #
114
104
  # Checks the output of byebug.
115
105
  #
116
106
  # By default it checks output queue of the current interface, but you can
@@ -163,4 +153,9 @@ module TestDsl
163
153
  new_content = old_content.split("\n").tap { |c| c[line - 1] = new_line_content }.join("\n")
164
154
  File.open(file, 'w') { |f| f.write(new_content) }
165
155
  end
156
+
157
+ def must_restart
158
+ Byebug::RestartCommand.any_instance.unstub(:exec)
159
+ Byebug::RestartCommand.any_instance.expects(:exec)
160
+ end
166
161
  end
@@ -5,4 +5,4 @@ require 'byebug'
5
5
 
6
6
  Dir.glob(File.expand_path("../support/*.rb", __FILE__)).each { |f| require f }
7
7
 
8
- Byebug::Command.settings[:testing] = true
8
+ Byebug.settings[:testing] = true
@@ -0,0 +1,106 @@
1
+ require_relative 'test_helper'
2
+
3
+ class TestThread < TestDsl::TestCase
4
+ let(:release) { 'eval Thread.main[:should_break] = true' }
5
+
6
+ describe 'list' do
7
+ it 'must show current thread by "plus" sign' do
8
+ thnum = nil
9
+ enter 'break 8', 'cont', 'thread list', release
10
+ debug_file('thread') { thnum = Byebug.contexts.first.thnum }
11
+ check_output_includes /\+ #{thnum} #<Thread:\S+ run>\t#{fullpath('thread')}:8/
12
+ end
13
+
14
+ it 'must work with shortcut' do
15
+ thnum = nil
16
+ enter 'break 8', 'cont', 'th list', release
17
+ debug_file('thread') { thnum = Byebug.contexts.first.thnum }
18
+ check_output_includes /\+ #{thnum} #<Thread:\S+ run>\t#{fullpath('thread')}:8/
19
+ end
20
+
21
+ it 'must show 3 available threads' do
22
+ enter 'break 21', 'cont', 'thread list', release
23
+ debug_file 'thread'
24
+ check_output_includes /(\+)?\d+ #<Thread:\S+ (sleep|run)>/,
25
+ /(\+)?\d+ #<Thread:\S+ (sleep|run)>/,
26
+ /(\+)?\d+ #<Thread:\S+ (sleep|run)>/
27
+ end
28
+ end
29
+
30
+ describe 'stop' do
31
+ it 'must mark thread as suspended' do
32
+ thnum = nil
33
+ enter 'c 21', ->{ "thread stop #{Byebug.contexts.last.thnum}" }, release
34
+ debug_file('thread') { thnum = Byebug.contexts.last.thnum }
35
+ check_output_includes /\$ #{thnum} #<Thread:/
36
+ end
37
+
38
+ it 'must actually suspend thread execution' do
39
+ enter 'c 21', 'trace on',
40
+ ->{ "thread stop #{Byebug.contexts.last.thnum}" }, release
41
+ debug_file('thread')
42
+ check_output_doesnt_include /Tracing: #{fullpath('thread')}:16/,
43
+ /Tracing: #{fullpath('thread')}:17/
44
+ end
45
+
46
+ it 'must show error message if thread number is not specified' do
47
+ enter 'break 8', 'cont', 'thread stop', release
48
+ debug_file 'thread'
49
+ check_error_includes '"thread stop" needs a thread number'
50
+ end
51
+
52
+ it 'must show error message when trying to stop current thread' do
53
+ enter 'cont 8', ->{"thread stop #{Byebug.contexts.first.thnum}"}, release
54
+ debug_file 'thread'
55
+ check_error_includes "It's the current thread"
56
+ end
57
+ end
58
+
59
+ describe 'resume' do
60
+ it 'must mark remove thread from the suspended state' do
61
+ thnum = nil
62
+ enter 'cont 21',
63
+ -> { thnum = Byebug.contexts.last.thnum ; "thread stop #{thnum}" },
64
+ -> { "thread resume #{thnum}" }, release
65
+ debug_file('thread') { Byebug.contexts.last.suspended?.must_equal false }
66
+ check_output_includes /\$ #{thnum} #<Thread:/, /#{thnum} #<Thread:/
67
+ end
68
+
69
+ it 'must show error message if thread number is not specified' do
70
+ enter 'break 8', 'cont', 'thread resume', release
71
+ debug_file 'thread'
72
+ check_error_includes '"thread resume" needs a thread number'
73
+ end
74
+
75
+ it 'must show error message when trying to resume current thread' do
76
+ enter 'c 8', ->{ "thread resume #{Byebug.contexts.first.thnum}" }, release
77
+ debug_file 'thread'
78
+ check_error_includes "It's the current thread"
79
+ end
80
+
81
+ it 'must show error message if it is not stopped' do
82
+ enter 'c 21', ->{ "thread resume #{Byebug.contexts.last.thnum}" }, release
83
+ debug_file 'thread'
84
+ check_error_includes 'Already running'
85
+ end
86
+ end
87
+
88
+ describe 'switch' do
89
+ it 'must switch to another thread' do
90
+ enter 'c 21', ->{ "thread switch #{Byebug.contexts.last.thnum}" }, release
91
+ debug_file('thread') { $state.line.must_equal 16 }
92
+ end
93
+
94
+ it 'must show error message if thread number is not specified' do
95
+ enter 'break 8', 'cont', 'thread switch', release
96
+ debug_file 'thread'
97
+ check_error_includes '"thread switch" needs a thread number'
98
+ end
99
+
100
+ it 'must show error message when trying to switch current thread' do
101
+ enter 'c 8', ->{ "thread switch #{Byebug.contexts.first.thnum}" }, release
102
+ debug_file 'thread'
103
+ check_error_includes "It's the current thread"
104
+ end
105
+ end
106
+ end