diff options
Diffstat (limited to 'spec/ruby/core/module/const_added_spec.rb')
| -rw-r--r-- | spec/ruby/core/module/const_added_spec.rb | 253 |
1 files changed, 183 insertions, 70 deletions
diff --git a/spec/ruby/core/module/const_added_spec.rb b/spec/ruby/core/module/const_added_spec.rb index 31ac6eb105..90cd36551a 100644 --- a/spec/ruby/core/module/const_added_spec.rb +++ b/spec/ruby/core/module/const_added_spec.rb @@ -1,125 +1,238 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'fixtures/const_added' describe "Module#const_added" do - ruby_version_is "3.2" do - it "is a private instance method" do - Module.should have_private_instance_method(:const_added) + it "is a private instance method" do + Module.should have_private_instance_method(:const_added) + end + + it "returns nil in the default implementation" do + Module.new do + const_added(:TEST).should == nil + end + end + + it "for a class defined with the `class` keyword, const_added runs before inherited" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(_) + ScratchPad << :const_added + end end - it "returns nil in the default implementation" do - Module.new do - const_added(:TEST).should == nil + parent = Class.new do + def self.inherited(_) + ScratchPad << :inherited end end - it "is called when a new constant is assigned on self" do - ScratchPad.record [] + class mod::C < parent; end - mod = Module.new do - def self.const_added(name) - ScratchPad << name - end + ScratchPad.recorded.should == [:const_added, :inherited] + end + + it "the superclass of a class assigned to a constant is set before const_added is called" do + ScratchPad.record [] + + parent = Class.new do + def self.const_added(name) + ScratchPad << name + ScratchPad << const_get(name).superclass end + end - mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) - TEST = 1 - RUBY + class parent::C < parent; end + + ScratchPad.recorded.should == [:C, parent] + end - ScratchPad.recorded.should == [:TEST] + it "is called when a new constant is assigned on self" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + ScratchPad << name + end end - it "is called when a new constant is assigned on self through const_set" do - ScratchPad.record [] + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + TEST = 1 + RUBY - mod = Module.new do - def self.const_added(name) - ScratchPad << name - end + ScratchPad.recorded.should == [:TEST] + end + + it "is called when a new constant is assigned on self through const_set" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + ScratchPad << name end + end + + mod.const_set(:TEST, 1) + + ScratchPad.recorded.should == [:TEST] + end - mod.const_set(:TEST, 1) + it "is called when a new module is defined under self" do + ScratchPad.record [] - ScratchPad.recorded.should == [:TEST] + mod = Module.new do + def self.const_added(name) + ScratchPad << name + end end - it "is called when a new module is defined under self" do - ScratchPad.record [] + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + module SubModule + end + + module SubModule + end + RUBY - mod = Module.new do + ScratchPad.recorded.should == [:SubModule] + end + + it "is called when a new module is defined under a named module (assigned to a constant)" do + ScratchPad.record [] + + ModuleSpecs::ConstAddedSpecs::NamedModule = Module.new do + def self.const_added(name) + ScratchPad << name + end + + module self::A def self.const_added(name) ScratchPad << name end - end - mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) - module SubModule + module self::B end + end + end - module SubModule - end - RUBY + ScratchPad.recorded.should == [:A, :B] + ModuleSpecs::ConstAddedSpecs.send :remove_const, :NamedModule + end - ScratchPad.recorded.should == [:SubModule] + it "is called when a new class is defined under self" do + ScratchPad.record [] + + mod = Module.new do + def self.const_added(name) + ScratchPad << name + end end - it "is called when a new class is defined under self" do - ScratchPad.record [] + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + class SubClass + end + + class SubClass + end + RUBY + + ScratchPad.recorded.should == [:SubClass] + end + + it "is called when a new class is defined under a named module (assigned to a constant)" do + ScratchPad.record [] + + ModuleSpecs::ConstAddedSpecs::NamedModuleB = Module.new do + def self.const_added(name) + ScratchPad << name + end - mod = Module.new do + class self::A def self.const_added(name) ScratchPad << name end - end - mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) - class SubClass + class self::B end + end + end - class SubClass - end - RUBY + ScratchPad.recorded.should == [:A, :B] + ModuleSpecs::ConstAddedSpecs.send :remove_const, :NamedModuleB + end + + it "is called when an autoload is defined" do + ScratchPad.record [] - ScratchPad.recorded.should == [:SubClass] + mod = Module.new do + def self.const_added(name) + ScratchPad << name + end end - it "is called when an autoload is defined" do - ScratchPad.record [] + mod.autoload :Autoload, "foo" + ScratchPad.recorded.should == [:Autoload] + end - mod = Module.new do - def self.const_added(name) - ScratchPad << name - end - end + it "is called with a precise caller location with the line of definition" do + ScratchPad.record [] - mod.autoload :Autoload, "foo" - ScratchPad.recorded.should == [:Autoload] + mod = Module.new do + def self.const_added(name) + location = caller_locations(1, 1)[0] + ScratchPad << location.lineno + end end - it "is called with a precise caller location with the line of definition" do - ScratchPad.record [] + line = __LINE__ + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + TEST = 1 - mod = Module.new do - def self.const_added(name) - location = caller_locations(1, 1)[0] - ScratchPad << location.lineno - end + module SubModule end - line = __LINE__ - mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) - TEST = 1 + class SubClass + end + RUBY - module SubModule - end + mod.const_set(:CONST_SET, 1) - class SubClass - end - RUBY + ScratchPad.recorded.should == [line + 2, line + 4, line + 7, line + 11] + end + + it "is called when the constant is already assigned a value" do + ScratchPad.record [] - mod.const_set(:CONST_SET, 1) + mod = Module.new do + def self.const_added(name) + ScratchPad.record const_get(name) + end + end + + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + TEST = 123 + RUBY + + ScratchPad.recorded.should == 123 + end + + it "records re-definition of existing constants" do + ScratchPad.record [] - ScratchPad.recorded.should == [line + 2, line + 4, line + 7, line + 11] + mod = Module.new do + def self.const_added(name) + ScratchPad << const_get(name) + end end + + -> { + mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1) + TEST = 123 + TEST = 456 + RUBY + }.should complain(/warning: already initialized constant .+::TEST/) + + ScratchPad.recorded.should == [123, 456] end end |
