pry-exception_explorer 0.1.1pre1 → 0.1.1pre3

Sign up to get free protection for your applications and to get access to all the features.
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
-