summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-15 06:23:43 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-15 06:23:43 +0000
commitef520e2faf2a8e5cc5beedcf1c2d5286a6e234a3 (patch)
tree4e07bbc9628b5d412c8a5ecdbe9a2621aec0e6c5 /test
parent3ab0a92bf1d9926f35dc7aaa1a7d8121d0a7ffcf (diff)
downloadruby-ef520e2faf2a8e5cc5beedcf1c2d5286a6e234a3.tar.gz
ruby-ef520e2faf2a8e5cc5beedcf1c2d5286a6e234a3.tar.xz
ruby-ef520e2faf2a8e5cc5beedcf1c2d5286a6e234a3.zip
* test/ruby/test_metaclass.rb: new test case for metaclass hierarchy.
* class.c (make_metametaclass): new function. extracted from rb_make_metaclass. * class.c (rb_make_metaclass): uses make_metametaclass when called for a metaclass. * class.c (rb_singleton_class): creates a meta^(n+2)-class in addition to a meta^(n+1)-class when called for a meta^(n)-class. This is because the returned meta^(n+1) class must acts as an instance of Class, metaclass of Class, ..., meta^(n+1)-class of Class, Module, metaclass of Module, ..., meta^(n+1)-class of Module, Object, metaclass of Object, ..., meta^(n+2)-class of Object, BasicObject, metaclass of BasicObject, ..., meta^(n+2)-class of and BasicObject even when Class, Module, Object or BasicObject has not have its meta^(i)-class yet. git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@20747 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test')
-rw-r--r--test/ruby/test_metaclass.rb169
1 files changed, 169 insertions, 0 deletions
diff --git a/test/ruby/test_metaclass.rb b/test/ruby/test_metaclass.rb
new file mode 100644
index 000000000..d531cb9dc
--- /dev/null
+++ b/test/ruby/test_metaclass.rb
@@ -0,0 +1,169 @@
+require 'test/unit'
+require_relative 'envutil'
+require '~/dev/metaclass_util/metaclass_util'
+
+class TestMetaclass < Test::Unit::TestCase
+ class Foo; end
+ class Bar < Foo; end
+ class Baz; end
+
+ def setup
+ Object.class_eval do
+ def method_o; end
+ end
+ Module.class_eval do
+ def method_m; end
+ end
+ Class.class_eval do
+ def method_c; end
+ end
+ end
+ def teardown
+ Object.class_eval do
+ remove_method :method_o rescue nil
+ end
+ Module.class_eval do
+ remove_method :method_m rescue nil
+ end
+ Class.class_eval do
+ remove_method :method_c rescue nil
+ end
+ Object.class_eval do
+ class << self
+ remove_method :class_method_o rescue nil
+ end
+ end
+ Module.class_eval do
+ class << self
+ remove_method :class_method_m rescue nil
+ end
+ end
+ Class.class_eval do
+ class << self
+ remove_method :class_method_c rescue nil
+ end
+ end
+ Object.class_eval do
+ class << self
+ class << self
+ remove_method :metaclass_method_o rescue nil
+ end
+ end
+ end
+ Module.class_eval do
+ class << self
+ class << self
+ remove_method :metaclass_method_m rescue nil
+ end
+ end
+ end
+ Class.class_eval do
+ class << self
+ class << self
+ remove_method :metaclass_method_c rescue nil
+ end
+ end
+ end
+ end
+
+ def test_metaclass
+ class << Object
+ def class_method_o; end
+ end
+ class << Foo
+ def class_method_f; end
+ end
+ class << Baz
+ def class_method_b; end
+ end
+ assert_nothing_raised{ Bar.method_o }
+ assert_nothing_raised{ Bar.method_m }
+ assert_nothing_raised{ Bar.method_c }
+ assert_nothing_raised{ Bar.class_method_o }
+ assert_nothing_raised{ Bar.class_method_f }
+ assert_raise(NoMethodError){ Bar.class_method_b }
+
+ class << Module
+ def class_method_m; end
+ end
+ class << Class
+ def class_method_c; end
+ end
+ class << Object
+ class << self
+ def metaclass_method_o; end
+ end
+ end
+ class << Foo
+ class << self
+ def metaclass_method_f; end
+ end
+ end
+ class << Baz
+ class << self
+ def metaclass_method_b; end
+ end
+ end
+ metaclass_of_bar = class << Bar; self end
+ assert_nothing_raised{ metaclass_of_bar.method_o }
+ assert_nothing_raised{ metaclass_of_bar.method_m }
+ assert_nothing_raised{ metaclass_of_bar.method_c }
+ assert_nothing_raised{ metaclass_of_bar.class_method_o }
+ assert_raise(NoMethodError){ metaclass_of_bar.class_method_f }
+ assert_raise(NoMethodError){ metaclass_of_bar.class_method_b }
+ assert_nothing_raised{ metaclass_of_bar.class_method_m }
+ assert_nothing_raised{ metaclass_of_bar.class_method_c }
+ assert_nothing_raised{ metaclass_of_bar.metaclass_method_o }
+ assert_nothing_raised{ metaclass_of_bar.metaclass_method_f }
+ assert_raise(NoMethodError){ metaclass_of_bar.metaclass_method_b }
+
+ class << Module
+ class << self
+ def metaclass_method_m; end
+ end
+ end
+ class << Class
+ class << self
+ def metaclass_method_c; end
+ end
+ end
+ class << Object
+ class << self
+ class << self
+ def metametaclass_method_o; end
+ end
+ end
+ end
+ class << Foo
+ class << self
+ class << self
+ def metametaclass_method_f; end
+ end
+ end
+ end
+ class << Baz
+ class << self
+ class << self
+ def metametaclass_method_b; end
+ end
+ end
+ end
+ metametaclass_of_bar = class << metaclass_of_bar; self end
+ assert_nothing_raised{ metametaclass_of_bar.method_o }
+ assert_nothing_raised{ metametaclass_of_bar.method_m }
+ assert_nothing_raised{ metametaclass_of_bar.method_c }
+ assert_nothing_raised{ metametaclass_of_bar.class_method_o }
+ assert_raise(NoMethodError){ metametaclass_of_bar.class_method_f }
+ assert_raise(NoMethodError){ metametaclass_of_bar.class_method_b }
+ assert_nothing_raised{ metametaclass_of_bar.class_method_m }
+ assert_nothing_raised{ metametaclass_of_bar.class_method_c }
+ assert_nothing_raised{ metametaclass_of_bar.metaclass_method_o }
+ assert_raise(NoMethodError){ metametaclass_of_bar.metaclass_method_f }
+ assert_raise(NoMethodError){ metametaclass_of_bar.metaclass_method_b }
+ assert_nothing_raised{ metametaclass_of_bar.metaclass_method_m }
+ assert_nothing_raised{ metametaclass_of_bar.metaclass_method_c }
+ assert_nothing_raised{ metametaclass_of_bar.metametaclass_method_o }
+ assert_nothing_raised{ metametaclass_of_bar.metametaclass_method_f }
+ assert_raise(NoMethodError){ metametaclass_of_bar.metaclass_method_b }
+ end
+end