summaryrefslogtreecommitdiff
path: root/spec/ruby/core/module/name_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/module/name_spec.rb')
-rw-r--r--spec/ruby/core/module/name_spec.rb133
1 files changed, 97 insertions, 36 deletions
diff --git a/spec/ruby/core/module/name_spec.rb b/spec/ruby/core/module/name_spec.rb
index ca9106a973..332c08d782 100644
--- a/spec/ruby/core/module/name_spec.rb
+++ b/spec/ruby/core/module/name_spec.rb
@@ -3,23 +3,13 @@ require_relative 'fixtures/module'
describe "Module#name" do
it "is nil for an anonymous module" do
- Module.new.name.should be_nil
+ Module.new.name.should == nil
end
- ruby_version_is ""..."3.0" do
- it "is nil when assigned to a constant in an anonymous module" do
- m = Module.new
- m::N = Module.new
- m::N.name.should be_nil
- end
- end
-
- ruby_version_is "3.0" do
- it "is not nil when assigned to a constant in an anonymous module" do
- m = Module.new
- m::N = Module.new
- m::N.name.should.end_with? '::N'
- end
+ it "is not nil when assigned to a constant in an anonymous module" do
+ m = Module.new
+ m::N = Module.new
+ m::N.name.should.end_with? '::N'
end
it "is not nil for a nested module created with the module keyword" do
@@ -29,9 +19,9 @@ describe "Module#name" do
end
it "returns nil for a singleton class" do
- Module.new.singleton_class.name.should be_nil
- String.singleton_class.name.should be_nil
- Object.new.singleton_class.name.should be_nil
+ Module.new.singleton_class.name.should == nil
+ String.singleton_class.name.should == nil
+ Object.new.singleton_class.name.should == nil
end
it "changes when the module is reachable through a constant path" do
@@ -40,6 +30,21 @@ describe "Module#name" do
m::N.name.should =~ /\A#<Module:0x\h+>::N\z/
ModuleSpecs::Anonymous::WasAnnon = m::N
m::N.name.should == "ModuleSpecs::Anonymous::WasAnnon"
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :WasAnnon)
+ end
+
+ it "may be the repeated in different module objects" do
+ m = Module.new
+ n = Module.new
+
+ suppress_warning do
+ ModuleSpecs::Anonymous::SameName = m
+ ModuleSpecs::Anonymous::SameName = n
+ end
+
+ m.name.should == "ModuleSpecs::Anonymous::SameName"
+ n.name.should == "ModuleSpecs::Anonymous::SameName"
end
it "is set after it is removed from a constant" do
@@ -69,10 +74,20 @@ describe "Module#name" do
ModuleSpecs::Anonymous.name.should == "ModuleSpecs::Anonymous"
end
- it "is set when assigning to a constant" do
+ it "is set when assigning to a constant (constant path matches outer module name)" do
m = Module.new
ModuleSpecs::Anonymous::A = m
m.name.should == "ModuleSpecs::Anonymous::A"
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :A)
+ end
+
+ it "is set when assigning to a constant (constant path does not match outer module name)" do
+ m = Module.new
+ ModuleSpecs::Anonymous::SameChild::A = m
+ m.name.should == "ModuleSpecs::Anonymous::Child::A"
+ ensure
+ ModuleSpecs::Anonymous::SameChild.send(:remove_const, :A)
end
it "is not modified when assigning to a new constant after it has been accessed" do
@@ -81,6 +96,9 @@ describe "Module#name" do
m.name.should == "ModuleSpecs::Anonymous::B"
ModuleSpecs::Anonymous::C = m
m.name.should == "ModuleSpecs::Anonymous::B"
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :B)
+ ModuleSpecs::Anonymous.send(:remove_const, :C)
end
it "is not modified when assigned to a different anonymous module" do
@@ -111,34 +129,77 @@ describe "Module#name" do
ModuleSpecs::NameEncoding.new.name.encoding.should == Encoding::UTF_8
end
- it "is set when the anonymous outer module name is set" do
+ it "is set when the anonymous outer module name is set (module in one single constant)" do
m = Module.new
m::N = Module.new
ModuleSpecs::Anonymous::E = m
m::N.name.should == "ModuleSpecs::Anonymous::E::N"
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :E)
end
- ruby_version_is ""..."2.7" do
- it "returns a mutable string" do
- ModuleSpecs.name.frozen?.should be_false
- end
+ # https://bugs.ruby-lang.org/issues/19681
+ it "is set when the anonymous outer module name is set (module in several constants)" do
+ m = Module.new
+ m::N = Module.new
+ m::O = m::N
+ ModuleSpecs::Anonymous::StoredInMultiplePlaces = m
+ valid_names = [
+ "ModuleSpecs::Anonymous::StoredInMultiplePlaces::N",
+ "ModuleSpecs::Anonymous::StoredInMultiplePlaces::O"
+ ]
+ valid_names.should.include?(m::N.name) # You get one of the two, but you don't know which one.
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :StoredInMultiplePlaces)
+ end
+
+ it "is set in #const_added callback when a module defined in the top-level scope" do
+ ruby_exe(<<~RUBY, args: "2>&1").chomp.should == "TEST1\nTEST2"
+ class Module
+ def const_added(name)
+ puts const_get(name).name
+ end
+ end
- it "returns a mutable string that when mutated does not modify the original module name" do
- ModuleSpecs.name << "foo"
+ # module with name
+ module TEST1
+ end
- ModuleSpecs.name.should == "ModuleSpecs"
- end
+ # anonymous module
+ TEST2 = Module.new
+ RUBY
end
- ruby_version_is "2.7" do
- it "returns a frozen String" do
- ModuleSpecs.name.should.frozen?
- end
+ it "is set in #const_added callback for a nested module when an outer module defined in the top-level scope" do
+ ScratchPad.record []
+
+ ModuleSpecs::NameSpecs::NamedModule = Module.new do
+ def self.const_added(name)
+ ScratchPad << const_get(name).name
+ end
- it "always returns the same String for a given Module" do
- s1 = ModuleSpecs.name
- s2 = ModuleSpecs.name
- s1.should equal(s2)
+ module self::A
+ def self.const_added(name)
+ ScratchPad << const_get(name).name
+ end
+
+ module self::B
+ end
+ end
end
+
+ ScratchPad.recorded.should.one?(/#<Module.+>::A$/)
+ ScratchPad.recorded.should.one?(/#<Module.+>::A::B$/)
+ ModuleSpecs::NameSpecs.send :remove_const, :NamedModule
+ end
+
+ it "returns a frozen String" do
+ ModuleSpecs.name.should.frozen?
+ end
+
+ it "always returns the same String for a given Module" do
+ s1 = ModuleSpecs.name
+ s2 = ModuleSpecs.name
+ s1.should.equal?(s2)
end
end