pry-exception_explorer 0.1.1pre1 → 0.1.1pre3

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/.gemtest ADDED
File without changes
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ Makefile
2
+ *.so
3
+ *.o
4
+ *.def
5
+ doc/
6
+ pkg/
7
+ .yardoc/
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ script:
2
+ rake test --trace
3
+
4
+ rvm:
5
+ - 1.9.2
6
+ - 1.9.3
7
+
8
+ notifications:
9
+ irc: "irc.freenode.org#pry"
10
+ recipients:
11
+ - jrmair@gmail.com
12
+
13
+ branches:
14
+ only:
15
+ - master
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ License
2
+ -------
3
+
4
+ (The MIT License)
5
+
6
+ Copyright (c) 2011 John Mair (banisterfiend)
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ 'Software'), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be
17
+ included in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
20
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,76 +1,91 @@
1
- $:.unshift 'lib'
2
-
3
- dlext = Config::CONFIG['DLEXT']
4
- direc = File.dirname(__FILE__)
5
-
6
- PROJECT_NAME = "pry-exception_explorer"
7
-
8
- require 'rake/clean'
9
- require 'rake/gempackagetask'
10
- require "#{PROJECT_NAME}/version"
11
-
12
- CLOBBER.include("**/*~", "**/*#*", "**/*.log")
13
- CLEAN.include("**/*#*", "**/*#*.*", "**/*_flymake*.*", "**/*_flymake",
14
- "**/*.rbc", "**/.#*.*")
15
-
16
- def apply_spec_defaults(s)
17
- s.name = PROJECT_NAME
18
- s.summary = "FIX ME"
19
- s.version = PryExceptionExplorer::VERSION
20
- s.date = Time.now.strftime '%Y-%m-%d'
21
- s.author = "John Mair (banisterfiend)"
22
- s.email = 'jrmair@gmail.com'
23
- s.description = s.summary
24
- s.require_path = 'lib'
25
- s.homepage = "https://github.com/banister/pry-exception_explorer"
26
- s.add_dependency('pry-stack_explorer')
27
- s.files = Dir["lib/**/*.rb", "test/*.rb", "CHANGELOG", "README.md", "Rakefile"]
28
- end
29
-
30
- desc "run pry with plugin enabled"
31
- task :pry do
32
- exec("pry -I#{direc}/lib/ -r #{direc}/lib/#{PROJECT_NAME}")
33
- end
34
-
35
- desc "reinstall gem"
36
- task :reinstall => :gems do
1
+ $:.unshift 'lib'
2
+
3
+ dlext = RbConfig::CONFIG['DLEXT']
4
+ direc = File.dirname(__FILE__)
5
+
6
+ PROJECT_NAME = "pry-exception_explorer"
7
+
8
+ require 'rake/clean'
9
+ require 'rake/gempackagetask'
10
+ require "#{PROJECT_NAME}/version"
11
+
12
+ CLOBBER.include("**/*~", "**/*#*", "**/*.log")
13
+ CLEAN.include("**/*#*", "**/*#*.*", "**/*_flymake*.*", "**/*_flymake",
14
+ "**/*.rbc", "**/.#*.*")
15
+
16
+ def apply_spec_defaults(s)
17
+ s.name = PROJECT_NAME
18
+ s.summary = "Enter the context of exceptions"
19
+ s.version = PryExceptionExplorer::VERSION
20
+ s.date = Time.now.strftime '%Y-%m-%d'
21
+ s.author = "John Mair (banisterfiend)"
22
+ s.email = 'jrmair@gmail.com'
23
+ s.description = s.summary
24
+ s.require_path = 'lib'
25
+ s.homepage = "https://github.com/banister/pry-exception_explorer"
26
+ s.add_dependency('pry-stack_explorer')
27
+ s.add_development_dependency("bacon","~>1.1.0")
28
+ s.add_development_dependency('rake', '~> 0.9')
29
+
30
+ s.files = `git ls-files`.split("\n")
31
+ s.test_files = `git ls-files -- test/*`.split("\n")
32
+ end
33
+
34
+ desc "run pry with plugin enabled"
35
+ task :pry do
36
+ exec("pry -I#{direc}/lib/ -r #{direc}/lib/#{PROJECT_NAME}")
37
+ end
38
+
39
+ desc "reinstall gem"
40
+ task :reinstall => :gems do
41
+ sh "rm -rf ~/.pry-exception_explorer"
37
42
  sh "gem uninstall pry-exception_explorer" rescue nil
38
- sh "gem install #{direc}/pkg/pry-exception_explorer-#{PryExceptionExplorer::VERSION}.gem"
43
+ sh "gem install #{direc}/pkg/pry-exception_explorer-#{PryExceptionExplorer::VERSION}.gem"
44
+ end
45
+
46
+ desc "run tests"
47
+ task :test do
48
+ sh "bacon -Itest -rubygems -a"
49
+ end
50
+
51
+ desc "Build gemspec"
52
+ task :gemspec => "ruby:gemspec"
53
+
54
+ namespace :ruby do
55
+ spec = Gem::Specification.new do |s|
56
+ apply_spec_defaults(s)
57
+ s.platform = Gem::Platform::RUBY
58
+ end
59
+
60
+ Rake::GemPackageTask.new(spec) do |pkg|
61
+ pkg.need_zip = false
62
+ pkg.need_tar = false
63
+ end
64
+
65
+ desc "Generate gemspec file"
66
+ task :gemspec do
67
+ File.open("#{spec.name}.gemspec", "w") do |f|
68
+ f << spec.to_ruby
69
+ end
70
+ end
71
+ end
72
+
73
+ desc "shorthand for :gems task"
74
+ task :gem => :gems
75
+
76
+ desc "build all platform gems at once"
77
+ task :gems => [:clean, :rmgems, "ruby:gem"]
78
+
79
+ desc "remove all platform gems"
80
+ task :rmgems => ["ruby:clobber_package"]
81
+
82
+ desc "build and push latest gems"
83
+ task :pushgems => :gems do
84
+ chdir("#{File.dirname(__FILE__)}/pkg") do
85
+ Dir["*.gem"].each do |gemfile|
86
+ sh "gem push #{gemfile}"
87
+ end
88
+ end
39
89
  end
40
-
41
- desc "run tests"
42
- task :test do
43
- sh "bacon -Itest -rubygems -a"
44
- end
45
-
46
- namespace :ruby do
47
- spec = Gem::Specification.new do |s|
48
- apply_spec_defaults(s)
49
- s.platform = Gem::Platform::RUBY
50
- end
51
-
52
- Rake::GemPackageTask.new(spec) do |pkg|
53
- pkg.need_zip = false
54
- pkg.need_tar = false
55
- end
56
- end
57
-
58
- desc "shorthand for :gems task"
59
- task :gem => :gems
60
-
61
- desc "build all platform gems at once"
62
- task :gems => [:clean, :rmgems, "ruby:gem"]
63
-
64
- desc "remove all platform gems"
65
- task :rmgems => ["ruby:clobber_package"]
66
-
67
- desc "build and push latest gems"
68
- task :pushgems => :gems do
69
- chdir("#{File.dirname(__FILE__)}/pkg") do
70
- Dir["*.gem"].each do |gemfile|
71
- sh "gem push #{gemfile}"
72
- end
73
- end
74
- end
75
-
76
-
90
+
91
+
@@ -0,0 +1,42 @@
1
+ require 'pry-stack_explorer'
2
+
3
+ PryExceptionExplorer::Commands = Pry::CommandSet.new do
4
+
5
+ command "enter-exception", "Enter the context of the last exception" do
6
+ ex = _pry_.last_exception
7
+ if ex && ex.exception_call_stack
8
+ PryStackExplorer.create_and_push_frame_manager(ex.exception_call_stack, _pry_)
9
+ PryStackExplorer.frame_manager(_pry_).user[:exception] = ex
10
+ PryStackExplorer.frame_manager(_pry_).refresh_frame
11
+ elsif ex
12
+ output.puts "Current exception can't be entered! (perhaps a C exception)"
13
+ else
14
+ output.puts "No exception to enter!"
15
+ end
16
+ end
17
+
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!"
25
+ end
26
+ end
27
+
28
+ command "continue-exception", "Attempt to continue the current exception." do
29
+ fm = PryStackExplorer.frame_manager(_pry_)
30
+
31
+ if fm && fm.user[:exception] && fm.user[:inline_exception]
32
+ _pry_.run_command "exit-all PryExceptionExplorer::CONTINUE_INLINE_EXCEPTION"
33
+ PryStackExplorer.pop_frame_manager(_pry_)
34
+ elsif fm && fm.user[:exception] && fm.user[:exception].continuation
35
+ PryStackExplorer.pop_frame_manager(_pry_)
36
+ fm.user[:exception].continue
37
+ else
38
+ output.puts "No exception to continue!"
39
+ end
40
+ end
41
+
42
+ end
@@ -1,9 +1,14 @@
1
- require 'pry_stack_explorer'
1
+ require 'pry-exception_explorer'
2
2
 
3
3
  Pry.config.hooks.delete_hook(:when_started, :save_caller_bindings)
4
4
 
5
+ # default is to capture all exceptions that bubble to the top
6
+ PryExceptionExplorer.intercept { true }
7
+
5
8
  module PryExceptionExplorer
9
+
6
10
  def self.wrap
11
+ self.wrap_active = true
7
12
  yield
8
13
  rescue Exception => ex
9
14
  Pry.config.hooks.add_hook(:when_started, :setup_exception_context) do |binding_stack, _pry_|
@@ -12,6 +17,13 @@ module PryExceptionExplorer
12
17
  PryStackExplorer.frame_manager(_pry_).user[:exception] = ex
13
18
  end
14
19
 
15
- pry
20
+ if ex.should_capture?
21
+ pry
22
+ else
23
+ raise ex
24
+ end
25
+ ensure
26
+ self.wrap_active = false
16
27
  end
17
28
  end
29
+
@@ -0,0 +1,32 @@
1
+ module PryExceptionExplorer
2
+ class LazyFrame
3
+
4
+ # we need to jump over a few irrelevant frames to begin with
5
+ START_FRAME_OFFSET = 5
6
+
7
+ def initialize(frame, frame_counter = 0)
8
+ @frame = frame
9
+ @frame_counter = frame_counter
10
+ end
11
+
12
+ def raw_frame
13
+ @frame
14
+ end
15
+
16
+ def klass
17
+ @frame.eval("self.class")
18
+ end
19
+
20
+ def self
21
+ @frame.eval("self")
22
+ end
23
+
24
+ def method_name
25
+ @frame.eval("__method__")
26
+ end
27
+
28
+ def prev
29
+ LazyFrame.new(binding.of_caller(@frame_counter + START_FRAME_OFFSET), @frame_counter + 1)
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,3 @@
1
1
  module PryExceptionExplorer
2
- VERSION = "0.1.1pre1"
2
+ VERSION = "0.1.1pre3"
3
3
  end
@@ -3,22 +3,78 @@
3
3
 
4
4
  require 'pry-stack_explorer'
5
5
  require "pry-exception_explorer/version"
6
+ require "pry-exception_explorer/lazy_frame"
7
+ require "pry-exception_explorer/commands"
6
8
  require "pry"
7
9
 
8
10
  if RUBY_VERSION =~ /1.9/
9
11
  require 'continuation'
10
12
  end
11
13
 
14
+ module PryExceptionExplorer
15
+ CONTINUE_INLINE_EXCEPTION = Object.new
16
+
17
+ class << self
18
+ def wrap_active=(v)
19
+ Thread.current[:__pry_exception_explorer_wrap__] = v
20
+ end
21
+
22
+ def wrap_active
23
+ !!Thread.current[:__pry_exception_explorer_wrap__]
24
+ end
25
+
26
+ alias_method :wrap_active?, :wrap_active
27
+ end
28
+
29
+ self.wrap_active = false
30
+
31
+ def self.should_capture_exception?(ex)
32
+ true
33
+ end
34
+
35
+ def self.intercept(&block)
36
+ Thread.current[:__pry_exception_explorer_intercept_block__] = block
37
+ end
38
+
39
+ def self.intercept_block
40
+ Thread.current[:__pry_exception_explorer_intercept_block__]
41
+ end
42
+
43
+ def self.should_capture_exception?(ex, frame)
44
+ if intercept_block
45
+ intercept_block.call(LazyFrame.new(frame), ex)
46
+ else
47
+ false
48
+ end
49
+ end
50
+
51
+ def self.enter_exception_inline(ex)
52
+ _pry_ = Pry.new
53
+
54
+ Pry.initial_session_setup
55
+ PryStackExplorer.create_and_push_frame_manager(ex.exception_call_stack, _pry_)
56
+ PryStackExplorer.frame_manager(_pry_).user[:exception] = ex
57
+ PryStackExplorer.frame_manager(_pry_).user[:inline_exception] = true
58
+ _pry_.repl(ex.exception_call_stack.first)
59
+
60
+ ensure
61
+ PryStackExplorer.clear_frame_managers(_pry_)
62
+ end
63
+ end
64
+
12
65
  class Exception
13
66
  NoContinuation = Class.new(StandardError)
14
67
 
15
68
  attr_accessor :continuation
16
69
  attr_accessor :exception_call_stack
70
+ attr_accessor :should_capture
17
71
 
18
72
  def continue
19
73
  raise NoContinuation unless continuation.respond_to?(:call)
20
74
  continuation.call
21
75
  end
76
+
77
+ alias_method :should_capture?, :should_capture
22
78
  end
23
79
 
24
80
  class Object
@@ -30,51 +86,31 @@ class Object
30
86
 
31
87
  ex = exception.exception(string)
32
88
  ex.set_backtrace(array)
33
- ex.exception_call_stack = binding.callers.tap(&:shift)
34
-
35
- callcc do |cc|
36
- ex.continuation = cc
37
- super(ex)
38
- end
39
- end
40
- end
41
89
 
42
- PryExceptionExplorer::Commands = Pry::CommandSet.new do
90
+ if PryExceptionExplorer.should_capture_exception?(ex, binding.of_caller(1))
91
+ ex.exception_call_stack = binding.callers.tap(&:shift)
92
+ ex.should_capture = true
43
93
 
44
- command "enter-exception", "Enter the context of the last exception" do
45
- ex = _pry_.last_exception
46
- if ex && ex.exception_call_stack
47
- PryStackExplorer.create_and_push_frame_manager(ex.exception_call_stack, _pry_)
48
- PryStackExplorer.frame_manager(_pry_).user[:exception] = ex
49
- PryStackExplorer.frame_manager(_pry_).refresh_frame
50
- elsif ex
51
- output.puts "Current exception can't be entered! (perhaps a C exception)"
52
- else
53
- output.puts "No exception to enter!"
94
+ if !PryExceptionExplorer.wrap_active?
95
+ retval = PryExceptionExplorer.enter_exception_inline(ex)
96
+ end
54
97
  end
55
- end
56
98
 
57
- command "exit-exception", "Leave the context of the current exception." do
58
- fm = PryStackExplorer.frame_manager(_pry_)
59
- if fm && fm.user[:exception]
60
- PryStackExplorer.pop_frame_manager(_pry_)
61
- PryStackExplorer.frame_manager(_pry_).refresh_frame
62
- else
63
- output.puts "You are not in an exception!"
99
+ if retval != PryExceptionExplorer::CONTINUE_INLINE_EXCEPTION
100
+ callcc do |cc|
101
+ ex.continuation = cc
102
+ super(ex)
103
+ end
64
104
  end
65
105
  end
106
+ end
66
107
 
67
- command "continue-exception", "Attempt to continue the current exception." do
68
- fm = PryStackExplorer.frame_manager(_pry_)
69
108
 
70
- if fm && fm.user[:exception] && fm.user[:exception].continuation
71
- PryStackExplorer.pop_frame_manager(_pry_)
72
- fm.user[:exception].continue
73
- else
74
- output.puts "No exception to continue!"
75
- end
76
- end
109
+ # Let exceptions get caught by Pry REPL loop (i.e dont catch
110
+ # immediately at point of 'raise')
111
+ PryExceptionExplorer.wrap_active = true
77
112
 
78
- end
113
+ # default is to capture all exceptions that bubble to the top
114
+ PryExceptionExplorer.intercept { true }
79
115
 
80
116
  Pry.config.commands.import PryExceptionExplorer::Commands
@@ -0,0 +1,36 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "pry-exception_explorer"
5
+ s.version = "0.1.1pre3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["John Mair (banisterfiend)"]
9
+ s.date = "2012-01-05"
10
+ s.description = "Enter the context of exceptions"
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"]
13
+ s.homepage = "https://github.com/banister/pry-exception_explorer"
14
+ s.require_paths = ["lib"]
15
+ s.rubygems_version = "1.8.11"
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"]
18
+
19
+ if s.respond_to? :specification_version then
20
+ s.specification_version = 3
21
+
22
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
23
+ s.add_runtime_dependency(%q<pry-stack_explorer>, [">= 0"])
24
+ s.add_development_dependency(%q<bacon>, ["~> 1.1.0"])
25
+ s.add_development_dependency(%q<rake>, ["~> 0.9"])
26
+ else
27
+ s.add_dependency(%q<pry-stack_explorer>, [">= 0"])
28
+ s.add_dependency(%q<bacon>, ["~> 1.1.0"])
29
+ s.add_dependency(%q<rake>, ["~> 0.9"])
30
+ end
31
+ else
32
+ s.add_dependency(%q<pry-stack_explorer>, [">= 0"])
33
+ s.add_dependency(%q<bacon>, ["~> 1.1.0"])
34
+ s.add_dependency(%q<rake>, ["~> 0.9"])
35
+ end
36
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,101 @@
1
+ require 'rubygems'
2
+
3
+ unless Object.const_defined? 'PryExceptionExplorer'
4
+ $:.unshift File.expand_path '../../lib', __FILE__
5
+ require 'pry-exception_explorer'
6
+ end
7
+
8
+ require 'bacon'
9
+
10
+ puts "Testing pry-exception_explorer version #{PryExceptionExplorer::VERSION}..."
11
+ puts "Ruby version: #{RUBY_VERSION}"
12
+
13
+ EE = PryExceptionExplorer
14
+
15
+ class Ratty
16
+ def ratty
17
+ Weasel.new.weasel
18
+ end
19
+ end
20
+
21
+ class Weasel
22
+ def weasel
23
+ Toad.new.toad
24
+ end
25
+ end
26
+
27
+ class Toad
28
+ def toad
29
+ raise "toad hall"
30
+ end
31
+ end
32
+
33
+ class << Pry
34
+ alias_method :orig_reset_defaults, :reset_defaults
35
+ def reset_defaults
36
+ orig_reset_defaults
37
+
38
+ Pry.color = false
39
+ Pry.pager = false
40
+ Pry.config.should_load_rc = false
41
+ Pry.config.plugins.enabled = false
42
+ Pry.config.history.should_load = false
43
+ Pry.config.history.should_save = false
44
+ Pry.config.auto_indent = false
45
+ Pry.config.hooks = Pry::Hooks.new
46
+ Pry.config.collision_warning = false
47
+ end
48
+ end
49
+
50
+ Pry.reset_defaults
51
+
52
+ class InputTester
53
+ def initialize(*actions)
54
+ if actions.last.is_a?(Hash) && actions.last.keys == [:history]
55
+ @hist = actions.pop[:history]
56
+ end
57
+ @orig_actions = actions.dup
58
+ @actions = actions
59
+ end
60
+
61
+ def readline(*)
62
+ @actions.shift.tap{ |line| @hist << line if @hist }
63
+ end
64
+
65
+ def rewind
66
+ @actions = @orig_actions.dup
67
+ end
68
+ end
69
+
70
+ # Set I/O streams.
71
+ #
72
+ # Out defaults to an anonymous StringIO.
73
+ #
74
+ def redirect_pry_io(new_in, new_out = StringIO.new)
75
+ old_in = Pry.input
76
+ old_out = Pry.output
77
+
78
+ Pry.input = new_in
79
+ Pry.output = new_out
80
+ begin
81
+ yield
82
+ ensure
83
+ Pry.input = old_in
84
+ Pry.output = old_out
85
+ end
86
+ end
87
+
88
+ def mock_pry(*args)
89
+
90
+ binding = args.first.is_a?(Binding) ? args.shift : binding()
91
+
92
+ input = InputTester.new(*args)
93
+ output = StringIO.new
94
+
95
+ redirect_pry_io(input, output) do
96
+ binding.pry
97
+ end
98
+
99
+ output.string
100
+ end
101
+
@@ -0,0 +1,159 @@
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
@@ -0,0 +1,29 @@
1
+ require 'helper'
2
+
3
+ describe PryExceptionExplorer do
4
+
5
+ describe "Exceptions caught by Pry" do
6
+ describe "enter-exception" do
7
+ it "should be able to enter an exception caught by pry" do
8
+
9
+ PryExceptionExplorer.intercept { true }
10
+
11
+ # there are 3 types of situations where exception_explorer is invoked:
12
+ # 1. when 'wrap' is used, i.e only exceptions that bubble to
13
+ # the top are intercepted.
14
+ # 2. when exceptions are intercepted 'inline' (i.e dropped
15
+ # into pry directly from `raise` itself)
16
+ # 3. exceptions are caught by pry and entered into by using
17
+ # the 'enter-exception' command
18
+ # The case of 1. and 3. are actually very similar, but in
19
+ # 3. the exception never bubbles to the top as it's caught by
20
+ # pry instead; also in 3. a pry session is not started
21
+ # automatically, the user must explicitly type
22
+ # `enter-exception` to start the session.
23
+ #
24
+ # This test is for type 3.
25
+ mock_pry("Ratty.new.ratty", "enter-exception", "show-stack", "exit").should =~ /toad.*?weasel.*?ratty/m
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,160 @@
1
+ require 'helper'
2
+
3
+ require 'pry-exception_explorer/exception_wrap'
4
+
5
+ CaughtException = Class.new(StandardError)
6
+ UncaughtException = Class.new(StandardError)
7
+
8
+ describe PryExceptionExplorer do
9
+
10
+ before do
11
+ Pry.config.input = StringIO.new("exit :caught\n")
12
+ Pry.config.output = StringIO.new
13
+ end
14
+
15
+ after do
16
+ Pry.config.hooks.clear(:when_started)
17
+ end
18
+
19
+ describe "PryExceptionExplorer.wrap" do
20
+
21
+ it 'should default to capturing ALL exceptions' do
22
+ PryExceptionExplorer.wrap do
23
+ raise CaughtException, "catch me if u can"
24
+ end.should == :caught
25
+ end
26
+
27
+ it 'should NOT capture rescued exceptions' do
28
+ o = Object.new
29
+ def o.evil_fish
30
+ Ratty.new.ratty
31
+ rescue Exception
32
+ end
33
+
34
+ PryExceptionExplorer.intercept { true }
35
+
36
+ PryExceptionExplorer.wrap do
37
+ o.evil_fish
38
+ end.should.not == :caught
39
+ end
40
+
41
+ it 'should have the full callstack attached to exception' do
42
+ PryExceptionExplorer.intercept { |frame, ex| frame.method_name == :toad }
43
+
44
+ PryExceptionExplorer.wrap do
45
+ begin
46
+ Ratty.new.ratty
47
+ rescue Exception => ex
48
+ ex.exception_call_stack[0..2].map { |b| b.eval("__method__") }.should == [:toad, :weasel, :ratty]
49
+ end
50
+ end
51
+ end
52
+
53
+ it 'should NOT have callstack attached if exception not matched' do
54
+ PryExceptionExplorer.intercept { |frame, ex| false }
55
+
56
+ begin
57
+ PryExceptionExplorer.wrap do
58
+ raise UncaughtException, "Catch me if you can't.."
59
+ end
60
+ rescue UncaughtException => ex
61
+ ex.exception_call_stack.should == nil
62
+ end
63
+ end
64
+
65
+ describe "PryExceptionExplorer.intercept with wrapped exceptions" do
66
+ describe "klass" do
67
+ describe "first frame" do
68
+ it 'should catch a matched exception based on klass' do
69
+ PryExceptionExplorer.intercept { |frame, ex| frame.klass == Toad }
70
+
71
+ PryExceptionExplorer.wrap do
72
+ Ratty.new.ratty
73
+ end.should == :caught
74
+ end
75
+
76
+ it 'should NOT catch an unmatched exception' do
77
+ PryExceptionExplorer.intercept { |frame, ex| frame.klass == Weasel }
78
+
79
+ begin
80
+ PryExceptionExplorer.wrap do
81
+ raise UncaughtException, "Catch me if you can't.."
82
+ end
83
+ rescue Exception => ex
84
+ ex.is_a?(UncaughtException).should == true
85
+ end
86
+ end
87
+ end
88
+
89
+ describe "third frame" do
90
+ it 'should catch a matched exception' do
91
+ PryExceptionExplorer.intercept { |frame, ex| frame.prev.prev.klass == Ratty }
92
+
93
+ PryExceptionExplorer.wrap do
94
+ Ratty.new.ratty
95
+ end.should == :caught
96
+ end
97
+
98
+ it 'should NOT catch an unmatched exception' do
99
+ PryExceptionExplorer.intercept { |frame, ex| frame.prev.prev.klass == Weasel }
100
+
101
+ begin
102
+ PryExceptionExplorer.wrap do
103
+ raise UncaughtException, "Catch me if you can't.."
104
+ end
105
+ rescue Exception => ex
106
+ ex.is_a?(UncaughtException).should == true
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ describe "method_name" do
113
+ describe "first frame" do
114
+ it 'should catch a matched exception' do
115
+ PryExceptionExplorer.intercept { |frame, ex| frame.method_name == :toad }
116
+
117
+ PryExceptionExplorer.wrap do
118
+ Ratty.new.ratty
119
+ end.should == :caught
120
+ end
121
+
122
+ it 'should NOT catch an unmatched exception' do
123
+ PryExceptionExplorer.intercept { |frame, ex| frame.method_name == :weasel }
124
+
125
+ begin
126
+ PryExceptionExplorer.wrap do
127
+ raise UncaughtException, "Catch me if you can't.."
128
+ end
129
+ rescue Exception => ex
130
+ ex.is_a?(UncaughtException).should == true
131
+ end
132
+ end
133
+ end
134
+
135
+ describe "third frame" do
136
+ it 'should catch a matched exception' do
137
+ PryExceptionExplorer.intercept { |frame, ex| frame.prev.prev.method_name == :ratty }
138
+
139
+ PryExceptionExplorer.wrap do
140
+ Ratty.new.ratty
141
+ end.should == :caught
142
+ end
143
+
144
+ it 'should NOT catch an unmatched exception' do
145
+ PryExceptionExplorer.intercept { |frame, ex| frame.prev.prev.method_name == :weasel }
146
+
147
+ begin
148
+ PryExceptionExplorer.wrap do
149
+ raise UncaughtException, "Catch me if you can't.."
150
+ end
151
+ rescue Exception => ex
152
+ ex.is_a?(UncaughtException).should == true
153
+ end
154
+ end
155
+ end
156
+
157
+ end
158
+ end
159
+ end
160
+ end
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.1pre1
5
+ version: 0.1.1pre3
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: 2011-12-17 00:00:00 Z
13
+ date: 2012-01-05 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: pry-stack_explorer
@@ -23,7 +23,29 @@ dependencies:
23
23
  version: "0"
24
24
  type: :runtime
25
25
  version_requirements: *id001
26
- description: FIX ME
26
+ - !ruby/object:Gem::Dependency
27
+ name: bacon
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.1.0
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: "0.9"
46
+ type: :development
47
+ version_requirements: *id003
48
+ description: Enter the context of exceptions
27
49
  email: jrmair@gmail.com
28
50
  executables: []
29
51
 
@@ -32,15 +54,27 @@ extensions: []
32
54
  extra_rdoc_files: []
33
55
 
34
56
  files:
57
+ - .gemtest
58
+ - .gitignore
59
+ - .travis.yml
60
+ - .yardopts
61
+ - CHANGELOG
62
+ - Gemfile
63
+ - LICENSE
64
+ - README.md
65
+ - Rakefile
66
+ - lib/pry-exception_explorer.rb
35
67
  - lib/pry-exception_explorer/cli.rb
68
+ - lib/pry-exception_explorer/commands.rb
36
69
  - lib/pry-exception_explorer/exception_wrap.rb
70
+ - lib/pry-exception_explorer/lazy_frame.rb
37
71
  - lib/pry-exception_explorer/shim_builder.rb
38
72
  - lib/pry-exception_explorer/version.rb
39
- - lib/pry-exception_explorer.rb
40
- - test/test.rb
41
- - CHANGELOG
42
- - README.md
43
- - Rakefile
73
+ - pry-exception_explorer.gemspec
74
+ - test/helper.rb
75
+ - test/test_exception_explorer.rb
76
+ - test/test_exceptions_in_pry.rb
77
+ - test/test_wrapped_exceptions.rb
44
78
  homepage: https://github.com/banister/pry-exception_explorer
45
79
  licenses: []
46
80
 
@@ -67,6 +101,9 @@ rubyforge_project:
67
101
  rubygems_version: 1.8.11
68
102
  signing_key:
69
103
  specification_version: 3
70
- summary: FIX ME
71
- test_files: []
72
-
104
+ summary: Enter the context of exceptions
105
+ test_files:
106
+ - test/helper.rb
107
+ - test/test_exception_explorer.rb
108
+ - test/test_exceptions_in_pry.rb
109
+ - test/test_wrapped_exceptions.rb
data/test/test.rb DELETED
@@ -1,12 +0,0 @@
1
- direc = File.dirname(__FILE__)
2
-
3
- require 'rubygems'
4
- require "#{direc}/../lib/pry-exception_explorer"
5
- require 'bacon'
6
-
7
- puts "Testing pry-exception_explorer version #{PryExceptionExplorer::VERSION}..."
8
- puts "Ruby version: #{RUBY_VERSION}"
9
-
10
- describe PryExceptionExplorer do
11
- end
12
-