4 def labeled_module(name, &block)
6 (class <<self; self end).class_eval do
7 define_method(:to_s) { name }
8 alias_method :inspect, :to_s
10 class_eval(&block) if block
14 def labeled_class(name, supklass = Object, &block)
15 Class.new(supklass) do
16 (class <<self; self end).class_eval do
17 define_method(:to_s) { name }
18 alias_method :inspect, :to_s
20 class_eval(&block) if block
24 assert('Module', '15.2.2') do
25 assert_equal Class, Module.class
28 # TODO not implemented ATM assert('Module.constants', '15.2.2.3.1') do
30 assert('Module#ancestors', '15.2.2.4.9') do
31 class Test4ModuleAncestors
35 assert_equal Array, r.class
36 assert_true r.include?(String)
37 assert_true r.include?(Object)
40 assert('Module#append_features', '15.2.2.4.10') do
41 module Test4AppendFeatures
42 def self.append_features(mod)
43 Test4AppendFeatures2.const_set(:Const4AppendFeatures2, mod)
46 module Test4AppendFeatures2
47 include Test4AppendFeatures
50 assert_equal Test4AppendFeatures2, Test4AppendFeatures2.const_get(:Const4AppendFeatures2)
53 assert('Module#attr NameError') do
62 assert_raise(NameError) do
63 NameTest.module_eval { attr_reader name.to_sym }
66 assert_raise(NameError) do
67 NameTest.module_eval { attr_writer name.to_sym }
70 assert_raise(NameError) do
71 NameTest.module_eval { attr name.to_sym }
74 assert_raise(NameError) do
75 NameTest.module_eval { attr_accessor name.to_sym }
81 assert('Module#attr', '15.2.2.4.11') do
96 assert_true AttrTest.respond_to?(:cattr)
97 assert_true test.respond_to?(:iattr)
99 assert_false AttrTest.respond_to?(:cattr=)
100 assert_false test.respond_to?(:iattr=)
102 test.iattr_val = 'test'
103 assert_equal 'test', test.iattr
105 AttrTest.cattr_val = 'test'
106 assert_equal 'test', AttrTest.cattr
109 assert('Module#attr_accessor', '15.2.2.4.12') do
110 class AttrTestAccessor
114 attr_accessor :iattr, 'iattr2'
117 attr_instance = AttrTestAccessor.new
118 assert_true AttrTestAccessor.respond_to?(:cattr=)
119 assert_true attr_instance.respond_to?(:iattr=)
120 assert_true attr_instance.respond_to?(:iattr2=)
121 assert_true AttrTestAccessor.respond_to?(:cattr)
122 assert_true attr_instance.respond_to?(:iattr)
123 assert_true attr_instance.respond_to?(:iattr2)
125 attr_instance.iattr = 'test'
126 assert_equal 'test', attr_instance.iattr
128 AttrTestAccessor.cattr = 'test'
129 assert_equal 'test', AttrTestAccessor.cattr
132 assert('Module#attr_reader', '15.2.2.4.13') do
140 attr_reader :iattr, 'iattr2'
146 attr_instance = AttrTestReader.new
147 assert_true AttrTestReader.respond_to?(:cattr)
148 assert_true attr_instance.respond_to?(:iattr)
149 assert_true attr_instance.respond_to?(:iattr2)
151 assert_false AttrTestReader.respond_to?(:cattr=)
152 assert_false attr_instance.respond_to?(:iattr=)
153 assert_false attr_instance.respond_to?(:iattr2=)
155 attr_instance.iattr_val = 'test'
156 assert_equal 'test', attr_instance.iattr
158 AttrTestReader.cattr_val = 'test'
159 assert_equal 'test', AttrTestReader.cattr
162 assert('Module#attr_writer', '15.2.2.4.14') do
170 attr_writer :iattr, 'iattr2'
176 attr_instance = AttrTestWriter.new
177 assert_true AttrTestWriter.respond_to?(:cattr=)
178 assert_true attr_instance.respond_to?(:iattr=)
179 assert_true attr_instance.respond_to?(:iattr2=)
181 assert_false AttrTestWriter.respond_to?(:cattr)
182 assert_false attr_instance.respond_to?(:iattr)
183 assert_false attr_instance.respond_to?(:iattr2)
185 attr_instance.iattr = 'test'
186 assert_equal 'test', attr_instance.iattr_val
188 AttrTestWriter.cattr = 'test'
189 assert_equal 'test', AttrTestWriter.cattr_val
192 assert('Module#class_eval', '15.2.2.4.15') do
197 Test4ClassEval.class_eval do
201 assert_equal 11, Test4ClassEval.class_eval{ @a }
202 assert_equal 12, Test4ClassEval.class_eval{ @b }
203 assert_equal true, Test4ClassEval.new.respond_to?(:method1)
206 assert('Module#const_defined?', '15.2.2.4.20') do
207 module Test4ConstDefined
208 Const4Test4ConstDefined = true
211 assert_true Test4ConstDefined.const_defined?(:Const4Test4ConstDefined)
212 assert_false Test4ConstDefined.const_defined?(:NotExisting)
213 assert_raise(NameError){ Test4ConstDefined.const_defined?(:wrong_name) }
216 assert('Module#const_get', '15.2.2.4.21') do
218 Const4Test4ConstGet = 42
221 assert_equal 42, Test4ConstGet.const_get(:Const4Test4ConstGet)
222 assert_equal 42, Test4ConstGet.const_get("Const4Test4ConstGet")
223 assert_equal 42, Object.const_get("Test4ConstGet::Const4Test4ConstGet")
225 assert_raise(TypeError){ Test4ConstGet.const_get(123) }
226 assert_raise(NameError){ Test4ConstGet.const_get(:I_DO_NOT_EXIST) }
227 assert_raise(NameError){ Test4ConstGet.const_get("I_DO_NOT_EXIST::ME_NEITHER") }
228 assert_raise(NameError){ Test4ConstGet.const_get(:wrong_name) }
231 assert('Module#const_set', '15.2.2.4.23') do
233 Const4Test4ConstSet = 42
236 assert_equal 23, Test4ConstSet.const_set(:Const4Test4ConstSet, 23)
237 assert_equal 23, Test4ConstSet.const_get(:Const4Test4ConstSet)
238 ["", "wrongNAME", "Wrong-Name"].each do |n|
239 assert_raise(NameError) { Test4ConstSet.const_set(n, 1) }
243 assert('Module#remove_const', '15.2.2.4.40') do
244 module Test4RemoveConst
248 assert_equal 23, Test4RemoveConst.remove_const(:ExistingConst)
249 assert_false Test4RemoveConst.const_defined?(:ExistingConst)
250 assert_raise(NameError) { Test4RemoveConst.remove_const(:NonExistingConst) }
252 assert_raise(NameError) { Test4RemoveConst.remove_const(n) }
256 assert('Module#const_missing', '15.2.2.4.22') do
257 module Test4ConstMissing
258 def self.const_missing(sym)
259 42 # the answer to everything
263 assert_equal 42, Test4ConstMissing.const_get(:ConstDoesntExist)
266 assert('Module#include', '15.2.2.4.27') do
271 @include_result = include Test4Include
273 attr_reader :include_result
277 assert_equal 42, Test4Include2.const_get(:Const4Include)
278 assert_equal Test4Include2, Test4Include2.include_result
281 assert('Module#include?', '15.2.2.4.28') do
285 include Test4IncludeP
287 class Test4IncludeP3 < Test4IncludeP2
290 assert_true Test4IncludeP2.include?(Test4IncludeP)
291 assert_true Test4IncludeP3.include?(Test4IncludeP)
292 assert_false Test4IncludeP.include?(Test4IncludeP)
295 assert('Module#included', '15.2.2.4.29') do
298 def self.included mod
299 Test4Included.const_set(:Const4Included2, mod)
302 module Test4Included2
303 include Test4Included
306 assert_equal 42, Test4Included2.const_get(:Const4Included)
307 assert_equal Test4Included2, Test4Included2.const_get(:Const4Included2)
310 assert('Module#initialize', '15.2.2.4.31') do
311 assert_kind_of Module, Module.new
312 mod = Module.new { def hello; "hello"; end }
313 cls = Class.new{include mod}
314 assert_true cls.new.respond_to?(:hello)
316 mod = Module.new { |m| a = m }
320 assert('Module#method_defined?', '15.2.2.4.34') do
321 module Test4MethodDefined
336 assert_true Test4MethodDefined::A.method_defined? :method1
337 assert_true Test4MethodDefined::C.method_defined? :method1
338 assert_true Test4MethodDefined::C.method_defined? "method2"
339 assert_true Test4MethodDefined::C.method_defined? "method3"
340 assert_false Test4MethodDefined::C.method_defined? "method4"
343 assert('Module#module_eval', '15.2.2.4.35') do
344 module Test4ModuleEval
349 assert_equal 11, Test4ModuleEval.module_eval{ @a }
350 assert_equal 12, Test4ModuleEval.module_eval{ @b }
353 assert('Module#undef_method', '15.2.2.4.42') do
354 module Test4UndefMethod
365 class GrandChild < Child
368 Test4UndefMethod::Child.class_eval{ undef_method :hello }
370 assert_true Test4UndefMethod::Parent.new.respond_to?(:hello)
371 assert_false Test4UndefMethod::Child.new.respond_to?(:hello)
372 assert_false Test4UndefMethod::GrandChild.new.respond_to?(:hello)
377 assert('Module#define_method') do
379 define_method(:m1) { :ok }
380 define_method(:m2, Proc.new { :ok })
382 assert_equal c.new.m1, :ok
383 assert_equal c.new.m2, :ok
384 assert_raise(TypeError) do
385 Class.new { define_method(:n1, nil) }
390 assert('Module#prepend') do
395 def m1; [:M1, super, :M1] end
398 def m1; [:M2, super, :M2] end
401 def m1; [:M3, super, :M3] end
404 def m1; [:M4, super, :M4] end
410 def m1; [:C0, super, :C0] end
415 def m1; [:C1, super, :C1] end
419 expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2]
420 assert_equal(expected, obj.m1)
423 assert('Module#prepend result') do
424 module TestPrepended; end
425 module TestPrependResult
426 @prepend_result = prepend TestPrepended
428 attr_reader :prepend_result
432 assert_equal TestPrependResult, TestPrependResult.prepend_result
435 # mruby shouldn't be affected by this since there is
436 # no visibility control (yet)
437 assert('Module#prepend public') do
438 assert_nothing_raised('ruby/ruby #8846') do
439 Class.new.prepend(Module.new)
443 assert('Module#prepend inheritance') do
444 bug6654 = '[ruby-core:45914]'
445 a = labeled_module('a')
446 b = labeled_module('b') { include a }
447 c = labeled_module('c') { prepend b }
450 # the Module#< operator should be used here instead, but we don't have it
451 assert_include(c.ancestors, a)
452 assert_include(c.ancestors, b)
455 bug8357 = '[ruby-core:54736] [Bug #8357]'
456 b = labeled_module('b') { prepend a }
457 c = labeled_class('c') { include b }
460 # the Module#< operator should be used here instead, but we don't have it
461 assert_include(c.ancestors, a)
462 assert_include(c.ancestors, b)
465 bug8357 = '[ruby-core:54742] [Bug #8357]'
466 assert_kind_of(b, c.new, bug8357)
469 assert 'Module#prepend + Class#ancestors' do
470 bug6658 = '[ruby-core:45919]'
471 m = labeled_module("m")
472 c = labeled_class("c") {prepend m}
473 assert_equal([m, c], c.ancestors[0, 2], bug6658)
475 bug6662 = '[ruby-dev:45868]'
476 c2 = labeled_class("c2", c)
478 assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662)
481 assert 'Module#prepend + Module#ancestors' do
482 bug6659 = '[ruby-dev:45861]'
483 m0 = labeled_module("m0") { def x; [:m0, *super] end }
484 m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 }
485 m2 = labeled_module("m2") { def x; [:m2, *super] end; prepend m1 }
486 c0 = labeled_class("c0") { def x; [:c0] end }
487 c1 = labeled_class("c1") { def x; [:c1] end; prepend m2 }
488 c2 = labeled_class("c2", c0) { def x; [:c2, *super] end; include m2 }
490 assert_equal([m0, m1], m1.ancestors, bug6659)
492 bug6662 = '[ruby-dev:45868]'
493 assert_equal([m0, m1, m2], m2.ancestors, bug6662)
494 assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662)
495 assert_equal([:m0, :m1, :m2, :c1], c1.new.x)
496 assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662)
497 assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x)
499 m3 = labeled_module("m3") { include m1; prepend m1 }
500 assert_equal([m3, m0, m1], m3.ancestors)
501 m3 = labeled_module("m3") { prepend m1; include m1 }
502 assert_equal([m0, m1, m3], m3.ancestors)
503 m3 = labeled_module("m3") { prepend m1; prepend m1 }
504 assert_equal([m0, m1, m3], m3.ancestors)
505 m3 = labeled_module("m3") { include m1; include m1 }
506 assert_equal([m3, m0, m1], m3.ancestors)
509 assert 'cyclic Module#prepend' do
510 bug7841 = '[ruby-core:52205] [Bug #7841]'
513 m1.instance_eval { prepend(m2) }
514 assert_raise(ArgumentError, bug7841) do
515 m2.instance_eval { prepend(m1) }
519 # these assertions will not run without a #assert_separately method
520 #assert 'test_prepend_optmethod' do
521 # bug7983 = '[ruby-dev:47124] [Bug #7983]'
522 # assert_separately [], %{
528 # Fixnum.send(:prepend, M)
529 # assert_equal(0.5, 1 / 2, "#{bug7983}")
531 # assert_equal(0, 1 / 2)
534 # mruby has no visibility control
535 # assert 'Module#prepend visibility' do
536 # bug8005 = '[ruby-core:53106] [Bug #8005]'
538 # prepend Module.new {}
543 # assert_true a.respond_to?(:foo), bug8005
544 # assert_nothing_raised(bug8005) {a.send :foo}
547 # mruby has no visibility control
548 # assert 'Module#prepend inherited visibility' do
549 # bug8238 = '[ruby-core:54105] [Bug #8238]'
550 # module Test4PrependVisibilityInherited
560 # assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}")
563 # assert 'Module#prepend super in alias' do
564 # skip "super does not currently work in aliased methods"
565 # bug7842 = '[Bug #7842]'
567 # p = labeled_module("P") do
568 # def m; "P"+super; end
571 # a = labeled_class("A") do
575 # b = labeled_class("B", a) do
576 # def m; "B"+super; end
582 # assert_nothing_raised do
583 # assert_equal("BA", b.new.m2, bug7842)
586 # assert_nothing_raised do
587 # assert_equal("PBA", b.new.m3, bug7842)
591 assert 'Module#prepend each class' do
592 m = labeled_module("M")
593 c1 = labeled_class("C1") {prepend m}
594 c2 = labeled_class("C2", c1) {prepend m}
595 assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should be able to prepend each class")
598 assert 'Module#prepend no duplication' do
599 m = labeled_module("M")
600 c = labeled_class("C") {prepend m; prepend m}
601 assert_equal([m, c], c.ancestors[0, 2], "should never duplicate")
604 assert 'Module#prepend in superclass' do
605 m = labeled_module("M")
606 c1 = labeled_class("C1")
607 c2 = labeled_class("C2", c1) {prepend m}
608 c1.class_eval {prepend m}
609 assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should accesisble prepended module in superclass")
612 # requires #assert_separately
613 #assert 'Module#prepend call super' do
614 # assert_separately([], <<-'end;') #do
615 # bug10847 = '[ruby-core:68093] [Bug #10847]'
618 # assert_nothing_raised(SystemStackError, bug10847) do
625 assert('Module#to_s') do
628 const_set :SetInner, Class.new
631 assert_equal 'Outer', Outer.to_s
632 assert_equal 'Outer::Inner', Outer::Inner.to_s
633 assert_equal 'Outer::SetInner', Outer::SetInner.to_s
635 outer = Module.new do
636 const_set :SetInner, Class.new
638 Object.const_set :SetOuter, outer
640 assert_equal 'SetOuter', SetOuter.to_s
641 assert_equal 'SetOuter::SetInner', SetOuter::SetInner.to_s
646 assert_equal "#<Module:0x", mod.to_s[0,11]
647 assert_equal "#<Class:0x", cls.to_s[0,10]
650 assert('Module#inspect') do
651 module Test4to_sModules
654 assert_equal 'Test4to_sModules', Test4to_sModules.inspect
657 assert('Issue 1467') do
679 assert('clone Module') do
693 assert('Module#module_function') do
696 module_function :modfunc
699 assert_true M.respond_to?(:modfunc)
702 assert('module with non-class/module outer raises TypeError') do
703 assert_raise(TypeError) { module 0::M1 end }
704 assert_raise(TypeError) { module []::M2 end }
707 assert('module to return the last value') do
712 assert('module to return nil if body is empty') do
713 assert_nil(module M end)
716 assert('get constant of parent module in singleton class; issue #3568') do
717 actual = module GetConstantInSingletonTest
724 assert_equal("value", actual)