summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mair <jrmair@gmail.com>2012-12-12 02:45:54 +0100
committerJohn Mair <jrmair@gmail.com>2012-12-12 02:48:30 +0100
commitf2d6a926f9e3cb0de0b36733168df2baf440878f (patch)
treea5c41ed5bb67b1254ebd5bbf617d18c7f1db7006
parent74498216571527626c589a074ad8b46eea4e4fb1 (diff)
downloadpry-f2d6a926f9e3cb0de0b36733168df2baf440878f.tar.gz
add Pry::WrappedModule#super
It's useful having Pry::WrappedModule and Pry::Method share as much interface as possible so that methods can be indifferent to which one they get (a la show-source / edit)
-rw-r--r--lib/pry/wrapped_module.rb18
-rw-r--r--spec/wrapped_module_spec.rb56
2 files changed, 73 insertions, 1 deletions
diff --git a/lib/pry/wrapped_module.rb b/lib/pry/wrapped_module.rb
index 693ebee4..4791d63c 100644
--- a/lib/pry/wrapped_module.rb
+++ b/lib/pry/wrapped_module.rb
@@ -204,6 +204,24 @@ class Pry
!!(defined?(YARD) && YARD::Registry.at(name))
end
+ # @param [Fixnum] times How far to travel up the ancestor chain.
+ # @return [Pry::WrappedModule, nil] The wrapped module that is the
+ # superclass.
+ # When `self` is a `Module` then return the
+ # nth ancestor, otherwise (in the case of classes) return the
+ # nth ancestor that is a class.
+ def super(times=1)
+ return self if times.zero?
+
+ if wrapped.is_a?(Class)
+ sup = ancestors.select { |v| v.is_a?(Class) }[times]
+ else
+ sup = ancestors[times]
+ end
+
+ Pry::WrappedModule(sup) if sup
+ end
+
private
# @return [Pry::WrappedModule::Candidate] The candidate of rank 0,
diff --git a/spec/wrapped_module_spec.rb b/spec/wrapped_module_spec.rb
index 91445ef3..db62ca40 100644
--- a/spec/wrapped_module_spec.rb
+++ b/spec/wrapped_module_spec.rb
@@ -168,5 +168,59 @@ describe Pry::WrappedModule do
Pry::WrappedModule.new(class << Object; self; end).singleton_instance.should.equal?(Object)
end
end
-end
+ describe ".super" do
+ describe "receiver is a class" do
+ before do
+ @a = Class.new
+ @m = Module.new
+ @b = Class.new(@a)
+ @b.send(:include, @m)
+ @c = Class.new(@b)
+ end
+
+ it 'should return superclass for a wrapped class' do
+ Pry::WrappedModule(@c).super.wrapped.should == @b
+ end
+
+ it 'should return nth superclass for a wrapped class' do
+ d = Class.new(@c)
+ Pry::WrappedModule(d).super(2).wrapped.should == @b
+ end
+
+ it 'should ignore modules when retrieving nth superclass' do
+ Pry::WrappedModule(@c).super(2).wrapped.should == @a
+ end
+
+ it 'should return nil when no nth superclass exists' do
+ Pry::WrappedModule(@c).super(10).should == nil
+ end
+
+ it 'should return self when .super(0) is used' do
+ c = Pry::WrappedModule(@c)
+ c.super(0).should == c
+ end
+ end
+
+ describe "receiver is a module" do
+ before do
+ @m1 = Module.new
+ @m2 = Module.new.tap { |v| v.send(:include, @m1) }
+ @m3 = Module.new.tap { |v| v.send(:include, @m2) }
+ end
+
+ it 'should not ignore modules when retrieving supers' do
+ Pry::WrappedModule(@m3).super.wrapped.should == @m2
+ end
+
+ it 'should retrieve nth super' do
+ Pry::WrappedModule(@m3).super(2).wrapped.should == @m1
+ end
+
+ it 'should return self when .super(0) is used' do
+ m = Pry::WrappedModule(@m1)
+ m.super(0).should == m
+ end
+ end
+ end
+end