blob: 036c6b7f8c714fbf6c8830ddcfd2732e2133f9c8 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
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
ruby_version_is ""..."3.2" do
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
end
ruby_version_is "3.2" do
it "returns true if same method but one extracted from a subclass" do
(@parent == @child1).should == true
(@child1 == @parent).should == true
end
it "returns false if same method but extracted from two different subclasses" do
(@child2 == @child1).should == true
(@child1 == @child2).should == true
end
it "returns true if methods are the same but added from an included Module" do
(@includee == @includer).should == true
(@includer == @includee).should == true
end
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
it "considers methods through aliasing equal" do
c = Class.new do
class << self
alias_method :n, :new
end
end
c.method(:new).should == c.method(:n)
c.method(:n).should == Class.instance_method(:new).bind(c)
end
# On CRuby < 3.2, the 2 specs below pass due to method/instance_method skipping zsuper methods.
# We are interested in the general pattern working, i.e. the combination of method/instance_method
# and #== exposes the wanted behavior.
it "considers methods through visibility change equal" do
c = Class.new do
class << self
private :new
end
end
c.method(:new).should == Class.instance_method(:new).bind(c)
end
it "considers methods through aliasing and visibility change equal" do
c = Class.new do
class << self
alias_method :n, :new
private :new
end
end
c.method(:new).should == c.method(:n)
c.method(:n).should == Class.instance_method(:new).bind(c)
c.method(:new).should == Class.instance_method(:new).bind(c)
end
end
|