pry-exception_explorer 0.1.1pre3 → 0.1.1pre5

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