mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	 26766ee89c
			
		
	
	
		26766ee89c
		
	
	
	
	
		
			
			git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42809 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			1826 lines
		
	
	
	
		
			45 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			1826 lines
		
	
	
	
		
			45 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| require 'test/unit'
 | |
| require 'pp'
 | |
| require_relative 'envutil'
 | |
| 
 | |
| $m0 = Module.nesting
 | |
| 
 | |
| class TestModule < Test::Unit::TestCase
 | |
|   def _wrap_assertion
 | |
|     yield
 | |
|   end
 | |
| 
 | |
|   def assert_method_defined?(klass, mid, message="")
 | |
|     message = build_message(message, "#{klass}\##{mid} expected to be defined.")
 | |
|     _wrap_assertion do
 | |
|       klass.method_defined?(mid) or
 | |
|         raise Test::Unit::AssertionFailedError, message, caller(3)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def assert_method_not_defined?(klass, mid, message="")
 | |
|     message = build_message(message, "#{klass}\##{mid} expected to not be defined.")
 | |
|     _wrap_assertion do
 | |
|       klass.method_defined?(mid) and
 | |
|         raise Test::Unit::AssertionFailedError, message, caller(3)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def setup
 | |
|     @verbose = $VERBOSE
 | |
|     $VERBOSE = nil
 | |
|   end
 | |
| 
 | |
|   def teardown
 | |
|     $VERBOSE = @verbose
 | |
|   end
 | |
| 
 | |
|   def test_LT_0
 | |
|     assert_equal true, String < Object
 | |
|     assert_equal false, Object < String
 | |
|     assert_nil String < Array
 | |
|     assert_equal true, Array < Enumerable
 | |
|     assert_equal false, Enumerable < Array
 | |
|     assert_nil Proc < Comparable
 | |
|     assert_nil Comparable < Proc
 | |
|   end
 | |
| 
 | |
|   def test_GT_0
 | |
|     assert_equal false, String > Object
 | |
|     assert_equal true, Object > String
 | |
|     assert_nil String > Array
 | |
|     assert_equal false, Array > Enumerable
 | |
|     assert_equal true, Enumerable > Array
 | |
|     assert_nil Comparable > Proc
 | |
|     assert_nil Proc > Comparable
 | |
|   end
 | |
| 
 | |
|   def test_CMP_0
 | |
|     assert_equal(-1, (String <=> Object))
 | |
|     assert_equal 1, (Object <=> String)
 | |
|     assert_nil(Array <=> String)
 | |
|   end
 | |
| 
 | |
|   ExpectedException = NoMethodError
 | |
| 
 | |
|   # Support stuff
 | |
| 
 | |
|   module Mixin
 | |
|     MIXIN = 1
 | |
|     def mixin
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   module User
 | |
|     USER = 2
 | |
|     include Mixin
 | |
|     def user
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   module Other
 | |
|     def other
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   class AClass
 | |
|     def AClass.cm1
 | |
|       "cm1"
 | |
|     end
 | |
|     def AClass.cm2
 | |
|       cm1 + "cm2" + cm3
 | |
|     end
 | |
|     def AClass.cm3
 | |
|       "cm3"
 | |
|     end
 | |
| 
 | |
|     private_class_method :cm1, "cm3"
 | |
| 
 | |
|     def aClass
 | |
|       :aClass
 | |
|     end
 | |
| 
 | |
|     def aClass1
 | |
|       :aClass1
 | |
|     end
 | |
| 
 | |
|     def aClass2
 | |
|       :aClass2
 | |
|     end
 | |
| 
 | |
|     private :aClass1
 | |
|     protected :aClass2
 | |
|   end
 | |
| 
 | |
|   class BClass < AClass
 | |
|     def bClass1
 | |
|       :bClass1
 | |
|     end
 | |
| 
 | |
|     private
 | |
| 
 | |
|     def bClass2
 | |
|       :bClass2
 | |
|     end
 | |
| 
 | |
|     protected
 | |
|     def bClass3
 | |
|       :bClass3
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   class CClass < BClass
 | |
|     def self.cClass
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   MyClass = AClass.clone
 | |
|   class MyClass
 | |
|     public_class_method :cm1
 | |
|   end
 | |
| 
 | |
|   # -----------------------------------------------------------
 | |
| 
 | |
|   def test_CMP # '<=>'
 | |
|     assert_equal( 0, Mixin <=> Mixin)
 | |
|     assert_equal(-1, User <=> Mixin)
 | |
|     assert_equal( 1, Mixin <=> User)
 | |
| 
 | |
|     assert_equal( 0, Object <=> Object)
 | |
|     assert_equal(-1, String <=> Object)
 | |
|     assert_equal( 1, Object <=> String)
 | |
|   end
 | |
| 
 | |
|   def test_GE # '>='
 | |
|     assert(Mixin >= User)
 | |
|     assert(Mixin >= Mixin)
 | |
|     assert(!(User >= Mixin))
 | |
| 
 | |
|     assert(Object >= String)
 | |
|     assert(String >= String)
 | |
|     assert(!(String >= Object))
 | |
|   end
 | |
| 
 | |
|   def test_GT # '>'
 | |
|     assert(Mixin   > User)
 | |
|     assert(!(Mixin > Mixin))
 | |
|     assert(!(User  > Mixin))
 | |
| 
 | |
|     assert(Object > String)
 | |
|     assert(!(String > String))
 | |
|     assert(!(String > Object))
 | |
|   end
 | |
| 
 | |
|   def test_LE # '<='
 | |
|     assert(User <= Mixin)
 | |
|     assert(Mixin <= Mixin)
 | |
|     assert(!(Mixin <= User))
 | |
| 
 | |
|     assert(String <= Object)
 | |
|     assert(String <= String)
 | |
|     assert(!(Object <= String))
 | |
|   end
 | |
| 
 | |
|   def test_LT # '<'
 | |
|     assert(User < Mixin)
 | |
|     assert(!(Mixin < Mixin))
 | |
|     assert(!(Mixin < User))
 | |
| 
 | |
|     assert(String < Object)
 | |
|     assert(!(String < String))
 | |
|     assert(!(Object < String))
 | |
|   end
 | |
| 
 | |
|   def test_VERY_EQUAL # '==='
 | |
|     assert(Object === self)
 | |
|     assert(Test::Unit::TestCase === self)
 | |
|     assert(TestModule === self)
 | |
|     assert(!(String === self))
 | |
|   end
 | |
| 
 | |
|   def test_ancestors
 | |
|     assert_equal([User, Mixin],      User.ancestors)
 | |
|     assert_equal([Mixin],            Mixin.ancestors)
 | |
| 
 | |
|     ancestors = Object.ancestors
 | |
|     mixins = ancestors - [Object, Kernel, BasicObject]
 | |
|     mixins << JSON::Ext::Generator::GeneratorMethods::String if defined?(JSON::Ext::Generator::GeneratorMethods::String)
 | |
|     assert_equal([Object, Kernel, BasicObject], ancestors - mixins)
 | |
|     assert_equal([String, Comparable, Object, Kernel, BasicObject], String.ancestors - mixins)
 | |
|   end
 | |
| 
 | |
|   CLASS_EVAL = 2
 | |
|   @@class_eval = 'b'
 | |
| 
 | |
|   def test_class_eval
 | |
|     Other.class_eval("CLASS_EVAL = 1")
 | |
|     assert_equal(1, Other::CLASS_EVAL)
 | |
|     assert(Other.constants.include?(:CLASS_EVAL))
 | |
|     assert_equal(2, Other.class_eval { CLASS_EVAL })
 | |
| 
 | |
|     Other.class_eval("@@class_eval = 'a'")
 | |
|     assert_equal('a', Other.class_variable_get(:@@class_eval))
 | |
|     assert_equal('b', Other.class_eval { @@class_eval })
 | |
| 
 | |
|     Other.class_eval do
 | |
|       module_function
 | |
| 
 | |
|       def class_eval_test
 | |
|         "foo"
 | |
|       end
 | |
|     end
 | |
|     assert_equal("foo", Other.class_eval_test)
 | |
| 
 | |
|     assert_equal([Other], Other.class_eval { |*args| args })
 | |
|   end
 | |
| 
 | |
|   def test_const_defined?
 | |
|     assert(Math.const_defined?(:PI))
 | |
|     assert(Math.const_defined?("PI"))
 | |
|     assert(!Math.const_defined?(:IP))
 | |
|     assert(!Math.const_defined?("IP"))
 | |
|   end
 | |
| 
 | |
|   def test_bad_constants
 | |
|     [
 | |
|       "#<Class:0x7b8b718b>",
 | |
|       ":Object",
 | |
|       "",
 | |
|       ":",
 | |
|       ["String::", "[Bug #7573]"],
 | |
|     ].each do |name, msg|
 | |
|       e = assert_raises(NameError, "#{msg}#{': ' if msg}wrong constant name #{name.dump}") {
 | |
|         Object.const_get name
 | |
|       }
 | |
|       assert_equal("wrong constant name %s" % name, e.message)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_leading_colons
 | |
|     assert_equal Object, AClass.const_get('::Object')
 | |
|   end
 | |
| 
 | |
|   def test_const_get
 | |
|     assert_equal(Math::PI, Math.const_get("PI"))
 | |
|     assert_equal(Math::PI, Math.const_get(:PI))
 | |
| 
 | |
|     n = Object.new
 | |
|     def n.to_str; @count = defined?(@count) ? @count + 1 : 1; "PI"; end
 | |
|     def n.count; @count; end
 | |
|     assert_equal(Math::PI, Math.const_get(n))
 | |
|     assert_equal(1, n.count)
 | |
|   end
 | |
| 
 | |
|   def test_nested_get
 | |
|     assert_equal Other, Object.const_get([self.class, Other].join('::'))
 | |
|     assert_equal User::USER, self.class.const_get([User, 'USER'].join('::'))
 | |
|   end
 | |
| 
 | |
|   def test_nested_get_symbol
 | |
|     const = [self.class, Other].join('::').to_sym
 | |
|     assert_raise(NameError) {Object.const_get(const)}
 | |
| 
 | |
|     const = [User, 'USER'].join('::').to_sym
 | |
|     assert_raise(NameError) {self.class.const_get(const)}
 | |
|   end
 | |
| 
 | |
|   def test_nested_get_const_missing
 | |
|     classes = []
 | |
|     klass = Class.new {
 | |
|       define_singleton_method(:const_missing) { |name|
 | |
| 	classes << name
 | |
| 	klass
 | |
|       }
 | |
|     }
 | |
|     klass.const_get("Foo::Bar::Baz")
 | |
|     assert_equal [:Foo, :Bar, :Baz], classes
 | |
|   end
 | |
| 
 | |
|   def test_nested_bad_class
 | |
|     assert_raises(TypeError) do
 | |
|       self.class.const_get([User, 'USER', 'Foo'].join('::'))
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_const_set
 | |
|     assert(!Other.const_defined?(:KOALA))
 | |
|     Other.const_set(:KOALA, 99)
 | |
|     assert(Other.const_defined?(:KOALA))
 | |
|     assert_equal(99, Other::KOALA)
 | |
|     Other.const_set("WOMBAT", "Hi")
 | |
|     assert_equal("Hi", Other::WOMBAT)
 | |
| 
 | |
|     n = Object.new
 | |
|     def n.to_str; @count = defined?(@count) ? @count + 1 : 1; "HOGE"; end
 | |
|     def n.count; @count; end
 | |
|     def n.count=(v); @count=v; end
 | |
|     assert(!Other.const_defined?(:HOGE))
 | |
|     Other.const_set(n, 999)
 | |
|     assert_equal(1, n.count)
 | |
|     n.count = 0
 | |
|     assert_equal(999, Other.const_get(n))
 | |
|     assert_equal(1, n.count)
 | |
|     n.count = 0
 | |
|     assert_equal(true, Other.const_defined?(n))
 | |
|     assert_equal(1, n.count)
 | |
|   end
 | |
| 
 | |
|   def test_constants
 | |
|     assert_equal([:MIXIN], Mixin.constants)
 | |
|     assert_equal([:MIXIN, :USER], User.constants.sort)
 | |
|   end
 | |
| 
 | |
|   def test_dup
 | |
|     bug6454 = '[ruby-core:45132]'
 | |
| 
 | |
|     a = Module.new
 | |
|     Other.const_set :BUG6454, a
 | |
|     b = a.dup
 | |
|     Other.const_set :BUG6454_dup, b
 | |
| 
 | |
|     assert_equal "TestModule::Other::BUG6454_dup", b.inspect, bug6454
 | |
|   end
 | |
| 
 | |
|   def test_dup_anonymous
 | |
|     bug6454 = '[ruby-core:45132]'
 | |
| 
 | |
|     a = Module.new
 | |
|     original = a.inspect
 | |
| 
 | |
|     b = a.dup
 | |
| 
 | |
|     refute_equal original, b.inspect, bug6454
 | |
|   end
 | |
| 
 | |
|   def test_public_include
 | |
|     assert_nothing_raised('#8846') do
 | |
|       Module.new.include(Module.new { def foo; end }).instance_methods == [:foo]
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_included_modules
 | |
|     assert_equal([], Mixin.included_modules)
 | |
|     assert_equal([Mixin], User.included_modules)
 | |
| 
 | |
|     mixins = Object.included_modules - [Kernel]
 | |
|     mixins << JSON::Ext::Generator::GeneratorMethods::String if defined?(JSON::Ext::Generator::GeneratorMethods::String)
 | |
|     assert_equal([Kernel], Object.included_modules - mixins)
 | |
|     assert_equal([Comparable, Kernel], String.included_modules - mixins)
 | |
|   end
 | |
| 
 | |
|   def test_instance_methods
 | |
|     assert_equal([:user], User.instance_methods(false))
 | |
|     assert_equal([:user, :mixin].sort, User.instance_methods(true).sort)
 | |
|     assert_equal([:mixin], Mixin.instance_methods)
 | |
|     assert_equal([:mixin], Mixin.instance_methods(true))
 | |
|     assert_equal([:cClass], (class << CClass; self; end).instance_methods(false))
 | |
|     assert_equal([], (class << BClass; self; end).instance_methods(false))
 | |
|     assert_equal([:cm2], (class << AClass; self; end).instance_methods(false))
 | |
|     # Ruby 1.8 feature change:
 | |
|     # #instance_methods includes protected methods.
 | |
|     #assert_equal([:aClass], AClass.instance_methods(false))
 | |
|     assert_equal([:aClass, :aClass2], AClass.instance_methods(false).sort)
 | |
|     assert_equal([:aClass, :aClass2],
 | |
|         (AClass.instance_methods(true) - Object.instance_methods(true)).sort)
 | |
|   end
 | |
| 
 | |
|   def test_method_defined?
 | |
|     assert_method_not_defined?(User, :wombat)
 | |
|     assert_method_defined?(User, :user)
 | |
|     assert_method_defined?(User, :mixin)
 | |
|     assert_method_not_defined?(User, :wombat)
 | |
|     assert_method_defined?(User, :user)
 | |
|     assert_method_defined?(User, :mixin)
 | |
|   end
 | |
| 
 | |
|   def module_exec_aux
 | |
|     Proc.new do
 | |
|       def dynamically_added_method_3; end
 | |
|     end
 | |
|   end
 | |
|   def module_exec_aux_2(&block)
 | |
|     User.module_exec(&block)
 | |
|   end
 | |
| 
 | |
|   def test_module_exec
 | |
|     User.module_exec do
 | |
|       def dynamically_added_method_1; end
 | |
|     end
 | |
|     assert_method_defined?(User, :dynamically_added_method_1)
 | |
| 
 | |
|     block = Proc.new do
 | |
|       def dynamically_added_method_2; end
 | |
|     end
 | |
|     User.module_exec(&block)
 | |
|     assert_method_defined?(User, :dynamically_added_method_2)
 | |
| 
 | |
|     User.module_exec(&module_exec_aux)
 | |
|     assert_method_defined?(User, :dynamically_added_method_3)
 | |
| 
 | |
|     module_exec_aux_2 do
 | |
|       def dynamically_added_method_4; end
 | |
|     end
 | |
|     assert_method_defined?(User, :dynamically_added_method_4)
 | |
|   end
 | |
| 
 | |
|   def test_module_eval
 | |
|     User.module_eval("MODULE_EVAL = 1")
 | |
|     assert_equal(1, User::MODULE_EVAL)
 | |
|     assert(User.constants.include?(:MODULE_EVAL))
 | |
|     User.instance_eval("remove_const(:MODULE_EVAL)")
 | |
|     assert(!User.constants.include?(:MODULE_EVAL))
 | |
|   end
 | |
| 
 | |
|   def test_name
 | |
|     assert_equal("Fixnum", Fixnum.name)
 | |
|     assert_equal("TestModule::Mixin",  Mixin.name)
 | |
|     assert_equal("TestModule::User",   User.name)
 | |
|   end
 | |
| 
 | |
|   def test_classpath
 | |
|     m = Module.new
 | |
|     n = Module.new
 | |
|     m.const_set(:N, n)
 | |
|     assert_nil(m.name)
 | |
|     assert_nil(n.name)
 | |
|     assert_equal([:N], m.constants)
 | |
|     m.module_eval("module O end")
 | |
|     assert_equal([:N, :O], m.constants)
 | |
|     m.module_eval("class C; end")
 | |
|     assert_equal([:N, :O, :C], m.constants)
 | |
|     assert_nil(m::N.name)
 | |
|     assert_match(/\A#<Module:.*>::O\z/, m::O.name)
 | |
|     assert_match(/\A#<Module:.*>::C\z/, m::C.name)
 | |
|     self.class.const_set(:M, m)
 | |
|     prefix = self.class.name + "::M::"
 | |
|     assert_equal(prefix+"N", m.const_get(:N).name)
 | |
|     assert_equal(prefix+"O", m.const_get(:O).name)
 | |
|     assert_equal(prefix+"C", m.const_get(:C).name)
 | |
|   end
 | |
| 
 | |
|   def test_private_class_method
 | |
|     assert_raise(ExpectedException) { AClass.cm1 }
 | |
|     assert_raise(ExpectedException) { AClass.cm3 }
 | |
|     assert_equal("cm1cm2cm3", AClass.cm2)
 | |
|   end
 | |
| 
 | |
|   def test_private_instance_methods
 | |
|     assert_equal([:aClass1], AClass.private_instance_methods(false))
 | |
|     assert_equal([:bClass2], BClass.private_instance_methods(false))
 | |
|     assert_equal([:aClass1, :bClass2],
 | |
|         (BClass.private_instance_methods(true) -
 | |
|          Object.private_instance_methods(true)).sort)
 | |
|   end
 | |
| 
 | |
|   def test_protected_instance_methods
 | |
|     assert_equal([:aClass2], AClass.protected_instance_methods)
 | |
|     assert_equal([:bClass3], BClass.protected_instance_methods(false))
 | |
|     assert_equal([:bClass3, :aClass2].sort,
 | |
|                  (BClass.protected_instance_methods(true) -
 | |
|                   Object.protected_instance_methods(true)).sort)
 | |
|   end
 | |
| 
 | |
|   def test_public_class_method
 | |
|     assert_equal("cm1",       MyClass.cm1)
 | |
|     assert_equal("cm1cm2cm3", MyClass.cm2)
 | |
|     assert_raise(ExpectedException) { eval "MyClass.cm3" }
 | |
|   end
 | |
| 
 | |
|   def test_public_instance_methods
 | |
|     assert_equal([:aClass],  AClass.public_instance_methods(false))
 | |
|     assert_equal([:bClass1], BClass.public_instance_methods(false))
 | |
|   end
 | |
| 
 | |
|   def test_s_constants
 | |
|     c1 = Module.constants
 | |
|     Object.module_eval "WALTER = 99"
 | |
|     c2 = Module.constants
 | |
|     assert_equal([:WALTER], c2 - c1)
 | |
| 
 | |
|     assert_equal([], Module.constants(true))
 | |
|     assert_equal([], Module.constants(false))
 | |
| 
 | |
|     src = <<-INPUT
 | |
|       ary = Module.constants
 | |
|       module M
 | |
|         WALTER = 99
 | |
|       end
 | |
|       class Module
 | |
|         include M
 | |
|       end
 | |
|       p Module.constants - ary, Module.constants(true), Module.constants(false)
 | |
|     INPUT
 | |
|     assert_in_out_err([], src, %w([:M] [:WALTER] []), [])
 | |
| 
 | |
|     klass = Class.new do
 | |
|       const_set(:X, 123)
 | |
|     end
 | |
|     assert_equal(false, klass.class_eval { Module.constants }.include?(:X))
 | |
|   end
 | |
| 
 | |
|   module M1
 | |
|     $m1 = Module.nesting
 | |
|     module M2
 | |
|       $m2 = Module.nesting
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_s_nesting
 | |
|     assert_equal([],                               $m0)
 | |
|     assert_equal([TestModule::M1, TestModule],     $m1)
 | |
|     assert_equal([TestModule::M1::M2,
 | |
|                   TestModule::M1, TestModule],     $m2)
 | |
|   end
 | |
| 
 | |
|   def test_s_new
 | |
|     m = Module.new
 | |
|     assert_instance_of(Module, m)
 | |
|   end
 | |
| 
 | |
|   def test_freeze
 | |
|     m = Module.new
 | |
|     m.freeze
 | |
|     assert_raise(RuntimeError) do
 | |
|       m.module_eval do
 | |
|         def foo; end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_attr_obsoleted_flag
 | |
|     c = Class.new
 | |
|     c.class_eval do
 | |
|       def initialize
 | |
|         @foo = :foo
 | |
|         @bar = :bar
 | |
|       end
 | |
|       attr :foo, true
 | |
|       attr :bar, false
 | |
|     end
 | |
|     o = c.new
 | |
|     assert_equal(true, o.respond_to?(:foo))
 | |
|     assert_equal(true, o.respond_to?(:foo=))
 | |
|     assert_equal(true, o.respond_to?(:bar))
 | |
|     assert_equal(false, o.respond_to?(:bar=))
 | |
|   end
 | |
| 
 | |
|   def test_const_get_evaled
 | |
|     c1 = Class.new
 | |
|     c2 = Class.new(c1)
 | |
| 
 | |
|     eval("c1::Foo = :foo")
 | |
|     assert_equal(:foo, c1::Foo)
 | |
|     assert_equal(:foo, c2::Foo)
 | |
|     assert_equal(:foo, c2.const_get(:Foo))
 | |
|     assert_raise(NameError) { c2.const_get(:Foo, false) }
 | |
| 
 | |
|     eval("c1::Foo = :foo")
 | |
|     assert_raise(NameError) { c1::Bar }
 | |
|     assert_raise(NameError) { c2::Bar }
 | |
|     assert_raise(NameError) { c2.const_get(:Bar) }
 | |
|     assert_raise(NameError) { c2.const_get(:Bar, false) }
 | |
|     assert_raise(NameError) { c2.const_get("Bar", false) }
 | |
|     assert_raise(NameError) { c2.const_get("BaR11", false) }
 | |
|     assert_raise(NameError) { Object.const_get("BaR11", false) }
 | |
| 
 | |
|     c1.instance_eval do
 | |
|       def const_missing(x)
 | |
|         x
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     assert_equal(:Bar, c1::Bar)
 | |
|     assert_equal(:Bar, c2::Bar)
 | |
|     assert_equal(:Bar, c2.const_get(:Bar))
 | |
|     assert_equal(:Bar, c2.const_get(:Bar, false))
 | |
|     assert_equal(:Bar, c2.const_get("Bar"))
 | |
|     assert_equal(:Bar, c2.const_get("Bar", false))
 | |
| 
 | |
|     v = c2.const_get("Bar11", false)
 | |
|     assert_equal("Bar11".to_sym, v)
 | |
| 
 | |
|     assert_raise(NameError) { c1.const_get(:foo) }
 | |
|   end
 | |
| 
 | |
|   def test_const_set_invalid_name
 | |
|     c1 = Class.new
 | |
|     assert_raise(NameError) { c1.const_set(:foo, :foo) }
 | |
|     assert_raise(NameError) { c1.const_set("bar", :foo) }
 | |
|     assert_raise(TypeError) { c1.const_set(1, :foo) }
 | |
|   end
 | |
| 
 | |
|   def test_const_get_invalid_name
 | |
|     c1 = Class.new
 | |
|     assert_raise(NameError) { c1.const_get(:foo) }
 | |
|     bug5084 = '[ruby-dev:44200]'
 | |
|     assert_raise(TypeError, bug5084) { c1.const_get(1) }
 | |
|     bug7574 = '[ruby-dev:46749]'
 | |
|     e = assert_raise(NameError) { Object.const_get("String\0") }
 | |
|     assert_equal("wrong constant name \"String\\u0000\"", e.message, bug7574)
 | |
|   end
 | |
| 
 | |
|   def test_const_defined_invalid_name
 | |
|     c1 = Class.new
 | |
|     assert_raise(NameError) { c1.const_defined?(:foo) }
 | |
|     bug5084 = '[ruby-dev:44200]'
 | |
|     assert_raise(TypeError, bug5084) { c1.const_defined?(1) }
 | |
|     bug7574 = '[ruby-dev:46749]'
 | |
|     e = assert_raise(NameError) { Object.const_defined?("String\0") }
 | |
|     assert_equal("wrong constant name \"String\\u0000\"", e.message, bug7574)
 | |
|   end
 | |
| 
 | |
|   def test_const_get_no_inherited
 | |
|     bug3422 = '[ruby-core:30719]'
 | |
|     assert_in_out_err([], <<-INPUT, %w[1 NameError A], [], bug3422)
 | |
|     BasicObject::A = 1
 | |
|     puts [true, false].map {|inh|
 | |
|       begin
 | |
|         Object.const_get(:A, inh)
 | |
|       rescue NameError => e
 | |
|         [e.class, e.name]
 | |
|       end
 | |
|     }
 | |
|     INPUT
 | |
|   end
 | |
| 
 | |
|   def test_const_get_inherited
 | |
|     bug3423 = '[ruby-core:30720]'
 | |
|     assert_in_out_err([], <<-INPUT, %w[NameError A NameError A], [], bug3423)
 | |
|     module Foo; A = 1; end
 | |
|     class Object; include Foo; end
 | |
|     class Bar; include Foo; end
 | |
| 
 | |
|     puts [Object, Bar].map {|klass|
 | |
|       begin
 | |
|         klass.const_get(:A, false)
 | |
|       rescue NameError => e
 | |
|         [e.class, e.name]
 | |
|       end
 | |
|     }
 | |
|     INPUT
 | |
|   end
 | |
| 
 | |
|   def test_const_in_module
 | |
|     bug3423 = '[ruby-core:37698]'
 | |
|     assert_in_out_err([], <<-INPUT, %w[ok], [], bug3423)
 | |
|     module LangModuleSpecInObject
 | |
|       module LangModuleTop
 | |
|       end
 | |
|     end
 | |
|     include LangModuleSpecInObject
 | |
|     module LangModuleTop
 | |
|     end
 | |
|     puts "ok" if LangModuleSpecInObject::LangModuleTop == LangModuleTop
 | |
|     INPUT
 | |
| 
 | |
|     bug5264 = '[ruby-core:39227]'
 | |
|     assert_in_out_err([], <<-'INPUT', [], [], bug5264)
 | |
|     class A
 | |
|       class X; end
 | |
|     end
 | |
|     class B < A
 | |
|       module X; end
 | |
|     end
 | |
|     INPUT
 | |
|   end
 | |
| 
 | |
|   def test_class_variable_get
 | |
|     c = Class.new
 | |
|     c.class_eval('@@foo = :foo')
 | |
|     assert_equal(:foo, c.class_variable_get(:@@foo))
 | |
|     assert_raise(NameError) { c.class_variable_get(:@@bar) } # c.f. instance_variable_get
 | |
|     assert_raise(NameError) { c.class_variable_get('@@') }
 | |
|     assert_raise(NameError) { c.class_variable_get(:foo) }
 | |
|     assert_raise(NameError) { c.class_variable_get("bar") }
 | |
|     assert_raise(TypeError) { c.class_variable_get(1) }
 | |
| 
 | |
|     n = Object.new
 | |
|     def n.to_str; @count = defined?(@count) ? @count + 1 : 1; "@@foo"; end
 | |
|     def n.count; @count; end
 | |
|     assert_equal(:foo, c.class_variable_get(n))
 | |
|     assert_equal(1, n.count)
 | |
|   end
 | |
| 
 | |
|   def test_class_variable_set
 | |
|     c = Class.new
 | |
|     c.class_variable_set(:@@foo, :foo)
 | |
|     assert_equal(:foo, c.class_eval('@@foo'))
 | |
|     assert_raise(NameError) { c.class_variable_set('@@', 1) }
 | |
|     assert_raise(NameError) { c.class_variable_set(:foo, 1) }
 | |
|     assert_raise(NameError) { c.class_variable_set("bar", 1) }
 | |
|     assert_raise(TypeError) { c.class_variable_set(1, 1) }
 | |
| 
 | |
|     n = Object.new
 | |
|     def n.to_str; @count = defined?(@count) ? @count + 1 : 1; "@@foo"; end
 | |
|     def n.count; @count; end
 | |
|     c.class_variable_set(n, :bar)
 | |
|     assert_equal(:bar, c.class_eval('@@foo'))
 | |
|     assert_equal(1, n.count)
 | |
|   end
 | |
| 
 | |
|   def test_class_variable_defined
 | |
|     c = Class.new
 | |
|     c.class_eval('@@foo = :foo')
 | |
|     assert_equal(true, c.class_variable_defined?(:@@foo))
 | |
|     assert_equal(false, c.class_variable_defined?(:@@bar))
 | |
|     assert_raise(NameError) { c.class_variable_defined?(:foo) }
 | |
|     assert_raise(NameError) { c.class_variable_defined?("bar") }
 | |
|     assert_raise(TypeError) { c.class_variable_defined?(1) }
 | |
|     n = Object.new
 | |
|     def n.to_str; @count = defined?(@count) ? @count + 1 : 1; "@@foo"; end
 | |
|     def n.count; @count; end
 | |
|     assert_equal(true, c.class_variable_defined?(n))
 | |
|     assert_equal(1, n.count)
 | |
|   end
 | |
| 
 | |
|   def test_remove_class_variable
 | |
|     c = Class.new
 | |
|     c.class_eval('@@foo = :foo')
 | |
|     c.class_eval { remove_class_variable(:@@foo) }
 | |
|     assert_equal(false, c.class_variable_defined?(:@@foo))
 | |
|   end
 | |
| 
 | |
|   def test_export_method
 | |
|     m = Module.new
 | |
|     assert_raise(NameError) do
 | |
|       m.instance_eval { public(:foo) }
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_attr
 | |
|     assert_in_out_err([], <<-INPUT, %w(:ok nil), /warning: private attribute\?$/)
 | |
|       $VERBOSE = true
 | |
|       c = Class.new
 | |
|       c.instance_eval do
 | |
|         private
 | |
|         attr_reader :foo
 | |
|       end
 | |
|       o = c.new
 | |
|       o.foo rescue p(:ok)
 | |
|       p(o.instance_eval { foo })
 | |
|     INPUT
 | |
| 
 | |
|     c = Class.new
 | |
|     assert_raise(NameError) do
 | |
|       c.instance_eval { attr_reader :"." }
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_undef
 | |
|     c = Class.new
 | |
|     assert_raise(NameError) do
 | |
|       c.instance_eval { undef_method(:foo) }
 | |
|     end
 | |
| 
 | |
|     m = Module.new
 | |
|     assert_raise(NameError) do
 | |
|       m.instance_eval { undef_method(:foo) }
 | |
|     end
 | |
| 
 | |
|     o = Object.new
 | |
|     assert_raise(NameError) do
 | |
|       class << o; self; end.instance_eval { undef_method(:foo) }
 | |
|     end
 | |
| 
 | |
|     %w(object_id __send__ initialize).each do |n|
 | |
|       assert_in_out_err([], <<-INPUT, [], %r"warning: undefining `#{n}' may cause serious problems$")
 | |
|         $VERBOSE = false
 | |
|         Class.new.instance_eval { undef_method(:#{n}) }
 | |
|       INPUT
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_alias
 | |
|     m = Module.new
 | |
|     assert_raise(NameError) do
 | |
|       m.class_eval { alias foo bar }
 | |
|     end
 | |
| 
 | |
|     assert_in_out_err([], <<-INPUT, %w(2), /discarding old foo$/)
 | |
|       $VERBOSE = true
 | |
|       c = Class.new
 | |
|       c.class_eval do
 | |
|         def foo; 1; end
 | |
|         def bar; 2; end
 | |
|       end
 | |
|       c.class_eval { alias foo bar }
 | |
|       p c.new.foo
 | |
|     INPUT
 | |
|   end
 | |
| 
 | |
|   def test_mod_constants
 | |
|     m = Module.new
 | |
|     m.const_set(:Foo, :foo)
 | |
|     assert_equal([:Foo], m.constants(true))
 | |
|     assert_equal([:Foo], m.constants(false))
 | |
|     m.instance_eval { remove_const(:Foo) }
 | |
|   end
 | |
| 
 | |
|   def test_frozen_class
 | |
|     m = Module.new
 | |
|     m.freeze
 | |
|     assert_raise(RuntimeError) do
 | |
|       m.instance_eval { undef_method(:foo) }
 | |
|     end
 | |
| 
 | |
|     c = Class.new
 | |
|     c.freeze
 | |
|     assert_raise(RuntimeError) do
 | |
|       c.instance_eval { undef_method(:foo) }
 | |
|     end
 | |
| 
 | |
|     o = Object.new
 | |
|     c = class << o; self; end
 | |
|     c.freeze
 | |
|     assert_raise(RuntimeError) do
 | |
|       c.instance_eval { undef_method(:foo) }
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_method_defined
 | |
|     c = Class.new
 | |
|     c.class_eval do
 | |
|       def foo; end
 | |
|       def bar; end
 | |
|       def baz; end
 | |
|       public :foo
 | |
|       protected :bar
 | |
|       private :baz
 | |
|     end
 | |
| 
 | |
|     assert_equal(true, c.public_method_defined?(:foo))
 | |
|     assert_equal(false, c.public_method_defined?(:bar))
 | |
|     assert_equal(false, c.public_method_defined?(:baz))
 | |
| 
 | |
|     assert_equal(false, c.protected_method_defined?(:foo))
 | |
|     assert_equal(true, c.protected_method_defined?(:bar))
 | |
|     assert_equal(false, c.protected_method_defined?(:baz))
 | |
| 
 | |
|     assert_equal(false, c.private_method_defined?(:foo))
 | |
|     assert_equal(false, c.private_method_defined?(:bar))
 | |
|     assert_equal(true, c.private_method_defined?(:baz))
 | |
|   end
 | |
| 
 | |
|   def test_top_public_private
 | |
|     assert_in_out_err([], <<-INPUT, %w([:foo] [:bar]), [])
 | |
|       private
 | |
|       def foo; :foo; end
 | |
|       public
 | |
|       def bar; :bar; end
 | |
|       p self.private_methods.grep(/^foo$|^bar$/)
 | |
|       p self.methods.grep(/^foo$|^bar$/)
 | |
|     INPUT
 | |
|   end
 | |
| 
 | |
|   def test_append_features
 | |
|     t = nil
 | |
|     m = Module.new
 | |
|     m.module_eval do
 | |
|       def foo; :foo; end
 | |
|     end
 | |
|     class << m; self; end.class_eval do
 | |
|       define_method(:append_features) do |mod|
 | |
|         t = mod
 | |
|         super(mod)
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     m2 = Module.new
 | |
|     m2.module_eval { include(m) }
 | |
|     assert_equal(m2, t)
 | |
| 
 | |
|     o = Object.new
 | |
|     o.extend(m2)
 | |
|     assert_equal(true, o.respond_to?(:foo))
 | |
|   end
 | |
| 
 | |
|   def test_append_features_raise
 | |
|     m = Module.new
 | |
|     m.module_eval do
 | |
|       def foo; :foo; end
 | |
|     end
 | |
|     class << m; self; end.class_eval do
 | |
|       define_method(:append_features) {|mod| raise }
 | |
|     end
 | |
| 
 | |
|     m2 = Module.new
 | |
|     assert_raise(RuntimeError) do
 | |
|       m2.module_eval { include(m) }
 | |
|     end
 | |
| 
 | |
|     o = Object.new
 | |
|     o.extend(m2)
 | |
|     assert_equal(false, o.respond_to?(:foo))
 | |
|   end
 | |
| 
 | |
|   def test_append_features_type_error
 | |
|     assert_raise(TypeError) do
 | |
|       Module.new.instance_eval { append_features(1) }
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_included
 | |
|     m = Module.new
 | |
|     m.module_eval do
 | |
|       def foo; :foo; end
 | |
|     end
 | |
|     class << m; self; end.class_eval do
 | |
|       define_method(:included) {|mod| raise }
 | |
|     end
 | |
| 
 | |
|     m2 = Module.new
 | |
|     assert_raise(RuntimeError) do
 | |
|       m2.module_eval { include(m) }
 | |
|     end
 | |
| 
 | |
|     o = Object.new
 | |
|     o.extend(m2)
 | |
|     assert_equal(true, o.respond_to?(:foo))
 | |
|   end
 | |
| 
 | |
|   def test_cyclic_include
 | |
|     m1 = Module.new
 | |
|     m2 = Module.new
 | |
|     m1.instance_eval { include(m2) }
 | |
|     assert_raise(ArgumentError) do
 | |
|       m2.instance_eval { include(m1) }
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_include_p
 | |
|     m = Module.new
 | |
|     c1 = Class.new
 | |
|     c1.instance_eval { include(m) }
 | |
|     c2 = Class.new(c1)
 | |
|     assert_equal(true, c1.include?(m))
 | |
|     assert_equal(true, c2.include?(m))
 | |
|     assert_equal(false, m.include?(m))
 | |
|   end
 | |
| 
 | |
|   def test_send
 | |
|     a = AClass.new
 | |
|     assert_equal(:aClass, a.__send__(:aClass))
 | |
|     assert_equal(:aClass1, a.__send__(:aClass1))
 | |
|     assert_equal(:aClass2, a.__send__(:aClass2))
 | |
|     b = BClass.new
 | |
|     assert_equal(:aClass, b.__send__(:aClass))
 | |
|     assert_equal(:aClass1, b.__send__(:aClass1))
 | |
|     assert_equal(:aClass2, b.__send__(:aClass2))
 | |
|     assert_equal(:bClass1, b.__send__(:bClass1))
 | |
|     assert_equal(:bClass2, b.__send__(:bClass2))
 | |
|     assert_equal(:bClass3, b.__send__(:bClass3))
 | |
|   end
 | |
| 
 | |
| 
 | |
|   def test_nonascii_name
 | |
|     c = eval("class ::C\u{df}; self; end")
 | |
|     assert_equal("C\u{df}", c.name, '[ruby-core:24600]')
 | |
|     c = eval("class C\u{df}; self; end")
 | |
|     assert_equal("TestModule::C\u{df}", c.name, '[ruby-core:24600]')
 | |
|   end
 | |
| 
 | |
|   def test_method_added
 | |
|     memo = []
 | |
|     mod = Module.new do
 | |
|       mod = self
 | |
|       (class << self ; self ; end).class_eval do
 | |
|         define_method :method_added do |sym|
 | |
|           memo << sym
 | |
|           memo << mod.instance_methods(false)
 | |
|           memo << (mod.instance_method(sym) rescue nil)
 | |
|         end
 | |
|       end
 | |
|       def f
 | |
|       end
 | |
|       alias g f
 | |
|       attr_reader :a
 | |
|       attr_writer :a
 | |
|     end
 | |
|     assert_equal :f, memo.shift
 | |
|     assert_equal [:f], memo.shift, '[ruby-core:25536]'
 | |
|     assert_equal mod.instance_method(:f), memo.shift
 | |
|     assert_equal :g, memo.shift
 | |
|     assert_equal [:f, :g], memo.shift
 | |
|     assert_equal mod.instance_method(:f), memo.shift
 | |
|     assert_equal :a, memo.shift
 | |
|     assert_equal [:f, :g, :a], memo.shift
 | |
|     assert_equal mod.instance_method(:a), memo.shift
 | |
|     assert_equal :a=, memo.shift
 | |
|     assert_equal [:f, :g, :a, :a=], memo.shift
 | |
|     assert_equal mod.instance_method(:a=), memo.shift
 | |
|   end
 | |
| 
 | |
|   def test_method_undefined
 | |
|     added = []
 | |
|     undefed = []
 | |
|     removed = []
 | |
|     mod = Module.new do
 | |
|       mod = self
 | |
|       def f
 | |
|       end
 | |
|       (class << self ; self ; end).class_eval do
 | |
|         define_method :method_added do |sym|
 | |
|           added << sym
 | |
|         end
 | |
|         define_method :method_undefined do |sym|
 | |
|           undefed << sym
 | |
|         end
 | |
|         define_method :method_removed do |sym|
 | |
|           removed << sym
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|     assert_method_defined?(mod, :f)
 | |
|     mod.module_eval do
 | |
|       undef :f
 | |
|     end
 | |
|     assert_equal [], added
 | |
|     assert_equal [:f], undefed
 | |
|     assert_equal [], removed
 | |
|   end
 | |
| 
 | |
|   def test_method_removed
 | |
|     added = []
 | |
|     undefed = []
 | |
|     removed = []
 | |
|     mod = Module.new do
 | |
|       mod = self
 | |
|       def f
 | |
|       end
 | |
|       (class << self ; self ; end).class_eval do
 | |
|         define_method :method_added do |sym|
 | |
|           added << sym
 | |
|         end
 | |
|         define_method :method_undefined do |sym|
 | |
|           undefed << sym
 | |
|         end
 | |
|         define_method :method_removed do |sym|
 | |
|           removed << sym
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|     assert_method_defined?(mod, :f)
 | |
|     mod.module_eval do
 | |
|       remove_method :f
 | |
|     end
 | |
|     assert_equal [], added
 | |
|     assert_equal [], undefed
 | |
|     assert_equal [:f], removed
 | |
|   end
 | |
| 
 | |
|   def test_method_redefinition
 | |
|     feature2155 = '[ruby-dev:39400]'
 | |
| 
 | |
|     line = __LINE__+4
 | |
|     stderr = EnvUtil.verbose_warning do
 | |
|       Module.new do
 | |
|         def foo; end
 | |
|         def foo; end
 | |
|       end
 | |
|     end
 | |
|     assert_match(/:#{line}: warning: method redefined; discarding old foo/, stderr)
 | |
|     assert_match(/:#{line-1}: warning: previous definition of foo/, stderr, feature2155)
 | |
| 
 | |
|     assert_warning '' do
 | |
|       Module.new do
 | |
|         def foo; end
 | |
|         alias bar foo
 | |
|         def foo; end
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     assert_warning '' do
 | |
|       Module.new do
 | |
|         def foo; end
 | |
|         alias bar foo
 | |
|         alias bar foo
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     line = __LINE__+4
 | |
|     stderr = EnvUtil.verbose_warning do
 | |
|       Module.new do
 | |
|         define_method(:foo) do end
 | |
|         def foo; end
 | |
|       end
 | |
|     end
 | |
|     assert_match(/:#{line}: warning: method redefined; discarding old foo/, stderr)
 | |
|     assert_match(/:#{line-1}: warning: previous definition of foo/, stderr, feature2155)
 | |
| 
 | |
|     assert_warning '' do
 | |
|       Module.new do
 | |
|         define_method(:foo) do end
 | |
|         alias bar foo
 | |
|         alias bar foo
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     assert_warning('', '[ruby-dev:39397]') do
 | |
|       Module.new do
 | |
|         module_function
 | |
|         def foo; end
 | |
|         module_function :foo
 | |
|       end
 | |
|     end
 | |
| 
 | |
|     assert_warning '' do
 | |
|       Module.new do
 | |
|         def foo; end
 | |
|         undef foo
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_protected_singleton_method
 | |
|     klass = Class.new
 | |
|     x = klass.new
 | |
|     class << x
 | |
|       protected
 | |
| 
 | |
|       def foo
 | |
|       end
 | |
|     end
 | |
|     assert_raise(NoMethodError) do
 | |
|       x.foo
 | |
|     end
 | |
|     klass.send(:define_method, :bar) do
 | |
|       x.foo
 | |
|     end
 | |
|     assert_nothing_raised do
 | |
|       x.bar
 | |
|     end
 | |
|     y = klass.new
 | |
|     assert_raise(NoMethodError) do
 | |
|       y.bar
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_uninitialized_toplevel_constant
 | |
|     bug3123 = '[ruby-dev:40951]'
 | |
|     e = assert_raise(NameError) {eval("Bug3123", TOPLEVEL_BINDING)}
 | |
|     assert_not_match(/Object::/, e.message, bug3123)
 | |
|   end
 | |
| 
 | |
|   def test_attr_inherited_visibility
 | |
|     bug3406 = '[ruby-core:30638]'
 | |
|     c = Class.new do
 | |
|       class << self
 | |
|         private
 | |
|         def attr_accessor(*); super; end
 | |
|       end
 | |
|       attr_accessor :x
 | |
|     end.new
 | |
|     assert_nothing_raised(bug3406) {c.x = 1}
 | |
|     assert_equal(1, c.x, bug3406)
 | |
|   end
 | |
| 
 | |
|   def test_attr_writer_with_no_arguments
 | |
|     bug8540 = "[ruby-core:55543]"
 | |
|     c = Class.new do
 | |
|       attr_writer :foo
 | |
|     end
 | |
|     assert_raise(ArgumentError) { c.new.send :foo= }
 | |
|   end
 | |
| 
 | |
|   def test_private_constant
 | |
|     c = Class.new
 | |
|     c.const_set(:FOO, "foo")
 | |
|     assert_equal("foo", c::FOO)
 | |
|     c.private_constant(:FOO)
 | |
|     assert_raise(NameError) { c::FOO }
 | |
|     assert_equal("foo", c.class_eval("FOO"))
 | |
|     assert_equal("foo", c.const_get("FOO"))
 | |
|     $VERBOSE, verbose = nil, $VERBOSE
 | |
|     c.const_set(:FOO, "foo")
 | |
|     $VERBOSE = verbose
 | |
|     assert_raise(NameError) { c::FOO }
 | |
|   end
 | |
| 
 | |
|   def test_private_constant2
 | |
|     c = Class.new
 | |
|     c.const_set(:FOO, "foo")
 | |
|     c.const_set(:BAR, "bar")
 | |
|     assert_equal("foo", c::FOO)
 | |
|     assert_equal("bar", c::BAR)
 | |
|     c.private_constant(:FOO, :BAR)
 | |
|     assert_raise(NameError) { c::FOO }
 | |
|     assert_raise(NameError) { c::BAR }
 | |
|     assert_equal("foo", c.class_eval("FOO"))
 | |
|     assert_equal("bar", c.class_eval("BAR"))
 | |
|   end
 | |
| 
 | |
|   def test_private_constant_with_no_args
 | |
|     assert_in_out_err([], <<-RUBY, [], ["-:3: warning: private_constant with no argument is just ignored"])
 | |
|       $-w = true
 | |
|       class X
 | |
|         private_constant
 | |
|       end
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   class PrivateClass
 | |
|   end
 | |
|   private_constant :PrivateClass
 | |
| 
 | |
|   def test_define_module_under_private_constant
 | |
|     assert_raise(NameError) do
 | |
|       eval %q{class TestModule::PrivateClass; end}
 | |
|     end
 | |
|     assert_raise(NameError) do
 | |
|       eval %q{module TestModule::PrivateClass::TestModule; end}
 | |
|     end
 | |
|     eval %q{class PrivateClass; end}
 | |
|     eval %q{module PrivateClass::TestModule; end}
 | |
|     assert_instance_of(Module, PrivateClass::TestModule)
 | |
|     PrivateClass.class_eval { remove_const(:TestModule) }
 | |
|   end
 | |
| 
 | |
|   def test_public_constant
 | |
|     c = Class.new
 | |
|     c.const_set(:FOO, "foo")
 | |
|     assert_equal("foo", c::FOO)
 | |
|     c.private_constant(:FOO)
 | |
|     assert_raise(NameError) { c::FOO }
 | |
|     assert_equal("foo", c.class_eval("FOO"))
 | |
|     c.public_constant(:FOO)
 | |
|     assert_equal("foo", c::FOO)
 | |
|   end
 | |
| 
 | |
|   def test_constants_with_private_constant
 | |
|     assert(!(::TestModule).constants.include?(:PrivateClass))
 | |
|   end
 | |
| 
 | |
|   def test_toplevel_private_constant
 | |
|     src = <<-INPUT
 | |
|       class Object
 | |
|         private_constant :Object
 | |
|       end
 | |
|       p Object
 | |
|       begin
 | |
|         p ::Object
 | |
|       rescue
 | |
|         p :ok
 | |
|       end
 | |
|     INPUT
 | |
|     assert_in_out_err([], src, %w(Object :ok), [])
 | |
|   end
 | |
| 
 | |
|   def test_private_constants_clear_inlinecache
 | |
|     bug5702 = '[ruby-dev:44929]'
 | |
|     src = <<-INPUT
 | |
|     class A
 | |
|       C = :Const
 | |
|       def self.get_C
 | |
|         A::C
 | |
|       end
 | |
|       # fill cache
 | |
|       A.get_C
 | |
|       private_constant :C, :D rescue nil
 | |
|       begin
 | |
|         A.get_C
 | |
|       rescue NameError
 | |
|         puts "A.get_C"
 | |
|       end
 | |
|     end
 | |
|     INPUT
 | |
|     assert_in_out_err([], src, %w(A.get_C), [], bug5702)
 | |
|   end
 | |
| 
 | |
|   def test_constant_lookup_in_method_defined_by_class_eval
 | |
|     src = <<-INPUT
 | |
|       class A
 | |
|         B = 42
 | |
|       end
 | |
| 
 | |
|       A.class_eval do
 | |
|         def self.f
 | |
|           B
 | |
|         end
 | |
| 
 | |
|         def f
 | |
|           B
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       begin
 | |
|         A.f
 | |
|       rescue NameError
 | |
|         puts "A.f"
 | |
|       end
 | |
|       begin
 | |
|         A.new.f
 | |
|       rescue NameError
 | |
|         puts "A.new.f"
 | |
|       end
 | |
|     INPUT
 | |
|     assert_in_out_err([], src, %w(A.f A.new.f), [])
 | |
|   end
 | |
| 
 | |
|   def test_constant_lookup_in_toplevel_class_eval
 | |
|     src = <<-INPUT
 | |
|       module X
 | |
|         A = 123
 | |
|       end
 | |
|       begin
 | |
|         X.class_eval { A }
 | |
|       rescue NameError => e
 | |
|         puts e
 | |
|       end
 | |
|     INPUT
 | |
|     assert_in_out_err([], src, ["uninitialized constant A"], [])
 | |
|   end
 | |
| 
 | |
|   def test_constant_lookup_in_module_in_class_eval
 | |
|     src = <<-INPUT
 | |
|       class A
 | |
|         B = 42
 | |
|       end
 | |
| 
 | |
|       A.class_eval do
 | |
|         module C
 | |
|           begin
 | |
|             B
 | |
|           rescue NameError
 | |
|             puts "NameError"
 | |
|           end
 | |
|         end
 | |
|       end
 | |
|     INPUT
 | |
|     assert_in_out_err([], src, ["NameError"], [])
 | |
|   end
 | |
| 
 | |
|   module M0
 | |
|     def m1; [:M0] end
 | |
|   end
 | |
|   module M1
 | |
|     def m1; [:M1, *super] end
 | |
|   end
 | |
|   module M2
 | |
|     def m1; [:M2, *super] end
 | |
|   end
 | |
|   M3 = Module.new do
 | |
|     def m1; [:M3, *super] end
 | |
|   end
 | |
|   module M4
 | |
|     def m1; [:M4, *super] end
 | |
|   end
 | |
|   class C
 | |
|     def m1; end
 | |
|   end
 | |
|   class C0 < C
 | |
|     include M0
 | |
|     prepend M1
 | |
|     def m1; [:C0, *super] end
 | |
|   end
 | |
|   class C1 < C0
 | |
|     prepend M2, M3
 | |
|     include M4
 | |
|     def m1; [:C1, *super] end
 | |
|   end
 | |
| 
 | |
|   def test_prepend
 | |
|     obj = C0.new
 | |
|     expected = [:M1,:C0,:M0]
 | |
|     assert_equal(expected, obj.m1)
 | |
|     obj = C1.new
 | |
|     expected = [:M2,:M3,:C1,:M4,:M1,:C0,:M0]
 | |
|     assert_equal(expected, obj.m1)
 | |
|   end
 | |
| 
 | |
|   def test_public_prepend
 | |
|     assert_nothing_raised('#8846') do
 | |
|       Class.new.prepend(Module.new)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_prepend_inheritance
 | |
|     bug6654 = '[ruby-core:45914]'
 | |
|     a = labeled_module("a")
 | |
|     b = labeled_module("b") {include a}
 | |
|     c = labeled_class("c") {prepend b}
 | |
|     assert_operator(c, :<, b, bug6654)
 | |
|     assert_operator(c, :<, a, bug6654)
 | |
|     bug8357 = '[ruby-core:54736] [Bug #8357]'
 | |
|     b = labeled_module("b") {prepend a}
 | |
|     c = labeled_class("c") {include b}
 | |
|     assert_operator(c, :<, b, bug8357)
 | |
|     assert_operator(c, :<, a, bug8357)
 | |
|     bug8357 = '[ruby-core:54742] [Bug #8357]'
 | |
|     assert_kind_of(b, c.new, bug8357)
 | |
|   end
 | |
| 
 | |
|   def test_prepend_instance_methods
 | |
|     bug6655 = '[ruby-core:45915]'
 | |
|     assert_equal(Object.instance_methods, Class.new {prepend Module.new}.instance_methods, bug6655)
 | |
|   end
 | |
| 
 | |
|   def test_prepend_singleton_methods
 | |
|     o = Object.new
 | |
|     o.singleton_class.class_eval {prepend Module.new}
 | |
|     assert_equal([], o.singleton_methods)
 | |
|   end
 | |
| 
 | |
|   def test_prepend_remove_method
 | |
|     c = Class.new do
 | |
|       prepend Module.new {def foo; end}
 | |
|     end
 | |
|     assert_raise(NameError) do
 | |
|       c.class_eval do
 | |
|         remove_method(:foo)
 | |
|       end
 | |
|     end
 | |
|     c.class_eval do
 | |
|       def foo; end
 | |
|     end
 | |
|     removed = nil
 | |
|     c.singleton_class.class_eval do
 | |
|       define_method(:method_removed) {|id| removed = id}
 | |
|     end
 | |
|     assert_nothing_raised(NoMethodError, NameError, '[Bug #7843]') do
 | |
|       c.class_eval do
 | |
|         remove_method(:foo)
 | |
|       end
 | |
|     end
 | |
|     assert_equal(:foo, removed)
 | |
|   end
 | |
| 
 | |
|   def test_prepend_class_ancestors
 | |
|     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
 | |
| 
 | |
|   def test_prepend_module_ancestors
 | |
|     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
 | |
| 
 | |
|   def labeled_module(name, &block)
 | |
|     Module.new do
 | |
|       singleton_class.class_eval {define_method(:to_s) {name}; alias inspect to_s}
 | |
|       class_eval(&block) if block
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def labeled_class(name, superclass = Object, &block)
 | |
|     Class.new(superclass) do
 | |
|       singleton_class.class_eval {define_method(:to_s) {name}; alias inspect to_s}
 | |
|       class_eval(&block) if block
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_prepend_instance_methods_false
 | |
|     bug6660 = '[ruby-dev:45863]'
 | |
|     assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
 | |
|     assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
 | |
|   end
 | |
| 
 | |
|   def test_cyclic_prepend
 | |
|     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
 | |
| 
 | |
|   def test_prepend_optmethod
 | |
|     bug7983 = '[ruby-dev:47124] [Bug #7983]'
 | |
|     assert_separately [], %{
 | |
|       module M
 | |
|         def /(other)
 | |
|           to_f / other
 | |
|         end
 | |
|       end
 | |
|       Fixnum.send(:prepend, M)
 | |
|       assert_equal(0.5, 1 / 2, "#{bug7983}")
 | |
|     }
 | |
|     assert_equal(0, 1 / 2)
 | |
|   end
 | |
| 
 | |
|   def test_prepend_visibility
 | |
|     bug8005 = '[ruby-core:53106] [Bug #8005]'
 | |
|     c = Class.new do
 | |
|       prepend Module.new {}
 | |
|       def foo() end
 | |
|       protected :foo
 | |
|     end
 | |
|     a = c.new
 | |
|     assert_respond_to a, [:foo, true], bug8005
 | |
|     assert_nothing_raised(NoMethodError, bug8005) {a.send :foo}
 | |
|   end
 | |
| 
 | |
|   def test_prepend_visibility_inherited
 | |
|     bug8238 = '[ruby-core:54105] [Bug #8238]'
 | |
|     assert_separately [], <<-"end;", timeout: 3
 | |
|       class A
 | |
|         def foo() A; end
 | |
|         private :foo
 | |
|       end
 | |
|       class B < A
 | |
|         public :foo
 | |
|         prepend Module.new
 | |
|       end
 | |
|       assert_equal(A, B.new.foo, "#{bug8238}")
 | |
|     end;
 | |
|   end
 | |
| 
 | |
|   def test_prepend_included_modules
 | |
|     bug8025 = '[ruby-core:53158] [Bug #8025]'
 | |
|     mixin = labeled_module("mixin")
 | |
|     c = labeled_module("c") {prepend mixin}
 | |
|     im = c.included_modules
 | |
|     assert_not_include(im, c, bug8025)
 | |
|     assert_include(im, mixin, bug8025)
 | |
|     c1 = labeled_class("c1") {prepend mixin}
 | |
|     c2 = labeled_class("c2", c1)
 | |
|     im = c2.included_modules
 | |
|     assert_not_include(im, c1, bug8025)
 | |
|     assert_not_include(im, c2, bug8025)
 | |
|     assert_include(im, mixin, bug8025)
 | |
|   end
 | |
| 
 | |
|   def test_class_variables
 | |
|     m = Module.new
 | |
|     m.class_variable_set(:@@foo, 1)
 | |
|     m2 = Module.new
 | |
|     m2.send(:include, m)
 | |
|     m2.class_variable_set(:@@bar, 2)
 | |
|     assert_equal([:@@foo], m.class_variables)
 | |
|     assert_equal([:@@bar, :@@foo], m2.class_variables)
 | |
|     assert_equal([:@@bar, :@@foo], m2.class_variables(true))
 | |
|     assert_equal([:@@bar], m2.class_variables(false))
 | |
|   end
 | |
| 
 | |
|   Bug6891 = '[ruby-core:47241]'
 | |
| 
 | |
|   def test_extend_module_with_protected_method
 | |
|     list = []
 | |
| 
 | |
|     x = Class.new {
 | |
|       @list = list
 | |
| 
 | |
|       extend Module.new {
 | |
|         protected
 | |
| 
 | |
|         def inherited(klass)
 | |
|           @list << "protected"
 | |
|           super(klass)
 | |
|         end
 | |
|       }
 | |
| 
 | |
|       extend Module.new {
 | |
|         def inherited(klass)
 | |
|           @list << "public"
 | |
|           super(klass)
 | |
|         end
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     assert_nothing_raised(NoMethodError, Bug6891) {Class.new(x)}
 | |
|     assert_equal(['public', 'protected'], list)
 | |
|   end
 | |
| 
 | |
|   def test_extend_module_with_protected_bmethod
 | |
|     list = []
 | |
| 
 | |
|     x = Class.new {
 | |
|       extend Module.new {
 | |
|         protected
 | |
| 
 | |
|         define_method(:inherited) do |klass|
 | |
|           list << "protected"
 | |
|           super(klass)
 | |
|         end
 | |
|       }
 | |
| 
 | |
|       extend Module.new {
 | |
|         define_method(:inherited) do |klass|
 | |
|           list << "public"
 | |
|           super(klass)
 | |
|         end
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     assert_nothing_raised(NoMethodError, Bug6891) {Class.new(x)}
 | |
|     assert_equal(['public', 'protected'], list)
 | |
|   end
 | |
| 
 | |
|   def test_invalid_attr
 | |
|     %w[
 | |
|       foo?
 | |
|       @foo
 | |
|       @@foo
 | |
|       $foo
 | |
|     ].each do |name|
 | |
|       assert_raises(NameError) do
 | |
|         Module.new { attr_accessor name.to_sym }
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   class AttrTest
 | |
|     class << self
 | |
|       attr_accessor :cattr
 | |
|     end
 | |
|     attr_accessor :iattr
 | |
|     def ivar
 | |
|       @ivar
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_uninitialized_instance_variable
 | |
|     a = AttrTest.new
 | |
|     assert_warning(/instance variable @ivar not initialized/) do
 | |
|       assert_nil(a.ivar)
 | |
|     end
 | |
|     a.instance_variable_set(:@ivar, 42)
 | |
|     assert_warning '' do
 | |
|       assert_equal(42, a.ivar)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_uninitialized_attr
 | |
|     a = AttrTest.new
 | |
|     assert_warning '' do
 | |
|       assert_nil(a.iattr)
 | |
|     end
 | |
|     a.iattr = 42
 | |
|     assert_warning '' do
 | |
|       assert_equal(42, a.iattr)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_uninitialized_attr_class
 | |
|     assert_warning '' do
 | |
|       assert_nil(AttrTest.cattr)
 | |
|     end
 | |
|     AttrTest.cattr = 42
 | |
|     assert_warning '' do
 | |
|       assert_equal(42, AttrTest.cattr)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_uninitialized_attr_non_object
 | |
|     a = Class.new(Array) do
 | |
|       attr_accessor :iattr
 | |
|     end.new
 | |
|     assert_warning '' do
 | |
|       assert_nil(a.iattr)
 | |
|     end
 | |
|     a.iattr = 42
 | |
|     assert_warning '' do
 | |
|       assert_equal(42, a.iattr)
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_remove_const
 | |
|     m = Module.new
 | |
|     assert_raise(NameError){ m.instance_eval { remove_const(:__FOO__) } }
 | |
|   end
 | |
| 
 | |
|   def test_private_top_methods
 | |
|     assert_top_method_is_private(:include)
 | |
|     assert_top_method_is_private(:public)
 | |
|     assert_top_method_is_private(:private)
 | |
|     assert_top_method_is_private(:define_method)
 | |
|   end
 | |
| 
 | |
|   module PrivateConstantReopen
 | |
|     PRIVATE_CONSTANT = true
 | |
|     private_constant :PRIVATE_CONSTANT
 | |
|   end
 | |
| 
 | |
|   def test_private_constant_reopen
 | |
|     assert_raise(NameError) do
 | |
|       eval <<-EOS, TOPLEVEL_BINDING
 | |
|         module TestModule::PrivateConstantReopen::PRIVATE_CONSTANT
 | |
|         end
 | |
|       EOS
 | |
|     end
 | |
|     assert_raise(NameError) do
 | |
|       eval <<-EOS, TOPLEVEL_BINDING
 | |
|         class TestModule::PrivateConstantReopen::PRIVATE_CONSTANT
 | |
|         end
 | |
|       EOS
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def test_singleton_class_ancestors
 | |
|     feature8035 = '[ruby-core:53171]'
 | |
|     obj = Object.new
 | |
|     assert_equal [obj.singleton_class, Object], obj.singleton_class.ancestors.first(2), feature8035
 | |
| 
 | |
|     mod = Module.new
 | |
|     obj.extend mod
 | |
|     assert_equal [obj.singleton_class, mod, Object], obj.singleton_class.ancestors.first(3)
 | |
| 
 | |
|     obj = Object.new
 | |
|     obj.singleton_class.send :prepend, mod
 | |
|     assert_equal [mod, obj.singleton_class, Object], obj.singleton_class.ancestors.first(3)
 | |
|   end
 | |
| 
 | |
|   def test_visibility_by_public_class_method
 | |
|     bug8284 = '[ruby-core:54404] [Bug #8284]'
 | |
|     assert_raise(NoMethodError) {Object.define_method}
 | |
|     Module.new.public_class_method(:define_method)
 | |
|     assert_raise(NoMethodError, bug8284) {Object.define_method}
 | |
|   end
 | |
| 
 | |
|   def test_include_module_with_constants_invalidates_method_cache
 | |
|     assert_in_out_err([], <<-RUBY, %w(123 456), [])
 | |
|       A = 123
 | |
| 
 | |
|       class Foo
 | |
|         def self.a
 | |
|           A
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       module M
 | |
|         A = 456
 | |
|       end
 | |
| 
 | |
|       puts Foo.a
 | |
|       Foo.send(:include, M)
 | |
|       puts Foo.a
 | |
|     RUBY
 | |
|   end
 | |
| 
 | |
|   def test_return_value_of_define_method
 | |
|     retvals = []
 | |
|     Class.new.class_eval do
 | |
|       retvals << define_method(:foo){}
 | |
|       retvals << define_method(:bar, instance_method(:foo))
 | |
|     end
 | |
|     assert_equal :foo, retvals[0]
 | |
|     assert_equal :bar, retvals[1]
 | |
|   end
 | |
| 
 | |
|   def test_return_value_of_define_singleton_method
 | |
|     retvals = []
 | |
|     Class.new do
 | |
|       retvals << define_singleton_method(:foo){}
 | |
|       retvals << define_singleton_method(:bar, method(:foo))
 | |
|     end
 | |
|     assert_equal :foo, retvals[0]
 | |
|     assert_equal :bar, retvals[1]
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def assert_top_method_is_private(method)
 | |
|     top = eval("self", TOPLEVEL_BINDING)
 | |
|     methods = top.singleton_class.private_instance_methods(false)
 | |
|     assert(methods.include?(method), "#{method} should be private")
 | |
| 
 | |
|     assert_in_out_err([], <<-INPUT, [], /private method `#{method}' called for main:Object \(NoMethodError\)/)
 | |
|       self.#{method}
 | |
|     INPUT
 | |
|   end
 | |
| 
 | |
|   def test_prepend_gc
 | |
|     assert_separately [], %{
 | |
|       module Foo
 | |
|       end
 | |
|       class Object
 | |
|         prepend Foo
 | |
|       end
 | |
|       GC.start     # make created T_ICLASS old (or remembered shady)
 | |
|       class Object # add methods into T_ICLASS (need WB if it is old)
 | |
|         def foo; end
 | |
|         attr_reader :bar
 | |
|       end
 | |
|       1_000_000.times{''} # cause GC
 | |
|     }
 | |
|   end
 | |
| end
 |