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 def assert_uninitialized_const(&block)
25 assert_raise_with_message_pattern(NameError, "uninitialized constant *", &block)
28 def assert_wrong_const_name(&block)
29 assert_raise_with_message_pattern(NameError, "wrong constant name *", &block)
32 assert('Module', '15.2.2') do
33 assert_equal Class, Module.class
36 assert('Module#alias_method', '15.2.2.4.8') do
43 assert_same(cls, cls.alias_method(:bar, :foo))
44 assert_equal("FOO", cls.new.bar)
47 # TODO not implemented ATM assert('Module.constants', '15.2.2.3.1') do
49 assert('Module#ancestors', '15.2.2.4.9') do
50 class Test4ModuleAncestors
54 assert_equal Array, r.class
55 assert_true r.include?(String)
56 assert_true r.include?(Object)
59 assert('Module#append_features', '15.2.2.4.10') do
60 module Test4AppendFeatures
61 def self.append_features(mod)
62 Test4AppendFeatures2.const_set(:Const4AppendFeatures2, mod)
65 module Test4AppendFeatures2
66 include Test4AppendFeatures
69 assert_equal Test4AppendFeatures2, Test4AppendFeatures2.const_get(:Const4AppendFeatures2)
70 assert_raise(FrozenError) { Module.new.append_features Class.new.freeze }
73 assert('Module#attr NameError') do
82 assert_raise(NameError) do
83 NameTest.module_eval { attr_reader name.to_sym }
86 assert_raise(NameError) do
87 NameTest.module_eval { attr_writer name.to_sym }
90 assert_raise(NameError) do
91 NameTest.module_eval { attr name.to_sym }
94 assert_raise(NameError) do
95 NameTest.module_eval { attr_accessor name.to_sym }
101 assert('Module#attr', '15.2.2.4.11') do
116 assert_true AttrTest.respond_to?(:cattr)
117 assert_true test.respond_to?(:iattr)
119 assert_false AttrTest.respond_to?(:cattr=)
120 assert_false test.respond_to?(:iattr=)
122 test.iattr_val = 'test'
123 assert_equal 'test', test.iattr
125 AttrTest.cattr_val = 'test'
126 assert_equal 'test', AttrTest.cattr
129 assert('Module#attr_accessor', '15.2.2.4.12') do
130 class AttrTestAccessor
134 attr_accessor :iattr, 'iattr2'
137 attr_instance = AttrTestAccessor.new
138 assert_true AttrTestAccessor.respond_to?(:cattr=)
139 assert_true attr_instance.respond_to?(:iattr=)
140 assert_true attr_instance.respond_to?(:iattr2=)
141 assert_true AttrTestAccessor.respond_to?(:cattr)
142 assert_true attr_instance.respond_to?(:iattr)
143 assert_true attr_instance.respond_to?(:iattr2)
145 attr_instance.iattr = 'test'
146 assert_equal 'test', attr_instance.iattr
148 AttrTestAccessor.cattr = 'test'
149 assert_equal 'test', AttrTestAccessor.cattr
152 assert('Module#attr_reader', '15.2.2.4.13') do
160 attr_reader :iattr, 'iattr2'
166 attr_instance = AttrTestReader.new
167 assert_true AttrTestReader.respond_to?(:cattr)
168 assert_true attr_instance.respond_to?(:iattr)
169 assert_true attr_instance.respond_to?(:iattr2)
171 assert_false AttrTestReader.respond_to?(:cattr=)
172 assert_false attr_instance.respond_to?(:iattr=)
173 assert_false attr_instance.respond_to?(:iattr2=)
175 attr_instance.iattr_val = 'test'
176 assert_equal 'test', attr_instance.iattr
178 AttrTestReader.cattr_val = 'test'
179 assert_equal 'test', AttrTestReader.cattr
182 assert('Module#attr_writer', '15.2.2.4.14') do
190 attr_writer :iattr, 'iattr2'
196 attr_instance = AttrTestWriter.new
197 assert_true AttrTestWriter.respond_to?(:cattr=)
198 assert_true attr_instance.respond_to?(:iattr=)
199 assert_true attr_instance.respond_to?(:iattr2=)
201 assert_false AttrTestWriter.respond_to?(:cattr)
202 assert_false attr_instance.respond_to?(:iattr)
203 assert_false attr_instance.respond_to?(:iattr2)
205 attr_instance.iattr = 'test'
206 assert_equal 'test', attr_instance.iattr_val
208 AttrTestWriter.cattr = 'test'
209 assert_equal 'test', AttrTestWriter.cattr_val
212 assert('Module#class_eval', '15.2.2.4.15') do
217 Test4ClassEval.class_eval do
221 assert_equal 11, Test4ClassEval.class_eval{ @a }
222 assert_equal 12, Test4ClassEval.class_eval{ @b }
223 assert_equal true, Test4ClassEval.new.respond_to?(:method1)
226 assert('Module#const_defined?', '15.2.2.4.20') do
227 module Test4ConstDefined
228 Const4Test4ConstDefined = true
231 assert_true Test4ConstDefined.const_defined?(:Const4Test4ConstDefined)
232 assert_false Test4ConstDefined.const_defined?(:NotExisting)
233 assert_wrong_const_name{ Test4ConstDefined.const_defined?(:wrong_name) }
236 assert('Module#const_get', '15.2.2.4.21') do
238 Const4Test4ConstGet = 42
241 assert_equal 42, Test4ConstGet.const_get(:Const4Test4ConstGet)
242 assert_equal 42, Test4ConstGet.const_get("Const4Test4ConstGet")
243 assert_equal 42, Object.const_get("Test4ConstGet::Const4Test4ConstGet")
245 assert_raise(TypeError){ Test4ConstGet.const_get(123) }
246 assert_uninitialized_const{ Test4ConstGet.const_get(:I_DO_NOT_EXIST) }
247 assert_uninitialized_const{ Test4ConstGet.const_get("I_DO_NOT_EXIST::ME_NEITHER") }
248 assert_wrong_const_name{ Test4ConstGet.const_get(:wrong_name) }
251 assert('Module#const_set', '15.2.2.4.23') do
253 Const4Test4ConstSet = 42
256 assert_equal 23, Test4ConstSet.const_set(:Const4Test4ConstSet, 23)
257 assert_equal 23, Test4ConstSet.const_get(:Const4Test4ConstSet)
258 ["", "wrongNAME", "Wrong-Name"].each do |n|
259 assert_wrong_const_name { Test4ConstSet.const_set(n, 1) }
263 assert('Module#remove_const', '15.2.2.4.40') do
264 module Test4RemoveConst
268 assert_equal 23, Test4RemoveConst.remove_const(:ExistingConst)
269 assert_false Test4RemoveConst.const_defined?(:ExistingConst)
270 assert_raise_with_message_pattern(NameError, "constant * not defined") do
271 Test4RemoveConst.remove_const(:NonExistingConst)
274 assert_wrong_const_name { Test4RemoveConst.remove_const(n) }
276 assert_raise(FrozenError) { Test4RemoveConst.freeze.remove_const(:A) }
279 assert('Module#const_missing', '15.2.2.4.22') do
280 module Test4ConstMissing
281 def self.const_missing(sym)
282 42 # the answer to everything
286 assert_equal 42, Test4ConstMissing.const_get(:ConstDoesntExist)
289 assert('Module#extend_object', '15.2.2.4.25') do
291 mod = Module.new { def foo; end }
295 assert_false a.respond_to?(:foo)
296 assert_true b.respond_to?(:foo)
297 assert_raise(FrozenError) { mod.extend_object(cls.new.freeze) }
298 assert_raise(FrozenError, TypeError) { mod.extend_object(1) }
301 assert('Module#include', '15.2.2.4.27') do
306 @include_result = include Test4Include
308 attr_reader :include_result
312 assert_equal 42, Test4Include2.const_get(:Const4Include)
313 assert_equal Test4Include2, Test4Include2.include_result
314 assert_raise(FrozenError) { Module.new.freeze.include Test4Include }
317 assert('Module#include?', '15.2.2.4.28') do
321 include Test4IncludeP
323 class Test4IncludeP3 < Test4IncludeP2
326 assert_true Test4IncludeP2.include?(Test4IncludeP)
327 assert_true Test4IncludeP3.include?(Test4IncludeP)
328 assert_false Test4IncludeP.include?(Test4IncludeP)
331 assert('Module#included', '15.2.2.4.29') do
334 def self.included mod
335 Test4Included.const_set(:Const4Included2, mod)
338 module Test4Included2
339 include Test4Included
342 assert_equal 42, Test4Included2.const_get(:Const4Included)
343 assert_equal Test4Included2, Test4Included2.const_get(:Const4Included2)
346 assert('Module#initialize', '15.2.2.4.31') do
347 assert_kind_of Module, Module.new
348 mod = Module.new { def hello; "hello"; end }
349 cls = Class.new{include mod}
350 assert_true cls.new.respond_to?(:hello)
352 mod = Module.new { |m| a = m }
356 assert('Module#method_defined?', '15.2.2.4.34') do
357 module Test4MethodDefined
372 assert_true Test4MethodDefined::A.method_defined? :method1
373 assert_true Test4MethodDefined::C.method_defined? :method1
374 assert_true Test4MethodDefined::C.method_defined? "method2"
375 assert_true Test4MethodDefined::C.method_defined? "method3"
376 assert_false Test4MethodDefined::C.method_defined? "method4"
379 assert('Module#module_eval', '15.2.2.4.35') do
380 module Test4ModuleEval
385 assert_equal 11, Test4ModuleEval.module_eval{ @a }
386 assert_equal 12, Test4ModuleEval.module_eval{ @b }
389 assert('Module#undef_method', '15.2.2.4.42') do
390 module Test4UndefMethod
401 class GrandChild < Child
404 Test4UndefMethod::Child.class_eval{ undef_method :hello }
406 assert_true Test4UndefMethod::Parent.new.respond_to?(:hello)
407 assert_false Test4UndefMethod::Child.new.respond_to?(:hello)
408 assert_false Test4UndefMethod::GrandChild.new.respond_to?(:hello)
413 assert('Module#dup') do
418 def cmeth; :cmeth end
421 def imeth; :imeth end
425 m = TestModuleDup.dup
426 o = Object.include(m).new
427 assert_equal(:cattr, m.cattr)
428 assert_equal(:cmeth, m.cmeth)
429 assert_equal(:cvar, o.cvar)
430 assert_equal(:imeth, o.imeth)
431 assert_match("#<Module:0x*>", m.to_s)
432 assert_not_predicate(m, :frozen?)
433 assert_not_predicate(TestModuleDup.freeze.dup, :frozen?)
436 assert('Module#define_method') do
438 define_method(:m1) { :ok }
439 define_method(:m2, Proc.new { :ok })
441 assert_equal c.new.m1, :ok
442 assert_equal c.new.m2, :ok
443 assert_raise(TypeError) do
444 Class.new { define_method(:n1, nil) }
448 assert 'Module#prepend_features' do
449 mod = Module.new { def m; :mod end }
450 cls = Class.new { def m; :cls end }
451 assert_equal :cls, cls.new.m
452 mod.prepend_features(cls)
453 assert_equal :mod, cls.new.m
454 assert_raise(FrozenError) { Module.new.prepend_features(Class.new.freeze) }
458 assert('Module#prepend') do
463 def m1; [:M1, super, :M1] end
466 def m1; [:M2, super, :M2] end
469 def m1; [:M3, super, :M3] end
472 def m1; [:M4, super, :M4] end
478 def m1; [:C0, super, :C0] end
483 def m1; [:C1, super, :C1] end
487 expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2]
488 assert_equal(expected, obj.m1)
491 assert('Module#prepend result') do
492 module TestPrepended; end
493 module TestPrependResult
494 @prepend_result = prepend TestPrepended
496 attr_reader :prepend_result
500 assert_equal TestPrependResult, TestPrependResult.prepend_result
503 # mruby shouldn't be affected by this since there is
504 # no visibility control (yet)
505 assert('Module#prepend public') do
506 assert_nothing_raised('ruby/ruby #8846') do
507 Class.new.prepend(Module.new)
511 assert('Module#prepend inheritance') do
512 bug6654 = '[ruby-core:45914]'
513 a = labeled_module('a')
514 b = labeled_module('b') { include a }
515 c = labeled_module('c') { prepend b }
518 # the Module#< operator should be used here instead, but we don't have it
519 assert_include(c.ancestors, a)
520 assert_include(c.ancestors, b)
523 bug8357 = '[ruby-core:54736] [Bug #8357]'
524 b = labeled_module('b') { prepend a }
525 c = labeled_class('c') { include b }
528 # the Module#< operator should be used here instead, but we don't have it
529 assert_include(c.ancestors, a)
530 assert_include(c.ancestors, b)
533 bug8357 = '[ruby-core:54742] [Bug #8357]'
534 assert_kind_of(b, c.new, bug8357)
537 assert 'Module#prepend + Class#ancestors' do
538 bug6658 = '[ruby-core:45919]'
539 m = labeled_module("m")
540 c = labeled_class("c") {prepend m}
541 assert_equal([m, c], c.ancestors[0, 2], bug6658)
543 bug6662 = '[ruby-dev:45868]'
544 c2 = labeled_class("c2", c)
546 assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662)
549 assert 'Module#prepend + Module#ancestors' do
550 bug6659 = '[ruby-dev:45861]'
551 m0 = labeled_module("m0") { def x; [:m0, *super] end }
552 m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 }
553 m2 = labeled_module("m2") { def x; [:m2, *super] end; prepend m1 }
554 c0 = labeled_class("c0") { def x; [:c0] end }
555 c1 = labeled_class("c1") { def x; [:c1] end; prepend m2 }
556 c2 = labeled_class("c2", c0) { def x; [:c2, *super] end; include m2 }
558 assert_equal([m0, m1], m1.ancestors, bug6659)
560 bug6662 = '[ruby-dev:45868]'
561 assert_equal([m0, m1, m2], m2.ancestors, bug6662)
562 assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662)
563 assert_equal([:m0, :m1, :m2, :c1], c1.new.x)
564 assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662)
565 assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x)
567 m3 = labeled_module("m3") { include m1; prepend m1 }
568 assert_equal([m3, m0, m1], m3.ancestors)
569 m3 = labeled_module("m3") { prepend m1; include m1 }
570 assert_equal([m0, m1, m3], m3.ancestors)
571 m3 = labeled_module("m3") { prepend m1; prepend m1 }
572 assert_equal([m0, m1, m3], m3.ancestors)
573 m3 = labeled_module("m3") { include m1; include m1 }
574 assert_equal([m3, m0, m1], m3.ancestors)
577 assert 'cyclic Module#prepend' do
578 bug7841 = '[ruby-core:52205] [Bug #7841]'
581 m1.instance_eval { prepend(m2) }
582 assert_raise(ArgumentError, bug7841) do
583 m2.instance_eval { prepend(m1) }
587 # these assertions will not run without a #assert_separately method
588 #assert 'test_prepend_optmethod' do
589 # bug7983 = '[ruby-dev:47124] [Bug #7983]'
590 # assert_separately [], %{
596 # Fixnum.send(:prepend, M)
597 # assert_equal(0.5, 1 / 2, "#{bug7983}")
599 # assert_equal(0, 1 / 2)
602 # mruby has no visibility control
603 # assert 'Module#prepend visibility' do
604 # bug8005 = '[ruby-core:53106] [Bug #8005]'
606 # prepend Module.new {}
611 # assert_true a.respond_to?(:foo), bug8005
612 # assert_nothing_raised(bug8005) {a.send :foo}
615 # mruby has no visibility control
616 # assert 'Module#prepend inherited visibility' do
617 # bug8238 = '[ruby-core:54105] [Bug #8238]'
618 # module Test4PrependVisibilityInherited
628 # assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}")
631 # assert 'Module#prepend super in alias' do
632 # skip "super does not currently work in aliased methods"
633 # bug7842 = '[Bug #7842]'
635 # p = labeled_module("P") do
636 # def m; "P"+super; end
639 # a = labeled_class("A") do
643 # b = labeled_class("B", a) do
644 # def m; "B"+super; end
650 # assert_nothing_raised do
651 # assert_equal("BA", b.new.m2, bug7842)
654 # assert_nothing_raised do
655 # assert_equal("PBA", b.new.m3, bug7842)
659 assert 'Module#prepend each class' do
660 m = labeled_module("M")
661 c1 = labeled_class("C1") {prepend m}
662 c2 = labeled_class("C2", c1) {prepend m}
663 assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should be able to prepend each class")
666 assert 'Module#prepend no duplication' do
667 m = labeled_module("M")
668 c = labeled_class("C") {prepend m; prepend m}
669 assert_equal([m, c], c.ancestors[0, 2], "should never duplicate")
672 assert 'Module#prepend in superclass' do
673 m = labeled_module("M")
674 c1 = labeled_class("C1")
675 c2 = labeled_class("C2", c1) {prepend m}
676 c1.class_eval {prepend m}
677 assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should accesisble prepended module in superclass")
680 # requires #assert_separately
681 #assert 'Module#prepend call super' do
682 # assert_separately([], <<-'end;') #do
683 # bug10847 = '[ruby-core:68093] [Bug #10847]'
686 # assert_nothing_raised(SystemStackError, bug10847) do
692 assert 'Module#prepend to frozen class' do
693 assert_raise(FrozenError) { Class.new.freeze.prepend Module.new }
697 assert('Module#to_s') do
700 const_set :SetInner, Class.new
703 assert_equal 'Outer', Outer.to_s
704 assert_equal 'Outer::Inner', Outer::Inner.to_s
705 assert_equal 'Outer::SetInner', Outer::SetInner.to_s
707 outer = Module.new do
708 const_set :SetInner, Class.new
710 Object.const_set :SetOuter, outer
712 assert_equal 'SetOuter', SetOuter.to_s
713 assert_equal 'SetOuter::SetInner', SetOuter::SetInner.to_s
715 assert_match "#<Module:0x*>", Module.new.to_s
716 assert_match "#<Class:0x*>", Class.new.to_s
718 assert_equal "FrozenClassToS", (FrozenClassToS = Class.new.freeze).to_s
719 assert_equal "Outer::A", (Outer::A = Module.new.freeze).to_s
720 assert_match "#<Module:0x*>::A", (Module.new::A = Class.new.freeze).to_s
723 assert('Module#inspect') do
724 module Test4to_sModules
727 assert_equal 'Test4to_sModules', Test4to_sModules.inspect
730 assert('Issue 1467') do
748 assert_kind_of(M1, C1.new)
749 assert_kind_of(M1, C2.new)
752 assert('clone Module') do
763 assert_true(B.new.foo)
766 assert('Module#module_function') do
769 module_function :modfunc
772 assert_true M.respond_to?(:modfunc)
775 assert('module with non-class/module outer raises TypeError') do
776 assert_raise(TypeError) { module 0::M1 end }
777 assert_raise(TypeError) { module []::M2 end }
780 assert('module to return the last value') do
785 assert('module to return nil if body is empty') do
786 assert_nil(module M end)
789 assert('get constant of parent module in singleton class; issue #3568') do
790 actual = module GetConstantInSingletonTest
797 assert_equal("value", actual)