byebug 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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