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.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/.rubocop.yml +18 -1
  4. data/.travis.yml +21 -1
  5. data/CHANGELOG.md +356 -308
  6. data/CONTRIBUTING.md +31 -15
  7. data/GUIDE.md +859 -475
  8. data/Gemfile +8 -10
  9. data/LICENSE +1 -1
  10. data/README.md +41 -45
  11. data/Rakefile +30 -28
  12. data/byebug.gemspec +18 -18
  13. data/ext/byebug/breakpoint.c +88 -75
  14. data/ext/byebug/byebug.c +253 -252
  15. data/ext/byebug/byebug.h +53 -53
  16. data/ext/byebug/context.c +188 -159
  17. data/ext/byebug/extconf.rb +9 -6
  18. data/ext/byebug/locker.c +53 -11
  19. data/ext/byebug/threads.c +137 -39
  20. data/lib/byebug/attacher.rb +7 -2
  21. data/lib/byebug/breakpoint.rb +30 -0
  22. data/lib/byebug/command.rb +36 -32
  23. data/lib/byebug/commands/break.rb +49 -48
  24. data/lib/byebug/commands/catch.rb +64 -0
  25. data/lib/byebug/commands/condition.rb +13 -9
  26. data/lib/byebug/commands/continue.rb +8 -4
  27. data/lib/byebug/commands/delete.rb +10 -4
  28. data/lib/byebug/commands/display.rb +33 -25
  29. data/lib/byebug/commands/edit.rb +18 -13
  30. data/lib/byebug/commands/enable_disable.rb +26 -24
  31. data/lib/byebug/commands/eval.rb +77 -35
  32. data/lib/byebug/commands/finish.rb +9 -5
  33. data/lib/byebug/commands/frame.rb +66 -125
  34. data/lib/byebug/commands/help.rb +14 -21
  35. data/lib/byebug/commands/history.rb +5 -1
  36. data/lib/byebug/commands/info.rb +41 -106
  37. data/lib/byebug/commands/interrupt.rb +6 -2
  38. data/lib/byebug/commands/irb.rb +5 -2
  39. data/lib/byebug/commands/kill.rb +6 -2
  40. data/lib/byebug/commands/list.rb +21 -14
  41. data/lib/byebug/commands/method.rb +17 -9
  42. data/lib/byebug/commands/pry.rb +13 -3
  43. data/lib/byebug/commands/quit.rb +10 -5
  44. data/lib/byebug/commands/restart.rb +12 -19
  45. data/lib/byebug/commands/save.rb +10 -6
  46. data/lib/byebug/commands/set.rb +15 -14
  47. data/lib/byebug/commands/show.rb +8 -8
  48. data/lib/byebug/commands/source.rb +14 -8
  49. data/lib/byebug/commands/stepping.rb +15 -29
  50. data/lib/byebug/commands/threads.rb +73 -49
  51. data/lib/byebug/commands/tracevar.rb +56 -0
  52. data/lib/byebug/commands/undisplay.rb +8 -4
  53. data/lib/byebug/commands/untracevar.rb +38 -0
  54. data/lib/byebug/commands/var.rb +107 -0
  55. data/lib/byebug/context.rb +78 -42
  56. data/lib/byebug/core.rb +78 -40
  57. data/lib/byebug/helper.rb +58 -42
  58. data/lib/byebug/history.rb +12 -1
  59. data/lib/byebug/interface.rb +91 -11
  60. data/lib/byebug/interfaces/local_interface.rb +12 -19
  61. data/lib/byebug/interfaces/remote_interface.rb +12 -15
  62. data/lib/byebug/interfaces/script_interface.rb +14 -18
  63. data/lib/byebug/interfaces/test_interface.rb +54 -0
  64. data/lib/byebug/printers/base.rb +64 -0
  65. data/lib/byebug/printers/plain.rb +53 -0
  66. data/lib/byebug/processor.rb +20 -1
  67. data/lib/byebug/processors/command_processor.rb +57 -172
  68. data/lib/byebug/processors/control_command_processor.rb +16 -43
  69. data/lib/byebug/remote.rb +13 -7
  70. data/lib/byebug/runner.rb +102 -54
  71. data/lib/byebug/setting.rb +45 -68
  72. data/lib/byebug/settings/autoeval.rb +2 -0
  73. data/lib/byebug/settings/autoirb.rb +3 -0
  74. data/lib/byebug/settings/autolist.rb +3 -0
  75. data/lib/byebug/settings/autosave.rb +2 -0
  76. data/lib/byebug/settings/basename.rb +2 -0
  77. data/lib/byebug/settings/callstyle.rb +2 -0
  78. data/lib/byebug/settings/fullpath.rb +2 -0
  79. data/lib/byebug/settings/histfile.rb +2 -0
  80. data/lib/byebug/settings/histsize.rb +2 -0
  81. data/lib/byebug/settings/linetrace.rb +2 -0
  82. data/lib/byebug/settings/listsize.rb +2 -0
  83. data/lib/byebug/settings/post_mortem.rb +7 -2
  84. data/lib/byebug/settings/stack_on_error.rb +2 -0
  85. data/lib/byebug/settings/verbose.rb +2 -0
  86. data/lib/byebug/settings/width.rb +2 -0
  87. data/lib/byebug/state.rb +12 -0
  88. data/lib/byebug/states/control_state.rb +26 -0
  89. data/lib/byebug/states/regular_state.rb +178 -0
  90. data/lib/byebug/version.rb +1 -1
  91. metadata +24 -109
  92. data/lib/byebug/commands/catchpoint.rb +0 -53
  93. data/lib/byebug/commands/reload.rb +0 -29
  94. data/lib/byebug/commands/trace.rb +0 -50
  95. data/lib/byebug/commands/variables.rb +0 -206
  96. data/lib/byebug/options.rb +0 -46
  97. data/lib/byebug/settings/autoreload.rb +0 -12
  98. data/lib/byebug/settings/forcestep.rb +0 -14
  99. data/lib/byebug/settings/testing.rb +0 -12
  100. data/lib/byebug/settings/tracing_plus.rb +0 -11
  101. data/test/commands/break_test.rb +0 -364
  102. data/test/commands/condition_test.rb +0 -85
  103. data/test/commands/continue_test.rb +0 -47
  104. data/test/commands/delete_test.rb +0 -26
  105. data/test/commands/display_test.rb +0 -37
  106. data/test/commands/edit_test.rb +0 -52
  107. data/test/commands/eval_test.rb +0 -89
  108. data/test/commands/finish_test.rb +0 -74
  109. data/test/commands/frame_test.rb +0 -223
  110. data/test/commands/help_test.rb +0 -66
  111. data/test/commands/history_test.rb +0 -61
  112. data/test/commands/info_test.rb +0 -238
  113. data/test/commands/interrupt_test.rb +0 -45
  114. data/test/commands/irb_test.rb +0 -28
  115. data/test/commands/kill_test.rb +0 -50
  116. data/test/commands/list_test.rb +0 -174
  117. data/test/commands/method_test.rb +0 -52
  118. data/test/commands/post_mortem_test.rb +0 -71
  119. data/test/commands/pry_test.rb +0 -26
  120. data/test/commands/quit_test.rb +0 -53
  121. data/test/commands/reload_test.rb +0 -39
  122. data/test/commands/restart_test.rb +0 -46
  123. data/test/commands/save_test.rb +0 -67
  124. data/test/commands/set_test.rb +0 -140
  125. data/test/commands/show_test.rb +0 -76
  126. data/test/commands/source_test.rb +0 -46
  127. data/test/commands/stepping_test.rb +0 -192
  128. data/test/commands/thread_test.rb +0 -164
  129. data/test/commands/trace_test.rb +0 -71
  130. data/test/commands/undisplay_test.rb +0 -75
  131. data/test/commands/variables_test.rb +0 -105
  132. data/test/debugger_alias_test.rb +0 -7
  133. data/test/runner_test.rb +0 -150
  134. data/test/support/matchers.rb +0 -65
  135. data/test/support/test_interface.rb +0 -59
  136. data/test/support/utils.rb +0 -122
  137. 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
@@ -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,12 +0,0 @@
1
- module Byebug
2
- #
3
- # Setting for automatically reloading source code when it is changed.
4
- #
5
- class AutoreloadSetting < Setting
6
- DEFAULT = true
7
-
8
- def banner
9
- 'Automatically reload source code when it is changed'
10
- end
11
- end
12
- 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
@@ -1,12 +0,0 @@
1
- module Byebug
2
- #
3
- # Special setting to flag that byebug is being tested.
4
- #
5
- # FIXME: make this private.
6
- #
7
- class TestingSetting < Setting
8
- def banner
9
- 'Used when testing byebug'
10
- end
11
- end
12
- end
@@ -1,11 +0,0 @@
1
- module Byebug
2
- #
3
- # Setting to allow consecutive repeated lines to be displayed when line
4
- # tracing is enabled.
5
- #
6
- class TracingPlusSetting < Setting
7
- def banner
8
- 'Set line execution tracing to always show different lines'
9
- end
10
- end
11
- end
@@ -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