byebug 3.5.1 → 4.0.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.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/.rubocop.yml +18 -1
- data/.travis.yml +21 -1
- data/CHANGELOG.md +356 -308
- data/CONTRIBUTING.md +31 -15
- data/GUIDE.md +859 -475
- data/Gemfile +8 -10
- data/LICENSE +1 -1
- data/README.md +41 -45
- data/Rakefile +30 -28
- data/byebug.gemspec +18 -18
- data/ext/byebug/breakpoint.c +88 -75
- data/ext/byebug/byebug.c +253 -252
- data/ext/byebug/byebug.h +53 -53
- data/ext/byebug/context.c +188 -159
- data/ext/byebug/extconf.rb +9 -6
- data/ext/byebug/locker.c +53 -11
- data/ext/byebug/threads.c +137 -39
- data/lib/byebug/attacher.rb +7 -2
- data/lib/byebug/breakpoint.rb +30 -0
- data/lib/byebug/command.rb +36 -32
- data/lib/byebug/commands/break.rb +49 -48
- data/lib/byebug/commands/catch.rb +64 -0
- data/lib/byebug/commands/condition.rb +13 -9
- data/lib/byebug/commands/continue.rb +8 -4
- data/lib/byebug/commands/delete.rb +10 -4
- data/lib/byebug/commands/display.rb +33 -25
- data/lib/byebug/commands/edit.rb +18 -13
- data/lib/byebug/commands/enable_disable.rb +26 -24
- data/lib/byebug/commands/eval.rb +77 -35
- data/lib/byebug/commands/finish.rb +9 -5
- data/lib/byebug/commands/frame.rb +66 -125
- data/lib/byebug/commands/help.rb +14 -21
- data/lib/byebug/commands/history.rb +5 -1
- data/lib/byebug/commands/info.rb +41 -106
- data/lib/byebug/commands/interrupt.rb +6 -2
- data/lib/byebug/commands/irb.rb +5 -2
- data/lib/byebug/commands/kill.rb +6 -2
- data/lib/byebug/commands/list.rb +21 -14
- data/lib/byebug/commands/method.rb +17 -9
- data/lib/byebug/commands/pry.rb +13 -3
- data/lib/byebug/commands/quit.rb +10 -5
- data/lib/byebug/commands/restart.rb +12 -19
- data/lib/byebug/commands/save.rb +10 -6
- data/lib/byebug/commands/set.rb +15 -14
- data/lib/byebug/commands/show.rb +8 -8
- data/lib/byebug/commands/source.rb +14 -8
- data/lib/byebug/commands/stepping.rb +15 -29
- data/lib/byebug/commands/threads.rb +73 -49
- data/lib/byebug/commands/tracevar.rb +56 -0
- data/lib/byebug/commands/undisplay.rb +8 -4
- data/lib/byebug/commands/untracevar.rb +38 -0
- data/lib/byebug/commands/var.rb +107 -0
- data/lib/byebug/context.rb +78 -42
- data/lib/byebug/core.rb +78 -40
- data/lib/byebug/helper.rb +58 -42
- data/lib/byebug/history.rb +12 -1
- data/lib/byebug/interface.rb +91 -11
- data/lib/byebug/interfaces/local_interface.rb +12 -19
- data/lib/byebug/interfaces/remote_interface.rb +12 -15
- data/lib/byebug/interfaces/script_interface.rb +14 -18
- data/lib/byebug/interfaces/test_interface.rb +54 -0
- data/lib/byebug/printers/base.rb +64 -0
- data/lib/byebug/printers/plain.rb +53 -0
- data/lib/byebug/processor.rb +20 -1
- data/lib/byebug/processors/command_processor.rb +57 -172
- data/lib/byebug/processors/control_command_processor.rb +16 -43
- data/lib/byebug/remote.rb +13 -7
- data/lib/byebug/runner.rb +102 -54
- data/lib/byebug/setting.rb +45 -68
- data/lib/byebug/settings/autoeval.rb +2 -0
- data/lib/byebug/settings/autoirb.rb +3 -0
- data/lib/byebug/settings/autolist.rb +3 -0
- data/lib/byebug/settings/autosave.rb +2 -0
- data/lib/byebug/settings/basename.rb +2 -0
- data/lib/byebug/settings/callstyle.rb +2 -0
- data/lib/byebug/settings/fullpath.rb +2 -0
- data/lib/byebug/settings/histfile.rb +2 -0
- data/lib/byebug/settings/histsize.rb +2 -0
- data/lib/byebug/settings/linetrace.rb +2 -0
- data/lib/byebug/settings/listsize.rb +2 -0
- data/lib/byebug/settings/post_mortem.rb +7 -2
- data/lib/byebug/settings/stack_on_error.rb +2 -0
- data/lib/byebug/settings/verbose.rb +2 -0
- data/lib/byebug/settings/width.rb +2 -0
- data/lib/byebug/state.rb +12 -0
- data/lib/byebug/states/control_state.rb +26 -0
- data/lib/byebug/states/regular_state.rb +178 -0
- data/lib/byebug/version.rb +1 -1
- metadata +24 -109
- data/lib/byebug/commands/catchpoint.rb +0 -53
- data/lib/byebug/commands/reload.rb +0 -29
- data/lib/byebug/commands/trace.rb +0 -50
- data/lib/byebug/commands/variables.rb +0 -206
- data/lib/byebug/options.rb +0 -46
- data/lib/byebug/settings/autoreload.rb +0 -12
- data/lib/byebug/settings/forcestep.rb +0 -14
- data/lib/byebug/settings/testing.rb +0 -12
- data/lib/byebug/settings/tracing_plus.rb +0 -11
- data/test/commands/break_test.rb +0 -364
- data/test/commands/condition_test.rb +0 -85
- data/test/commands/continue_test.rb +0 -47
- data/test/commands/delete_test.rb +0 -26
- data/test/commands/display_test.rb +0 -37
- data/test/commands/edit_test.rb +0 -52
- data/test/commands/eval_test.rb +0 -89
- data/test/commands/finish_test.rb +0 -74
- data/test/commands/frame_test.rb +0 -223
- data/test/commands/help_test.rb +0 -66
- data/test/commands/history_test.rb +0 -61
- data/test/commands/info_test.rb +0 -238
- data/test/commands/interrupt_test.rb +0 -45
- data/test/commands/irb_test.rb +0 -28
- data/test/commands/kill_test.rb +0 -50
- data/test/commands/list_test.rb +0 -174
- data/test/commands/method_test.rb +0 -52
- data/test/commands/post_mortem_test.rb +0 -71
- data/test/commands/pry_test.rb +0 -26
- data/test/commands/quit_test.rb +0 -53
- data/test/commands/reload_test.rb +0 -39
- data/test/commands/restart_test.rb +0 -46
- data/test/commands/save_test.rb +0 -67
- data/test/commands/set_test.rb +0 -140
- data/test/commands/show_test.rb +0 -76
- data/test/commands/source_test.rb +0 -46
- data/test/commands/stepping_test.rb +0 -192
- data/test/commands/thread_test.rb +0 -164
- data/test/commands/trace_test.rb +0 -71
- data/test/commands/undisplay_test.rb +0 -75
- data/test/commands/variables_test.rb +0 -105
- data/test/debugger_alias_test.rb +0 -7
- data/test/runner_test.rb +0 -150
- data/test/support/matchers.rb +0 -65
- data/test/support/test_interface.rb +0 -59
- data/test/support/utils.rb +0 -122
- data/test/test_helper.rb +0 -58
@@ -1,53 +0,0 @@
|
|
1
|
-
module Byebug
|
2
|
-
#
|
3
|
-
# Implements exception catching.
|
4
|
-
#
|
5
|
-
# Enables the user to catch unhandled assertion when they happen.
|
6
|
-
#
|
7
|
-
class CatchCommand < Command
|
8
|
-
self.allow_in_control = true
|
9
|
-
|
10
|
-
def regexp
|
11
|
-
/^\s* cat(?:ch)? (?:\s+(\S+))? (?:\s+(off))? \s*$/x
|
12
|
-
end
|
13
|
-
|
14
|
-
def execute
|
15
|
-
excn = @match[1]
|
16
|
-
return info_catch unless excn
|
17
|
-
|
18
|
-
if !@match[2]
|
19
|
-
if 'off' == @match[1]
|
20
|
-
Byebug.catchpoints.clear if
|
21
|
-
confirm('Delete all catchpoints? (y or n) ')
|
22
|
-
else
|
23
|
-
puts "Warning #{@match[1]} is not known to be a Class" unless
|
24
|
-
bb_eval "#{@match[1]}.is_a?(Class)", get_binding
|
25
|
-
Byebug.add_catchpoint @match[1]
|
26
|
-
puts "Catching exception #{@match[1]}."
|
27
|
-
end
|
28
|
-
elsif @match[2] != 'off'
|
29
|
-
errmsg "Off expected. Got #{@match[2]}"
|
30
|
-
elsif Byebug.catchpoints.member?(@match[1])
|
31
|
-
Byebug.catchpoints.delete @match[1]
|
32
|
-
errmsg "Catch for exception #{match[1]} removed"
|
33
|
-
else
|
34
|
-
errmsg "Catch for exception #{@match[1]} not found"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class << self
|
39
|
-
def names
|
40
|
-
%w(catch)
|
41
|
-
end
|
42
|
-
|
43
|
-
def description
|
44
|
-
%(cat[ch][ (off|<exception>[ off])]
|
45
|
-
|
46
|
-
"catch" lists catchpoints.
|
47
|
-
"catch off" deletes all catchpoints.
|
48
|
-
"catch <exception>" enables handling <exception>.
|
49
|
-
"catch <exception> off" disables handling <exception>.)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Byebug
|
2
|
-
#
|
3
|
-
# Reload source code to pick up latest changes.
|
4
|
-
#
|
5
|
-
class ReloadCommand < Command
|
6
|
-
self.allow_in_control = true
|
7
|
-
self.allow_in_post_mortem = false
|
8
|
-
|
9
|
-
def regexp
|
10
|
-
/^\s* r(?:eload)? \s*$/x
|
11
|
-
end
|
12
|
-
|
13
|
-
def execute
|
14
|
-
Byebug.source_reload
|
15
|
-
onoff = Setting[:autoreload] ? 'on' : 'off'
|
16
|
-
puts "Source code was reloaded. Automatic reloading is #{onoff}"
|
17
|
-
end
|
18
|
-
|
19
|
-
class << self
|
20
|
-
def names
|
21
|
-
%w(reload)
|
22
|
-
end
|
23
|
-
|
24
|
-
def description
|
25
|
-
%(r[eload] Forces source code reloading.)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
module Byebug
|
2
|
-
#
|
3
|
-
# Show information about every line that is executed.
|
4
|
-
#
|
5
|
-
class TraceCommand < Command
|
6
|
-
def regexp
|
7
|
-
/^\s* tr(?:acevar)? (?: \s+ (\S+))? # (variable-name)?
|
8
|
-
(?: \s+ (\S+))? # (stop | nostop)?
|
9
|
-
\s*$/x
|
10
|
-
end
|
11
|
-
|
12
|
-
def execute
|
13
|
-
var = @match[1]
|
14
|
-
if global_variables.include?("$#{var}".to_sym)
|
15
|
-
if @match[2] && @match[2] !~ /(:?no)?stop/
|
16
|
-
errmsg "expecting \"stop\" or \"nostop\"; got \"#{@match[2]}\""
|
17
|
-
else
|
18
|
-
dbg_cmd = if @match[2] && @match[2] !~ /nostop/
|
19
|
-
'byebug(1, false)'
|
20
|
-
else
|
21
|
-
''
|
22
|
-
end
|
23
|
-
end
|
24
|
-
eval("trace_var(:\"\$#{var}\") do |val|
|
25
|
-
puts \"traced global variable '#{var}' has value '\#{val}'\"
|
26
|
-
#{dbg_cmd}
|
27
|
-
end")
|
28
|
-
puts "Tracing global variable \"#{var}\"."
|
29
|
-
else
|
30
|
-
errmsg "'#{var}' is not a global variable."
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class << self
|
35
|
-
def names
|
36
|
-
%w(trace)
|
37
|
-
end
|
38
|
-
|
39
|
-
def description
|
40
|
-
%(tr[acevar] <variable> [[no]stop]
|
41
|
-
|
42
|
-
Start tracing variable <variable>.
|
43
|
-
|
44
|
-
If "stop" is specified, execution will stop every time the variable
|
45
|
-
changes its value. If nothing or "nostop" is specified, execution
|
46
|
-
won't stop, changes will just be logged in byebug's output.)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,206 +0,0 @@
|
|
1
|
-
module Byebug
|
2
|
-
#
|
3
|
-
# Utilities for the var command.
|
4
|
-
#
|
5
|
-
module VarFunctions
|
6
|
-
def var_list(ary, b = get_binding)
|
7
|
-
ary.sort!
|
8
|
-
ary.each do |v|
|
9
|
-
begin
|
10
|
-
s = bb_eval(v.to_s, b).inspect
|
11
|
-
rescue
|
12
|
-
begin
|
13
|
-
s = bb_eval(v.to_s, b).to_s
|
14
|
-
rescue
|
15
|
-
s = '*Error in evaluation*'
|
16
|
-
end
|
17
|
-
end
|
18
|
-
s = "#{v} = #{s}"
|
19
|
-
s[Setting[:width] - 3..-1] = '...' if s.size > Setting[:width]
|
20
|
-
puts s
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def var_class_self
|
25
|
-
obj = bb_eval('self')
|
26
|
-
var_list(obj.class.class_variables, get_binding)
|
27
|
-
end
|
28
|
-
|
29
|
-
def var_global
|
30
|
-
globals = global_variables.reject do |v|
|
31
|
-
[:$IGNORECASE, :$=, :$KCODE, :$-K, :$binding].include?(v)
|
32
|
-
end
|
33
|
-
|
34
|
-
var_list(globals)
|
35
|
-
end
|
36
|
-
|
37
|
-
def var_instance(where)
|
38
|
-
obj = bb_eval(where)
|
39
|
-
var_list(obj.instance_variables, obj.instance_eval { binding })
|
40
|
-
end
|
41
|
-
|
42
|
-
def var_local
|
43
|
-
_self = @state.context.frame_self(@state.frame_pos)
|
44
|
-
locals = @state.context.frame_locals
|
45
|
-
locals.keys.sort.each do |name|
|
46
|
-
puts format(' %s => %p', name, locals[name])
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
#
|
52
|
-
# Show all variables and its values.
|
53
|
-
#
|
54
|
-
class VarAllCommand < Command
|
55
|
-
def regexp
|
56
|
-
/^\s* v(?:ar)? \s+ a(?:ll)? \s*$/x
|
57
|
-
end
|
58
|
-
|
59
|
-
def execute
|
60
|
-
var_class_self
|
61
|
-
var_global
|
62
|
-
var_instance('self')
|
63
|
-
var_local
|
64
|
-
end
|
65
|
-
|
66
|
-
class << self
|
67
|
-
def names
|
68
|
-
%w(var)
|
69
|
-
end
|
70
|
-
|
71
|
-
def description
|
72
|
-
%(v[ar] a[ll]
|
73
|
-
|
74
|
-
Show local, global and instance & class variables of self.)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
#
|
80
|
-
# Show class variables and its values.
|
81
|
-
#
|
82
|
-
class VarClassCommand < Command
|
83
|
-
def regexp
|
84
|
-
/^\s* v(?:ar)? \s+ cl(?:ass)? \s*/x
|
85
|
-
end
|
86
|
-
|
87
|
-
def execute
|
88
|
-
return errmsg "can't get class variables here.\n" unless @state.context
|
89
|
-
var_class_self
|
90
|
-
end
|
91
|
-
|
92
|
-
class << self
|
93
|
-
def names
|
94
|
-
%w(var)
|
95
|
-
end
|
96
|
-
|
97
|
-
def description
|
98
|
-
%(v[ar] cl[ass] Show class variables of self.)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
#
|
104
|
-
# Show constants and its values.
|
105
|
-
#
|
106
|
-
class VarConstantCommand < Command
|
107
|
-
def regexp
|
108
|
-
/^\s* v(?:ar)? \s+ co(?:nst(?:ant)?)? \s+/x
|
109
|
-
end
|
110
|
-
|
111
|
-
def execute
|
112
|
-
obj = bb_eval(@match.post_match)
|
113
|
-
if obj.is_a? Module
|
114
|
-
constants = bb_eval("#{@match.post_match}.constants")
|
115
|
-
constants.sort!
|
116
|
-
constants.each do |c|
|
117
|
-
value = obj.const_get(c)
|
118
|
-
puts format(' %s => %p', c, value)
|
119
|
-
end
|
120
|
-
else
|
121
|
-
puts "Should be Class/Module: #{@match.post_match}"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
class << self
|
126
|
-
def names
|
127
|
-
%w(var)
|
128
|
-
end
|
129
|
-
|
130
|
-
def description
|
131
|
-
%(v[ar] co[nst] <object> Show constants of <object>.)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
#
|
137
|
-
# Show global variables and its values.
|
138
|
-
#
|
139
|
-
class VarGlobalCommand < Command
|
140
|
-
def regexp
|
141
|
-
/^\s* v(?:ar)? \s+ g(?:lobal)? \s*$/x
|
142
|
-
end
|
143
|
-
|
144
|
-
def execute
|
145
|
-
var_global
|
146
|
-
end
|
147
|
-
|
148
|
-
class << self
|
149
|
-
def names
|
150
|
-
%w(var)
|
151
|
-
end
|
152
|
-
|
153
|
-
def description
|
154
|
-
%(v[ar] g[lobal] Show global variables.)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
#
|
160
|
-
# Show instance variables and its values.
|
161
|
-
#
|
162
|
-
class VarInstanceCommand < Command
|
163
|
-
def regexp
|
164
|
-
/^\s* v(?:ar)? \s+ ins(?:tance)? \s*/x
|
165
|
-
end
|
166
|
-
|
167
|
-
def execute
|
168
|
-
var_instance(@match.post_match.empty? ? 'self' : @match.post_match)
|
169
|
-
end
|
170
|
-
|
171
|
-
class << self
|
172
|
-
def names
|
173
|
-
%w(var)
|
174
|
-
end
|
175
|
-
|
176
|
-
def description
|
177
|
-
%(v[ar] i[nstance] <object>
|
178
|
-
|
179
|
-
Show instance variables of <object>.)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
#
|
185
|
-
# Show local variables and its values.
|
186
|
-
#
|
187
|
-
class VarLocalCommand < Command
|
188
|
-
def regexp
|
189
|
-
/^\s* v(?:ar)? \s+ l(?:ocal)? \s*$/x
|
190
|
-
end
|
191
|
-
|
192
|
-
def execute
|
193
|
-
var_local
|
194
|
-
end
|
195
|
-
|
196
|
-
class << self
|
197
|
-
def names
|
198
|
-
%w(var)
|
199
|
-
end
|
200
|
-
|
201
|
-
def description
|
202
|
-
%(v[ar] l[ocal] Sow local variables.)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
data/lib/byebug/options.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
module Byebug
|
2
|
-
#
|
3
|
-
# Set of options that byebug's script accepts.
|
4
|
-
#
|
5
|
-
class Options
|
6
|
-
def self.parse
|
7
|
-
Slop.parse!(strict: true) do
|
8
|
-
banner <<-EOB.gsub(/^ {8}/, '')
|
9
|
-
|
10
|
-
byebug #{Byebug::VERSION}
|
11
|
-
|
12
|
-
Usage: byebug [options] <script.rb> -- <script.rb parameters>
|
13
|
-
EOB
|
14
|
-
|
15
|
-
on :d, :debug, 'Set $DEBUG=true' do
|
16
|
-
$DEBUG = true
|
17
|
-
end
|
18
|
-
|
19
|
-
on :I, :include=, 'Add to $LOAD_PATH', as: Array, delimiter: ':' do |l|
|
20
|
-
$LOAD_PATH.push(l).flatten!
|
21
|
-
end
|
22
|
-
|
23
|
-
on :q, :quit, 'Quit when script finishes', default: true
|
24
|
-
|
25
|
-
on :s, :stop, 'Stop when script is loaded', default: true
|
26
|
-
|
27
|
-
on :x, :rc, 'Run byebug initialization file', default: true
|
28
|
-
|
29
|
-
on :m, :'post-mortem', 'Run byebug in post-mortem mode', default: false
|
30
|
-
|
31
|
-
on :r, :require=, 'Require library before script' do |name|
|
32
|
-
require name
|
33
|
-
end
|
34
|
-
|
35
|
-
on :R, :remote=, '[HOST:]PORT for remote debugging',
|
36
|
-
as: Array, delimiter: ':', limit: 2
|
37
|
-
|
38
|
-
on :t, :trace, 'Turn on line tracing'
|
39
|
-
|
40
|
-
on :v, :version, 'Print program version'
|
41
|
-
|
42
|
-
on :h, :help, 'Display this message'
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Byebug
|
2
|
-
#
|
3
|
-
# Setting to force changing lines when executing step or next commands.
|
4
|
-
#
|
5
|
-
class ForcestepSetting < Setting
|
6
|
-
def banner
|
7
|
-
'Force next/step commands to always move to a new line'
|
8
|
-
end
|
9
|
-
|
10
|
-
def print
|
11
|
-
"forced-stepping is #{getter}"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
data/test/commands/break_test.rb
DELETED
@@ -1,364 +0,0 @@
|
|
1
|
-
module Byebug
|
2
|
-
class BreakExample
|
3
|
-
def self.a(num)
|
4
|
-
4
|
5
|
-
end
|
6
|
-
|
7
|
-
def b
|
8
|
-
3
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class BreakTestCase < TestCase
|
13
|
-
def setup
|
14
|
-
@example = -> do
|
15
|
-
y = 3
|
16
|
-
# A comment
|
17
|
-
byebug
|
18
|
-
z = 5
|
19
|
-
BreakExample.new.b
|
20
|
-
BreakExample.a(y+z)
|
21
|
-
end
|
22
|
-
|
23
|
-
super
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_setting_breakpoint_sets_correct_fields
|
27
|
-
enter 'break 19'
|
28
|
-
|
29
|
-
debug_proc(@example) do
|
30
|
-
assert_equal 19, Breakpoint.first.pos
|
31
|
-
assert_equal __FILE__, Breakpoint.first.source
|
32
|
-
assert_equal nil, Breakpoint.first.expr
|
33
|
-
assert_equal 0, Breakpoint.first.hit_count
|
34
|
-
assert_equal 0, Breakpoint.first.hit_value
|
35
|
-
assert_equal true, Breakpoint.first.enabled?
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_setting_breakpoint_using_shortcut_properly_adds_the_breakpoint
|
40
|
-
enter 'break 19'
|
41
|
-
debug_proc(@example) { assert_equal 1, Byebug.breakpoints.size }
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_setting_breakpoint_to_nonexistent_line_does_not_create_breakpoint
|
45
|
-
enter 'break 1000'
|
46
|
-
debug_proc(@example) { assert_empty Byebug.breakpoints }
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_setting_breakpoint_to_nonexistent_file_does_not_create_breakpoint
|
50
|
-
enter 'break asf:324'
|
51
|
-
debug_proc(@example) { assert_empty Byebug.breakpoints }
|
52
|
-
check_error_includes 'No file named asf'
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_setting_breakpoint_to_invalid_line_does_not_create_breakpoint
|
56
|
-
enter 'break 6'
|
57
|
-
debug_proc(@example) { assert_empty Byebug.breakpoints }
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_stops_at_the_correct_place_when_a_breakpoint_is_set
|
61
|
-
enter 'break 19', 'cont'
|
62
|
-
debug_proc(@example) do
|
63
|
-
assert_equal 19, state.line
|
64
|
-
assert_equal __FILE__, state.file
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_setting_breakpoint_to_an_instance_method_stops_at_correct_place
|
69
|
-
enter 'break BreakExample#b', 'cont'
|
70
|
-
|
71
|
-
debug_proc(@example) do
|
72
|
-
assert_equal 7, state.line
|
73
|
-
assert_equal __FILE__, state.file
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def test_setting_breakpoint_to_a_class_method_stops_at_correct_place
|
78
|
-
enter 'break BreakExample.a', 'cont'
|
79
|
-
|
80
|
-
debug_proc(@example) do
|
81
|
-
assert_equal 3, state.line
|
82
|
-
assert_equal __FILE__, state.file
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_setting_breakpoint_to_nonexistent_class_does_not_create_breakpoint
|
87
|
-
enter 'break B.a'
|
88
|
-
|
89
|
-
debug_proc(@example)
|
90
|
-
check_error_includes 'Unknown class B'
|
91
|
-
end
|
92
|
-
|
93
|
-
def test_setting_breakpoint_to_nonexistent_class_shows_error_message
|
94
|
-
enter 'break B.a'
|
95
|
-
|
96
|
-
debug_proc(@example)
|
97
|
-
check_error_includes 'Unknown class B'
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_setting_breakpoint_to_invalid_location_does_not_create_breakpoint
|
101
|
-
enter 'break foo'
|
102
|
-
|
103
|
-
debug_proc(@example) { assert_empty Byebug.breakpoints }
|
104
|
-
end
|
105
|
-
|
106
|
-
def test_setting_breakpoint_to_invalid_location_shows_error_message
|
107
|
-
enter 'break foo'
|
108
|
-
|
109
|
-
debug_proc(@example)
|
110
|
-
check_error_includes 'Invalid breakpoint location: foo'
|
111
|
-
end
|
112
|
-
|
113
|
-
def test_breaking_w_byebug_keywork_stops_at_the_next_line
|
114
|
-
debug_proc(@example) { assert_equal 18, state.line }
|
115
|
-
end
|
116
|
-
|
117
|
-
class BreakDeepExample
|
118
|
-
def a
|
119
|
-
z = 2
|
120
|
-
b(z)
|
121
|
-
end
|
122
|
-
|
123
|
-
def b(num)
|
124
|
-
v2 = 5 if 1 == num ; [1,2,v2].map { |a| a.to_f }
|
125
|
-
c
|
126
|
-
end
|
127
|
-
|
128
|
-
def c
|
129
|
-
z = 4
|
130
|
-
z += 5
|
131
|
-
byebug
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def test_breaking_w_byebug_keywork_stops_at_frame_end_when_last_instruction
|
136
|
-
@deep_example = lambda do
|
137
|
-
ex = BreakDeepExample.new.a
|
138
|
-
2.times do
|
139
|
-
ex = ex ? ex : 1
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
debug_proc(@deep_example) { assert_equal 132, state.line }
|
144
|
-
end
|
145
|
-
|
146
|
-
def test_disabling_breakpoints_with_short_syntax_sets_enabled_to_false
|
147
|
-
enter 'break 19', 'break 20', -> { "disable #{Breakpoint.first.id}" }
|
148
|
-
|
149
|
-
debug_proc(@example) { assert_equal false, Breakpoint.first.enabled? }
|
150
|
-
end
|
151
|
-
|
152
|
-
def test_disabling_breakpoints_with_short_syntax_properly_ignores_them
|
153
|
-
enter 'b 19', 'b 20', -> { "disable #{Breakpoint.first.id}" } , 'cont'
|
154
|
-
|
155
|
-
debug_proc(@example) { assert_equal 20, state.line }
|
156
|
-
end
|
157
|
-
|
158
|
-
def test_disabling_breakpoints_with_full_syntax_sets_enabled_to_false
|
159
|
-
enter 'b 19', 'b 20', -> { "disable breakpoints #{Breakpoint.first.id}" }
|
160
|
-
|
161
|
-
debug_proc(@example) { assert_equal false, Breakpoint.first.enabled? }
|
162
|
-
end
|
163
|
-
|
164
|
-
def test_disabling_breakpoints_with_full_syntax_properly_ignores_them
|
165
|
-
enter 'break 19', 'break 20',
|
166
|
-
-> { "disable breakpoints #{Breakpoint.first.id}" }, 'cont'
|
167
|
-
|
168
|
-
debug_proc(@example) { assert_equal 20, state.line }
|
169
|
-
end
|
170
|
-
|
171
|
-
def test_disabling_all_breakpoints_sets_all_enabled_flags_to_false
|
172
|
-
enter 'break 19', 'break 20', 'disable breakpoints'
|
173
|
-
|
174
|
-
debug_proc(@example) do
|
175
|
-
assert_equal false, Breakpoint.first.enabled?
|
176
|
-
assert_equal false, Breakpoint.last.enabled?
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def test_disabling_all_breakpoints_ignores_all_breakpoints
|
181
|
-
enter 'break 19', 'break 20', 'disable breakpoints', 'cont'
|
182
|
-
|
183
|
-
debug_proc(@example)
|
184
|
-
assert_equal true, state.proceed # Obscure assert to check termination
|
185
|
-
end
|
186
|
-
|
187
|
-
def test_disabling_breakpoints_shows_an_error_in_syntax_is_incorrect
|
188
|
-
enter 'disable'
|
189
|
-
|
190
|
-
debug_proc(@example)
|
191
|
-
check_error_includes '"disable" must be followed by "display", ' \
|
192
|
-
'"breakpoints" or breakpoint ids'
|
193
|
-
end
|
194
|
-
|
195
|
-
def test_disabling_breakpoints_shows_an_error_if_no_breakpoints_are_set
|
196
|
-
enter 'disable 1'
|
197
|
-
|
198
|
-
debug_proc(@example)
|
199
|
-
check_error_includes 'No breakpoints have been set'
|
200
|
-
end
|
201
|
-
|
202
|
-
def test_disabling_breakpoints_shows_an_error_if_non_numeric_arg_is_provided
|
203
|
-
enter 'break 5', 'disable foo'
|
204
|
-
|
205
|
-
debug_proc(@example)
|
206
|
-
check_error_includes \
|
207
|
-
'"disable breakpoints" argument "foo" needs to be a number'
|
208
|
-
end
|
209
|
-
|
210
|
-
def test_enabling_breakpoints_with_short_syntax_sets_enabled_to_true
|
211
|
-
enter 'b 19', 'b 20', 'disable breakpoints',
|
212
|
-
-> { "enable #{Breakpoint.first.id}" }
|
213
|
-
|
214
|
-
debug_proc(@example) { assert_equal true, Breakpoint.first.enabled? }
|
215
|
-
end
|
216
|
-
|
217
|
-
def test_enabling_breakpoints_with_short_syntax_stops_at_enabled_breakpoint
|
218
|
-
enter 'break 19', 'break 20', 'disable breakpoints',
|
219
|
-
-> { "enable #{Breakpoint.first.id}" }, 'cont'
|
220
|
-
|
221
|
-
debug_proc(@example) { assert_equal 19, state.line }
|
222
|
-
end
|
223
|
-
|
224
|
-
def test_enabling_all_breakpoints_sets_all_enabled_flags_to_true
|
225
|
-
enter 'break 19', 'break 20', 'disable breakpoints', 'enable breakpoints'
|
226
|
-
|
227
|
-
debug_proc(@example) do
|
228
|
-
assert_equal true, Breakpoint.first.enabled?
|
229
|
-
assert_equal true, Breakpoint.last.enabled?
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
def test_enabling_all_breakpoints_stops_at_first_breakpoint
|
234
|
-
enter 'b 19', 'b 20', 'disable breakpoints', 'enable breakpoints', 'cont'
|
235
|
-
|
236
|
-
debug_proc(@example) { assert_equal 19, state.line }
|
237
|
-
end
|
238
|
-
|
239
|
-
def test_enabling_all_breakpoints_stops_at_last_breakpoint
|
240
|
-
enter 'break 19', 'break 20', 'disable breakpoints',
|
241
|
-
'enable breakpoints', 'cont', 'cont'
|
242
|
-
|
243
|
-
debug_proc(@example) { assert_equal 20, state.line }
|
244
|
-
end
|
245
|
-
|
246
|
-
def test_enabling_breakpoints_with_full_syntax_sets_enabled_to_false
|
247
|
-
enter 'break 19', 'break 20', 'disable breakpoints',
|
248
|
-
-> { "enable breakpoints #{Breakpoint.last.id}" }
|
249
|
-
|
250
|
-
debug_proc(@example) { assert_equal false, Breakpoint.first.enabled? }
|
251
|
-
end
|
252
|
-
|
253
|
-
def test_enabling_breakpoints_with_full_syntax_stops_at_enabled_breakpoint
|
254
|
-
enter 'break 19', 'break 20', 'disable breakpoints',
|
255
|
-
-> { "enable breakpoints #{Breakpoint.last.id}" }, 'cont'
|
256
|
-
|
257
|
-
debug_proc(@example) { assert_equal 20, state.line }
|
258
|
-
end
|
259
|
-
|
260
|
-
def test_enabling_breakpoints_shows_an_error_in_syntax_is_incorrect
|
261
|
-
enter 'enable'
|
262
|
-
|
263
|
-
debug_proc(@example)
|
264
|
-
check_error_includes '"enable" must be followed by "display", ' \
|
265
|
-
'"breakpoints" or breakpoint ids'
|
266
|
-
end
|
267
|
-
|
268
|
-
def test_conditional_breakpoint_stops_if_condition_is_true
|
269
|
-
enter 'break 19 if z == 5', 'break 20', 'cont'
|
270
|
-
debug_proc(@example) { assert_equal 19, state.line }
|
271
|
-
end
|
272
|
-
|
273
|
-
def test_conditional_breakpoint_is_ignored_if_condition_is_false
|
274
|
-
enter 'break 19 if z == 3', 'break 20', 'cont'
|
275
|
-
debug_proc(@example) { assert_equal 20, state.line }
|
276
|
-
end
|
277
|
-
|
278
|
-
def test_setting_conditional_breakpoint_shows_error_if_syntax_wrong
|
279
|
-
enter 'break 19 ifa z == 3', 'break 20', 'cont'
|
280
|
-
debug_proc(@example) { assert_equal 20, state.line }
|
281
|
-
check_error_includes \
|
282
|
-
'Expecting "if" in breakpoint condition, got: ifa z == 3'
|
283
|
-
end
|
284
|
-
|
285
|
-
def test_setting_conditional_breakpoint_shows_error_if_no_breakpoint_id
|
286
|
-
enter 'break if z == 3', 'break 20', 'cont'
|
287
|
-
debug_proc(@example) { assert_equal 20, state.line }
|
288
|
-
check_error_includes 'Invalid breakpoint location: if z == 3'
|
289
|
-
end
|
290
|
-
|
291
|
-
def test_setting_conditional_breakpoint_using_wrong_expression_ignores_it
|
292
|
-
enter 'break if z -=) 3', 'break 20', 'cont'
|
293
|
-
debug_proc(@example) { assert_equal 20, state.line }
|
294
|
-
end
|
295
|
-
|
296
|
-
def test_shows_info_about_setting_breakpoints_when_using_just_break
|
297
|
-
enter 'break', 'cont'
|
298
|
-
debug_proc(@example)
|
299
|
-
check_output_includes(/b\[reak\] file:line \[if expr\]/)
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
module FilenameTests
|
304
|
-
def test_setting_breakpoint_prints_confirmation_message
|
305
|
-
enter 'break 19'
|
306
|
-
debug_proc(@example) { @id = Breakpoint.first.id }
|
307
|
-
check_output_includes "Created breakpoint #{@id} at #{@filename}:19"
|
308
|
-
end
|
309
|
-
|
310
|
-
def test_setting_breakpoint_to_nonexistent_line_shows_an_error
|
311
|
-
enter 'break 1000'
|
312
|
-
debug_proc(@example)
|
313
|
-
n = %x{wc -l #{__FILE__}}.split.first.to_i
|
314
|
-
check_error_includes "There are only #{n} lines in file #{@filename}"
|
315
|
-
end
|
316
|
-
|
317
|
-
def test_setting_breakpoint_to_invalid_line_shows_an_error
|
318
|
-
enter 'break 6'
|
319
|
-
debug_proc(@example)
|
320
|
-
check_error_includes \
|
321
|
-
"Line 6 is not a valid breakpoint in file #{@filename}"
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
class BreakTestCaseBasename < BreakTestCase
|
326
|
-
def setup
|
327
|
-
@filename = File.basename(__FILE__)
|
328
|
-
super
|
329
|
-
enter 'set basename'
|
330
|
-
end
|
331
|
-
|
332
|
-
include FilenameTests
|
333
|
-
end
|
334
|
-
|
335
|
-
class BreakTestCaseNobasename < BreakTestCase
|
336
|
-
def setup
|
337
|
-
@filename = __FILE__
|
338
|
-
super
|
339
|
-
enter 'set nobasename'
|
340
|
-
end
|
341
|
-
|
342
|
-
include FilenameTests
|
343
|
-
end
|
344
|
-
|
345
|
-
def test_setting_breakpoint_with_autoreload_uses_new_source
|
346
|
-
enter 'set autoreload', -> do
|
347
|
-
change_line_in_file(__FILE__, 19, '')
|
348
|
-
'break 19'
|
349
|
-
end
|
350
|
-
|
351
|
-
debug_proc(@example) { assert_empty Byebug.breakpoints }
|
352
|
-
change_line_in_file(__FILE__,19, ' BreakExample.new.b')
|
353
|
-
end
|
354
|
-
|
355
|
-
def test_setting_breakpoint_with_noautoreload_uses_old_source
|
356
|
-
enter 'set noautoreload', -> do
|
357
|
-
change_line_in_file(__FILE__, 19, '')
|
358
|
-
'break 19'
|
359
|
-
end
|
360
|
-
|
361
|
-
debug_proc(@example) { assert_equal 1, Byebug.breakpoints.size }
|
362
|
-
change_line_in_file(__FILE__,19, ' BreakExample.new.b')
|
363
|
-
end
|
364
|
-
end
|