#!/usr/local/bin/ruby #$IMPORT_MODULE_debug = true #$d2 = true #$SUPER = true #$debug = true #$PIP = true Thread.abort_on_exception = true $single_thread = false $script_dir = ""#"../" ["..", "../lib", "../dev-lib"].each do |x| $LOAD_PATH.unshift x end $import_module = $script_dir + "import-module" ARGV.delete_if do |x| case x when "m" $import_module = $script_dir + "import-module" true when "p" $import_module = $script_dir + "import-module-pip" true when "q" $import_module = $script_dir + "import-module-pip-b" true when "h" $import_module = $script_dir + "import-module-hash" true when "u" $import_module = $script_dir + "import-module-unbound-method" $stderr.puts "Warning: 'import' is not tested for unbound-method" $UNBOUND = true true when "s" $import_module = $script_dir + "import-module-single-thread" $single_thread_mode = true true when /^:/ $spot = x.sub(/^:/, '') true when /\.rb$/ $import_module = x true else false end end require $import_module #puts Import_Module::IMPORT_MODULE_Version $N = 0 def assert(m, n = nil) return if $spot && self.to_s != $spot $N += 1 unless n.nil? if m == n puts "#$N (#{self}): OK" else puts "NG (#{self}): #{m.inspect} != #{n.inspect}" puts caller#.first exit!(255) end else if m puts "#$N (#{self}): OK" else puts "NG (#{self}): #{m.inspect}" puts caller#.first exit!(255) end end end puts "SINGLE THREAD TEST" module First class A def m; 0; end end module M def m; 1; end end a = A.new assert(a.m, 0) A.import_module(M) do assert(a.m, 1) end assert(a.m, 0) end module Second module M001 def m; 1; end end module M002 def m; 2; end end class A000 def m; 0; end end a = A000.new A000.import_module(M001) do A000.import_module(M002) do assert(a.m, 2) end assert(a.m, 1) end assert(a.m, 0) end # non existance module NonExistance module M021 def m; 1; end end module M022 def m; 2; end end class A020 end a = A020.new A020.import_module(M021) do A020.import_module(M022) do assert(a.m, 2) end assert(a.m, 1) end begin assert(a.m, 0) rescue NameError else raise end end # Elementary module Elementary module MMm0 def m; 0; end end module MMm1 def m; 1; end end module MMm2 def m; 2; end end class Am3 def m; 3; end end class Bm4 def m; 4; end end module MMm5 def m; 5; end end module MMm6 def m; 6; end def n; 7; end end module MMmi6 include MMm6 end a = Am3.new b = Bm4.new assert(a.m, 3) assert(b.m, 4) Am3.import_module(MMm0) do assert(a.m, 0) assert(b.m, 4) Bm4.import_module(MMm2) do assert(a.m, 0) assert(b.m, 2) Bm4.import_module(MMmi6) do assert(a.m, 0) assert(b.m, 6) # assert(b.n, 7) end assert(a.m, 0) assert(b.m, 2) Am3.import_module(MMm5) do assert(a.m, 5) assert(b.m, 2) end assert(a.m, 0) assert(b.m, 2) end assert(a.m, 0) assert(b.m, 4) end assert(a.m, 3) assert(b.m, 4) end module StarArg class Am3 def m; 3; end end module MMm7 def f(x); x; end def g(x, *a); [x]+a; end end module MMm8 def f(x); x+1; end def g(x, *a); [x+1]+a; end end a = Am3.new Am3.import_module(MMm7) do assert(a.f(0), 0) assert(a.g(0, 0), [0, 0]) Am3.import_module(MMm8) do assert(a.f(0), 1) assert(a.g(0, 1), [1, 1]) end assert(a.f(0), 0) assert(a.g(0, 0), [0, 0]) end end ##### inheritance module Inheritance class Foo21 def foo; 21; end end class Bar21 def bar; 21; end end module S22 def foo; 22; end def bar; 22; end end class Foo23 < Foo21 end class Bar23 < Bar21 def bar; 23; end end o = Foo23.new u = Bar23.new Foo21.import_module(S22) do assert(o.foo, 22) end #Foo21.import_module(S22) do Bar21.import_module(S22) do assert(u.bar, 23) end end # Private, New Method module Private_NewMethod class C0m_n def m; 0; end def n; 0; end def assert_n(x) assert(n, x) end private :n end module M1mnq def m; 1; end def n; 1; end def q; 1; end private :n end o = C0m_n.new assert(o.m, 0) o.assert_n(0) C0m_n.import_module(M1mnq) do assert(o.m, 1) o.assert_n(1) assert(o.q, 1) end assert(o.m, 0) o.assert_n(0) begin o.n rescue NameError else raise "ERROR: can call private method" end end module Private_Protected class Foo def public_foo; end def private_foo; end def protected_foo; end private :private_foo protected :protected_foo end module Bar def public_foo; end def private_foo; end def protected_foo; end end Foo.import_module(Bar) do assert(Foo.public_instance_methods(true).include?("public_foo"), true) assert(Foo.private_instance_methods(true).include?("private_foo"), true) assert(Foo.protected_instance_methods(true).include?("protected_foo"), true) end assert(Foo.public_instance_methods(true).include?("public_foo"), true) assert(Foo.private_instance_methods(true).include?("private_foo"), true) assert(Foo.protected_instance_methods(true).include?("protected_foo"), true) end module Private_Proteced_Inheritance class Foo def public_foo; end def private_foo; end def protected_foo; end private :public_foo protected :private_foo end module Bar def public_foo; end def private_foo; end def protected_foo; end end class Baz < Foo def public_foo; end def private_foo; end def protected_foo; end private :private_foo protected :protected_foo end if RUBY_VERSION >= "1.7.0" Baz.import_module(Bar) do assert(Baz.public_instance_methods(true).include?("public_foo"), true) assert(Baz.private_instance_methods(true).include?("public_foo"), false) assert(Baz.protected_instance_methods(true).include?("public_foo"), false) assert(Baz.public_instance_methods(true).include?("private_foo"), false) assert(Baz.private_instance_methods(true).include?("private_foo"), true) assert(Baz.protected_instance_methods(true).include?("private_foo"), false) assert(Baz.public_instance_methods(true).include?("protected_foo"), false) assert(Baz.public_instance_methods(true).include?("protected_foo"), false) assert(Baz.protected_instance_methods(true).include?("protected_foo"), true) end assert(Baz.public_instance_methods(true).include?("public_foo"), true) assert(Baz.private_instance_methods(true).include?("private_foo"), true) assert(Baz.protected_instance_methods(true).include?("protected_foo"), true) end end module Private_Proteced_Inheritance class Foo def public_foo; end def private_foo; end def protected_foo; end private :private_foo protected :protected_foo end module Bar def public_foo; end def private_foo; end def protected_foo; end private :public_foo protected :private_foo end class Baz < Foo end if RUBY_VERSION >= "1.7.0" Baz.import_module(Bar) do assert(Baz.public_instance_methods(true).include?("public_foo"), true) assert(Baz.private_instance_methods(true).include?("public_foo"), false) assert(Baz.protected_instance_methods(true).include?("public_foo"), false) assert(Baz.public_instance_methods(true).include?("private_foo"), false) assert(Baz.private_instance_methods(true).include?("private_foo"), true) assert(Baz.protected_instance_methods(true).include?("private_foo"), false) assert(Baz.public_instance_methods(true).include?("protected_foo"), false) assert(Baz.public_instance_methods(true).include?("protected_foo"), false) assert(Baz.protected_instance_methods(true).include?("protected_foo"), true) end assert(Baz.public_instance_methods(true).include?("public_foo"), true) assert(Baz.private_instance_methods(true).include?("private_foo"), true) assert(Baz.protected_instance_methods(true).include?("protected_foo"), true) end end #unless single_thread_mode? ## assert(C0m_n.instance_methods.size, 5) ## assert(C0m_n.private_instance_methods.size, 1) #p C0m_n.instance_methods #p C0m_n.private_instance_methods #else ## assert(C0m_n.instance_methods.size, 2+1) ## assert(C0m_n.private_instance_methods.size, 1+1) #end ### triple module Triple class F0 def f; 0; end def g; 0; end def h; 0; end end module F1 def f; 1; end def g; 1; end end module F2 def g; 2; end def h; 2; end end o = F0.new F0.import_module(F1) do assert([o.f, o.g, o.h], [1, 1, 0]) F0.import_module(F2) do assert([o.f, o.g, o.h], [1, 2, 2]) end assert([o.f, o.g, o.h], [1, 1, 0]) end assert([o.f, o.g, o.h], [0, 0, 0]) end # Deep Nesting 1 module DeepNesting1 module M031 def m; 1; end end module M032 def m; 2; end end class C030 def m; 0; end end o = C030.new C030.import_module(M031) do C030.import_module(M032) do end end assert(o.m, 0) C030.import_module(M031) do assert(o.m, 1) end end # Deep Nesting 2 module DeepNesting2 module M0mn def m; 0; end def n; 0; end end module M1mn def m; 1; end def n; 1; end end module M2mn def m; 2; end def n; 2; end end module M3mn def m; 3; end def n; 3; end end class DM0mn include M0mn end o = DM0mn.new DM0mn.import_module(M1mn) do DM0mn.import_module(M2mn) do assert(o.m, 2) assert(o.n, 2) end assert(o.m, 1) assert(o.n, 1) end assert(o.m, 0) assert(o.n, 0) DM0mn.import_module(M1mn) do assert(o.m, 1) assert(o.n, 1) DM0mn.import_module(M2mn) do assert(o.m, 2) assert(o.n, 2) DM0mn.import_module(M0mn) do assert(o.m, 0) assert(o.n, 0) end assert(o.m, 2) assert(o.n, 2) DM0mn.import_module(M3mn) do assert(o.m, 3) assert(o.n, 3) end assert(o.m, 2) assert(o.n, 2) end assert(o.m, 1) assert(o.n, 1) DM0mn.import_module(M3mn) do assert(o.m, 3) assert(o.n, 3) end assert(o.m, 1) assert(o.n, 1) end assert(o.m, 0) assert(o.n, 0) #assert(DM0mn.instance_methods.sort, ["m", "n"]) end # Singleton Method module SingletonMethod class Foo def m; 0; end end module Bar def m; 1; end end o0 = Foo.new o1 = Foo.new o0.import(Bar) do assert(o0.m, 1) unless $UNBOUND assert(o1.m, 0) unless $UNBOUND end end module SingletonMethod2 module Mm0 def self.m; 0; end end module Mm4 def m; 4; end end assert(Mm0.m, 0) Mm0.import(Mm4) do assert(Mm0.m, 4) unless $UNBOUND end assert(Mm0.m, 0) end ##### SUPER module Super module MB0 set_orig_method :_f, :f def f;[_f, 0]; end end module MB1 include MB0 def f;[super, 1]; end end module MB2 include MB1 def f; [super, 2]; end end class BB def f; 0; end end class FB < BB include MB2 def f; -1; end end o = FB.new FB.import_module(MB2) do assert(o.f, [[[-1, 0], 1], 2]) end end module Super2 module Each_Index set_orig_method :_each, :each def each(&b) i = 0 _each do |x| yield(x, 2 * i) i += 1 end end end # mapmap # assert([10, 11, 12].import(Each_Index) {|s| s.map{|x| x}}, # [[10, 0], [11, 2], [12, 4]]) unless $UNBOUND assert([10, 11, 12].map{|x| x}, [10, 11, 12]) unless $UNBOUND module Each_Char def each(&b); split(//).each(&b); end end assert("abc".import(Each_Char){|s| s.map{|x| x.succ}}.join(""), "bcd") unless $UNBOUND assert("abc".import(Each_Char){|s| s.map{|x| x.succ}}.join(""), "bcd") unless $UNBOUND end module Super3 class FE include Enumerable def each yield 10 yield 20 yield 30 end end module IndexedEach set_orig_method :_each, :each def each i = 0 _each do |x| i += 1 yield(i, x) end end end # module IndexedEach2 # def each # i = 0 # super do |x| # i += 1 # yield(2*i, x) # end # end # end foo = FE.new FE.import_module(IndexedEach) do assert(foo.to_a, [[1, 10], [2, 20], [3, 30]]) # FE.import_module(IndexedEach2) do # assert(foo.to_a, [[2, [1, 10]], [4, [2, 20]], [6, [3, 30]]]) # end # assert(foo.to_a, [[1, 10], [2, 20], [3, 30]]) end end ### Scope_module module ScopeCreate class A def foo 0 end end module M def foo 1 end end module N def foo 2 end end class SC0 def foo; 0; end end module SM1 def foo; 1; end end module SM2 def foo; 2; end end s1 = Import_Module::Scope.create(SC0, SM1) s2 = Import_Module::Scope.create(SC0, SM2) c = SC0.new assert(c.foo, 0) s1.activate do assert(c.foo, 1) s2.activate do assert(c.foo, 2) s1.activate do assert(c.foo, 1) end assert(c.foo, 2) end assert(c.foo, 1) end assert(c.foo, 0) end ######################################################################## ################## Multi Thread ######################################## ######################################################################## if $single_thread_mode puts "All tests (#$import_module) succeeded." exit end puts "MULTI THREAD TEST" # Multi Thread, Nesting module MultiThreadNesting module K1mn def m; 1; end def n; 1; end end module K2mn def m; 2; end def n; 2; end end module K3mn def m; 3; end def n; 3; end end class B0mn def m; 0; end def n; 0; end end thrs = [] o = B0mn.new thrs << Thread.start do assert(o.m, 0) assert(o.n, 0) B0mn.import_module(K1mn) do assert(o.m, 1) assert(o.n, 1) end assert(o.m, 0) assert(o.n, 0) B0mn.import_module(K2mn) do assert(o.m, 2) assert(o.n, 2) end assert(o.m, 0) assert(o.n, 0) thrs << Thread.start do assert(o.m, 0) assert(o.n, 0) B0mn.import_module(K3mn) do assert(o.m, 3) assert(o.n, 3) end assert(o.m, 0) assert(o.n, 0) end assert(o.m, 0) assert(o.n, 0) B0mn.import_module(K2mn) do assert(o.m, 2) assert(o.n, 2) end end assert(o.m, 0) assert(o.n, 0) thrs.each do |thr| thr.join end end # Do Not Erase Me module DoNotErace class E0m def m; 0; end end module L1m def m; 1; end end o = E0m.new thrs = [] E0m.import_module(L1m) do thrs << Thread.new do sleep 0.1 assert(o.m, 1) end end assert(o.m, 0) thrs.each do |th| th.join; end class E2m def m; 2; end end module L3m def m; 3; end end o = E2m.new thrs = [] thrs << Thread.new do E2m.import_module(L3m) do assert(o.m, 3) end end assert(o.m, 2) thrs.each do |th| th.join; end end # scopes in theads module ScopesInThreads class ST def f 0 end end module STM module M def f 1 end end end o = ST.new thrs = [] 3.times do thrs << Thread.start{ ST.import_module(STM::M) do 3.times do assert(o.f, 1) end end } end thrs.each{|th| th.join} end # Various Timing module VariousTiming module Mf0 def f; 0; end end module Mf1 def f; 1; end end module Mf2 def f; 2; end end module Mf3 def f; 3; end end module Mf4 def f; 4; end end module Mf5 def f; 5; end end class CMf0 include Mf0 end o = CMf0.new [ [0.0, 0.0, 0.0, 0.0], [0.01, 0.02, 0.0, 0.03], [0.02, 0.0, 0.01, 0.0], [0.02, 0.01, 0.01, 0.0], [0.01, 0.01, 0.01, 0.0], [0.01, 0.01, 0.0, 0.01], [0.01, 0.0, 0.01, 0.01], [0.0, 0.01, 0.01, 0.01], [0.01, 0.01, 0.01, 0.01], ].each do |a, b, c, d| thrs = [] assert(o.f, 0) thrs << Thread.start do CMf0.import_module(Mf1) do sleep a assert(o.f, 1) thrs << Thread.start do assert(o.f, 1) CMf0.import_module(Mf2) do assert(o.f, 2) thrs << Thread.start do CMf0.import_module(Mf3) do sleep b assert(o.f, 3) end end CMf0.import_module(Mf4) do assert(o.f, 4) end end end sleep c end end sleep d assert(o.f, 0) thrs.each do |th| th.join; end end end # Bottom Scope in Deep Thread module BottomScope class CN0m def m; 0; end end module N1m def m; 1; end end module N2m def m; 2; end end o = CN0m.new thrs = [] thrs << Thread.new do thrs << Thread.new do thrs << Thread.new do thrs << Thread.new do CN0m.import_module(N1m) do assert(o.m, 1) end end end sleep 0.1 CN0m.import_module(N2m) do assert(o.m, 2) end end end assert(o.m, 0) thrs.each do |th| th.join; end # Many Thread class B0m def m; 0; end end module K1m def m; 1; end end o = B0m.new thrs = [] 100.times do |n| thrs << Thread.start do B0m.import_module(K1m) do assert(o.m, 1) if n == 99 end end end thrs.each do |thr| thr.join end #puts B0m.instance_methods assert(B0m.instance_methods(false).size, 2) end puts "All tests (#$import_module) succeeded."