byebug 1.1.1 → 1.2.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/GUIDE.md +231 -0
  4. data/README.md +195 -7
  5. data/bin/byebug +1 -5
  6. data/byebug.gemspec +34 -35
  7. data/lib/byebug.rb +2 -5
  8. data/lib/byebug/command.rb +13 -13
  9. data/lib/byebug/commands/breakpoints.rb +1 -1
  10. data/lib/byebug/commands/control.rb +1 -1
  11. data/lib/byebug/commands/frame.rb +1 -1
  12. data/lib/byebug/commands/info.rb +1 -1
  13. data/lib/byebug/commands/list.rb +5 -5
  14. data/lib/byebug/commands/reload.rb +7 -10
  15. data/lib/byebug/commands/{irb.rb → repl.rb} +49 -13
  16. data/lib/byebug/commands/set.rb +10 -6
  17. data/lib/byebug/commands/show.rb +4 -7
  18. data/lib/byebug/commands/trace.rb +2 -2
  19. data/lib/byebug/context.rb +3 -5
  20. data/lib/byebug/helper.rb +2 -2
  21. data/lib/byebug/interface.rb +3 -0
  22. data/lib/byebug/processor.rb +2 -2
  23. data/lib/byebug/version.rb +1 -1
  24. data/old_doc/byebug.1 +1 -2
  25. data/old_doc/byebug.texi +125 -126
  26. data/old_doc/hanoi.rb +2 -3
  27. data/old_doc/triangle.rb +6 -7
  28. data/test/breakpoints_test.rb +43 -33
  29. data/test/display_test.rb +1 -1
  30. data/test/edit_test.rb +20 -15
  31. data/test/eval_test.rb +32 -26
  32. data/test/examples/list.rb +12 -1
  33. data/test/frame_test.rb +56 -43
  34. data/test/help_test.rb +11 -8
  35. data/test/info_test.rb +18 -13
  36. data/test/list_test.rb +74 -80
  37. data/test/method_test.rb +1 -3
  38. data/test/reload_test.rb +3 -3
  39. data/test/repl_test.rb +112 -0
  40. data/test/restart_test.rb +72 -70
  41. data/test/set_test.rb +43 -27
  42. data/test/show_test.rb +97 -102
  43. data/test/source_test.rb +6 -10
  44. data/test/stepping_test.rb +45 -49
  45. data/test/support/test_dsl.rb +47 -55
  46. data/test/test_helper.rb +2 -2
  47. data/test/trace_test.rb +4 -4
  48. data/test/variables_test.rb +10 -8
  49. metadata +9 -10
  50. data/old_doc/Makefile +0 -20
  51. data/test/examples/edit2.rb +0 -3
  52. data/test/irb_test.rb +0 -85
@@ -1,5 +1,4 @@
1
- #!/usr/bin/ruby
2
-
1
+ # Solves the classic Towers of Hanoi puzzle.
3
2
  def hanoi(n,a,b,c)
4
3
  if n-1 > 0
5
4
  hanoi(n-1, a, c, b)
@@ -21,7 +20,7 @@ n=3
21
20
  if i_args > 0
22
21
  begin
23
22
  n = ARGV[0].to_i
24
- rescue ValueError, msg:
23
+ rescue ValueError, :msg
25
24
  print "** Expecting an integer, got: %s" % ARGV[0].to_s
26
25
  exit 2
27
26
  end
@@ -1,12 +1,11 @@
1
- #!/usr/bin/env ruby
2
- # Compute the n'th triangle number - the hard way
3
- # triangle(n) == (n * (n+1)) / 2
1
+ # Compute the n'th triangle number, the hard way: triangle(n) == (n*(n+1))/2
4
2
  def triangle(n)
5
3
  tri = 0
6
4
  0.upto(n) do |i|
7
5
  tri += i
8
6
  end
9
- return tri
10
- end
11
-
12
- puts triangle(3)
7
+ tri
8
+ end
9
+
10
+ t = triangle(3)
11
+ puts t
@@ -77,47 +77,57 @@ describe 'Breakpoints' do
77
77
  end
78
78
 
79
79
  describe 'show a message' do
80
- it 'must show a message with full filename' do
81
- enter 'break 14', 'cont'
82
- debug_file('breakpoint1') { @id = Byebug.breakpoints.first.id }
83
- check_output_includes \
84
- "Created breakpoint #{@id} at #{fullpath('breakpoint1')}:14"
80
+ describe 'with full filename' do
81
+ temporary_change_hash Byebug::Command.settings, :basename, false
82
+
83
+ it 'must show a message with full filename' do
84
+ enter 'break 14', 'cont'
85
+ debug_file('breakpoint1') { @id = Byebug.breakpoints.first.id }
86
+ check_output_includes \
87
+ "Created breakpoint #{@id} at #{fullpath('breakpoint1')}:14"
88
+ end
85
89
  end
86
90
 
87
- it 'must show a message with basename' do
88
- enter 'set basename', 'break 14', 'cont'
89
- debug_file('breakpoint1') { @id = Byebug.breakpoints.first.id }
90
- check_output_includes "Created breakpoint #{@id} at breakpoint1.rb:14"
91
+ describe 'with basename' do
92
+ temporary_change_hash Byebug::Command.settings, :basename, true
93
+
94
+ it 'must show a message with basename' do
95
+ enter 'break 14', 'cont'
96
+ debug_file('breakpoint1') { @id = Byebug.breakpoints.first.id }
97
+ check_output_includes "Created breakpoint #{@id} at breakpoint1.rb:14"
98
+ end
91
99
  end
92
100
  end
93
101
  end
94
102
 
95
103
  describe 'reloading source on change' do
96
- it 'must not reload source if autoreload is not set' do
97
- id = nil
98
- enter \
99
- 'set noautoreload',
100
- ->{change_line_in_file(fullpath('breakpoint1'), 14, ''); 'break 14'},
101
- ->{change_line_in_file(fullpath('breakpoint1'), 14, 'c = a + b');
104
+ describe 'autoreload not set' do
105
+ temporary_change_hash Byebug::Command.settings, :autoreload, false
106
+
107
+ it 'must not reload source' do
108
+ id = nil
109
+ enter \
110
+ ->{change_line_in_file(fullpath('breakpoint1'), 14, ''); 'break 14'},
111
+ ->{change_line_in_file(fullpath('breakpoint1'), 14, 'c = a + b');
102
112
  'cont'}
103
- debug_file('breakpoint1') { id = Byebug.breakpoints.first.id }
104
- check_output_includes \
105
- "Created breakpoint #{id} at #{fullpath('breakpoint1')}:14"
106
- end
107
-
108
- it 'must reload source if autoreload is set' do
109
- enter \
110
- 'set autoreload',
111
- ->{change_line_in_file(fullpath('breakpoint1'), 14, ''); 'break 14'},
112
- # Setting second breakpoint just to reload the source code after rolling
113
- # the file changes back
114
- ->{change_line_in_file(fullpath('breakpoint1'), 14, 'c = a + b');
115
- 'break 15'},
116
- 'cont'
117
- debug_file 'breakpoint1'
118
- check_output_includes \
119
- "Line 14 is not a stopping point in file #{fullpath('breakpoint1')}",
120
- interface.error_queue
113
+ debug_file('breakpoint1') { id = Byebug.breakpoints.first.id }
114
+ check_output_includes \
115
+ "Created breakpoint #{id} at #{fullpath('breakpoint1')}:14"
116
+ end
117
+ end
118
+
119
+ describe 'autoreload set' do
120
+ it 'must reload source' do
121
+ enter \
122
+ ->{change_line_in_file(fullpath('breakpoint1'), 14, ''); 'break 14'},
123
+ # 2nd breakpoint just to reload source code after rolling changes back
124
+ ->{change_line_in_file(fullpath('breakpoint1'), 14, 'c = a + b');
125
+ 'break 15'}, 'cont'
126
+ debug_file 'breakpoint1'
127
+ check_output_includes \
128
+ "Line 14 is not a stopping point in file #{fullpath('breakpoint1')}",
129
+ interface.error_queue
130
+ end
121
131
  end
122
132
  end
123
133
 
@@ -136,7 +136,7 @@ describe 'Display Command' do
136
136
  end
137
137
 
138
138
  describe 'Post Mortem' do
139
- before { Byebug::Command.settings[:autoeval] = false }
139
+ temporary_change_hash Byebug::Command.settings, :autoeval, false
140
140
 
141
141
  it 'must be able to set display expressions in post-mortem mode' do
142
142
  enter 'cont', 'display 2 + 2'
@@ -3,8 +3,10 @@ require_relative 'test_helper'
3
3
  describe 'Edit Command' do
4
4
  include TestDsl
5
5
 
6
- it 'must open an editor with current file and line' do
7
- temporary_change_hash_value(ENV, 'EDITOR', 'editr') do
6
+ describe 'open configured editor' do
7
+ temporary_change_hash ENV, 'EDITOR', 'editr'
8
+
9
+ it 'must open current file in current line in configured editor' do
8
10
  Byebug::Edit.any_instance.expects(:system).
9
11
  with("editr +2 #{fullpath('edit')}")
10
12
  enter 'edit'
@@ -12,8 +14,10 @@ describe 'Edit Command' do
12
14
  end
13
15
  end
14
16
 
15
- it 'must open a default editor with current file and line' do
16
- temporary_change_hash_value(ENV, 'EDITOR', nil) do
17
+ describe 'open default editor' do
18
+ temporary_change_hash ENV, 'EDITOR', nil
19
+
20
+ it 'must call "ex" with current line and file if EDITOR env not set' do
17
21
  Byebug::Edit.any_instance.expects(:system).
18
22
  with("ex +2 #{fullpath('edit')}")
19
23
  enter 'edit'
@@ -21,11 +25,13 @@ describe 'Edit Command' do
21
25
  end
22
26
  end
23
27
 
24
- it 'must open an editor with specified file and line' do
25
- temporary_change_hash_value(ENV, 'EDITOR', 'editr') do
28
+ describe 'open configured editor specifying line and file' do
29
+ temporary_change_hash ENV, 'EDITOR', 'editr'
30
+
31
+ it 'must open specified line in specified file with configured editor' do
26
32
  Byebug::Edit.any_instance.expects(:system).
27
- with("editr +3 #{fullpath('edit2')}")
28
- enter "edit #{fullpath('edit2')}:3"
33
+ with("editr +3 #{fullpath('breakpoint1')}")
34
+ enter "edit #{fullpath('breakpoint1')}:3"
29
35
  debug_file 'edit'
30
36
  end
31
37
  end
@@ -44,15 +50,14 @@ describe 'Edit Command' do
44
50
  'Invalid file/line number specification: blabla', interface.error_queue
45
51
  end
46
52
 
47
-
48
53
  describe 'Post Mortem' do
54
+ temporary_change_hash ENV, 'EDITOR', 'editr'
55
+
49
56
  it 'must work in post-mortem mode' do
50
- temporary_change_hash_value(ENV, 'EDITOR', 'editr') do
51
- Byebug::Edit.any_instance.expects(:system).
52
- with("editr +2 #{fullpath('edit')}")
53
- enter 'cont', "edit #{fullpath('edit')}:2", 'cont'
54
- debug_file 'post_mortem'
55
- end
57
+ Byebug::Edit.any_instance.expects(:system).
58
+ with("editr +2 #{fullpath('edit')}")
59
+ enter 'cont', "edit #{fullpath('edit')}:2", 'cont'
60
+ debug_file 'post_mortem'
56
61
  end
57
62
  end
58
63
 
@@ -38,51 +38,57 @@ describe 'Eval Command' do
38
38
  end
39
39
 
40
40
  describe 'stack trace on error' do
41
- it 'must show a stack trace if showing trace on error is enabled' do
42
- enter 'set notrace', 'eval 2 / 0'
43
- debug_file 'eval'
44
- check_output_includes 'ZeroDivisionError Exception: divided by 0'
45
- check_output_doesnt_include /\S+:\d+:in `eval':divided by 0/
41
+ describe 'when enabled' do
42
+ temporary_change_hash Byebug::Command.settings, :stack_trace_on_error, true
43
+
44
+ it 'must show a stack trace' do
45
+ enter 'eval 2 / 0'
46
+ debug_file 'eval'
47
+ check_output_includes /\S+:\d+:in `eval':divided by 0/
48
+ check_output_doesnt_include 'ZeroDivisionError Exception: divided by 0'
49
+ end
46
50
  end
47
51
 
48
- it 'must show a stack trace if showing trace on error is enabled' do
49
- enter 'set trace', 'eval 2 / 0'
50
- debug_file 'eval'
51
- check_output_includes /\S+:\d+:in `eval':divided by 0/
52
- check_output_doesnt_include 'ZeroDivisionError Exception: divided by 0'
52
+ describe 'when disabled' do
53
+ temporary_change_hash Byebug::Command.settings, :stack_trace_on_error, false
54
+
55
+ it 'must only show exception' do
56
+ enter 'eval 2 / 0'
57
+ debug_file 'eval'
58
+ check_output_includes 'ZeroDivisionError Exception: divided by 0'
59
+ check_output_doesnt_include /\S+:\d+:in `eval':divided by 0/
60
+ end
53
61
  end
54
62
  end
55
63
 
56
- it 'must pretty print the expression result' do
57
- enter 'pp {a: \'3\' * 40, b: \'4\' * 30}'
58
- debug_file 'eval'
59
- check_output_includes "{:a=>\"#{'3' * 40}\",\n :b=>\"#{'4' * 30}\"}"
64
+ describe 'pp' do
65
+ it 'must pretty print the expression result' do
66
+ enter 'pp {a: \'3\' * 40, b: \'4\' * 30}'
67
+ debug_file 'eval'
68
+ check_output_includes "{:a=>\"#{'3' * 40}\",\n :b=>\"#{'4' * 30}\"}"
69
+ end
60
70
  end
61
71
 
62
- it 'must print expression and columnize the result' do
63
- temporary_change_hash_value(Byebug::PutLCommand.settings, :width, 20) do
72
+ describe 'putl' do
73
+ temporary_change_hash Byebug::Command.settings, :width, 20
74
+
75
+ it 'must print expression and columnize the result' do
64
76
  enter 'putl [1, 2, 3, 4, 5, 9, 8, 7, 6]'
65
77
  debug_file 'eval'
66
78
  check_output_includes "1 3 5 8 6\n2 4 9 7"
67
79
  end
68
80
  end
69
81
 
70
- it 'must print expression and sort and columnize the result' do
71
- temporary_change_hash_value(Byebug::PSCommand.settings, :width, 20) do
82
+ describe 'ps' do
83
+ temporary_change_hash Byebug::Command.settings, :width, 20
84
+
85
+ it 'must print expression and sort and columnize the result' do
72
86
  enter 'ps [1, 2, 3, 4, 5, 9, 8, 7, 6]'
73
87
  debug_file 'eval'
74
88
  check_output_includes "1 3 5 7 9\n2 4 6 8"
75
89
  end
76
90
  end
77
91
 
78
- it 'must set width by the "set" command' do
79
- temporary_change_hash_value(Byebug::PSCommand.settings, :width, 20) do
80
- enter 'set width 10', 'ps [1, 2, 3, 4, 5, 9, 8, 7, 6]'
81
- debug_file 'eval'
82
- check_output_includes "1 4 7\n2 5 8\n3 6 9"
83
- end
84
- end
85
-
86
92
  describe 'Post Mortem' do
87
93
  it 'must work in post-mortem mode' do
88
94
  enter 'cont', 'eval 2 + 2'
@@ -9,4 +9,15 @@ byebug
9
9
  9
10
10
  10
11
11
  11
12
- 12
12
+ 12
13
+ 13
14
+ 14
15
+ 15
16
+ 16
17
+ 17
18
+ 18
19
+ 19
20
+ 20
21
+ 21
22
+ 22
23
+ 23
@@ -3,10 +3,9 @@ require_relative 'test_helper'
3
3
  describe 'Frame Command' do
4
4
  include TestDsl
5
5
 
6
- def after_setup
7
- Byebug::Command.settings[:width] =
8
- "--> #0 A.d(e#String) at #{fullpath('frame')}:16".size
9
- end
6
+ # XXX: Calculate magic number dinamically, like
7
+ # "longest_string_in_test_output".size
8
+ temporary_change_hash Byebug::Command.settings, :width, 96
10
9
 
11
10
  it 'must go up' do
12
11
  enter 'break 16', 'cont', 'up'
@@ -40,7 +39,8 @@ describe 'Frame Command' do
40
39
 
41
40
  it 'must print current stack frame when without arguments' do
42
41
  enter 'break A.d', 'cont', 'up', 'frame'
43
- debug_file('frame') { check_output_includes "#0 A.d(e#String) at #{fullpath('frame')}:15" }
42
+ debug_file('frame') {
43
+ check_output_includes "#0 A.d(e#String) at #{fullpath('frame')}:15" }
44
44
  end
45
45
 
46
46
  it 'must set frame to the first one' do
@@ -70,64 +70,77 @@ describe 'Frame Command' do
70
70
  interface.error_queue
71
71
  end
72
72
 
73
- describe 'full path settings' do
73
+ describe 'fullpath' do
74
74
  def short_path(fullpath)
75
75
  separator = File::ALT_SEPARATOR || File::SEPARATOR
76
76
  "...#{separator}" + fullpath.split(separator)[-3..-1].join(separator)
77
77
  end
78
78
 
79
- before do
80
- Byebug::Command.settings[:callstyle] = :last
81
- end
79
+ describe 'when set' do
80
+ temporary_change_hash Byebug::Command.settings, :frame_fullpath, true
82
81
 
83
- it 'must display current backtrace with full path = true' do
84
- enter 'set fullpath', 'break 16', 'cont', 'where'
85
- debug_file 'frame'
86
- check_output_includes "--> #0 A.d(e#String) at #{fullpath('frame')}:16",
87
- " #1 A.c at #{fullpath('frame')}:12"
82
+ it 'must display current backtrace with fullpaths' do
83
+ enter 'break 16', 'cont', 'where'
84
+ debug_file 'frame'
85
+ check_output_includes \
86
+ "--> #0 A.d(e#String) at #{fullpath('frame')}:16",
87
+ " #1 A.c at #{fullpath('frame')}:12"
88
+ end
88
89
  end
89
90
 
90
- it 'must display current backtrace with full path = false' do
91
- enter 'set nofullpath', 'break 16', 'cont', 'where'
92
- debug_file 'frame'
93
- check_output_includes \
94
- "--> #0 A.d(e#String) at #{short_path(fullpath('frame'))}:16",
95
- " #1 A.c at #{short_path(fullpath('frame'))}:12"
91
+ describe 'when unset' do
92
+ temporary_change_hash Byebug::Command.settings, :frame_fullpath, false
93
+
94
+ it 'must display current backtrace with shortpaths' do
95
+ enter 'set nofullpath', 'break 16', 'cont', 'where'
96
+ debug_file 'frame'
97
+ check_output_includes \
98
+ "--> #0 A.d(e#String) at #{short_path(fullpath('frame'))}:16",
99
+ " #1 A.c at #{short_path(fullpath('frame'))}:12"
100
+ end
96
101
  end
97
102
  end
98
103
 
99
- describe 'callstyles' do
100
- it 'displays current backtrace with callstyle "last"' do
101
- enter 'set callstyle last', 'break 16', 'cont', 'where'
102
- debug_file 'frame'
103
- check_output_includes "--> #0 A.d(e#String) at #{fullpath('frame')}:16",
104
- " #1 A.c at #{fullpath('frame')}:12" ,
105
- " #2 A.b at #{fullpath('frame')}:8" ,
106
- " #3 A.a at #{fullpath('frame')}:5"
104
+ describe 'callstyle' do
105
+ describe 'last' do
106
+ temporary_change_hash Byebug::Command.settings, :callstyle, :last
107
+
108
+ it 'displays current backtrace with callstyle "last"' do
109
+ enter 'break 16', 'cont', 'where'
110
+ debug_file 'frame'
111
+ check_output_includes \
112
+ "--> #0 A.d(e#String) at #{fullpath('frame')}:16",
113
+ " #1 A.c at #{fullpath('frame')}:12" ,
114
+ " #2 A.b at #{fullpath('frame')}:8" ,
115
+ " #3 A.a at #{fullpath('frame')}:5"
116
+ end
107
117
  end
108
118
 
109
- it 'displays current backtrace with callstyle "short"' do
110
- enter 'set callstyle short', 'break 16', 'cont', 'where'
111
- debug_file 'frame'
112
- check_output_includes "--> #0 d(e) at #{fullpath('frame')}:16",
113
- " #1 c at #{fullpath('frame')}:12" ,
114
- " #2 b at #{fullpath('frame')}:8" ,
115
- " #3 a at #{fullpath('frame')}:5"
119
+ describe 'short' do
120
+ temporary_change_hash Byebug::Command.settings, :callstyle, :short
121
+
122
+ it 'displays current backtrace with callstyle "short"' do
123
+ enter 'break 16', 'cont', 'where'
124
+ debug_file 'frame'
125
+ check_output_includes "--> #0 d(e) at #{fullpath('frame')}:16",
126
+ " #1 c at #{fullpath('frame')}:12" ,
127
+ " #2 b at #{fullpath('frame')}:8" ,
128
+ " #3 a at #{fullpath('frame')}:5"
129
+ end
116
130
  end
117
131
 
118
- it 'displays current backtrace with callstyle "tracked"' do
119
- skip('XXX: Style supported but not working....')
120
- enter 'set callstyle tracked'
121
- debug_file 'frame'
122
- check_output_includes \
123
- 'Invalid call style tracked. Should be one of: "last".'
124
- Byebug::Command.settings[:callstyle].must_equal :last
132
+ describe 'tracked' do
133
+ temporary_change_hash Byebug::Command.settings, :callstyle, :tracked
134
+
135
+ it 'displays current backtrace with callstyle "tracked"' do
136
+ skip 'XXX: Style supported but not working....'
137
+ debug_file 'frame'
138
+ end
125
139
  end
126
140
  end
127
141
 
128
142
  describe 'Post Mortem' do
129
143
  it 'must work in post-mortem mode' do
130
- #skip 'TODO: This test fails with \'Segmentation fault\'.'
131
144
  enter 'cont', 'frame'
132
145
  debug_file('post_mortem') { state.line.must_equal 8 }
133
146
  end
@@ -5,15 +5,18 @@ describe 'Help Command' do
5
5
  include Columnize
6
6
 
7
7
  let(:available_commands) {
8
- Byebug::Command.commands.select(&:event).map(&:names).flatten.uniq.sort
9
- }
8
+ Byebug::Command.commands.select(&:event).map(&:names).flatten.uniq.sort }
10
9
 
11
- it '"help" alone must show how to use "help"' do
12
- enter 'set width 50', 'help'
13
- debug_file 'help'
14
- check_output_includes \
15
- 'Type "help <command-name>" for help on a specific command',
16
- 'Available commands:', columnize(available_commands, 50)
10
+ describe 'when typed alone' do
11
+ temporary_change_hash Byebug::Command.settings, :width, 50
12
+
13
+ it 'must show self help when typed alone' do
14
+ enter 'help'
15
+ debug_file 'help'
16
+ check_output_includes \
17
+ 'Type "help <command-name>" for help on a specific command',
18
+ 'Available commands:', columnize(available_commands, 50)
19
+ end
17
20
  end
18
21
 
19
22
  it 'must work when shortcut used' do