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,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