byebug 3.1.2 → 3.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 (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,5 +1,4 @@
1
1
  module Byebug
2
-
3
2
  module SaveFunctions
4
3
  # Create a temporary file to write in if file is nil
5
4
  def open_save
@@ -1,6 +1,4 @@
1
1
  module Byebug
2
-
3
- # Implements byebug "set" command.
4
2
  class SetCommand < Command
5
3
  self.allow_in_control = true
6
4
 
@@ -20,7 +18,7 @@ module Byebug
20
18
  elsif Setting.boolean?(full_key)
21
19
  value = get_onoff(value, key =~ /^no/ ? false : true)
22
20
  elsif Setting.integer?(full_key)
23
- return unless value = get_int(value, full_key, 1, 300)
21
+ return unless value = get_int(value, full_key, 1)
24
22
  end
25
23
 
26
24
  Setting[full_key.to_sym] = value
@@ -31,12 +29,12 @@ module Byebug
31
29
  def get_onoff(arg, default)
32
30
  return default if arg.nil?
33
31
  case arg
34
- when '1', 'on'
32
+ when '1', 'on', 'true'
35
33
  return true
36
- when '0', 'off'
34
+ when '0', 'off', 'false'
37
35
  return false
38
36
  else
39
- print "Expecting 'on', 1, 'off', or 0. Got: #{arg}.\n"
37
+ print "Expecting 'on', 1, true, 'off', 0, false. Got: #{arg}.\n"
40
38
  raise RuntimeError
41
39
  end
42
40
  end
@@ -69,5 +67,4 @@ module Byebug
69
67
  end
70
68
  end
71
69
  end
72
-
73
70
  end
@@ -1,6 +1,4 @@
1
1
  module Byebug
2
-
3
- # Implements byebug "show" command.
4
2
  class ShowCommand < Command
5
3
  self.allow_in_control = true
6
4
 
@@ -43,5 +41,4 @@ module Byebug
43
41
  end
44
42
  end
45
43
  end
46
-
47
44
  end
@@ -1,6 +1,4 @@
1
1
  module Byebug
2
-
3
- # Implements byebug "source" command.
4
2
  class SourceCommand < Command
5
3
  self.allow_in_control = true
6
4
 
@@ -32,5 +30,4 @@ module Byebug
32
30
  end
33
31
  end
34
32
  end
35
-
36
33
  end
@@ -1,6 +1,7 @@
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 SteppingFunctions
5
6
  def parse_stepping_args(command_name, match)
6
7
  if match[1].nil?
@@ -15,7 +16,6 @@ module Byebug
15
16
  end
16
17
  end
17
18
 
18
- # Implements byebug "next" command.
19
19
  class NextCommand < Command
20
20
  self.allow_in_post_mortem = false
21
21
 
@@ -44,7 +44,6 @@ module Byebug
44
44
  end
45
45
  end
46
46
 
47
- # Implements byebug "step" command.
48
47
  class StepCommand < Command
49
48
  self.allow_in_post_mortem = false
50
49
 
@@ -1,5 +1,4 @@
1
1
  module Byebug
2
-
3
2
  class TraceCommand < Command
4
3
  def regexp
5
4
  /^\s* tr(?:acevar)? (?: \s+ (\S+))? # (variable-name)?
@@ -12,8 +12,9 @@ module Byebug
12
12
  s = "*Error in evaluation*"
13
13
  end
14
14
  end
15
+ s = "#{v} = #{s}"
15
16
  s[Setting[:width]-3..-1] = "..." if s.size > Setting[:width]
16
- print "#{v} = #{s}\n"
17
+ print "#{s}\n"
17
18
  end
18
19
  end
19
20
 
@@ -27,7 +28,6 @@ module Byebug
27
28
  end
28
29
  end
29
30
 
30
- # Implements byebug's 'var class' command
31
31
  class VarClassCommand < Command
32
32
  def regexp
33
33
  /^\s* v(?:ar)? \s+ cl(?:ass)? \s*/x
@@ -110,7 +110,7 @@ module Byebug
110
110
 
111
111
  def execute
112
112
  obj = bb_eval(@match.post_match.empty? ? 'self' : @match.post_match)
113
- var_list(obj.instance_variables, obj.instance_eval{binding()})
113
+ var_list(obj.instance_variables, obj.instance_eval { binding() })
114
114
  end
115
115
 
116
116
  class << self
@@ -124,7 +124,6 @@ module Byebug
124
124
  end
125
125
  end
126
126
 
127
- # Implements byebug's 'var local' command
128
127
  class VarLocalCommand < Command
129
128
  def regexp
130
129
  /^\s* v(?:ar)? \s+ l(?:ocal)? \s*$/x
@@ -12,7 +12,6 @@ module Byebug
12
12
  end
13
13
  backtrace.size
14
14
  else
15
- print 'WARNING: No backtrace available!!'
16
15
  0
17
16
  end
18
17
  end
@@ -29,6 +29,29 @@ module Byebug
29
29
  end
30
30
  end
31
31
 
32
+ #
33
+ # Gets all lines in a source code file
34
+ #
35
+ def get_lines(filename)
36
+ return nil unless File.exist?(filename)
37
+
38
+ unless lines = SCRIPT_LINES__[filename]
39
+ lines = File.readlines(filename) rescue []
40
+ SCRIPT_LINES__[filename] = lines
41
+ end
42
+
43
+ return lines
44
+ end
45
+
46
+ #
47
+ # Gets a single line in a source code file
48
+ #
49
+ def get_line(filename, lineno)
50
+ return nil unless lines = get_lines(filename)
51
+
52
+ return lines[lineno-1]
53
+ end
54
+
32
55
  #
33
56
  # Returns true if code is syntactically correct for Ruby.
34
57
  #
@@ -1,5 +1,5 @@
1
1
  module Byebug
2
- class ScriptInterface < Byebug::Interface
2
+ class ScriptInterface < Interface
3
3
  def initialize(file, out, verbose=false)
4
4
  super()
5
5
  @file = file.respond_to?(:gets) ? file : open(file)
@@ -1,5 +1,4 @@
1
1
  module Byebug
2
-
3
2
  class CommandProcessor < Processor
4
3
  attr_reader :display
5
4
 
@@ -61,24 +60,26 @@ module Byebug
61
60
 
62
61
  def at_breakpoint(context, breakpoint)
63
62
  n = Byebug.breakpoints.index(breakpoint) + 1
64
- file = CommandProcessor.canonic_file(breakpoint.source)
63
+ file = self.class.canonic_file(breakpoint.source)
65
64
  line = breakpoint.pos
66
65
  print "Stopped by breakpoint #{n} at #{file}:#{line}\n"
67
66
  end
68
67
  protect :at_breakpoint
69
68
 
70
69
  def at_catchpoint(context, excpt)
71
- file = CommandProcessor.canonic_file(context.frame_file(0))
70
+ file = self.class.canonic_file(context.frame_file(0))
72
71
  line = context.frame_line(0)
73
72
  print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class
74
73
  end
75
74
  protect :at_catchpoint
76
75
 
76
+ include ParseFunctions
77
+
77
78
  def at_tracing(context, file, line)
78
79
  if file != @last_file || line != @last_line || Setting[:tracing_plus]
80
+ path = self.class.canonic_file(file)
79
81
  @last_file, @last_line = file, line
80
- print "Tracing: #{CommandProcessor.canonic_file(file)}:#{line} " \
81
- "#{Byebug.line_at(file,line)}\n"
82
+ print "Tracing: #{path}:#{line} #{get_line(file, line)}"
82
83
  end
83
84
  always_run(context, file, line, 2)
84
85
  end
@@ -236,13 +237,12 @@ module Byebug
236
237
  end
237
238
 
238
239
  def location
239
- loc = "#{CommandProcessor.canonic_file(@file)} @ #{@line}\n"
240
- loc += "#{Byebug.line_at(@file, @line)}\n" unless
240
+ path = self.class.canonic_file(@file)
241
+ loc = "#{path} @ #{@line}\n"
242
+ loc += "#{get_line(@file, @line)}\n" unless
241
243
  ['(irb)', '-e'].include? @file
242
244
  loc
243
245
  end
244
246
  end
245
-
246
247
  end # class CommandProcessor
247
-
248
248
  end
@@ -60,7 +60,7 @@ module Byebug
60
60
  return @actual_control_port if @control_thread
61
61
  server = TCPServer.new(host, ctrl_port)
62
62
  @actual_control_port = server.addr[1]
63
- @control_thread = Thread.new do
63
+ @control_thread = DebugThread.new do
64
64
  while (session = server.accept)
65
65
  interface = RemoteInterface.new(session)
66
66
  ControlCommandProcessor.new(interface).process_commands
@@ -73,7 +73,7 @@ module Byebug
73
73
  # Connects to the remote byebug
74
74
  #
75
75
  def start_client(host = 'localhost', port = PORT)
76
- interface = Byebug::LocalInterface.new
76
+ interface = LocalInterface.new
77
77
  socket = TCPSocket.new(host, port)
78
78
  puts "Connected."
79
79
 
@@ -2,8 +2,10 @@ module Byebug
2
2
  class Setting
3
3
  attr_accessor :value
4
4
 
5
+ DEFAULT = false
6
+
5
7
  def initialize
6
- @value = false
8
+ @value = self.class::DEFAULT
7
9
  end
8
10
 
9
11
  def self.settings
@@ -1,7 +1,9 @@
1
1
  module Byebug
2
2
  class AutoevalSetting < Setting
3
+ DEFAULT = true
4
+
3
5
  def initialize
4
- EvalCommand.unknown = true
6
+ EvalCommand.unknown = DEFAULT
5
7
  end
6
8
 
7
9
  def help
@@ -1,7 +1,9 @@
1
1
  module Byebug
2
2
  class AutoirbSetting < Setting
3
+ DEFAULT = 0
4
+
3
5
  def initialize
4
- IrbCommand.always_run = 0
6
+ IrbCommand.always_run = DEFAULT
5
7
  end
6
8
 
7
9
  def help
@@ -1,7 +1,9 @@
1
1
  module Byebug
2
2
  class AutolistSetting < Setting
3
+ DEFAULT = 1
4
+
3
5
  def initialize
4
- ListCommand.always_run = 1
6
+ ListCommand.always_run = DEFAULT
5
7
  end
6
8
 
7
9
  def help
@@ -1,8 +1,6 @@
1
1
  module Byebug
2
2
  class AutoreloadSetting < Setting
3
- def initialize
4
- @value = true
5
- end
3
+ DEFAULT = true
6
4
 
7
5
  def help
8
6
  'Reload source code when changed'
@@ -1,8 +1,6 @@
1
1
  module Byebug
2
2
  class AutosaveSetting < Setting
3
- def initialize
4
- @value = true
5
- end
3
+ DEFAULT = true
6
4
 
7
5
  def help
8
6
  'If true, command history record is saved on exit'
@@ -1,15 +1,13 @@
1
1
  module Byebug
2
2
  class CallstyleSetting < Setting
3
- def initialize
4
- @value = :long
5
- end
3
+ DEFAULT = 'long'
6
4
 
7
5
  def help
8
6
  'Set how you want method call parameters to be displayed'
9
7
  end
10
8
 
11
9
  def to_s
12
- "Frame display callstyle is :#{value}"
10
+ "Frame display callstyle is '#{value}'"
13
11
  end
14
12
  end
15
13
  end
@@ -1,8 +1,6 @@
1
1
  module Byebug
2
2
  class FullpathSetting < Setting
3
- def initialize
4
- @value = true
5
- end
3
+ DEFAULT = true
6
4
 
7
5
  def help
8
6
  'Display full file names in frames'
@@ -1,8 +1,6 @@
1
1
  module Byebug
2
2
  class HistfileSetting < Setting
3
- def initialize
4
- @value = File.expand_path("#{ENV['HOME']||'.'}/.byebug_hist")
5
- end
3
+ DEFAULT = File.expand_path("#{ENV['HOME'] || '.'}/.byebug_hist")
6
4
 
7
5
  def help
8
6
  "Customize file where history is loaded from and saved to. By default, " \
@@ -2,10 +2,6 @@ module Byebug
2
2
  class HistsizeSetting < Setting
3
3
  DEFAULT = 256
4
4
 
5
- def initialize
6
- @value = DEFAULT
7
- end
8
-
9
5
  def help
10
6
  "Customize maximum number of commands that can be stored in byebug's " \
11
7
  "history record. By default, #{DEFAULT}"
@@ -1,8 +1,6 @@
1
1
  module Byebug
2
2
  class ListsizeSetting < Setting
3
- def initialize
4
- @value = 10
5
- end
3
+ DEFAULT = 10
6
4
 
7
5
  def help
8
6
  'Set number of source lines to list by default'
@@ -5,11 +5,24 @@ module Byebug
5
5
  end
6
6
 
7
7
  def value=(v)
8
- v ? Byebug.post_mortem : Byebug.post_mortem = v
8
+ Byebug.post_mortem = v
9
+ at_exit { handle_post_mortem if Byebug.post_mortem? }
9
10
  end
10
11
 
11
12
  def value
12
13
  Byebug.post_mortem?
13
14
  end
15
+
16
+ private
17
+ #
18
+ # Saves information about the unhandled exception and gives a byebug
19
+ # prompt back to the user before program termination.
20
+ #
21
+ def handle_post_mortem
22
+ context = Byebug.raised_exception.__bb_context
23
+ file = Byebug.raised_exception.__bb_file
24
+ line = Byebug.raised_exception.__bb_line
25
+ Byebug.handler.at_line(context, file, line)
26
+ end
14
27
  end
15
28
  end
@@ -1,14 +1,6 @@
1
1
  module Byebug
2
2
  class WidthSetting < Setting
3
- def initialize
4
- if ENV['COLUMNS'] =~ /^\d+$/
5
- @value = ENV['COLUMNS'].to_i
6
- elsif STDIN.tty? && exists?('stty')
7
- @value = `stty size`.scan(/\d+/)[1].to_i
8
- else
9
- @value = 160
10
- end
11
- end
3
+ DEFAULT = 160
12
4
 
13
5
  def help
14
6
  "Number of characters per line in byebug's output"
@@ -17,13 +9,5 @@ module Byebug
17
9
  def to_s
18
10
  "Maximum width of byebug's output is #{value}"
19
11
  end
20
-
21
- private
22
-
23
- def exists?(command)
24
- ENV['PATH'].split(File::PATH_SEPARATOR).any? do |d|
25
- File.exist?(File.join(d, command))
26
- end
27
- end
28
12
  end
29
13
  end