summaryrefslogtreecommitdiff
path: root/test/ruby/test_variable.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_variable.rb')
-rw-r--r--test/ruby/test_variable.rb172
1 files changed, 168 insertions, 4 deletions
diff --git a/test/ruby/test_variable.rb b/test/ruby/test_variable.rb
index aa301f2bc7..5e8abb0734 100644
--- a/test/ruby/test_variable.rb
+++ b/test/ruby/test_variable.rb
@@ -29,9 +29,148 @@ class TestVariable < Test::Unit::TestCase
@@rule = "Cronus" # modifies @@rule in Gods
include Olympians
def ruler4
- EnvUtil.suppress_warning {
- @@rule
- }
+ @@rule
+ end
+ end
+
+ Athena = Gods.clone
+
+ def test_cloned_classes_copy_cvar_cache
+ assert_equal "Cronus", Athena.new.ruler0
+ end
+
+ def test_setting_class_variable_on_module_through_inheritance
+ mod = Module.new
+ mod.class_variable_set(:@@foo, 1)
+ mod.freeze
+ c = Class.new { include(mod) }
+ assert_raise(FrozenError) { c.class_variable_set(:@@foo, 2) }
+ assert_raise(FrozenError) { c.class_eval("@@foo = 2") }
+ assert_equal(1, c.class_variable_get(:@@foo))
+ end
+
+ Zeus = Gods.clone
+
+ def test_cloned_allows_setting_cvar
+ Zeus.class_variable_set(:@@rule, "Athena")
+
+ god = Gods.new.ruler0
+ zeus = Zeus.new.ruler0
+
+ assert_equal "Cronus", god
+ assert_equal "Athena", zeus
+ assert_not_equal god.object_id, zeus.object_id
+ end
+
+ def test_singleton_class_included_class_variable
+ c = Class.new
+ c.extend(Olympians)
+ assert_empty(c.singleton_class.class_variables)
+ assert_raise(NameError){ c.singleton_class.class_variable_get(:@@rule) }
+ c.class_variable_set(:@@foo, 1)
+ assert_equal([:@@foo], c.singleton_class.class_variables)
+ assert_equal(1, c.singleton_class.class_variable_get(:@@foo))
+
+ c = Class.new
+ c.extend(Olympians)
+ sc = Class.new(c)
+ assert_empty(sc.singleton_class.class_variables)
+ assert_raise(NameError){ sc.singleton_class.class_variable_get(:@@rule) }
+ c.class_variable_set(:@@foo, 1)
+ assert_equal([:@@foo], sc.singleton_class.class_variables)
+ assert_equal(1, sc.singleton_class.class_variable_get(:@@foo))
+
+ c = Class.new
+ o = c.new
+ o.extend(Olympians)
+ assert_equal([:@@rule], o.singleton_class.class_variables)
+ assert_equal("Zeus", o.singleton_class.class_variable_get(:@@rule))
+ c.class_variable_set(:@@foo, 1)
+ assert_equal([:@@foo, :@@rule], o.singleton_class.class_variables.sort)
+ assert_equal(1, o.singleton_class.class_variable_get(:@@foo))
+ end
+
+ def test_cvar_overtaken_by_parent_class
+ error = eval <<~EORB
+ class Parent
+ end
+
+ class Child < Parent
+ @@cvar = 1
+
+ def self.cvar
+ @@cvar
+ end
+ end
+
+ assert_equal 1, Child.cvar
+
+ class Parent
+ @@cvar = 2
+ end
+
+ assert_raise RuntimeError do
+ Child.cvar
+ end
+ EORB
+
+ assert_equal "class variable @@cvar of TestVariable::Child is overtaken by TestVariable::Parent", error.message
+ ensure
+ TestVariable.send(:remove_const, :Child) rescue nil
+ TestVariable.send(:remove_const, :Parent) rescue nil
+ end
+
+ def test_cvar_overtaken_by_module
+ error = eval <<~EORB
+ class ParentForModule
+ @@cvar = 1
+
+ def self.cvar
+ @@cvar
+ end
+ end
+
+ assert_equal 1, ParentForModule.cvar
+
+ module Mixin
+ @@cvar = 2
+ end
+
+ class ParentForModule
+ include Mixin
+ end
+
+ assert_raise RuntimeError do
+ ParentForModule.cvar
+ end
+ EORB
+
+ assert_equal "class variable @@cvar of TestVariable::ParentForModule is overtaken by TestVariable::Mixin", error.message
+ ensure
+ TestVariable.send(:remove_const, :Mixin) rescue nil
+ TestVariable.send(:remove_const, :ParentForModule) rescue nil
+ end
+
+ class IncludeRefinedModuleClassVariableNoWarning
+ module Mod
+ @@_test_include_refined_module_class_variable = true
+ end
+
+ module Mod2
+ refine Mod do
+ end
+ end
+
+ include Mod
+
+ def t
+ @@_test_include_refined_module_class_variable
+ end
+ end
+
+ def test_include_refined_module_class_variable
+ assert_warning('') do
+ IncludeRefinedModuleClassVariableNoWarning.new.t
end
end
@@ -56,7 +195,7 @@ class TestVariable < Test::Unit::TestCase
atlas = Titans.new
assert_equal("Cronus", atlas.ruler0)
assert_equal("Zeus", atlas.ruler3)
- assert_equal("Cronus", atlas.ruler4)
+ assert_raise(RuntimeError) { atlas.ruler4 }
assert_nothing_raised do
class << Gods
defined?(@@rule) && @@rule
@@ -141,6 +280,12 @@ class TestVariable < Test::Unit::TestCase
v.instance_variable_set(:@foo, :bar)
end
+ assert_raise_with_message(FrozenError, msg, "[Bug #19339]") do
+ v.instance_eval do
+ @a = 1
+ end
+ end
+
assert_nil EnvUtil.suppress_warning {v.instance_variable_get(:@foo)}
assert_not_send([v, :instance_variable_defined?, :@foo])
@@ -150,6 +295,25 @@ class TestVariable < Test::Unit::TestCase
end
end
+ class ExIvar < Hash
+ def initialize
+ @a = 1
+ @b = 2
+ @c = 3
+ end
+
+ def ivars
+ [@a, @b, @c]
+ end
+ end
+
+ def test_external_ivars
+ 3.times{
+ # check inline cache for external ivar access
+ assert_equal [1, 2, 3], ExIvar.new.ivars
+ }
+ end
+
def test_local_variables_with_kwarg
bug11674 = '[ruby-core:71437] [Bug #11674]'
v = with_kwargs_11(v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8,v9:9,v10:10,v11:11)