diff options
Diffstat (limited to 'test/ruby/test_variable.rb')
| -rw-r--r-- | test/ruby/test_variable.rb | 172 |
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) |
