## # Module ISO Test def labeled_module(name, &block) Module.new do (class <", m.to_s) assert_not_predicate(m, :frozen?) assert_not_predicate(TestModuleDup.freeze.dup, :frozen?) end assert('Module#define_method') do c = Class.new { define_method(:m1) { :ok } define_method(:m2, Proc.new { :ok }) } assert_equal c.new.m1, :ok assert_equal c.new.m2, :ok assert_raise(TypeError) do Class.new { define_method(:n1, nil) } end end assert 'Module#prepend_features' do mod = Module.new { def m; :mod end } cls = Class.new { def m; :cls end } assert_equal :cls, cls.new.m mod.prepend_features(cls) assert_equal :mod, cls.new.m assert_raise(FrozenError) { Module.new.prepend_features(Class.new.freeze) } end # @!group prepend assert('Module#prepend') do module M0 def m1; [:M0] end end module M1 def m1; [:M1, super, :M1] end end module M2 def m1; [:M2, super, :M2] end end M3 = Module.new do def m1; [:M3, super, :M3] end end module M4 def m1; [:M4, super, :M4] end end class P0 include M0 prepend M1 def m1; [:C0, super, :C0] end end class P1 < P0 prepend M2, M3 include M4 def m1; [:C1, super, :C1] end end obj = P1.new expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2] assert_equal(expected, obj.m1) end assert('Module#prepend result') do module TestPrepended; end module TestPrependResult @prepend_result = prepend TestPrepended class << self attr_reader :prepend_result end end assert_equal TestPrependResult, TestPrependResult.prepend_result end # mruby shouldn't be affected by this since there is # no visibility control (yet) assert('Module#prepend public') do assert_nothing_raised('ruby/ruby #8846') do Class.new.prepend(Module.new) end end assert('Module#prepend inheritance') do bug6654 = '[ruby-core:45914]' a = labeled_module('a') b = labeled_module('b') { include a } c = labeled_module('c') { prepend b } #assert bug6654 do # the Module#< operator should be used here instead, but we don't have it assert_include(c.ancestors, a) assert_include(c.ancestors, b) #end bug8357 = '[ruby-core:54736] [Bug #8357]' b = labeled_module('b') { prepend a } c = labeled_class('c') { include b } #assert bug8357 do # the Module#< operator should be used here instead, but we don't have it assert_include(c.ancestors, a) assert_include(c.ancestors, b) #end bug8357 = '[ruby-core:54742] [Bug #8357]' assert_kind_of(b, c.new, bug8357) end assert 'Module#prepend + Class#ancestors' do bug6658 = '[ruby-core:45919]' m = labeled_module("m") c = labeled_class("c") {prepend m} assert_equal([m, c], c.ancestors[0, 2], bug6658) bug6662 = '[ruby-dev:45868]' c2 = labeled_class("c2", c) anc = c2.ancestors assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662) end assert 'Module#prepend + Module#ancestors' do bug6659 = '[ruby-dev:45861]' m0 = labeled_module("m0") { def x; [:m0, *super] end } m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 } m2 = labeled_module("m2") { def x; [:m2, *super] end; prepend m1 } c0 = labeled_class("c0") { def x; [:c0] end } c1 = labeled_class("c1") { def x; [:c1] end; prepend m2 } c2 = labeled_class("c2", c0) { def x; [:c2, *super] end; include m2 } # assert_equal([m0, m1], m1.ancestors, bug6659) # bug6662 = '[ruby-dev:45868]' assert_equal([m0, m1, m2], m2.ancestors, bug6662) assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662) assert_equal([:m0, :m1, :m2, :c1], c1.new.x) assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662) assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x) # m3 = labeled_module("m3") { include m1; prepend m1 } assert_equal([m3, m0, m1], m3.ancestors) m3 = labeled_module("m3") { prepend m1; include m1 } assert_equal([m0, m1, m3], m3.ancestors) m3 = labeled_module("m3") { prepend m1; prepend m1 } assert_equal([m0, m1, m3], m3.ancestors) m3 = labeled_module("m3") { include m1; include m1 } assert_equal([m3, m0, m1], m3.ancestors) end assert 'cyclic Module#prepend' do bug7841 = '[ruby-core:52205] [Bug #7841]' m1 = Module.new m2 = Module.new m1.instance_eval { prepend(m2) } assert_raise(ArgumentError, bug7841) do m2.instance_eval { prepend(m1) } end end # these assertions will not run without a #assert_separately method #assert 'test_prepend_optmethod' do # bug7983 = '[ruby-dev:47124] [Bug #7983]' # assert_separately [], %{ # module M # def /(other) # to_f / other # end # end # Integer.send(:prepend, M) # assert_equal(0.5, 1 / 2, "#{bug7983}") # } # assert_equal(0, 1 / 2) #end # mruby has no visibility control # assert 'Module#prepend visibility' do # bug8005 = '[ruby-core:53106] [Bug #8005]' # c = Class.new do # prepend Module.new {} # def foo() end # protected :foo # end # a = c.new # assert_true a.respond_to?(:foo), bug8005 # assert_nothing_raised(bug8005) {a.send :foo} # end # mruby has no visibility control # assert 'Module#prepend inherited visibility' do # bug8238 = '[ruby-core:54105] [Bug #8238]' # module Test4PrependVisibilityInherited # class A # def foo() A; end # private :foo # end # class B < A # public :foo # prepend Module.new # end # end # assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}") # end # assert 'Module#prepend super in alias' do # skip "super does not currently work in aliased methods" # bug7842 = '[Bug #7842]' # p = labeled_module("P") do # def m; "P"+super; end # end # a = labeled_class("A") do # def m; "A"; end # end # b = labeled_class("B", a) do # def m; "B"+super; end # alias m2 m # prepend p # alias m3 m # end # assert_nothing_raised do # assert_equal("BA", b.new.m2, bug7842) # end # assert_nothing_raised do # assert_equal("PBA", b.new.m3, bug7842) # end # end assert 'Module#prepend each class' do m = labeled_module("M") c1 = labeled_class("C1") {prepend m} c2 = labeled_class("C2", c1) {prepend m} assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should be able to prepend each class") end assert 'Module#prepend no duplication' do m = labeled_module("M") c = labeled_class("C") {prepend m; prepend m} assert_equal([m, c], c.ancestors[0, 2], "should never duplicate") end assert 'Module#prepend in superclass' do m = labeled_module("M") c1 = labeled_class("C1") c2 = labeled_class("C2", c1) {prepend m} c1.class_eval {prepend m} assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should accessible prepended module in superclass") end # requires #assert_separately #assert 'Module#prepend call super' do # assert_separately([], <<-'end;') #do # bug10847 = '[ruby-core:68093] [Bug #10847]' # module M; end # Float.prepend M # assert_nothing_raised(SystemStackError, bug10847) do # 0.3.numerator # end # end #end assert 'Module#prepend to frozen class' do assert_raise(FrozenError) { Class.new.freeze.prepend Module.new } end # @!endgroup prepend assert('Module#to_s') do module Outer class Inner; end const_set :SetInner, Class.new end assert_equal 'Outer', Outer.to_s assert_equal 'Outer::Inner', Outer::Inner.to_s assert_equal 'Outer::SetInner', Outer::SetInner.to_s outer = Module.new do const_set :SetInner, Class.new end Object.const_set :SetOuter, outer assert_equal 'SetOuter', SetOuter.to_s assert_equal 'SetOuter::SetInner', SetOuter::SetInner.to_s assert_match "#", Module.new.to_s assert_match "#", Class.new.to_s assert_equal "FrozenClassToS", (FrozenClassToS = Class.new.freeze).to_s assert_equal "Outer::A", (Outer::A = Module.new.freeze).to_s assert_match "#::A", (Module.new::A = Class.new.freeze).to_s end assert('Module#inspect') do module Test4to_sModules end assert_equal 'Test4to_sModules', Test4to_sModules.inspect end assert('Issue 1467') do module M1 def initialize super() end end class C1 include M1 def initialize super() end end class C2 include M1 end assert_kind_of(M1, C1.new) assert_kind_of(M1, C2.new) end assert('clone Module') do module M1 def foo true end end class B include M1.clone end assert_true(B.new.foo) end assert('Module#module_function') do module M def modfunc; end module_function :modfunc end assert_true M.respond_to?(:modfunc) end assert('module with non-class/module outer raises TypeError') do assert_raise(TypeError) { module 0::M1 end } assert_raise(TypeError) { module []::M2 end } end assert('module to return the last value') do m = module M; :m end assert_equal(m, :m) end assert('module to return nil if body is empty') do assert_nil(module M end) end assert('get constant of parent module in singleton class; issue #3568') do actual = module GetConstantInSingletonTest EXPECTED = "value" class << self EXPECTED end end assert_equal("value", actual) end