Fix some symbol.to_proc problems
[jruby.git] / test / test_methods.rb
blobd84a0b43c3cabb27a447f663074def30c819bb5f
1 require 'test/unit'
3 class TestMethods < Test::Unit::TestCase
4   class A
5     undef_method :id
6     (class<<self;self;end).send(:undef_method,:id)
7   end
8   Adup = A.dup
10   def test_undef_id
11     assert_raise(NoMethodError) { A.id }
12     assert_raise(NoMethodError) { A.new.id }
13     assert_raise(NoMethodError) { Adup.id }
14     assert_raise(NoMethodError) { Adup.new.id }
15   end
16   
17   class Foo
18     private
19     def foo; end
20   end
21   
22   def test_foo
23     assert_raise(NoMethodError) {Foo.class_eval "new.foo"}
24     begin
25       Foo.class_eval "new.foo"
26     rescue NoMethodError
27       $!.to_s =~ /private/
28     end
29   end
31   # JRUBY-2277
32   def test_alias_method_calls_correct_method_added_with_sym
33     $methods_added = []
34     $singleton_methods_added = []
36     c  = Class.new do
37       class << self
38         def singleton_method_added(x) # will also add its own def!
39           $singleton_methods_added << x
40         end
41         def method_added(x)
42           $methods_added << x
43         end
44         def another_singleton
45         end
46         alias_method :yet_another_singleton, :another_singleton
47       end
48       def foo
49       end
50       def bar
51       end
52       alias_method :baz, :bar  
53     end
55     expected_methods = [:foo, :bar, :baz]
56     expected_singletons = [:singleton_method_added, :method_added, :another_singleton, :yet_another_singleton]
58     assert_equal(expected_methods, $methods_added)
59     assert_equal(expected_singletons, $singleton_methods_added)
61     # test coercion of alias names to symbols
62     name = Object.new
63     def name.to_str
64       "boo"
65     end
66     assert_nothing_raised { c.send("alias_method", name, "foo") }
67     assert_equal(:boo, $methods_added.last)
69   end
70 end
72 class TestMethodObjects < Test::Unit::TestCase
73   # all testing return values are in the format
74   # [receiver, origin, method_name]
75   # origin = Class/Module's name (as Symbol) for instance methods,
76   #          Object for singleton methods
77   class C
78     def foo; [self, :C, :foo]; end
79     def bar; [self, :C, :bar]; end
81     # for simplicity on singleton representations,
82     # let's assure #inspect = #to_s
83     alias inspect to_s
84   end
86   class D < C
87     def bar; [self, :D, :bar]; end
88     def xyz; [self, :D, :xyz]; end
89   end
91   class E < D
92     def qux; [self, :E, :qux]; end
93   end
95   class F < C
96     def foo; [self, :F, :foo]; end
97   end
99   def test_method_call_equivalence
100     c1 = C.new
101     c2 = C.new
102     c3 = C.new
103     def c3.bar; [self, self, :bar]; end
104     def c3.cor; [self, self, :cor]; end
105     d1 = D.new
106     d2 = D.new
107     def d2.bar; [self, self, :bar]; end
108     e1 = E.new
109     e2 = E.new
110     def e2.xyz; [self, self, :xyz]; end
112     [c1, c2, c3].each do |c|
113       assert_equal(c.foo, c.method(:foo).call)
114       assert_equal(c.bar, c.method(:bar).call)
115     end
116     assert_equal(c3.cor, c3.method(:cor).call)
118     [d1, d2].each do |d|
119       assert_equal(d.foo, d.method(:foo).call)
120       assert_equal(d.bar, d.method(:bar).call)
121       assert_equal(d.xyz, d.method(:xyz).call)
122     end
124     [e1, e2].each do |e|
125       assert_equal(e.foo, e.method(:foo).call)
126       assert_equal(e.bar, e.method(:bar).call)
127       assert_equal(e.xyz, e.method(:xyz).call)
128       assert_equal(e.qux, e.method(:qux).call)
129     end
130   end
132   def test_method_equivalence
133     c1 = C.new
134     c2 = C.new
135     d1 = D.new
136     e1 = E.new
138     c1_foo1 = c1.method(:foo)
139     c1_foo2 = c1.method(:foo)
140     assert_equal(c1_foo1, c1_foo2)
141     assert_equal(C.instance_method(:foo).bind(d1), d1.method(:foo))
142     assert_equal(C.instance_method(:foo).bind(e1), e1.method(:foo))
143     assert_equal(D.instance_method(:foo).bind(e1), e1.method(:foo))
144     assert_equal(D.instance_method(:bar).bind(e1), e1.method(:bar))
146     assert_not_equal(c1_foo1, c2.method(:foo))
147   end
149   def test_direct_method_to_s
150     c1 = C.new
151     c2 = C.new
152     d1 = D.new
154     assert_equal("#<Method: #{C}#foo>", c1.method(:foo).to_s)
155     assert_equal("#<Method: #{C}#bar>", c1.method(:bar).to_s)
156     assert_equal("#<Method: #{D}#bar>", d1.method(:bar).to_s)
157     assert_equal("#<Method: #{D}#xyz>", d1.method(:xyz).to_s)
159     # non-singleton methods of singleton-ized methods should still
160     # be treated as direct methods
161     def c2.foo; [self, self, :foo]; end
162     assert_equal("#<Method: #{c2}.foo>", c2.method(:foo).to_s)
163     assert_equal("#<Method: #{C}#bar>", c2.method(:bar).to_s)
164   end
166   def test_indirect_method_to_s
167     d = D.new
168     e = E.new
170     assert_equal("#<Method: #{D}(#{C})#foo>", d.method(:foo).to_s)
171     assert_equal("#<Method: #{E}(#{C})#foo>", e.method(:foo).to_s)
172     assert_equal("#<Method: #{E}(#{D})#bar>", e.method(:bar).to_s)
173   end
175   def test_method_rebind
176     c1 = C.new
177     c2 = C.new
178     c3 = C.new
179     def c3.bar; [self, self, :bar]; end
180     d1 = D.new
181     c1_foo = c1.method(:foo)
182     c2_foo = c2.method(:foo)
183     c3_bar = c3.method(:bar)
184     d1_foo = d1.method(:foo)
185     d1_bar = d1.method(:bar)
187     assert_equal(c1_foo, c1_foo.unbind.bind(c1))
188     assert_equal(c2_foo, c1_foo.unbind.bind(c2))
189     assert_equal(c1_foo.unbind, c2_foo.unbind.bind(c2).unbind)
190     assert_equal(d1_foo, c1_foo.unbind.bind(d1))
192     assert_equal(c2_foo, c1_foo.unbind.bind(c2))
193     assert_equal(c2.foo, c1_foo.unbind.bind(c2).call)
195     assert_raise(TypeError) { c3_bar.unbind.bind(c1) }
196     assert_raise(TypeError) { d1_bar.unbind.bind(c1) }
197   end
199   def test_method_redefinition
200     f = F.new
201     f_bar1 = f.method(:bar)
202     F.class_eval do
203       def bar; [self, :F, :bar]; end
204     end
205     f_bar2 = f.method(:bar)
206     assert_not_equal(f_bar1, f_bar2)
207     assert_equal([f, :C, :bar], f_bar1.call)
208     assert_equal([f, :F, :bar], f_bar2.call)
209     assert_equal(f_bar1, C.instance_method(:bar).bind(f))
210   end
212   def test_unbound_method_equivalence
213     c1 = C.new
214     c2 = C.new
215     def c2.bar; [self, self, :bar]; end
216     d1 = D.new
217     e1 = E.new
218     e2 = E.new
219     def e2.foo; [self, self, :foo]; end
221     unbind = lambda { |o, m| o.method(m).unbind }
222     c1_foo = unbind[c1, :foo]
223     c1_foo2 = unbind[c1, :foo]
224     e1_foo = unbind[e1, :foo]
226     assert_equal(c1_foo, c1_foo2)
227     assert_equal(c1_foo, unbind[c2, :foo])
228     assert_equal(unbind[e1, :bar], unbind[e2, :bar])
229     assert_equal(unbind[e1, :xyz], unbind[e2, :xyz])
230     assert_equal(unbind[e1, :qux], unbind[e2, :qux])
232     assert_not_equal(unbind[c1, :bar], unbind[c2, :bar])
233     assert_not_equal(c1_foo, unbind[d1, :foo])
234     assert_not_equal(e1_foo, c1_foo)
235     assert_not_equal(e1_foo, unbind[d1, :foo])
236     assert_not_equal(e1_foo, unbind[e2, :foo])
237     assert_not_equal(c1_foo, unbind[e2, :foo])
239     c__foo = C.instance_method(:foo)
240     c__bar = C.instance_method(:bar)
241     d__foo = D.instance_method(:foo)
242     e__foo = E.instance_method(:foo)
243     e__xyz = E.instance_method(:xyz)
245     assert_not_equal(c__foo, d__foo)
246     assert_not_equal(c__foo, e__foo)
248     assert_equal(c1_foo, c__foo)
249     assert_equal(e1_foo, e__foo)
250     assert_not_equal(unbind[e2, :foo], e__foo)
251   end
253   def test_unbound_method_to_s
254     c1 = C.new
255     c2 = C.new
256     d1 = D.new
258     unbind = lambda { |o, m| o.method(m).unbind }
260     c1_foo_u = unbind[c1, :foo]
261     c2_foo_u = unbind[c2, :foo]
262     d1_foo_u = unbind[d1, :foo]
264     assert_equal(c1_foo_u.to_s, c2_foo_u.to_s)
265     assert_equal("#<UnboundMethod: #{C}#foo>", c1_foo_u.to_s)
266     assert_equal("#<UnboundMethod: #{D}(#{C})#foo>", d1_foo_u.to_s)
268     e1 = E.new
269     sing_e1 =
270       class << e1
271         def xyz; [self, self, :xyz]; end
272         self
273       end
274     e1_foo_u = e1.method(:foo).unbind
275     e1_bar_u = e1.method(:bar).unbind
276     e1_xyz_u = e1.method(:xyz).unbind
278     assert_equal("#<UnboundMethod: #{E}(#{C})#foo>", e1_foo_u.to_s)
279     assert_equal("#<UnboundMethod: #{E}(#{D})#bar>", e1_bar_u.to_s)
280     assert_equal("#<UnboundMethod: #{sing_e1}#xyz>", e1_xyz_u.to_s)
281   end
284 class TestCaching < Test::Unit::TestCase
285   module Foo
286     def the_method
287       $THE_METHOD = 'Foo'
288     end
289   end
291   def setup
292     $a = Class.new do 
293       def the_method
294         $THE_METHOD = 'A'
295       end
296     end.new
297   end
298   
299   def test_extend
300     40.times do 
301       $a.the_method
302       assert_equal "A", $THE_METHOD
303     end
305     $a.extend Foo
307     40.times do 
308       $a.the_method
309       assert_equal "Foo", $THE_METHOD
310     end
311   end
313   def test_alias
314     40.times do 
315       $a.the_method
316       assert_equal "A", $THE_METHOD
317     end
319     $a.class.class_eval do 
320       def the_bar_method
321         $THE_METHOD = "Bar"
322       end
324       alias_method :the_method, :the_bar_method
325     end
326     
327     $a.the_method
328     assert_equal "Bar", $THE_METHOD
329   end