byebug 3.1.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -2
  3. data/CHANGELOG.md +15 -0
  4. data/GUIDE.md +17 -35
  5. data/Gemfile +8 -5
  6. data/LICENSE +1 -1
  7. data/README.md +10 -22
  8. data/Rakefile +1 -1
  9. data/ext/byebug/byebug.c +3 -2
  10. data/lib/byebug.rb +3 -38
  11. data/lib/byebug/commands/break.rb +83 -0
  12. data/lib/byebug/commands/catchpoint.rb +0 -1
  13. data/lib/byebug/commands/condition.rb +10 -6
  14. data/lib/byebug/commands/continue.rb +3 -6
  15. data/lib/byebug/commands/delete.rb +38 -0
  16. data/lib/byebug/commands/edit.rb +0 -2
  17. data/lib/byebug/commands/enable.rb +7 -8
  18. data/lib/byebug/commands/finish.rb +0 -2
  19. data/lib/byebug/commands/frame.rb +13 -15
  20. data/lib/byebug/commands/help.rb +1 -3
  21. data/lib/byebug/commands/history.rb +3 -3
  22. data/lib/byebug/commands/info.rb +4 -13
  23. data/lib/byebug/commands/interrupt.rb +25 -0
  24. data/lib/byebug/commands/kill.rb +0 -2
  25. data/lib/byebug/commands/list.rb +2 -4
  26. data/lib/byebug/commands/method.rb +2 -8
  27. data/lib/byebug/commands/quit.rb +0 -2
  28. data/lib/byebug/commands/reload.rb +2 -15
  29. data/lib/byebug/commands/repl.rb +0 -3
  30. data/lib/byebug/commands/{control.rb → restart.rb} +2 -26
  31. data/lib/byebug/commands/save.rb +0 -1
  32. data/lib/byebug/commands/set.rb +4 -7
  33. data/lib/byebug/commands/show.rb +0 -3
  34. data/lib/byebug/commands/source.rb +0 -3
  35. data/lib/byebug/commands/stepping.rb +3 -4
  36. data/lib/byebug/commands/trace.rb +0 -1
  37. data/lib/byebug/commands/variables.rb +3 -4
  38. data/lib/byebug/context.rb +0 -1
  39. data/lib/byebug/helper.rb +23 -0
  40. data/lib/byebug/interfaces/script_interface.rb +1 -1
  41. data/lib/byebug/processors/command_processor.rb +9 -9
  42. data/lib/byebug/remote.rb +2 -2
  43. data/lib/byebug/setting.rb +3 -1
  44. data/lib/byebug/settings/autoeval.rb +3 -1
  45. data/lib/byebug/settings/autoirb.rb +3 -1
  46. data/lib/byebug/settings/autolist.rb +3 -1
  47. data/lib/byebug/settings/autoreload.rb +1 -3
  48. data/lib/byebug/settings/autosave.rb +1 -3
  49. data/lib/byebug/settings/callstyle.rb +2 -4
  50. data/lib/byebug/settings/fullpath.rb +1 -3
  51. data/lib/byebug/settings/histfile.rb +1 -3
  52. data/lib/byebug/settings/histsize.rb +0 -4
  53. data/lib/byebug/settings/listsize.rb +1 -3
  54. data/lib/byebug/settings/post_mortem.rb +14 -1
  55. data/lib/byebug/settings/width.rb +1 -17
  56. data/lib/byebug/version.rb +1 -1
  57. data/test/break_test.rb +376 -0
  58. data/test/condition_test.rb +82 -0
  59. data/test/continue_test.rb +27 -30
  60. data/test/debugger_alias_test.rb +4 -4
  61. data/test/delete_test.rb +26 -0
  62. data/test/display_test.rb +80 -102
  63. data/test/edit_test.rb +28 -31
  64. data/test/eval_test.rb +50 -80
  65. data/test/finish_test.rb +23 -23
  66. data/test/frame_test.rb +172 -186
  67. data/test/help_test.rb +27 -37
  68. data/test/history_test.rb +32 -41
  69. data/test/info_test.rb +198 -230
  70. data/test/interrupt_test.rb +17 -36
  71. data/test/irb_test.rb +47 -0
  72. data/test/kill_test.rb +19 -19
  73. data/test/list_test.rb +126 -133
  74. data/test/method_test.rb +21 -54
  75. data/test/post_mortem_test.rb +44 -46
  76. data/test/pry_test.rb +42 -0
  77. data/test/quit_test.rb +17 -15
  78. data/test/reload_test.rb +23 -28
  79. data/test/restart_test.rb +35 -63
  80. data/test/save_test.rb +46 -62
  81. data/test/set_test.rb +93 -144
  82. data/test/show_test.rb +50 -71
  83. data/test/source_test.rb +23 -26
  84. data/test/stepping_test.rb +125 -153
  85. data/test/support/matchers.rb +1 -6
  86. data/test/support/test_interface.rb +1 -1
  87. data/test/support/{test_dsl.rb → utils.rb} +17 -64
  88. data/test/test_helper.rb +25 -7
  89. data/test/thread_test.rb +101 -89
  90. data/test/trace_test.rb +48 -85
  91. data/test/variables_test.rb +43 -80
  92. metadata +18 -13
  93. data/lib/byebug/commands/breakpoints.rb +0 -137
  94. data/lib/byebug/commands/skip.rb +0 -30
  95. data/test/breakpoints_test.rb +0 -474
  96. data/test/conditions_test.rb +0 -82
  97. data/test/repl_test.rb +0 -75
@@ -1,6 +1,4 @@
1
1
  module Byebug
2
-
3
- # Implements byebug "continue" command.
4
2
  class ContinueCommand < Command
5
3
  self.allow_in_post_mortem = true
6
4
 
@@ -12,10 +10,9 @@ module Byebug
12
10
  if @match[1] && !@state.context.dead?
13
11
  filename = File.expand_path(@state.file)
14
12
  return unless line_number = get_int(@match[1], "Continue", 0, nil, 0)
15
- return errmsg "Line #{line_number} is not a stopping point in file " \
16
- "\"#{filename}\"\n" unless
17
- LineCache.trace_line_numbers(filename).member?(line_number)
18
-
13
+ unless LineCache.trace_line_numbers(filename).member?(line_number)
14
+ return errmsg "Line #{line_number} is not a valid stopping point in file\n"
15
+ end
19
16
  Byebug.add_breakpoint filename, line_number
20
17
  end
21
18
  @state.proceed
@@ -0,0 +1,38 @@
1
+ module Byebug
2
+ class DeleteCommand < Command
3
+ self.allow_in_post_mortem = false
4
+ self.allow_in_control = true
5
+
6
+ def regexp
7
+ /^\s* del(?:ete)? (?:\s+(.*))?$/x
8
+ end
9
+
10
+ def execute
11
+ return errmsg "We are not in a state we can delete breakpoints.\n" unless
12
+ @state.context
13
+
14
+ if not @match[1]
15
+ Byebug.breakpoints.clear if confirm("Delete all breakpoints? (y or n) ")
16
+ else
17
+ @match[1].split(/[ \t]+/).each do |pos|
18
+ return unless pos = get_int(pos, "Delete", 1)
19
+ errmsg "No breakpoint number %d\n", pos unless
20
+ Byebug.remove_breakpoint(pos)
21
+ end
22
+ end
23
+ end
24
+
25
+ class << self
26
+ def names
27
+ %w(delete)
28
+ end
29
+
30
+ def description
31
+ %{del[ete][ nnn...]
32
+
33
+ Without and argument, deletes all breakpoints. With integer arguments,
34
+ it deletes specific breakpoints.}
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,4 @@
1
1
  module Byebug
2
-
3
2
  class EditCommand < Command
4
3
  self.allow_in_control = true
5
4
 
@@ -46,5 +45,4 @@ module Byebug
46
45
  end
47
46
  end
48
47
  end
49
-
50
48
  end
@@ -1,9 +1,10 @@
1
1
  module Byebug
2
-
3
- # Mix-in module to assist in command parsing.
2
+ #
3
+ # Mixin to assist command parsing
4
+ #
4
5
  module EnableDisableFunctions
5
6
  def enable_disable_breakpoints(is_enable, args)
6
- return errmsg "No breakpoints have been set." if Byebug.breakpoints.empty?
7
+ return errmsg "No breakpoints have been set" if Byebug.breakpoints.empty?
7
8
 
8
9
  all_breakpoints = Byebug.breakpoints.sort_by {|b| b.id }
9
10
  if args.empty?
@@ -32,8 +33,7 @@ module Byebug
32
33
 
33
34
  def enable_disable_display(is_enable, args)
34
35
  if 0 == @state.display.size
35
- errmsg "No display expressions have been set.\n"
36
- return
36
+ return errmsg "No display expressions have been set\n"
37
37
  end
38
38
  args.each do |pos|
39
39
  pos = get_int(pos, "#{is_enable} display", 1, @state.display.size)
@@ -64,7 +64,7 @@ module Byebug
64
64
 
65
65
  def execute
66
66
  return errmsg "\"enable\" must be followed by \"display\", " \
67
- "\"breakpoints\" or breakpoint numbers.\n" unless @match[1]
67
+ "\"breakpoints\" or breakpoint ids\n" unless @match[1]
68
68
 
69
69
  args = @match[1].split(/[ \t]+/)
70
70
  param = args.shift
@@ -118,7 +118,7 @@ module Byebug
118
118
 
119
119
  def execute
120
120
  return errmsg "\"disable\" must be followed by \"display\", " \
121
- "\"breakpoints\" or breakpoint numbers.\n" unless @match[1]
121
+ "\"breakpoints\" or breakpoint ids\n" unless @match[1]
122
122
 
123
123
  args = @match[1].split(/[ \t]+/)
124
124
  param = args.shift
@@ -151,5 +151,4 @@ module Byebug
151
151
  end
152
152
  end
153
153
  end
154
-
155
154
  end
@@ -1,6 +1,4 @@
1
1
  module Byebug
2
-
3
- # Implements byebug's 'finish' command.
4
2
  class FinishCommand < Command
5
3
  self.allow_in_post_mortem = false
6
4
 
@@ -1,7 +1,8 @@
1
1
  # encoding: utf-8
2
2
  module Byebug
3
-
4
- # Mix-in module to assist in command parsing.
3
+ #
4
+ # Mixin to assist command parsing
5
+ #
5
6
  module FrameFunctions
6
7
  def c_frame?(frame_no)
7
8
  @state.context.frame_binding(frame_no).nil?
@@ -52,7 +53,7 @@ module Byebug
52
53
  end
53
54
 
54
55
  def get_frame_class(style, pos)
55
- frame_class = style == :short ? '' : "#{@state.context.frame_class pos}"
56
+ frame_class = style == 'short' ? '' : "#{@state.context.frame_class pos}"
56
57
  return frame_class == '' ? '' : "#{frame_class}."
57
58
  end
58
59
 
@@ -67,7 +68,7 @@ module Byebug
67
68
  args = @state.context.frame_args pos
68
69
  return '' if args.empty?
69
70
 
70
- locals = @state.context.frame_locals pos if style == :long
71
+ locals = @state.context.frame_locals pos if style == 'long'
71
72
  my_args = args.map do |arg|
72
73
  case arg[0]
73
74
  when :block
@@ -77,7 +78,7 @@ module Byebug
77
78
  else
78
79
  prefix, default = '', nil
79
80
  end
80
- klass = style == :long && arg[1] ? "##{locals[arg[1]].class}" : ''
81
+ klass = style == 'long' && arg[1] ? "##{locals[arg[1]].class}" : ''
81
82
  "#{prefix}#{arg[1] || default}#{klass}"
82
83
  end
83
84
 
@@ -118,18 +119,16 @@ module Byebug
118
119
  end
119
120
  end
120
121
 
122
+ def shortpath(fullpath)
123
+ separator = File::ALT_SEPARATOR || File::SEPARATOR
124
+ "...#{separator}" + fullpath.split(separator)[-3..-1].join(separator)
125
+ end
126
+
121
127
  def print_frame(pos, mark_current = true)
122
- file = @state.context.frame_file pos
128
+ fullpath = @state.context.frame_file pos
129
+ file = Setting[:fullpath] ? fullpath : shortpath(fullpath)
123
130
  line = @state.context.frame_line pos
124
131
 
125
- unless Setting[:fullpath]
126
- path_components = file.split(/[\\\/]/)
127
- if path_components.size > 3
128
- path_components[0...-3] = '...'
129
- file = path_components.join(File::ALT_SEPARATOR || File::SEPARATOR)
130
- end
131
- end
132
-
133
132
  if mark_current
134
133
  frame_str = (pos == @state.frame_pos) ? '--> ' : ' '
135
134
  else
@@ -150,7 +149,6 @@ module Byebug
150
149
  end
151
150
  end
152
151
 
153
- # Implements byebug "where" or "backtrace" command.
154
152
  class WhereCommand < Command
155
153
  def regexp
156
154
  /^\s* (?:w(?:here)?|bt|backtrace) \s*$/x
@@ -1,6 +1,4 @@
1
1
  module Byebug
2
-
3
- # Implements byebug "help" command.
4
2
  class HelpCommand < Command
5
3
  include Columnize
6
4
 
@@ -26,7 +24,7 @@ module Byebug
26
24
  end
27
25
  end
28
26
 
29
- print "byebug help v#{Byebug::VERSION}\n" unless Setting[:testing]
27
+ print "byebug help v#{VERSION}\n" unless Setting[:testing]
30
28
 
31
29
  print "Type \"help <command-name>\" for help on a specific command\n\n"
32
30
  print "Available commands:\n"
@@ -5,11 +5,11 @@ module Byebug
5
5
  end
6
6
 
7
7
  def execute
8
- if Byebug::Setting[:autosave]
8
+ if Setting[:autosave]
9
9
  if arg = @match[:num_cmds]
10
- size = get_int(arg, 'history', 1, Byebug::Setting[:histsize])
10
+ size = get_int(arg, 'history', 1, Setting[:histsize])
11
11
  end
12
- print Byebug::History.to_s(size || Byebug::Setting[:histsize])
12
+ print History.to_s(size || Setting[:histsize])
13
13
  else
14
14
  errmsg "Not currently saving history. Enable it with \"set autosave\"\n"
15
15
  end
@@ -1,5 +1,4 @@
1
1
  module Byebug
2
-
3
2
  module InfoFunctions
4
3
  def info_catch(*args)
5
4
  return print "No frame selected.\n" unless @state.context
@@ -14,7 +13,6 @@ module Byebug
14
13
  end
15
14
  end
16
15
 
17
- # Implements byebug "info" command.
18
16
  class InfoCommand < Command
19
17
  include Columnize
20
18
  self.allow_in_control = true
@@ -41,7 +39,6 @@ module Byebug
41
39
  'position in source file' ],
42
40
  ['locals' , 2, 'Local variables of the current stack frame' ],
43
41
  ['program' , 2, 'Execution status of the program' ],
44
- ['stack' , 2, 'Backtrace of the stack' ],
45
42
  ['variables' , 1, 'Local and instance variables of the ' \
46
43
  'current stack frame' ]
47
44
  ].map do |name, min, help|
@@ -141,8 +138,8 @@ module Byebug
141
138
  private :info_file_path
142
139
 
143
140
  def info_file_lines(file)
144
- lines = LineCache.size(file)
145
- print "\t #{lines} lines\n" if lines
141
+ lines = File.foreach(file)
142
+ print "\t#{lines.count} lines\n" if lines
146
143
  end
147
144
  private :info_file_lines
148
145
 
@@ -156,13 +153,13 @@ module Byebug
156
153
  private :info_file_breakpoints
157
154
 
158
155
  def info_file_mtime(file)
159
- stat = LineCache.stat(file)
156
+ stat = File.stat(file)
160
157
  print "\t#{stat.mtime}\n" if stat
161
158
  end
162
159
  private :info_file_mtime
163
160
 
164
161
  def info_file_sha1(file)
165
- print "\t#{LineCache.sha1(file)}\n"
162
+ print "\t#{Digest::SHA1.hexdigest(file)}\n"
166
163
  end
167
164
  private :info_file_sha1
168
165
 
@@ -250,10 +247,6 @@ module Byebug
250
247
  info_stop_reason @state.context.stop_reason
251
248
  end
252
249
 
253
- def info_stack(*args)
254
- print_backtrace
255
- end
256
-
257
250
  def info_global_variables(*args)
258
251
  var_global
259
252
  end
@@ -295,7 +288,5 @@ module Byebug
295
288
  return str
296
289
  end
297
290
  end
298
-
299
291
  end
300
-
301
292
  end
@@ -0,0 +1,25 @@
1
+ module Byebug
2
+ class InterruptCommand < Command
3
+ self.allow_in_control = true
4
+ self.allow_in_post_mortem = false
5
+
6
+ def regexp
7
+ /^\s*i(?:nterrupt)?\s*$/
8
+ end
9
+
10
+ def execute
11
+ context = Byebug.thread_context(Thread.main)
12
+ context.interrupt
13
+ end
14
+
15
+ class << self
16
+ def names
17
+ %w(interrupt)
18
+ end
19
+
20
+ def description
21
+ %{i|nterrupt\t interrupt the program}
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,6 +1,4 @@
1
1
  module Byebug
2
-
3
- # Implements byebug "kill" command
4
2
  class KillCommand < Command
5
3
  self.allow_in_control = true
6
4
 
@@ -1,6 +1,4 @@
1
1
  module Byebug
2
-
3
- # Implements byebug "list" command.
4
2
  class ListCommand < Command
5
3
  def regexp
6
4
  /^\s* l(?:ist)? (?:\s*([-=])|\s+(\S+))? \s*$/x
@@ -8,8 +6,8 @@ module Byebug
8
6
 
9
7
  def execute
10
8
  Byebug.source_reload if Setting[:autoreload]
11
- lines = getlines(@state.file, @state.line)
12
- if !lines
9
+
10
+ unless lines = get_lines(@state.file)
13
11
  errmsg "No sourcefile available for #{@state.file}\n"
14
12
  return @state.previous_line
15
13
  end
@@ -1,19 +1,14 @@
1
1
  module Byebug
2
- # Implements byebug's 'method' command.
3
2
  class MethodCommand < Command
4
3
  include Columnize
5
4
 
6
5
  def regexp
7
- /^\s* m(?:ethod)? \s+ ((iv)|(i(:?nstance)?)\s+)?/x
6
+ /^\s* m(?:ethod)? \s+ (i(:?nstance)?\s+)?/x
8
7
  end
9
8
 
10
9
  def execute
11
10
  obj = bb_eval(@match.post_match)
12
- if @match[1] == 'iv'
13
- obj.instance_variables.sort.each do |v|
14
- print "#{v} = #{obj.instance_variable_get(v).inspect}\n"
15
- end
16
- elsif @match[1]
11
+ if @match[1]
17
12
  print "#{columnize(obj.methods.sort(), Setting[:width])}\n"
18
13
  elsif !obj.kind_of?(Module)
19
14
  print "Should be Class/Module: #{@match.post_match}\n"
@@ -29,7 +24,6 @@ module Byebug
29
24
 
30
25
  def description
31
26
  %{m[ethod] i[nstance] <obj>\tshow methods of object
32
- m[ethod] iv <obj>\t\tshow instance variables of object
33
27
  m[ethod] <class|module>\t\tshow instance methods of class or module}
34
28
  end
35
29
  end
@@ -1,6 +1,4 @@
1
1
  module Byebug
2
-
3
- # Implements byebug "quit" command
4
2
  class QuitCommand < Command
5
3
  self.allow_in_control = true
6
4
 
@@ -1,17 +1,4 @@
1
1
  module Byebug
2
-
3
- module ReloadFunctions
4
- def getlines(file, line)
5
- unless (lines = SCRIPT_LINES__[file]) and lines != true
6
- Tracer::Single.get_line(file, line) if File.exist?(file)
7
- lines = SCRIPT_LINES__[file]
8
- lines = nil if lines == true
9
- end
10
- lines
11
- end
12
- end
13
-
14
- # Implements byebug "reload" command.
15
2
  class ReloadCommand < Command
16
3
  self.allow_in_control = true
17
4
  self.allow_in_post_mortem = false
@@ -22,8 +9,8 @@ module Byebug
22
9
 
23
10
  def execute
24
11
  Byebug.source_reload
25
- print "Source code is reloaded. Automatic reloading is " \
26
- "#{Setting[:autoreload] ? 'on' : 'off'}.\n"
12
+ onoff = Setting[:autoreload] ? 'on' : 'off'
13
+ print "Source code was reloaded. Automatic reloading is #{onoff}\n"
27
14
  end
28
15
 
29
16
  class << self
@@ -48,8 +48,6 @@ module IRB
48
48
  end
49
49
 
50
50
  module Byebug
51
-
52
- # Implements byebug's "irb" command.
53
51
  class IrbCommand < Command
54
52
  def regexp
55
53
  /^\s* irb \s*$/x
@@ -101,7 +99,6 @@ module Byebug
101
99
  has_pry = false
102
100
  end
103
101
 
104
- # Implements byebug's "pry" command
105
102
  class PryCommand < Command
106
103
  def regexp
107
104
  /^\s* pry \s*$/x
@@ -7,8 +7,8 @@ module Byebug
7
7
  end
8
8
 
9
9
  def execute
10
- prog = Byebug::PROG_SCRIPT if defined?(Byebug::PROG_SCRIPT)
11
- byebug_script = Byebug::BYEBUG_SCRIPT if defined?(Byebug::BYEBUG_SCRIPT)
10
+ prog = PROG_SCRIPT if defined?(PROG_SCRIPT)
11
+ byebug_script = BYEBUG_SCRIPT if defined?(BYEBUG_SCRIPT)
12
12
 
13
13
  return errmsg "Don't know name of debugged program\n" unless prog
14
14
 
@@ -55,28 +55,4 @@ module Byebug
55
55
  end
56
56
  end
57
57
  end
58
-
59
- class InterruptCommand < Command
60
- self.allow_in_control = true
61
- self.allow_in_post_mortem = false
62
-
63
- def regexp
64
- /^\s*i(?:nterrupt)?\s*$/
65
- end
66
-
67
- def execute
68
- context = Byebug.thread_context(Thread.main)
69
- context.interrupt
70
- end
71
-
72
- class << self
73
- def names
74
- %w(interrupt)
75
- end
76
-
77
- def description
78
- %{i|nterrupt\t interrupt the program}
79
- end
80
- end
81
- end
82
58
  end