pry-rescue 1.0.0 → 1.1.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.
data/Rakefile CHANGED
@@ -11,6 +11,12 @@ task :example2 do
11
11
  sh "ruby -I./lib/ ./examples/example2.rb "
12
12
  end
13
13
 
14
+ desc 'Run syntax-err example'
15
+ task :sintax do
16
+ ENV['RUBYLIB'] = 'lib'
17
+ sh 'bin/rescue examples/syntax-err.rb'
18
+ end
19
+
14
20
  desc "Run tests"
15
21
  task :test do
16
22
  sh 'rspec spec'
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rspec'
3
+ require 'rspec/autorun'
4
+
5
+ $:.unshift File.expand_path '../../lib', __FILE__
6
+ require 'pry-rescue/rspec'
7
+
8
+ require 'capybara/rspec'
9
+
10
+ describe "Google", :type => :feature, :driver => :selenium do
11
+ it "should make a nice bell-like sound" do
12
+ visit 'http://google.com/'
13
+ page.should have_content 'Bing'
14
+ end
15
+ end
@@ -1,8 +1,9 @@
1
+ #!/usr/bin/env ruby
1
2
  require 'rspec'
2
3
  require 'rspec/autorun'
3
4
 
4
5
  $:.unshift File.expand_path '../../lib', __FILE__
5
- require 'pry-rescue'
6
+ require 'pry-rescue/rspec'
6
7
 
7
8
  describe "Float" do
8
9
  it "should be able to add" do
data/examples/loop.rb CHANGED
@@ -5,7 +5,9 @@ require 'pry-rescue'
5
5
  #
6
6
  # rescue --peek example/loop.rb
7
7
  #
8
- # Then hit <ctrl-c>, and be able to see what's going on.
8
+ # Then hit <ctrl-/>, and be able to see what's going on.
9
+ #
10
+ puts "Hit <ctrl-/> to peek with Pry, or <ctrl+c> to quit."
9
11
 
10
12
  def r
11
13
  some_var = 13
@@ -0,0 +1 @@
1
+ def initely not Ruby
@@ -41,19 +41,13 @@ Pry::Commands.create_command "cd-cause", "Move to the exception that caused this
41
41
  def process
42
42
  return Pry.rescued target.eval(args.first) if args.any?
43
43
 
44
- # TODO: better understand why !defined?(_ex_)
45
44
  ex = target.eval("defined?(_ex_) && _ex_")
46
- raised = target.eval("_raised_.dup rescue nil")
47
-
48
- ex_was_raised = raised && raised.last.first == ex
49
- if ex && !ex_was_raised
50
- Pry.rescued(ex)
51
- elsif ex_was_raised && raised.size > 1
52
- raised.pop
53
- PryRescue.enter_exception_context(raised)
54
- else
55
- raise Pry::CommandError, "No previous exception detected"
56
- end
45
+ rescued = target.eval("defined?(_rescued_) && _rescued_")
46
+
47
+ ex = ex.instance_variable_get(:@rescue_cause) if rescued == ex
48
+ raise Pry::CommandError, "No previous exception to cd-cause into" if ex.nil? || ex == rescued
49
+
50
+ Pry.rescued ex
57
51
  end
58
52
  end
59
53
 
@@ -11,7 +11,6 @@ class << Pry
11
11
  def rescue(&block)
12
12
  loop do
13
13
  catch(:try_again) do
14
- @raised = []
15
14
  begin
16
15
  return with_rescuing(&block)
17
16
  rescue Exception => e
@@ -34,8 +33,8 @@ class << Pry
34
33
  # end
35
34
  #
36
35
  def rescued(e=$!)
37
- if i = (@raised || []).index{ |(ee, _)| ee == e }
38
- PryRescue.enter_exception_context(@raised[0..i])
36
+ if e.instance_variable_get(:@rescue_bindings)
37
+ PryRescue.enter_exception_context(e)
39
38
  else
40
39
  stack = ''
41
40
  stack = "\n" + e.backtrace.join("\n") if e.backtrace
@@ -58,8 +57,6 @@ class << Pry
58
57
  end
59
58
  end
60
59
 
61
- ensure
62
- @raised = []
63
60
  end
64
61
 
65
62
  # Allow Pry::rescued(e) to work at any point in your program.
@@ -73,14 +70,12 @@ class << Pry
73
70
  # Pry::rescued(e)
74
71
  # end
75
72
  #
76
- def enable_rescuing!
77
- @raised ||= []
78
- @rescuing = true
79
- Interception.listen do |exception, binding|
80
- if defined?(PryStackExplorer)
81
- @raised << [exception, binding.callers]
82
- else
83
- @raised << [exception, Array(binding)]
73
+ def enable_rescuing!(block=nil)
74
+ Interception.listen(block) do |exception, binding|
75
+ bindings = binding.respond_to?(:callers) ? binding.callers : [binding]
76
+ unless exception.instance_variable_get(:@rescue_bindings)
77
+ exception.instance_variable_set(:@rescue_bindings, bindings)
78
+ exception.instance_variable_set(:@rescue_cause, $!)
84
79
  end
85
80
  end
86
81
  end
@@ -96,13 +91,7 @@ class << Pry
96
91
  else
97
92
  begin
98
93
  @rescuing = true
99
- Interception.listen(block) do |exception, binding|
100
- if defined?(PryStackExplorer)
101
- @raised << [exception, binding.callers]
102
- else
103
- @raised << [exception, Array(binding)]
104
- end
105
- end
94
+ enable_rescuing!(block)
106
95
  ensure
107
96
  @rescuing = false
108
97
  end
@@ -1,12 +1,58 @@
1
1
  require 'pry-rescue'
2
- RSpec.configure do |c|
3
- c.around(:each) do |example|
4
- Pry::rescue do
5
- example.binding.eval('@exception = nil')
6
- example.run
7
- if e = example.binding.eval('@exception')
8
- Pry::rescued(e)
2
+ class PryRescue
3
+ class RSpec
4
+
5
+ # Run an Rspec example within Pry::rescue{ }.
6
+ #
7
+ # Takes care to ensure that `try-again` will work.
8
+ def self.run(example)
9
+ Pry::rescue do
10
+ begin
11
+ before
12
+
13
+ example.binding.eval('@exception = nil')
14
+ example.run
15
+ if e = example.binding.eval('@exception')
16
+ Pry::rescued(e)
17
+ end
18
+
19
+ ensure
20
+ after
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.before
26
+ monkeypatch_capybara if defined?(Capybara)
27
+ end
28
+
29
+ def self.after
30
+ after_filters.each(&:call)
31
+ end
32
+
33
+ # Shunt Capybara's after filter from before Pry::rescued to after.
34
+ #
35
+ # The after filter navigates to 'about:blank', but people debugging
36
+ # tests probably want to see the page that failed.
37
+ def self.monkeypatch_capybara
38
+ unless Capybara.respond_to?(:reset_sessions_after_rescue!)
39
+ class << Capybara
40
+ alias_method :reset_sessions_after_rescue!, :reset_sessions!
41
+ def reset_sessions!; end
42
+ end
43
+
44
+ after_filters << Capybara.method(:reset_sessions_after_rescue!)
9
45
  end
10
46
  end
47
+
48
+ def self.after_filters
49
+ @after_filters ||= []
50
+ end
51
+ end
52
+ end
53
+
54
+ RSpec.configure do |c|
55
+ c.around(:each) do |example|
56
+ PryRescue::RSpec.run example
11
57
  end
12
58
  end
data/lib/pry-rescue.rb CHANGED
@@ -41,25 +41,23 @@ class PryRescue
41
41
 
42
42
  # Start a Pry session in the context of the exception.
43
43
  # @param [Array<Exception, Array<Binding>>] raised The exceptions raised
44
- def enter_exception_context(raised)
44
+ def enter_exception_context(exception)
45
45
  @exception_context_depth ||= 0
46
46
  @exception_context_depth += 1
47
47
 
48
- raised = raised.map do |e, bs|
49
- [e, without_bindings_below_raise(bs)]
50
- end
48
+ exception = exception.instance_variable_get(:@rescue_cause) if phantom_load_raise?(exception)
49
+ bindings = exception.instance_variable_get(:@rescue_bindings)
51
50
 
52
- raised.pop if phantom_load_raise?(*raised.last)
53
- exception, bindings = raised.last
51
+ bindings = without_bindings_below_raise(bindings)
54
52
  bindings = without_duplicates(bindings)
55
53
 
56
54
  with_program_name "#$PROGRAM_NAME [in pry-rescue @ #{Dir.pwd}]" do
57
55
  if defined?(PryStackExplorer)
58
56
  pry :call_stack => bindings,
59
- :hooks => pry_hooks(exception, raised),
57
+ :hooks => pry_hooks(exception),
60
58
  :initial_frame => initial_frame(bindings)
61
59
  else
62
- Pry.start bindings.first, :hooks => pry_hooks(exception, raised)
60
+ Pry.start bindings.first, :hooks => pry_hooks(exception)
63
61
  end
64
62
  end
65
63
  ensure
@@ -87,7 +85,8 @@ class PryRescue
87
85
  #
88
86
  # @param [Exception] e The raised exception
89
87
  # @param [Array<Binding>] bindings The call stack
90
- def phantom_load_raise?(e, bindings)
88
+ def phantom_load_raise?(e)
89
+ bindings = e.instance_variable_get(:@rescue_bindings)
91
90
  bindings.any? && bindings.first.eval("__FILE__") == __FILE__
92
91
  end
93
92
 
@@ -180,12 +179,12 @@ class PryRescue
180
179
  #
181
180
  # @param [Exception] ex The exception we're currently looking at
182
181
  # @param [Array<Exception, Array<Binding>>] raised The exceptions raised
183
- def pry_hooks(ex, raised)
182
+ def pry_hooks(ex)
184
183
  hooks = Pry.config.hooks.dup
185
184
  hooks.add_hook(:before_session, :save_captured_exception) do |_, _, _pry_|
186
185
  _pry_.last_exception = ex
187
186
  _pry_.backtrace = ex.backtrace
188
- _pry_.sticky_locals.merge!({ :_raised_ => raised })
187
+ _pry_.sticky_locals.merge!(:_rescued_ => ex)
189
188
  _pry_.exception_handler.call(_pry_.output, ex, _pry_)
190
189
  end
191
190
 
data/pry-rescue.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'pry-rescue'
3
- s.version = '1.0.0'
3
+ s.version = '1.1.0'
4
4
  s.summary = 'Open a pry session on any unhandled exceptions'
5
5
  s.description = 'Allows you to wrap code in Pry::rescue{ } to open a pry session at any unhandled exceptions'
6
6
  s.homepage = 'https://github.com/ConradIrwin/pry-rescue'
@@ -18,4 +18,5 @@ Gem::Specification.new do |s|
18
18
  s.add_development_dependency 'rspec'
19
19
  s.add_development_dependency 'yard'
20
20
  s.add_development_dependency 'redcarpet'
21
+ s.add_development_dependency 'capybara'
21
22
  end
@@ -36,40 +36,44 @@ describe "pry-rescue commands" do
36
36
  end
37
37
 
38
38
  it "should enter the context of _ex_ if no exception is given" do
39
- begin
40
- b1 = binding
41
- raise "original"
42
- rescue => _ex_
43
- b2 = binding
39
+ b2 = nil
40
+ _ex_ = nil
41
+ Pry::rescue do
42
+ begin
43
+ b1 = binding
44
+ raise "original"
45
+ rescue => _ex_
46
+ b2 = binding
47
+ end
44
48
  end
45
49
 
46
50
  Pry.should_receive(:rescued).once.with{ |raised|
47
51
  raised.should == _ex_
48
52
  }
49
53
 
50
- Pry.new.process_command 'cd-cause', '', binding
54
+ Pry.new.process_command 'cd-cause', '', b2
51
55
  end
52
56
  end
53
57
 
54
58
  describe "cd-cause" do
55
59
  it "should enter the next exception's context" do
56
- begin
60
+ _ex_ = nil
61
+ e1 = nil
62
+ Pry::rescue do
57
63
  begin
58
- b1 = binding
59
- raise "original"
60
- rescue => e1
61
- b2 = binding
62
- raise # similar to dubious re-raises you'll find in the wild
64
+ begin
65
+ b1 = binding
66
+ raise "original"
67
+ rescue => e1
68
+ b2 = binding
69
+ raise # similar to dubious re-raises you'll find in the wild
70
+ end
71
+ rescue => e2
72
+ _ex_ = e2
63
73
  end
64
- rescue => e2
65
- # Hacks due to us not really entering a pry session here
66
- _raised_ = [[e1, [b1]], [e2, [b2]]]
67
- _ex_ = e2
68
74
  end
69
75
 
70
- PryRescue.should_receive(:enter_exception_context).once.with{ |raised|
71
- raised.should == [[e1, [b1]]]
72
- }
76
+ PryRescue.should_receive(:enter_exception_context).once.with(e1)
73
77
 
74
78
  Pry.new.process_command 'cd-cause', '', binding
75
79
  end
@@ -80,7 +84,7 @@ describe "pry-rescue commands" do
80
84
  raise "original"
81
85
  rescue => e1
82
86
  # Hacks due to us not really entering a pry session here
83
- _raised_ = [[e1, [b1]]]
87
+ _rescued_ = e1
84
88
  _ex_ = e1
85
89
  end
86
90
 
@@ -89,6 +93,25 @@ describe "pry-rescue commands" do
89
93
  }.should raise_error Pry::CommandError, /No previous exception/
90
94
  end
91
95
 
96
+ it "should raise a CommandError on a re-raise" do
97
+ _ex_ = nil
98
+ Pry::rescue do
99
+ begin
100
+ begin
101
+ raise "oops"
102
+ rescue => e
103
+ raise e
104
+ end
105
+ rescue => _ex_
106
+ end
107
+ end
108
+ _rescued_ = _ex_
109
+
110
+ lambda{
111
+ Pry.new.process_command 'cd-cause', '', binding
112
+ }.should raise_error Pry::CommandError, /No previous exception/
113
+ end
114
+
92
115
  it "should raise a CommandError if not in Pry::rescue" do
93
116
  lambda{
94
117
  Pry.new.process_command 'cd-cause', '', binding
@@ -33,34 +33,6 @@ describe 'Pry.rescue' do
33
33
  @inner.should == 2
34
34
  end
35
35
 
36
- it "should clear out exceptions between retrys at the same level" do
37
- @outer = @inner = 0
38
- PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
39
- PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
40
- Pry::rescue do
41
- @outer += 1
42
- Pry::rescue do
43
- @inner += 1
44
- raise "oops" if @inner <= 2
45
- end
46
- end
47
- end
48
-
49
- it "should clear out exceptions between retrys at a higher level" do
50
- @outer = @inner = 0
51
- PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
52
- PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
53
- PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1; throw :try_again }
54
- Pry::rescue do
55
- @outer += 1
56
- Pry::rescue do
57
- @inner += 1
58
- raise "oops" if @inner <= 2
59
- end
60
- raise "foops" if @outer == 1
61
- end
62
- end
63
-
64
36
  it "should enter the first occurence of an exception that is re-raised" do
65
37
  PryRescue.should_receive(:enter_exception_context).once{ |raised| raised.size.should == 1 }
66
38
  lambda do
@@ -71,7 +43,7 @@ describe 'Pry.rescue' do
71
43
  raise
72
44
  end
73
45
  end
74
- end.should raise_error /first_occurance/
46
+ end.should raise_error(/first_occurance/)
75
47
  end
76
48
 
77
49
  it "should not catch SystemExit" do
@@ -95,6 +95,12 @@ describe "PryRescue.load" do
95
95
  PryRescue.load("spec/fixtures/raiseother.rb")
96
96
  }.should raise_error(/raiseother_exception/)
97
97
  end
98
+
99
+ it "should output a warning if the exception was not raised" do
100
+ PryRescue.should_not_receive(:enter_exception_context)
101
+ Pry.should_receive(:warn).once
102
+ Pry.rescued(RuntimeError.new("foo"))
103
+ end
98
104
  else
99
105
  it "should open at the correct point" do
100
106
  Pry.should_receive(:start).once{ |binding, h|
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pry-rescue
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,104 +11,120 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2013-02-17 00:00:00.000000000 Z
14
+ date: 2013-03-21 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- type: :runtime
17
+ name: pry
18
18
  requirement: !ruby/object:Gem::Requirement
19
+ none: false
19
20
  requirements:
20
21
  - - ! '>='
21
22
  - !ruby/object:Gem::Version
22
23
  version: '0'
23
- none: false
24
+ type: :runtime
25
+ prerelease: false
24
26
  version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
25
28
  requirements:
26
29
  - - ! '>='
27
30
  - !ruby/object:Gem::Version
28
31
  version: '0'
29
- none: false
30
- prerelease: false
31
- name: pry
32
32
  - !ruby/object:Gem::Dependency
33
- type: :runtime
33
+ name: interception
34
34
  requirement: !ruby/object:Gem::Requirement
35
+ none: false
35
36
  requirements:
36
37
  - - ! '>='
37
38
  - !ruby/object:Gem::Version
38
39
  version: '0.3'
39
- none: false
40
+ type: :runtime
41
+ prerelease: false
40
42
  version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
41
44
  requirements:
42
45
  - - ! '>='
43
46
  - !ruby/object:Gem::Version
44
47
  version: '0.3'
45
- none: false
46
- prerelease: false
47
- name: interception
48
48
  - !ruby/object:Gem::Dependency
49
- type: :development
49
+ name: pry-stack_explorer
50
50
  requirement: !ruby/object:Gem::Requirement
51
+ none: false
51
52
  requirements:
52
53
  - - ! '>='
53
54
  - !ruby/object:Gem::Version
54
55
  version: '0'
55
- none: false
56
+ type: :development
57
+ prerelease: false
56
58
  version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
57
60
  requirements:
58
61
  - - ! '>='
59
62
  - !ruby/object:Gem::Version
60
63
  version: '0'
61
- none: false
62
- prerelease: false
63
- name: pry-stack_explorer
64
64
  - !ruby/object:Gem::Dependency
65
- type: :development
65
+ name: rspec
66
66
  requirement: !ruby/object:Gem::Requirement
67
+ none: false
67
68
  requirements:
68
69
  - - ! '>='
69
70
  - !ruby/object:Gem::Version
70
71
  version: '0'
71
- none: false
72
+ type: :development
73
+ prerelease: false
72
74
  version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
73
76
  requirements:
74
77
  - - ! '>='
75
78
  - !ruby/object:Gem::Version
76
79
  version: '0'
77
- none: false
78
- prerelease: false
79
- name: rspec
80
80
  - !ruby/object:Gem::Dependency
81
- type: :development
81
+ name: yard
82
82
  requirement: !ruby/object:Gem::Requirement
83
+ none: false
83
84
  requirements:
84
85
  - - ! '>='
85
86
  - !ruby/object:Gem::Version
86
87
  version: '0'
87
- none: false
88
+ type: :development
89
+ prerelease: false
88
90
  version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
89
92
  requirements:
90
93
  - - ! '>='
91
94
  - !ruby/object:Gem::Version
92
95
  version: '0'
93
- none: false
94
- prerelease: false
95
- name: yard
96
96
  - !ruby/object:Gem::Dependency
97
- type: :development
97
+ name: redcarpet
98
98
  requirement: !ruby/object:Gem::Requirement
99
+ none: false
99
100
  requirements:
100
101
  - - ! '>='
101
102
  - !ruby/object:Gem::Version
102
103
  version: '0'
103
- none: false
104
+ type: :development
105
+ prerelease: false
104
106
  version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
105
108
  requirements:
106
109
  - - ! '>='
107
110
  - !ruby/object:Gem::Version
108
111
  version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: capybara
114
+ requirement: !ruby/object:Gem::Requirement
109
115
  none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ type: :development
110
121
  prerelease: false
111
- name: redcarpet
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
112
128
  description: Allows you to wrap code in Pry::rescue{ } to open a pry session at any
113
129
  unhandled exceptions
114
130
  email:
@@ -128,6 +144,7 @@ files:
128
144
  - Rakefile
129
145
  - bin/kill-pry-rescue
130
146
  - bin/rescue
147
+ - examples/capybara_spec.rb
131
148
  - examples/example.rb
132
149
  - examples/example2.rb
133
150
  - examples/example_spec.rb
@@ -135,6 +152,7 @@ files:
135
152
  - examples/random-exit.rb
136
153
  - examples/rescue.rb
137
154
  - examples/sigsegv.rb
155
+ - examples/syntax-err.rb
138
156
  - lib/pry-rescue.rb
139
157
  - lib/pry-rescue/cli.rb
140
158
  - lib/pry-rescue/commands.rb
@@ -170,20 +188,20 @@ rdoc_options: []
170
188
  require_paths:
171
189
  - lib
172
190
  required_ruby_version: !ruby/object:Gem::Requirement
191
+ none: false
173
192
  requirements:
174
193
  - - ! '>='
175
194
  - !ruby/object:Gem::Version
176
195
  version: '0'
177
- none: false
178
196
  required_rubygems_version: !ruby/object:Gem::Requirement
197
+ none: false
179
198
  requirements:
180
199
  - - ! '>='
181
200
  - !ruby/object:Gem::Version
182
201
  version: '0'
183
- none: false
184
202
  requirements: []
185
203
  rubyforge_project:
186
- rubygems_version: 1.8.25
204
+ rubygems_version: 1.8.23
187
205
  signing_key:
188
206
  specification_version: 3
189
207
  summary: Open a pry session on any unhandled exceptions