[rubygems/rubygems] Use a constant empty tar header to avoid extra allocations
[ruby.git] / test / test_delegate.rb
blobf7bedf37fbfb1841b2151f6f81b4686d5516fb66
1 # frozen_string_literal: true
2 require 'test/unit'
3 require 'delegate'
5 class TestDelegateClass < Test::Unit::TestCase
6   module M
7     attr_reader :m
8   end
10   def test_extend
11     obj = DelegateClass(Array).new([])
12     obj.instance_eval { @m = :m }
13     obj.extend M
14     assert_equal(:m, obj.m, "[ruby-dev:33116]")
15   end
17   def test_delegate_class_block
18     klass = DelegateClass(Array) do
19       alias foo first
20     end
21     assert_equal(1, klass.new([1]).foo)
22   end
24   def test_systemcallerror_eq
25     e = SystemCallError.new(0)
26     assert((SimpleDelegator.new(e) == e) == (e == SimpleDelegator.new(e)), "[ruby-dev:34808]")
27   end
29   class Myclass < DelegateClass(Array);end
31   def test_delegateclass_class
32     myclass=Myclass.new([])
33     assert_equal(Myclass,myclass.class)
34     assert_equal(Myclass,myclass.dup.class,'[ruby-dev:40313]')
35     assert_equal(Myclass,myclass.clone.class,'[ruby-dev:40313]')
36   end
38   def test_simpledelegator_class
39     simple=SimpleDelegator.new([])
40     assert_equal(SimpleDelegator,simple.class)
41     assert_equal(SimpleDelegator,simple.dup.class)
42     assert_equal(SimpleDelegator,simple.clone.class)
43   end
45   def test_simpledelegator_clone
46     simple=SimpleDelegator.new([])
47     simple.freeze
49     clone = simple.clone
50     assert_predicate clone, :frozen?
51     assert_predicate clone.__getobj__, :frozen?
52     assert_equal true, Kernel.instance_method(:frozen?).bind(clone).call
54     clone = simple.clone(freeze: false)
55     assert_not_predicate clone, :frozen?
56     assert_not_predicate clone.__getobj__, :frozen?
57     assert_equal false, Kernel.instance_method(:frozen?).bind(clone).call
58   end
60   class Object
61     def m
62       :o
63     end
64     private
65     def delegate_test_m
66       :o
67     end
68   end
70   class Foo
71     def m
72       :m
73     end
74     def delegate_test_m
75       :m
76     end
77   end
79   class Bar < DelegateClass(Foo)
80   end
82   def test_override
83     foo = Foo.new
84     foo2 = SimpleDelegator.new(foo)
85     bar = Bar.new(foo)
86     assert_equal(:o, Object.new.m)
87     assert_equal(:m, foo.m)
88     assert_equal(:m, foo2.m)
89     assert_equal(:m, bar.m)
90     bug = '[ruby-dev:39154]'
91     assert_equal(:m, foo2.send(:delegate_test_m), bug)
92     assert_equal(:m, bar.send(:delegate_test_m), bug)
93   end
95   class Parent
96     def parent_public; end
98     protected
100     def parent_protected; end
102     private
104     def parent_private; end
105   end
107   class Child < DelegateClass(Parent)
108   end
110   class Parent
111     def parent_public_added; end
113     protected
115     def parent_protected_added; end
117     private
119     def parent_private_added; end
120   end
122   def test_public_instance_methods
123     ignores = Object.public_instance_methods | Delegator.public_instance_methods
124     assert_equal([:parent_public, :parent_public_added], (Child.public_instance_methods - ignores).sort)
125     assert_equal([:parent_public, :parent_public_added], (Child.new(Parent.new).public_methods - ignores).sort)
126   end
128   def test_protected_instance_methods
129     ignores = Object.protected_instance_methods | Delegator.protected_instance_methods
130     assert_equal([:parent_protected, :parent_protected_added], (Child.protected_instance_methods - ignores).sort)
131     assert_equal([:parent_protected, :parent_protected_added], (Child.new(Parent.new).protected_methods - ignores).sort)
132   end
134   def test_instance_methods
135     ignores = Object.instance_methods | Delegator.instance_methods
136     assert_equal([:parent_protected, :parent_protected_added, :parent_public, :parent_public_added], (Child.instance_methods - ignores).sort)
137     assert_equal([:parent_protected, :parent_protected_added, :parent_public, :parent_public_added], (Child.new(Parent.new).methods - ignores).sort)
138   end
140   def test_DelegateClass_instance_method
141     assert_instance_of UnboundMethod, Child.instance_method(:parent_public)
142     assert_instance_of UnboundMethod, Child.instance_method(:parent_public_added)
143     assert_instance_of UnboundMethod, Child.instance_method(:parent_protected)
144     assert_instance_of UnboundMethod, Child.instance_method(:parent_protected_added)
145     assert_raise(NameError) { Child.instance_method(:parent_private) }
146     assert_raise(NameError) { Child.instance_method(:parent_private_added) }
147     assert_instance_of UnboundMethod, Child.instance_method(:to_s)
148   end
150   def test_DelegateClass_public_instance_method
151     assert_instance_of UnboundMethod, Child.public_instance_method(:parent_public)
152     assert_instance_of UnboundMethod, Child.public_instance_method(:parent_public_added)
153     assert_raise(NameError) { Child.public_instance_method(:parent_protected) }
154     assert_raise(NameError) { Child.public_instance_method(:parent_protected_added) }
155     assert_raise(NameError) { Child.instance_method(:parent_private) }
156     assert_raise(NameError) { Child.instance_method(:parent_private_added) }
157     assert_instance_of UnboundMethod, Child.public_instance_method(:to_s)
158   end
160   class IV < DelegateClass(Integer)
161     attr_accessor :var
163     def initialize
164       @var = 1
165       super(0)
166     end
167   end
169   def test_marshal
170     bug1744 = '[ruby-core:24211]'
171     c = IV.new
172     assert_equal(1, c.var)
173     d = Marshal.load(Marshal.dump(c))
174     assert_equal(1, d.var, bug1744)
175   end
177   def test_copy_frozen
178     bug2679 = '[ruby-dev:40242]'
179     a = [42, :hello].freeze
180     d = SimpleDelegator.new(a)
181     assert_nothing_raised(bug2679) {d.dup[0] += 1}
182     assert_raise(FrozenError) {d.clone[0] += 1}
183     d.freeze
184     assert(d.clone.frozen?)
185     assert(!d.dup.frozen?)
186   end
188   def test_frozen
189     d = SimpleDelegator.new([1, :foo])
190     d.freeze
191     assert_raise(FrozenError, '[ruby-dev:40314]#1') {d.__setobj__("foo")}
192     assert_equal([1, :foo], d)
193   end
195   def test_instance_method
196     s = SimpleDelegator.new("foo")
197     m = s.method("upcase")
198     s.__setobj__([1,2,3])
199     assert_raise(NoMethodError, '[ruby-dev:40314]#3') {m.call}
200   end
202   def test_methods
203     s = SimpleDelegator.new("foo")
204     assert_equal([], s.methods(false))
205     def s.bar; end
206     assert_equal([:bar], s.methods(false))
207   end
209   def test_eql?
210     s0 = SimpleDelegator.new("foo")
211     s1 = SimpleDelegator.new("bar")
212     s2 = SimpleDelegator.new("foo")
213     assert_operator(s0, :eql?, s0)
214     assert_operator(s0, :eql?, "foo")
215     assert_operator(s0, :eql?, s2)
216     assert_not_operator(s0, :eql?, s1)
217     assert_not_operator(s0, :eql?, "bar")
218   end
220   def test_keyword_and_hash
221     foo = Object.new
222     def foo.bar(*args)
223       args
224     end
225     def foo.foo(*args, **kw)
226       [args, kw]
227     end
228     d = SimpleDelegator.new(foo)
229     assert_equal([[], {}], d.foo)
230     assert_equal([], d.bar)
231     assert_equal([[], {:a=>1}], d.foo(:a=>1))
232     assert_equal([{:a=>1}], d.bar(:a=>1))
233     assert_equal([[{:a=>1}], {}], d.foo({:a=>1}))
234     assert_equal([{:a=>1}], d.bar({:a=>1}))
235   end
237   class Foo
238     private
239     def delegate_test_private
240       :m
241     end
242   end
244   def test_private_method
245     foo = Foo.new
246     d = SimpleDelegator.new(foo)
247     assert_raise(NoMethodError) {foo.delegate_test_private}
248     assert_equal(:m, foo.send(:delegate_test_private))
249     assert_raise(NoMethodError, '[ruby-dev:40314]#4') {d.delegate_test_private}
250     assert_raise(NoMethodError, '[ruby-dev:40314]#5') {d.send(:delegate_test_private)}
251   end
253   def test_global_function
254     klass = Class.new do
255       def open
256       end
257     end
258     obj = klass.new
259     d = SimpleDelegator.new(obj)
260     assert_nothing_raised(ArgumentError) {obj.open}
261     assert_nothing_raised(ArgumentError) {d.open}
262     assert_nothing_raised(ArgumentError) {d.send(:open)}
263   end
265   def test_send_method_in_delegator
266     d = Class.new(SimpleDelegator) do
267       def foo
268         "foo"
269       end
270     end.new(Object.new)
271     assert_equal("foo", d.send(:foo))
272   end
274   def test_unset_simple_delegator
275     d = SimpleDelegator.allocate
276     assert_raise_with_message(ArgumentError, /not delegated/) {
277       d.__getobj__
278     }
279   end
281   def test_unset_delegate_class
282     d = IV.allocate
283     assert_raise_with_message(ArgumentError, /not delegated/) {
284       d.__getobj__
285     }
286   end
288   class Bug9155 < DelegateClass(Integer)
289     def initialize(value)
290       super(Integer(value))
291     end
292   end
294   def test_global_method_if_no_target
295     bug9155 = '[ruby-core:58572] [Bug #9155]'
296     x = assert_nothing_raised(ArgumentError, bug9155) {break Bug9155.new(1)}
297     assert_equal(1, x.to_i, bug9155)
298   end
300   class Bug9403
301     Name = '[ruby-core:59718] [Bug #9403]'
302     SD = SimpleDelegator.new(new)
303     class << SD
304       def method_name
305         __method__
306       end
307       def callee_name
308         __callee__
309       end
310       alias aliased_name callee_name
311       def dir_name
312         __dir__
313       end
314     end
315     dc = DelegateClass(self)
316     dc.class_eval do
317       def method_name
318         __method__
319       end
320       def callee_name
321         __callee__
322       end
323       alias aliased_name callee_name
324       def dir_name
325         __dir__
326       end
327     end
328     DC = dc.new(new)
329   end
331   def test_method_in_simple_delegator
332     assert_equal(:method_name, Bug9403::SD.method_name, Bug9403::Name)
333   end
335   def test_callee_in_simple_delegator
336     assert_equal(:callee_name, Bug9403::SD.callee_name, Bug9403::Name)
337     assert_equal(:aliased_name, Bug9403::SD.aliased_name, Bug9403::Name)
338   end
340   def test_dir_in_simple_delegator
341     assert_equal(__dir__, Bug9403::SD.dir_name, Bug9403::Name)
342   end
344   def test_method_in_delegator_class
345     assert_equal(:method_name, Bug9403::DC.method_name, Bug9403::Name)
346   end
348   def test_callee_in_delegator_class
349     assert_equal(:callee_name, Bug9403::DC.callee_name, Bug9403::Name)
350     assert_equal(:aliased_name, Bug9403::DC.aliased_name, Bug9403::Name)
351   end
353   def test_dir_in_delegator_class
354     assert_equal(__dir__, Bug9403::DC.dir_name, Bug9403::Name)
355   end
357   def test_module_methods_vs_kernel_methods
358     delegate = SimpleDelegator.new(Object.new)
359     assert_raise(NoMethodError) do
360       delegate.constants
361     end
362   end
364   def test_basicobject
365     o = BasicObject.new
366     def o.bar; 1; end
367     delegate = SimpleDelegator.new(o)
368     assert_equal(1, delegate.bar)
369     assert_raise(NoMethodError, /undefined method `foo' for/) { delegate.foo }
370   end
372   def test_basicobject_respond_to
373     o = BasicObject.new
374     def o.bar
375       nil
376     end
378     def o.respond_to?(method, include_private=false)
379       return false if method == :bar
380       ::Kernel.instance_method(:respond_to?).bind_call(self, method, include_private)
381     end
382     delegate = SimpleDelegator.new(o)
383     refute delegate.respond_to?(:bar)
384   end
386   def test_keyword_argument
387     k = EnvUtil.labeled_class("Target") do
388       def test(a, k:) [a, k]; end
389     end
390     a = DelegateClass(k).new(k.new)
391     assert_equal([1, 0], a.test(1, k: 0))
392   end