aboutsummaryrefslogtreecommitdiffstats
path: root/spec/rubyspec/core/unboundmethod
diff options
context:
space:
mode:
Diffstat (limited to 'spec/rubyspec/core/unboundmethod')
-rw-r--r--spec/rubyspec/core/unboundmethod/arity_spec.rb207
-rw-r--r--spec/rubyspec/core/unboundmethod/bind_spec.rb51
-rw-r--r--spec/rubyspec/core/unboundmethod/clone_spec.rb12
-rw-r--r--spec/rubyspec/core/unboundmethod/eql_spec.rb5
-rw-r--r--spec/rubyspec/core/unboundmethod/equal_value_spec.rb101
-rw-r--r--spec/rubyspec/core/unboundmethod/fixtures/classes.rb86
-rw-r--r--spec/rubyspec/core/unboundmethod/hash_spec.rb17
-rw-r--r--spec/rubyspec/core/unboundmethod/inspect_spec.rb7
-rw-r--r--spec/rubyspec/core/unboundmethod/name_spec.rb15
-rw-r--r--spec/rubyspec/core/unboundmethod/owner_spec.rb26
-rw-r--r--spec/rubyspec/core/unboundmethod/parameters_spec.rb5
-rw-r--r--spec/rubyspec/core/unboundmethod/shared/to_s.rb25
-rw-r--r--spec/rubyspec/core/unboundmethod/source_location_spec.rb52
-rw-r--r--spec/rubyspec/core/unboundmethod/super_method_spec.rb28
-rw-r--r--spec/rubyspec/core/unboundmethod/to_s_spec.rb7
15 files changed, 644 insertions, 0 deletions
diff --git a/spec/rubyspec/core/unboundmethod/arity_spec.rb b/spec/rubyspec/core/unboundmethod/arity_spec.rb
new file mode 100644
index 0000000000..a804235b70
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/arity_spec.rb
@@ -0,0 +1,207 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "UnboundMethod#arity" do
+ SpecEvaluate.desc = "for method definition"
+
+ context "returns zero" do
+ evaluate <<-ruby do
+ def m() end
+ ruby
+
+ method(:m).unbind.arity.should == 0
+ end
+
+ evaluate <<-ruby do
+ def n(&b) end
+ ruby
+
+ method(:n).unbind.arity.should == 0
+ end
+ end
+
+ context "returns positive values" do
+ evaluate <<-ruby do
+ def m(a) end
+ def n(a, b) end
+ def o(a, b, c) end
+ def p(a, b, c, d) end
+ ruby
+
+ method(:m).unbind.arity.should == 1
+ method(:n).unbind.arity.should == 2
+ method(:o).unbind.arity.should == 3
+ method(:p).unbind.arity.should == 4
+ end
+
+ evaluate <<-ruby do
+ def m(a:) end
+ def n(a:, b:) end
+ def o(a: 1, b:, c:, d: 2) end
+ ruby
+
+ method(:m).unbind.arity.should == 1
+ method(:n).unbind.arity.should == 1
+ method(:o).unbind.arity.should == 1
+ end
+
+ evaluate <<-ruby do
+ def m(a, b:) end
+ def n(a, b:, &l) end
+ ruby
+
+ method(:m).unbind.arity.should == 2
+ method(:n).unbind.arity.should == 2
+ end
+
+ evaluate <<-ruby do
+ def m(a, b, c:, d: 1) end
+ def n(a, b, c:, d: 1, **k, &l) end
+ ruby
+
+ method(:m).unbind.arity.should == 3
+ method(:n).unbind.arity.should == 3
+ end
+ end
+
+ context "returns negative values" do
+ evaluate <<-ruby do
+ def m(a=1) end
+ def n(a=1, b=2) end
+ ruby
+
+ method(:m).unbind.arity.should == -1
+ method(:n).unbind.arity.should == -1
+ end
+
+ evaluate <<-ruby do
+ def m(a, b=1) end
+ def n(a, b, c=1, d=2) end
+ ruby
+
+ method(:m).unbind.arity.should == -2
+ method(:n).unbind.arity.should == -3
+ end
+
+ evaluate <<-ruby do
+ def m(a=1, *b) end
+ def n(a=1, b=2, *c) end
+ ruby
+
+ method(:m).unbind.arity.should == -1
+ method(:n).unbind.arity.should == -1
+ end
+
+ evaluate <<-ruby do
+ def m(*) end
+ def n(*a) end
+ ruby
+
+ method(:m).unbind.arity.should == -1
+ method(:n).unbind.arity.should == -1
+ end
+
+ evaluate <<-ruby do
+ def m(a, *) end
+ def n(a, *b) end
+ def o(a, b, *c) end
+ def p(a, b, c, *d) end
+ ruby
+
+ method(:m).unbind.arity.should == -2
+ method(:n).unbind.arity.should == -2
+ method(:o).unbind.arity.should == -3
+ method(:p).unbind.arity.should == -4
+ end
+
+ evaluate <<-ruby do
+ def m(*a, b) end
+ def n(*a, b, c) end
+ def o(*a, b, c, d) end
+ ruby
+
+ method(:m).unbind.arity.should == -2
+ method(:n).unbind.arity.should == -3
+ method(:o).unbind.arity.should == -4
+ end
+
+ evaluate <<-ruby do
+ def m(a, *b, c) end
+ def n(a, b, *c, d, e) end
+ ruby
+
+ method(:m).unbind.arity.should == -3
+ method(:n).unbind.arity.should == -5
+ end
+
+ evaluate <<-ruby do
+ def m(a, b=1, c=2, *d, e, f) end
+ def n(a, b, c=1, *d, e, f, g) end
+ ruby
+
+ method(:m).unbind.arity.should == -4
+ method(:n).unbind.arity.should == -6
+ end
+
+ evaluate <<-ruby do
+ def m(a: 1) end
+ def n(a: 1, b: 2) end
+ ruby
+
+ method(:m).unbind.arity.should == -1
+ method(:n).unbind.arity.should == -1
+ end
+
+ evaluate <<-ruby do
+ def m(a=1, b: 2) end
+ def n(*a, b: 1) end
+ def o(a=1, b: 2) end
+ def p(a=1, *b, c: 2, &l) end
+ ruby
+
+ method(:m).unbind.arity.should == -1
+ method(:n).unbind.arity.should == -1
+ method(:o).unbind.arity.should == -1
+ method(:p).unbind.arity.should == -1
+ end
+
+ evaluate <<-ruby do
+ def m(**k, &l) end
+ def n(*a, **k) end
+ def o(a: 1, b: 2, **k) end
+ ruby
+
+ method(:m).unbind.arity.should == -1
+ method(:n).unbind.arity.should == -1
+ method(:o).unbind.arity.should == -1
+ end
+
+ evaluate <<-ruby do
+ def m(a=1, *b, c:, d: 2, **k, &l) end
+ ruby
+
+ method(:m).unbind.arity.should == -2
+ end
+
+ evaluate <<-ruby do
+ def m(a, b=1, *c, d, e:, f: 2, **k, &l) end
+ def n(a, b=1, *c, d:, e:, f: 2, **k, &l) end
+ def o(a=0, b=1, *c, d, e:, f: 2, **k, &l) end
+ def p(a=0, b=1, *c, d:, e:, f: 2, **k, &l) end
+ ruby
+
+ method(:m).unbind.arity.should == -4
+ method(:n).unbind.arity.should == -3
+ method(:o).unbind.arity.should == -3
+ method(:p).unbind.arity.should == -2
+ end
+ end
+
+ context "for a Method generated by respond_to_missing?" do
+ it "returns -1" do
+ obj = mock("method arity respond_to_missing")
+ obj.should_receive(:respond_to_missing?).and_return(true)
+
+ obj.method(:m).unbind.arity.should == -1
+ end
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/bind_spec.rb b/spec/rubyspec/core/unboundmethod/bind_spec.rb
new file mode 100644
index 0000000000..3f7a7bf3ac
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/bind_spec.rb
@@ -0,0 +1,51 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+
+describe "UnboundMethod#bind" do
+ before :each do
+ @normal_um = UnboundMethodSpecs::Methods.new.method(:foo).unbind
+ @parent_um = UnboundMethodSpecs::Parent.new.method(:foo).unbind
+ @child1_um = UnboundMethodSpecs::Child1.new.method(:foo).unbind
+ @child2_um = UnboundMethodSpecs::Child2.new.method(:foo).unbind
+ end
+
+ it "raises TypeError if object is not kind_of? the Module the method defined in" do
+ lambda { @normal_um.bind(UnboundMethodSpecs::B.new) }.should raise_error(TypeError)
+ end
+
+ it "returns Method for any object that is kind_of? the Module method was extracted from" do
+ @normal_um.bind(UnboundMethodSpecs::Methods.new).should be_kind_of(Method)
+ end
+
+ it "returns Method on any object when UnboundMethod is unbound from a module" do
+ UnboundMethodSpecs::Mod.instance_method(:from_mod).bind(Object.new).should be_kind_of(Method)
+ end
+
+ it "returns Method returned for obj is equal to one directly returned by obj.method" do
+ obj = UnboundMethodSpecs::Methods.new
+ @normal_um.bind(obj).should == obj.method(:foo)
+ end
+
+ it "returns a callable method" do
+ obj = UnboundMethodSpecs::Methods.new
+ @normal_um.bind(obj).call.should == obj.foo
+ end
+
+ it "binds a Parent's class method to any Child's class methods" do
+ m = UnboundMethodSpecs::Parent.method(:class_method).unbind.bind(UnboundMethodSpecs::Child1)
+ m.should be_an_instance_of(Method)
+ m.call.should == "I am UnboundMethodSpecs::Child1"
+ end
+
+ it "will raise when binding a an object singleton's method to another object" do
+ other = UnboundMethodSpecs::Parent.new
+ p = UnboundMethodSpecs::Parent.new
+ class << p
+ def singleton_method
+ :single
+ end
+ end
+ um = p.method(:singleton_method).unbind
+ lambda{ um.bind(other) }.should raise_error(TypeError)
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/clone_spec.rb b/spec/rubyspec/core/unboundmethod/clone_spec.rb
new file mode 100644
index 0000000000..2f3fd834ad
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/clone_spec.rb
@@ -0,0 +1,12 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+
+describe "UnboundMethod#clone" do
+ it "returns a copy of the UnboundMethod" do
+ um1 = UnboundMethodSpecs::Methods.instance_method(:foo)
+ um2 = um1.clone
+
+ (um1 == um2).should == true
+ um1.bind(UnboundMethodSpecs::Methods.new).call.should == um2.bind(UnboundMethodSpecs::Methods.new).call
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/eql_spec.rb b/spec/rubyspec/core/unboundmethod/eql_spec.rb
new file mode 100644
index 0000000000..8e91ef375e
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/eql_spec.rb
@@ -0,0 +1,5 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "UnboundMethod#eql?" do
+ it "needs to be reviewed for spec completeness"
+end
diff --git a/spec/rubyspec/core/unboundmethod/equal_value_spec.rb b/spec/rubyspec/core/unboundmethod/equal_value_spec.rb
new file mode 100644
index 0000000000..de141254c1
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/equal_value_spec.rb
@@ -0,0 +1,101 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+
+context "Creating UnboundMethods" do
+ specify "there is no difference between Method#unbind and Module#instance_method" do
+ UnboundMethodSpecs::Methods.instance_method(:foo).should be_kind_of(UnboundMethod)
+ UnboundMethodSpecs::Methods.new.method(:foo).unbind.should be_kind_of(UnboundMethod)
+ end
+end
+
+describe "UnboundMethod#==" do
+ before :all do
+ @from_module = UnboundMethodSpecs::Methods.instance_method(:foo)
+ @from_unbind = UnboundMethodSpecs::Methods.new.method(:foo).unbind
+
+ @with_block = UnboundMethodSpecs::Methods.instance_method(:with_block)
+
+ @includee = UnboundMethodSpecs::Mod.instance_method(:from_mod)
+ @includer = UnboundMethodSpecs::Methods.instance_method(:from_mod)
+
+ @alias_1 = UnboundMethodSpecs::Methods.instance_method(:alias_1)
+ @alias_2 = UnboundMethodSpecs::Methods.instance_method(:alias_2)
+
+ @original_body = UnboundMethodSpecs::Methods.instance_method(:original_body)
+ @identical_body = UnboundMethodSpecs::Methods.instance_method(:identical_body)
+
+ @parent = UnboundMethodSpecs::Parent.instance_method(:foo)
+ @child1 = UnboundMethodSpecs::Child1.instance_method(:foo)
+ @child2 = UnboundMethodSpecs::Child2.instance_method(:foo)
+
+ @child1_alt = UnboundMethodSpecs::Child1.instance_method(:foo)
+
+ @discard_1 = UnboundMethodSpecs::Methods.instance_method(:discard_1)
+ @discard_2 = UnboundMethodSpecs::Methods.instance_method(:discard_2)
+
+ @method_one = UnboundMethodSpecs::Methods.instance_method(:one)
+ @method_two = UnboundMethodSpecs::Methods.instance_method(:two)
+ end
+
+ it "returns true if objects refer to the same method" do
+ (@from_module == @from_module).should == true
+ (@from_unbind == @from_unbind).should == true
+ (@from_module == @from_unbind).should == true
+ (@from_unbind == @from_module).should == true
+ (@with_block == @with_block).should == true
+ end
+
+ it "returns true if either is an alias for the other" do
+ (@from_module == @alias_1).should == true
+ (@alias_1 == @from_module).should == true
+ end
+
+ it "returns true if both are aliases for a third method" do
+ (@from_module == @alias_1).should == true
+ (@alias_1 == @from_module).should == true
+
+ (@from_module == @alias_2).should == true
+ (@alias_2 == @from_module).should == true
+
+ (@alias_1 == @alias_2).should == true
+ (@alias_2 == @alias_1).should == true
+ end
+
+ it "returns true if same method is extracted from the same subclass" do
+ (@child1 == @child1_alt).should == true
+ (@child1_alt == @child1).should == true
+ end
+
+ it "returns false if UnboundMethods are different methods" do
+ (@method_one == @method_two).should == false
+ (@method_two == @method_one).should == false
+ end
+
+ it "returns false if both have identical body but are not the same" do
+ (@original_body == @identical_body).should == false
+ (@identical_body == @original_body).should == false
+ end
+
+ it "returns false if same method but one extracted from a subclass" do
+ (@parent == @child1).should == false
+ (@child1 == @parent).should == false
+ end
+
+ it "returns false if same method but extracted from two different subclasses" do
+ (@child2 == @child1).should == false
+ (@child1 == @child2).should == false
+ end
+
+ it "returns false if methods are the same but added from an included Module" do
+ (@includee == @includer).should == false
+ (@includer == @includee).should == false
+ end
+
+ it "returns false if both have same Module, same name, identical body but not the same" do
+ class UnboundMethodSpecs::Methods
+ def discard_1; :discard; end
+ end
+
+ (@discard_1 == UnboundMethodSpecs::Methods.instance_method(:discard_1)).should == false
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/fixtures/classes.rb b/spec/rubyspec/core/unboundmethod/fixtures/classes.rb
new file mode 100644
index 0000000000..43e21916bf
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/fixtures/classes.rb
@@ -0,0 +1,86 @@
+module UnboundMethodSpecs
+
+
+ class SourceLocation
+ def self.location # This needs to be on this line
+ :location # for the spec to pass
+ end
+
+ def self.redefined
+ :first
+ end
+
+ def self.redefined
+ :last
+ end
+
+ def original
+ end
+
+ alias :aka :original
+ end
+
+ module Mod
+ def from_mod; end
+ end
+
+ class Methods
+ include Mod
+
+ def foo
+ true
+ end
+
+ def with_block(&block); end
+
+ alias bar foo
+ alias alias_1 foo
+ alias alias_2 foo
+
+ def original_body(); :this; end
+ def identical_body(); :this; end
+
+ def one; end
+ def two(a); end
+ def three(a, b); end
+ def four(a, b, &c); end
+
+ def neg_one(*a); end
+ def neg_two(a, *b); end
+ def neg_three(a, b, *c); end
+ def neg_four(a, b, *c, &d); end
+
+ def discard_1(); :discard; end
+ def discard_2(); :discard; end
+ end
+
+ class Parent
+ def foo; end
+ def self.class_method
+ "I am #{name}"
+ end
+ end
+
+ class Child1 < Parent; end
+ class Child2 < Parent; end
+ class Child3 < Parent
+ class << self
+ alias_method :another_class_method, :class_method
+ end
+ end
+
+ class A
+ def baz(a, b)
+ return [__FILE__, self.class]
+ end
+ def overridden; end
+ end
+
+ class B < A
+ def overridden; end
+ end
+
+ class C < B
+ def overridden; end
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/hash_spec.rb b/spec/rubyspec/core/unboundmethod/hash_spec.rb
new file mode 100644
index 0000000000..6ba6c04834
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/hash_spec.rb
@@ -0,0 +1,17 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+
+describe "UnboundMethod#hash" do
+ it "needs to be reviewed for spec completeness"
+
+ it "returns the same value for user methods that are eql?" do
+ foo, bar = UnboundMethodSpecs::Methods.instance_method(:foo), UnboundMethodSpecs::Methods.instance_method(:bar)
+ foo.hash.should == bar.hash
+ end
+
+ # See also redmine #6048
+ it "returns the same value for builtin methods that are eql?" do
+ to_s, inspect = Array.instance_method(:to_s), Array.instance_method(:inspect)
+ to_s.hash.should == inspect.hash
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/inspect_spec.rb b/spec/rubyspec/core/unboundmethod/inspect_spec.rb
new file mode 100644
index 0000000000..ffef61a639
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/inspect_spec.rb
@@ -0,0 +1,7 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+require File.expand_path('../shared/to_s', __FILE__)
+
+describe "UnboundMethod#inspect" do
+ it_behaves_like(:unboundmethod_to_s, :inspect)
+end
diff --git a/spec/rubyspec/core/unboundmethod/name_spec.rb b/spec/rubyspec/core/unboundmethod/name_spec.rb
new file mode 100644
index 0000000000..c4602d529a
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/name_spec.rb
@@ -0,0 +1,15 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+
+describe "UnboundMethod#name" do
+ it "returns the name of the method" do
+ String.instance_method(:upcase).name.should == :upcase
+ end
+
+ it "returns the name even when aliased" do
+ obj = UnboundMethodSpecs::Methods.new
+ obj.method(:foo).unbind.name.should == :foo
+ obj.method(:bar).unbind.name.should == :bar
+ UnboundMethodSpecs::Methods.instance_method(:bar).name.should == :bar
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/owner_spec.rb b/spec/rubyspec/core/unboundmethod/owner_spec.rb
new file mode 100644
index 0000000000..165b175147
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/owner_spec.rb
@@ -0,0 +1,26 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+
+describe "UnboundMethod#owner" do
+ it "returns the owner of the method" do
+ String.instance_method(:upcase).owner.should == String
+ end
+
+ it "returns the same owner when aliased in the same classes" do
+ UnboundMethodSpecs::Methods.instance_method(:foo).owner.should == UnboundMethodSpecs::Methods
+ UnboundMethodSpecs::Methods.instance_method(:bar).owner.should == UnboundMethodSpecs::Methods
+ end
+
+ it "returns the class/module it was defined in" do
+ UnboundMethodSpecs::C.instance_method(:baz).owner.should == UnboundMethodSpecs::A
+ UnboundMethodSpecs::Methods.instance_method(:from_mod).owner.should == UnboundMethodSpecs::Mod
+ end
+
+ it "returns the new owner for aliased methods on singleton classes" do
+ parent_singleton_class = UnboundMethodSpecs::Parent.singleton_class
+ child_singleton_class = UnboundMethodSpecs::Child3.singleton_class
+
+ child_singleton_class.instance_method(:class_method).owner.should == parent_singleton_class
+ child_singleton_class.instance_method(:another_class_method).owner.should == child_singleton_class
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/parameters_spec.rb b/spec/rubyspec/core/unboundmethod/parameters_spec.rb
new file mode 100644
index 0000000000..a48c967ea5
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/parameters_spec.rb
@@ -0,0 +1,5 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+
+describe "UnboundMethod#parameters" do
+ it "needs to be reviewed for spec completeness"
+end
diff --git a/spec/rubyspec/core/unboundmethod/shared/to_s.rb b/spec/rubyspec/core/unboundmethod/shared/to_s.rb
new file mode 100644
index 0000000000..07ba0903e2
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/shared/to_s.rb
@@ -0,0 +1,25 @@
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+
+describe :unboundmethod_to_s, shared: true do
+ before :each do
+ @from_module = UnboundMethodSpecs::Methods.instance_method(:from_mod)
+ @from_method = UnboundMethodSpecs::Methods.new.method(:from_mod).unbind
+ end
+
+ it "returns a String" do
+ @from_module.send(@method).should be_kind_of(String)
+ @from_method.send(@method).should be_kind_of(String)
+ end
+
+ it "the String reflects that this is an UnboundMethod object" do
+ @from_module.send(@method).should =~ /\bUnboundMethod\b/
+ @from_method.send(@method).should =~ /\bUnboundMethod\b/
+ end
+
+ it "the String shows the method name, Module defined in and Module extracted from" do
+ @from_module.send(@method).should =~ /\bfrom_mod\b/
+ @from_module.send(@method).should =~ /\bUnboundMethodSpecs::Mod\b/
+ @from_method.send(@method).should =~ /\bUnboundMethodSpecs::Methods\b/
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/source_location_spec.rb b/spec/rubyspec/core/unboundmethod/source_location_spec.rb
new file mode 100644
index 0000000000..8b95f0776b
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/source_location_spec.rb
@@ -0,0 +1,52 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+
+describe "UnboundMethod#source_location" do
+ before :each do
+ @method = UnboundMethodSpecs::SourceLocation.method(:location).unbind
+ end
+
+ it "sets the first value to the path of the file in which the method was defined" do
+ file = @method.source_location.first
+ file.should be_an_instance_of(String)
+ file.should == File.dirname(__FILE__) + '/fixtures/classes.rb'
+ end
+
+ it "sets the last value to a Fixnum representing the line on which the method was defined" do
+ line = @method.source_location.last
+ line.should be_an_instance_of(Fixnum)
+ line.should == 5
+ end
+
+ it "returns the last place the method was defined" do
+ UnboundMethodSpecs::SourceLocation.method(:redefined).unbind.source_location.last.should == 13
+ end
+
+ it "returns the location of the original method even if it was aliased" do
+ UnboundMethodSpecs::SourceLocation.instance_method(:aka).source_location.last.should == 17
+ end
+
+ it "works for define_method methods" do
+ line = nil
+ cls = Class.new do
+ line = __LINE__ + 1
+ define_method(:foo) { }
+ end
+
+ method = cls.instance_method(:foo)
+ method.source_location[0].should =~ /#{__FILE__}/
+ method.source_location[1].should == line
+ end
+
+ it "works for define_singleton_method methods" do
+ line = nil
+ cls = Class.new do
+ line = __LINE__ + 1
+ define_singleton_method(:foo) { }
+ end
+
+ method = cls.method(:foo)
+ method.source_location[0].should =~ /#{__FILE__}/
+ method.source_location[1].should == line
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/super_method_spec.rb b/spec/rubyspec/core/unboundmethod/super_method_spec.rb
new file mode 100644
index 0000000000..49d356fd2b
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/super_method_spec.rb
@@ -0,0 +1,28 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+
+describe "UnboundMethod#super_method" do
+ it "returns the method that would be called by super in the method" do
+ meth = UnboundMethodSpecs::C.instance_method(:overridden)
+ meth = meth.super_method
+ meth.should == UnboundMethodSpecs::B.instance_method(:overridden)
+ meth = meth.super_method
+ meth.should == UnboundMethodSpecs::A.instance_method(:overridden)
+ end
+
+ it "returns nil when there's no super method in the parent" do
+ method = Kernel.instance_method(:method)
+ method.super_method.should == nil
+ end
+
+ it "returns nil when the parent's method is removed" do
+ parent = Class.new { def foo; end }
+ child = Class.new(parent) { def foo; end }
+
+ method = child.instance_method(:foo)
+
+ parent.send(:undef_method, :foo)
+
+ method.super_method.should == nil
+ end
+end
diff --git a/spec/rubyspec/core/unboundmethod/to_s_spec.rb b/spec/rubyspec/core/unboundmethod/to_s_spec.rb
new file mode 100644
index 0000000000..77e1d713f0
--- /dev/null
+++ b/spec/rubyspec/core/unboundmethod/to_s_spec.rb
@@ -0,0 +1,7 @@
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+require File.expand_path('../shared/to_s', __FILE__)
+
+describe "UnboundMethod#to_s" do
+ it_behaves_like(:unboundmethod_to_s, :to_s)
+end