pry-exception_explorer 0.1.1pre3 → 0.1.1pre5

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -43,9 +43,21 @@ task :reinstall => :gems do
43
43
  sh "gem install #{direc}/pkg/pry-exception_explorer-#{PryExceptionExplorer::VERSION}.gem"
44
44
  end
45
45
 
46
+ desc "Run example"
47
+ task :example do
48
+ sh "ruby -I#{direc}/lib/ #{direc}/examples/example.rb "
49
+ end
50
+
51
+ task :default => :test
52
+
53
+ desc "Show version"
54
+ task :version do
55
+ puts "PryExceptionExplorer version: #{PryExceptionExplorer::VERSION}"
56
+ end
57
+
46
58
  desc "run tests"
47
59
  task :test do
48
- sh "bacon -Itest -rubygems -a"
60
+ sh "bacon -Itest -rubygems -a -q"
49
61
  end
50
62
 
51
63
  desc "Build gemspec"
@@ -0,0 +1,30 @@
1
+ unless Object.const_defined? :PryExceptionExplorer
2
+ $:.unshift File.expand_path '../../lib', __FILE__
3
+ require 'pry'
4
+ end
5
+
6
+ require 'pry-exception_explorer'
7
+ require 'pry-exception_explorer/exception_wrap'
8
+
9
+ def alpha
10
+ name = "john"
11
+ beta
12
+ puts name
13
+ end
14
+
15
+ def beta
16
+ x = 20
17
+ gamma
18
+ puts x
19
+ end
20
+
21
+ def gamma
22
+ raise "oh my, an exception"
23
+ end
24
+
25
+
26
+ PryExceptionExplorer.intercept(Exception)
27
+
28
+ PryExceptionExplorer.wrap do
29
+ alpha
30
+ end
@@ -5,6 +5,7 @@ PryExceptionExplorer::Commands = Pry::CommandSet.new do
5
5
  command "enter-exception", "Enter the context of the last exception" do
6
6
  ex = _pry_.last_exception
7
7
  if ex && ex.exception_call_stack
8
+ _pry_.backtrace = ex.backtrace
8
9
  PryStackExplorer.create_and_push_frame_manager(ex.exception_call_stack, _pry_)
9
10
  PryStackExplorer.frame_manager(_pry_).user[:exception] = ex
10
11
  PryStackExplorer.frame_manager(_pry_).refresh_frame
@@ -15,13 +16,42 @@ PryExceptionExplorer::Commands = Pry::CommandSet.new do
15
16
  end
16
17
  end
17
18
 
18
- command "exit-exception", "Leave the context of the current exception." do
19
- fm = PryStackExplorer.frame_manager(_pry_)
20
- if fm && fm.user[:exception]
21
- PryStackExplorer.pop_frame_manager(_pry_)
22
- PryStackExplorer.frame_manager(_pry_).refresh_frame
23
- else
24
- output.puts "You are not in an exception!"
19
+ command_class "exit-exception", "Leave the context of the current exception." do
20
+ banner <<-BANNER
21
+ Usage: exit-exception
22
+ Exit active exception and return to containing context.
23
+ BANNER
24
+
25
+ def process
26
+ if !in_exception?
27
+ raise Pry::CommandError, "You are not in an exception!"
28
+ elsif !prior_context_exists?
29
+ run "exit-all"
30
+ else
31
+ popped_fm = PryStackExplorer.pop_frame_manager(_pry_)
32
+ if frame_manager
33
+ frame_manager.refresh_frame
34
+ else
35
+ _pry_.binding_stack[-1] = popped_fm.prior_binding
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+ def frame_manager
42
+ PryStackExplorer.frame_manager(_pry_)
43
+ end
44
+
45
+ def frame_managers
46
+ PryStackExplorer.frame_managers(_pry_)
47
+ end
48
+
49
+ def prior_context_exists?
50
+ frame_managers.count > 1 || frame_manager.prior_binding
51
+ end
52
+
53
+ def in_exception?
54
+ frame_manager && frame_manager.user[:exception]
25
55
  end
26
56
  end
27
57
 
@@ -29,8 +59,8 @@ PryExceptionExplorer::Commands = Pry::CommandSet.new do
29
59
  fm = PryStackExplorer.frame_manager(_pry_)
30
60
 
31
61
  if fm && fm.user[:exception] && fm.user[:inline_exception]
32
- _pry_.run_command "exit-all PryExceptionExplorer::CONTINUE_INLINE_EXCEPTION"
33
62
  PryStackExplorer.pop_frame_manager(_pry_)
63
+ _pry_.run_command "exit-all PryExceptionExplorer::CONTINUE_INLINE_EXCEPTION"
34
64
  elsif fm && fm.user[:exception] && fm.user[:exception].continuation
35
65
  PryStackExplorer.pop_frame_manager(_pry_)
36
66
  fm.user[:exception].continue
@@ -1,6 +1,6 @@
1
1
  require 'pry-exception_explorer'
2
2
 
3
- Pry.config.hooks.delete_hook(:when_started, :save_caller_bindings)
3
+ #Pry.config.hooks.delete_hook(:when_started, :save_caller_bindings)
4
4
 
5
5
  # default is to capture all exceptions that bubble to the top
6
6
  PryExceptionExplorer.intercept { true }
@@ -8,22 +8,26 @@ PryExceptionExplorer.intercept { true }
8
8
  module PryExceptionExplorer
9
9
 
10
10
  def self.wrap
11
+ old_enabled, old_wrap_active = enabled, wrap_active
12
+ self.enabled = true
11
13
  self.wrap_active = true
12
14
  yield
13
15
  rescue Exception => ex
14
- Pry.config.hooks.add_hook(:when_started, :setup_exception_context) do |binding_stack, _pry_|
15
- binding_stack.replace([ex.exception_call_stack.first])
16
- PryStackExplorer.create_and_push_frame_manager(ex.exception_call_stack, _pry_)
17
- PryStackExplorer.frame_manager(_pry_).user[:exception] = ex
18
- end
19
-
20
16
  if ex.should_capture?
21
- pry
17
+ hooks = Pry.config.hooks.dup.add_hook(:before_session, :set_exception_flag) do |_, _, _pry_|
18
+ PryStackExplorer.frame_manager(_pry_).user[:exception] = ex
19
+
20
+ _pry_.last_exception = ex
21
+ _pry_.backtrace = ex.backtrace
22
+ end
23
+
24
+ Pry.start self, :call_stack => ex.exception_call_stack, :hooks => hooks
22
25
  else
23
26
  raise ex
24
27
  end
25
28
  ensure
26
- self.wrap_active = false
29
+ self.enabled = old_enabled
30
+ self.wrap_active = old_wrap_active
27
31
  end
28
32
  end
29
33
 
@@ -1,3 +1,3 @@
1
1
  module PryExceptionExplorer
2
- VERSION = "0.1.1pre3"
2
+ VERSION = "0.1.1pre5"
3
3
  end
@@ -15,6 +15,10 @@ module PryExceptionExplorer
15
15
  CONTINUE_INLINE_EXCEPTION = Object.new
16
16
 
17
17
  class << self
18
+
19
+ # @return [Boolean] Whether `PryStackExplorer` is enabled.
20
+ attr_accessor :enabled
21
+
18
22
  def wrap_active=(v)
19
23
  Thread.current[:__pry_exception_explorer_wrap__] = v
20
24
  end
@@ -24,6 +28,7 @@ module PryExceptionExplorer
24
28
  end
25
29
 
26
30
  alias_method :wrap_active?, :wrap_active
31
+ alias_method :enabled?, :enabled
27
32
  end
28
33
 
29
34
  self.wrap_active = false
@@ -32,7 +37,11 @@ module PryExceptionExplorer
32
37
  true
33
38
  end
34
39
 
35
- def self.intercept(&block)
40
+ def self.intercept(*exceptions, &block)
41
+ if !exceptions.empty?
42
+ block = proc { |_, ex| exceptions.any? { |v| v === ex } }
43
+ end
44
+
36
45
  Thread.current[:__pry_exception_explorer_intercept_block__] = block
37
46
  end
38
47
 
@@ -79,6 +88,7 @@ end
79
88
 
80
89
  class Object
81
90
  def raise(exception = RuntimeError, string = nil, array = caller)
91
+
82
92
  if exception.is_a?(String)
83
93
  string = exception
84
94
  exception = RuntimeError
@@ -87,6 +97,11 @@ class Object
87
97
  ex = exception.exception(string)
88
98
  ex.set_backtrace(array)
89
99
 
100
+ # revert to normal exception behaviour if EE not enabled.
101
+ if !PryExceptionExplorer.enabled?
102
+ return super(ex)
103
+ end
104
+
90
105
  if PryExceptionExplorer.should_capture_exception?(ex, binding.of_caller(1))
91
106
  ex.exception_call_stack = binding.callers.tap(&:shift)
92
107
  ex.should_capture = true
@@ -114,3 +129,10 @@ PryExceptionExplorer.wrap_active = true
114
129
  PryExceptionExplorer.intercept { true }
115
130
 
116
131
  Pry.config.commands.import PryExceptionExplorer::Commands
132
+
133
+ # disable by default
134
+ PryExceptionExplorer.enabled = false
135
+
136
+ Pry.config.hooks.add_hook(:when_started, :try_enable_exception_explorer) do
137
+ PryExceptionExplorer.enabled = true if Pry.cli
138
+ end
@@ -2,19 +2,19 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "pry-exception_explorer"
5
- s.version = "0.1.1pre3"
5
+ s.version = "0.1.1pre5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["John Mair (banisterfiend)"]
9
- s.date = "2012-01-05"
9
+ s.date = "2012-01-12"
10
10
  s.description = "Enter the context of exceptions"
11
11
  s.email = "jrmair@gmail.com"
12
- s.files = [".gemtest", ".gitignore", ".travis.yml", ".yardopts", "CHANGELOG", "Gemfile", "LICENSE", "README.md", "Rakefile", "lib/pry-exception_explorer.rb", "lib/pry-exception_explorer/cli.rb", "lib/pry-exception_explorer/commands.rb", "lib/pry-exception_explorer/exception_wrap.rb", "lib/pry-exception_explorer/lazy_frame.rb", "lib/pry-exception_explorer/shim_builder.rb", "lib/pry-exception_explorer/version.rb", "pry-exception_explorer.gemspec", "test/helper.rb", "test/test_exception_explorer.rb", "test/test_exceptions_in_pry.rb", "test/test_wrapped_exceptions.rb"]
12
+ s.files = [".gemtest", ".gitignore", ".travis.yml", ".yardopts", "CHANGELOG", "Gemfile", "LICENSE", "README.md", "Rakefile", "examples/example.rb", "lib/pry-exception_explorer.rb", "lib/pry-exception_explorer/cli.rb", "lib/pry-exception_explorer/commands.rb", "lib/pry-exception_explorer/exception_wrap.rb", "lib/pry-exception_explorer/lazy_frame.rb", "lib/pry-exception_explorer/shim_builder.rb", "lib/pry-exception_explorer/version.rb", "pry-exception_explorer.gemspec", "test/helper.rb", "test/test_exceptions_in_pry.rb", "test/test_inline_exceptions.rb", "test/test_wrapped_exceptions.rb"]
13
13
  s.homepage = "https://github.com/banister/pry-exception_explorer"
14
14
  s.require_paths = ["lib"]
15
15
  s.rubygems_version = "1.8.11"
16
16
  s.summary = "Enter the context of exceptions"
17
- s.test_files = ["test/helper.rb", "test/test_exception_explorer.rb", "test/test_exceptions_in_pry.rb", "test/test_wrapped_exceptions.rb"]
17
+ s.test_files = ["test/helper.rb", "test/test_exceptions_in_pry.rb", "test/test_inline_exceptions.rb", "test/test_wrapped_exceptions.rb"]
18
18
 
19
19
  if s.respond_to? :specification_version then
20
20
  s.specification_version = 3
data/test/helper.rb CHANGED
@@ -6,10 +6,17 @@ unless Object.const_defined? 'PryExceptionExplorer'
6
6
  end
7
7
 
8
8
  require 'bacon'
9
+ require 'ostruct'
9
10
 
10
11
  puts "Testing pry-exception_explorer version #{PryExceptionExplorer::VERSION}..."
11
12
  puts "Ruby version: #{RUBY_VERSION}"
12
13
 
14
+ class OpenStruct
15
+ def clear
16
+ @table.clear
17
+ end
18
+ end
19
+
13
20
  EE = PryExceptionExplorer
14
21
 
15
22
  class Ratty
@@ -47,6 +54,9 @@ class << Pry
47
54
  end
48
55
  end
49
56
 
57
+ AfterSessionHook = Pry.config.hooks.get_hook(:after_session, :delete_frame_manager)
58
+ WhenStartedHook = Pry.config.hooks.get_hook(:when_started, :save_caller_bindings)
59
+
50
60
  Pry.reset_defaults
51
61
 
52
62
  class InputTester
@@ -99,3 +109,4 @@ def mock_pry(*args)
99
109
  output.string
100
110
  end
101
111
 
112
+ PryExceptionExplorer.enabled = true
@@ -1,13 +1,21 @@
1
1
  require 'helper'
2
2
 
3
+ O = OpenStruct.new
4
+
3
5
  describe PryExceptionExplorer do
4
6
 
7
+ before do
8
+ PryExceptionExplorer.intercept { true }
9
+ PryExceptionExplorer.wrap_active = true
10
+ end
11
+
12
+ after do
13
+ O.clear
14
+ end
15
+
5
16
  describe "Exceptions caught by Pry" do
6
17
  describe "enter-exception" do
7
18
  it "should be able to enter an exception caught by pry" do
8
-
9
- PryExceptionExplorer.intercept { true }
10
-
11
19
  # there are 3 types of situations where exception_explorer is invoked:
12
20
  # 1. when 'wrap' is used, i.e only exceptions that bubble to
13
21
  # the top are intercepted.
@@ -22,8 +30,67 @@ describe PryExceptionExplorer do
22
30
  # `enter-exception` to start the session.
23
31
  #
24
32
  # This test is for type 3.
33
+ redirect_pry_io(InputTester.new("Ratty.new.ratty",
34
+ "enter-exception",
35
+ "O.method_name = __method__",
36
+ "exit", StringIO.new)) do
37
+ Pry.start
38
+ end
39
+
40
+ O.method_name.should == :toad
41
+ end
42
+
43
+ it "should have access to exception's caller" do
25
44
  mock_pry("Ratty.new.ratty", "enter-exception", "show-stack", "exit").should =~ /toad.*?weasel.*?ratty/m
26
45
  end
46
+
47
+ describe "exit-exception" do
48
+ it 'should display error message when exit-exception used outside of exception context' do
49
+ mock_pry("exit-exception").should =~ /You are not in an exception!/
50
+ end
51
+
52
+ it "should exit a nested exception and correctly pop FrameManagers" do
53
+ redirect_pry_io(InputTester.new("Ratty.new.ratty",
54
+ "enter-exception",
55
+ "raise 'yo'",
56
+ "enter-exception",
57
+ "O.first_pry = _pry_",
58
+ "O.first_count = PryStackExplorer.frame_managers(_pry_).count",
59
+ "exit-exception",
60
+ "O.second_pry = _pry_",
61
+ "O.second_count = PryStackExplorer.frame_managers(_pry_).count",
62
+ "exit-exception",
63
+ "exit-all", StringIO.new)) do
64
+ Pry.start(binding)
65
+ end
66
+
67
+ O.first_pry.should == O.second_pry
68
+ O.first_count.should == 2
69
+ O.second_count.should == 1
70
+ PryStackExplorer.frame_managers(O.first_pry).count.should == 0
71
+ end
72
+
73
+ it "should exit an exception and return to initial context" do
74
+ redirect_pry_io(InputTester.new("Ratty.new.ratty",
75
+ "O.initial_self = self",
76
+ "enter-exception",
77
+ "O.exception_self = self",
78
+ "exit-exception",
79
+ "O.return_self = self",
80
+ "exit-all", StringIO.new)) do
81
+ Pry.start(binding)
82
+ end
83
+
84
+ O.initial_self.should == self
85
+ O.initial_self.should == O.return_self
86
+
87
+ # actual exception context is Toad, as call chain is:
88
+ # Ratty -> Weasel -> Toad (raise is here)
89
+ O.exception_self.is_a?(Toad).should == true
90
+ end
91
+ end
27
92
  end
28
93
  end
29
94
  end
95
+
96
+ Object.send(:remove_const, :O)
@@ -0,0 +1,262 @@
1
+ require 'helper'
2
+ require 'ostruct'
3
+
4
+ # globally accessible state
5
+ O = OpenStruct.new
6
+
7
+ prev_wrap_state = PryExceptionExplorer.wrap_active
8
+ PryExceptionExplorer.wrap_active = false
9
+
10
+ prev_intercept_state = PryExceptionExplorer.intercept_block
11
+
12
+ describe PryExceptionExplorer do
13
+
14
+ before do
15
+ PryExceptionExplorer.wrap_active = false
16
+ O.exception_intercepted = false
17
+
18
+ # Ensure that when an exception is intercepted (a pry session
19
+ # started) that this is registered by setting state on `O`
20
+ Pry.config.input = StringIO.new("O.exception_intercepted = true\ncontinue-exception")
21
+ Pry.config.output = StringIO.new
22
+ end
23
+
24
+ after do
25
+ Pry.config.input.rewind
26
+ O.clear
27
+ end
28
+
29
+ describe "PryExceptionExplorer.intercept" do
30
+ describe "special case exception-only syntax" do
31
+
32
+ describe "single exception" do
33
+ it 'should intercept provided exceptions when given parameters (and no block)' do
34
+ my_error = Class.new(StandardError)
35
+ EE.intercept(my_error)
36
+ raise my_error
37
+ O.exception_intercepted.should == true
38
+ end
39
+
40
+ it 'should NOT intercept provided exceptions when not matched' do
41
+ my_error = Class.new(StandardError)
42
+ EE.intercept(my_error)
43
+
44
+ begin
45
+ raise RuntimeError
46
+ rescue => ex
47
+ ex.is_a?(RuntimeError).should == true
48
+ end
49
+ end
50
+ end
51
+
52
+ describe "multiple exceptions" do
53
+ it 'should intercept provided exceptions when given parameters (and no block)' do
54
+ errors = Array.new(3) { Class.new(StandardError) }
55
+ EE.intercept(*errors)
56
+
57
+ errors.each do |my_error|
58
+ raise my_error
59
+ O.exception_intercepted.should == true
60
+ O.exception_intercepted = false
61
+ Pry.config.input.rewind
62
+ end
63
+ end
64
+
65
+ it 'should NOT intercept provided exceptions when not matched' do
66
+ errors = Array.new(3) { Class.new(StandardError) }
67
+
68
+ EE.intercept(*errors)
69
+
70
+ errors.each do |my_error|
71
+ begin
72
+ raise RuntimeError
73
+ rescue => ex
74
+ ex.is_a?(RuntimeError).should == true
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ describe "class" do
83
+ describe "first frame" do
84
+ it "should intercept exception based on first frame's class" do
85
+ EE.intercept { |frame, ex| frame.klass == Toad }
86
+ Ratty.new.ratty
87
+ O.exception_intercepted.should == true
88
+ end
89
+
90
+ it "should NOT intercept exception if class doesn't match" do
91
+ EE.intercept { |frame, ex| frame.klass == Ratty }
92
+ begin
93
+ Ratty.new.ratty
94
+ rescue Exception => ex
95
+ ex.is_a?(RuntimeError).should == true
96
+ end
97
+ O.exception_intercepted.should == false
98
+ end
99
+ end
100
+
101
+ describe "second frame" do
102
+ it "should intercept exception based on second frame's method name" do
103
+ EE.intercept { |frame, ex| frame.prev.klass == Weasel }
104
+ Ratty.new.ratty
105
+ O.exception_intercepted.should == true
106
+ end
107
+
108
+ it "should NOT intercept exception if method name doesn't match" do
109
+ EE.intercept { |frame, ex| frame.prev.klass == Toad }
110
+ begin
111
+ Ratty.new.ratty
112
+ rescue Exception => ex
113
+ ex.is_a?(RuntimeError).should == true
114
+ end
115
+ O.exception_intercepted.should == false
116
+ end
117
+ end
118
+
119
+ describe "third frame" do
120
+ it "should intercept exception based on third frame's method name" do
121
+ EE.intercept { |frame, ex| frame.prev.prev.klass == Ratty }
122
+ Ratty.new.ratty
123
+ O.exception_intercepted.should == true
124
+ end
125
+
126
+ it "should NOT intercept exception if method name doesn't match" do
127
+ EE.intercept { |frame, ex| frame.prev.prev.klass == Toad }
128
+ begin
129
+ Ratty.new.ratty
130
+ rescue Exception => ex
131
+ ex.is_a?(RuntimeError).should == true
132
+ end
133
+ O.exception_intercepted.should == false
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+ describe "method_name" do
140
+ describe "first frame" do
141
+ it "should intercept exception based on first frame's method name" do
142
+ EE.intercept { |frame, ex| frame.method_name == :toad }
143
+ Ratty.new.ratty
144
+ O.exception_intercepted.should == true
145
+ end
146
+
147
+ it "should NOT intercept exception if method name doesn't match" do
148
+ EE.intercept { |frame, ex| frame.method_name == :ratty }
149
+ begin
150
+ Ratty.new.ratty
151
+ rescue Exception => ex
152
+ ex.is_a?(RuntimeError).should == true
153
+ end
154
+ O.exception_intercepted.should == false
155
+ end
156
+ end
157
+
158
+ describe "second frame" do
159
+ it "should intercept exception based on second frame's method name" do
160
+ EE.intercept { |frame, ex| frame.prev.method_name == :weasel }
161
+ Ratty.new.ratty
162
+ O.exception_intercepted.should == true
163
+ end
164
+
165
+ it "should NOT intercept exception if method name doesn't match" do
166
+ EE.intercept { |frame, ex| frame.prev.method_name == :toad }
167
+ begin
168
+ Ratty.new.ratty
169
+ rescue Exception => ex
170
+ ex.is_a?(RuntimeError).should == true
171
+ end
172
+ O.exception_intercepted.should == false
173
+ end
174
+ end
175
+
176
+ describe "third frame" do
177
+ it "should intercept exception based on third frame's method name" do
178
+ EE.intercept { |frame, ex| frame.prev.prev.method_name == :ratty }
179
+ Ratty.new.ratty
180
+ O.exception_intercepted.should == true
181
+ end
182
+
183
+ it "should NOT intercept exception if method name doesn't match" do
184
+ EE.intercept { |frame, ex| frame.prev.prev.method_name == :toad }
185
+ begin
186
+ Ratty.new.ratty
187
+ rescue Exception => ex
188
+ ex.is_a?(RuntimeError).should == true
189
+ end
190
+ O.exception_intercepted.should == false
191
+ end
192
+ end
193
+
194
+ end
195
+
196
+
197
+ end
198
+
199
+ describe "call-stack management" do
200
+ it 'should pop the call-stack after session ends (continue)' do
201
+ EE.intercept { |frame, ex| frame.prev.prev.method_name == :ratty }
202
+
203
+ redirect_pry_io(InputTester.new(
204
+ "O.stack_count = PryStackExplorer.frame_managers(_pry_).count",
205
+ "O._pry_ = _pry_",
206
+ "continue-exception"), StringIO.new) do
207
+ Ratty.new.ratty
208
+ end
209
+ O.stack_count.should == 1
210
+ PryStackExplorer.frame_managers(O._pry_).count.should == 0
211
+ end
212
+
213
+ it 'should pop the call-stack after session ends (exit)' do
214
+ EE.intercept { |frame, ex| frame.prev.prev.method_name == :ratty }
215
+
216
+ redirect_pry_io(InputTester.new(
217
+ "O.stack_count = PryStackExplorer.frame_managers(_pry_).count",
218
+ "O._pry_ = _pry_",
219
+ "exit"), StringIO.new) do
220
+ begin
221
+ Ratty.new.ratty
222
+ rescue
223
+ end
224
+ end
225
+ O.stack_count.should == 1
226
+ PryStackExplorer.frame_managers(O._pry_).count.should == 0
227
+ end
228
+
229
+ describe "nested exceptions" do
230
+ it 'Each successive exception interception should be managed by its own pry instance and have its own call-stack' do
231
+ EE.intercept { |frame, ex| frame.prev.prev.method_name == :ratty }
232
+
233
+ redirect_pry_io(InputTester.new(
234
+ "O.first_stack_count = PryStackExplorer.frame_managers(_pry_).count",
235
+ "O._pry_ = _pry_",
236
+ "EE.intercept(ArgumentError)",
237
+ "raise ArgumentError",
238
+ "O._pry_2 = _pry_",
239
+ "O.second_stack_count = PryStackExplorer.frame_managers(_pry_).count",
240
+ "continue-exception",
241
+ "continue-exception"), StringIO.new) do
242
+ Ratty.new.ratty
243
+ end
244
+
245
+ O._pry_.should.not == O._pry_2
246
+ O.first_stack_count.should == 1
247
+ O.second_stack_count.should == 1
248
+ PryStackExplorer.frame_managers(O._pry_).count.should == 0
249
+ PryStackExplorer.frame_managers(O._pry_2).count.should == 0
250
+ end
251
+
252
+ end
253
+
254
+ end
255
+
256
+ end
257
+
258
+ # restore to default
259
+ PryExceptionExplorer.wrap_active = prev_wrap_state
260
+ PryExceptionExplorer.intercept &prev_intercept_state
261
+
262
+ Object.send(:remove_const, :O)
@@ -5,19 +5,42 @@ require 'pry-exception_explorer/exception_wrap'
5
5
  CaughtException = Class.new(StandardError)
6
6
  UncaughtException = Class.new(StandardError)
7
7
 
8
+
8
9
  describe PryExceptionExplorer do
9
10
 
11
+
10
12
  before do
11
13
  Pry.config.input = StringIO.new("exit :caught\n")
12
14
  Pry.config.output = StringIO.new
15
+ Pry.config.hooks.add_hook(:when_started, :save_caller_bindings, &WhenStartedHook)
16
+ Pry.config.hooks.add_hook(:after_session, :delete_frame_manager, &AfterSessionHook)
13
17
  end
14
18
 
15
19
  after do
16
- Pry.config.hooks.clear(:when_started)
20
+ Pry.config.hooks.delete_hook(:when_started, :save_caller_bindings)
21
+ Pry.config.hooks.delete_hook(:after_session, :delete_frame_manager)
17
22
  end
18
23
 
19
24
  describe "PryExceptionExplorer.wrap" do
20
25
 
26
+ # use of exit-exception inside a wrapped exception is weird
27
+ # (because exit-exception is really designed for pry exceptions)
28
+ # but when we do receive one, we should exit out of pry
29
+ # altogether.
30
+ # This test is weird as we can't use lambda { }.should.not.raise, as we override
31
+ # 'raise' method ourself, which kills bacon's functionality here.
32
+ it 'should exit out of Pry session when using exit-exception' do
33
+ PryExceptionExplorer.intercept { true }
34
+
35
+ x = :no_exception_raised
36
+ redirect_pry_io(InputTester.new("exit-exception"), $stdout) do
37
+ PryExceptionExplorer.wrap do
38
+ Ratty.new.ratty
39
+ end
40
+ end
41
+ x.should == :no_exception_raised
42
+ end
43
+
21
44
  it 'should default to capturing ALL exceptions' do
22
45
  PryExceptionExplorer.wrap do
23
46
  raise CaughtException, "catch me if u can"
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: pry-exception_explorer
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 5
5
- version: 0.1.1pre3
5
+ version: 0.1.1pre5
6
6
  platform: ruby
7
7
  authors:
8
8
  - John Mair (banisterfiend)
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-01-05 00:00:00 Z
13
+ date: 2012-01-12 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: pry-stack_explorer
@@ -63,6 +63,7 @@ files:
63
63
  - LICENSE
64
64
  - README.md
65
65
  - Rakefile
66
+ - examples/example.rb
66
67
  - lib/pry-exception_explorer.rb
67
68
  - lib/pry-exception_explorer/cli.rb
68
69
  - lib/pry-exception_explorer/commands.rb
@@ -72,8 +73,8 @@ files:
72
73
  - lib/pry-exception_explorer/version.rb
73
74
  - pry-exception_explorer.gemspec
74
75
  - test/helper.rb
75
- - test/test_exception_explorer.rb
76
76
  - test/test_exceptions_in_pry.rb
77
+ - test/test_inline_exceptions.rb
77
78
  - test/test_wrapped_exceptions.rb
78
79
  homepage: https://github.com/banister/pry-exception_explorer
79
80
  licenses: []
@@ -104,6 +105,6 @@ specification_version: 3
104
105
  summary: Enter the context of exceptions
105
106
  test_files:
106
107
  - test/helper.rb
107
- - test/test_exception_explorer.rb
108
108
  - test/test_exceptions_in_pry.rb
109
+ - test/test_inline_exceptions.rb
109
110
  - test/test_wrapped_exceptions.rb
@@ -1,159 +0,0 @@
1
- require 'helper'
2
-
3
-
4
- # override enter_exception_inline so we can use it for testing purposes
5
- EE.instance_eval do
6
- alias original_enter_exception_inline enter_exception_inline
7
- end
8
-
9
- def EE.exception_intercepted?
10
- @exception_intercepted
11
- end
12
-
13
- EE.instance_eval do
14
- @exception_intercepted = false
15
- end
16
-
17
- def EE.enter_exception_inline(ex)
18
- @exception_intercepted = true
19
- EE::CONTINUE_INLINE_EXCEPTION
20
- end
21
-
22
- prev_wrap_state = PryExceptionExplorer.wrap_active
23
- PryExceptionExplorer.wrap_active = false
24
-
25
- describe PryExceptionExplorer do
26
-
27
- before do
28
- PryExceptionExplorer.wrap_active = false
29
- end
30
-
31
- after do
32
- EE.instance_eval do
33
- @exception_intercepted = false
34
- end
35
- end
36
-
37
- describe "PryExceptionExplorer.intercept" do
38
- describe "class" do
39
- describe "first frame" do
40
- it "should intercept exception based on first frame's method name" do
41
- EE.intercept { |frame, ex| frame.klass == Toad }
42
- Ratty.new.ratty
43
- EE.exception_intercepted?.should == true
44
- end
45
-
46
- it "should NOT intercept exception if method name doesn't match" do
47
- EE.intercept { |frame, ex| frame.klass == Ratty }
48
- begin
49
- Ratty.new.ratty
50
- rescue Exception => ex
51
- ex.is_a?(RuntimeError).should == true
52
- end
53
- EE.exception_intercepted?.should == false
54
- end
55
- end
56
-
57
- describe "second frame" do
58
- it "should intercept exception based on second frame's method name" do
59
- EE.intercept { |frame, ex| frame.prev.klass == Weasel }
60
- Ratty.new.ratty
61
- EE.exception_intercepted?.should == true
62
- end
63
-
64
- it "should NOT intercept exception if method name doesn't match" do
65
- EE.intercept { |frame, ex| frame.prev.klass == Toad }
66
- begin
67
- Ratty.new.ratty
68
- rescue Exception => ex
69
- ex.is_a?(RuntimeError).should == true
70
- end
71
- EE.exception_intercepted?.should == false
72
- end
73
- end
74
-
75
- describe "third frame" do
76
- it "should intercept exception based on third frame's method name" do
77
- EE.intercept { |frame, ex| frame.prev.prev.klass == Ratty }
78
- Ratty.new.ratty
79
- EE.exception_intercepted?.should == true
80
- end
81
-
82
- it "should NOT intercept exception if method name doesn't match" do
83
- EE.intercept { |frame, ex| frame.prev.prev.klass == Toad }
84
- begin
85
- Ratty.new.ratty
86
- rescue Exception => ex
87
- ex.is_a?(RuntimeError).should == true
88
- end
89
- EE.exception_intercepted?.should == false
90
- end
91
- end
92
-
93
- end
94
-
95
- describe "method_name" do
96
- describe "first frame" do
97
- it "should intercept exception based on first frame's method name" do
98
- EE.intercept { |frame, ex| frame.method_name == :toad }
99
- Ratty.new.ratty
100
- EE.exception_intercepted?.should == true
101
- end
102
-
103
- it "should NOT intercept exception if method name doesn't match" do
104
- EE.intercept { |frame, ex| frame.method_name == :ratty }
105
- begin
106
- Ratty.new.ratty
107
- rescue Exception => ex
108
- ex.is_a?(RuntimeError).should == true
109
- end
110
- EE.exception_intercepted?.should == false
111
- end
112
- end
113
-
114
- describe "second frame" do
115
- it "should intercept exception based on second frame's method name" do
116
- EE.intercept { |frame, ex| frame.prev.method_name == :weasel }
117
- Ratty.new.ratty
118
- EE.exception_intercepted?.should == true
119
- end
120
-
121
- it "should NOT intercept exception if method name doesn't match" do
122
- EE.intercept { |frame, ex| frame.prev.method_name == :toad }
123
- begin
124
- Ratty.new.ratty
125
- rescue Exception => ex
126
- ex.is_a?(RuntimeError).should == true
127
- end
128
- EE.exception_intercepted?.should == false
129
- end
130
- end
131
-
132
- describe "third frame" do
133
- it "should intercept exception based on third frame's method name" do
134
- EE.intercept { |frame, ex| frame.prev.prev.method_name == :ratty }
135
- Ratty.new.ratty
136
- EE.exception_intercepted?.should == true
137
- end
138
-
139
- it "should NOT intercept exception if method name doesn't match" do
140
- EE.intercept { |frame, ex| frame.prev.prev.method_name == :toad }
141
- begin
142
- Ratty.new.ratty
143
- rescue Exception => ex
144
- ex.is_a?(RuntimeError).should == true
145
- end
146
- EE.exception_intercepted?.should == false
147
- end
148
- end
149
-
150
- end
151
-
152
- end
153
- end
154
-
155
- EE.instance_eval do
156
- alias enter_exception_inline original_enter_exception_inline
157
- end
158
-
159
- PryExceptionExplorer.wrap_active = prev_wrap_state