diff options
Diffstat (limited to 'spec/ruby/core/module')
| -rw-r--r-- | spec/ruby/core/module/append_features_spec.rb | 14 | ||||
| -rw-r--r-- | spec/ruby/core/module/autoload_spec.rb | 20 | ||||
| -rw-r--r-- | spec/ruby/core/module/const_source_location_spec.rb | 333 | ||||
| -rw-r--r-- | spec/ruby/core/module/deprecate_constant_spec.rb | 20 | ||||
| -rw-r--r-- | spec/ruby/core/module/extend_object_spec.rb | 14 | ||||
| -rw-r--r-- | spec/ruby/core/module/name_spec.rb | 26 | ||||
| -rw-r--r-- | spec/ruby/core/module/prepend_features_spec.rb | 14 | ||||
| -rw-r--r-- | spec/ruby/core/module/refine_spec.rb | 126 | ||||
| -rw-r--r-- | spec/ruby/core/module/ruby2_keywords_spec.rb | 360 |
9 files changed, 457 insertions, 470 deletions
diff --git a/spec/ruby/core/module/append_features_spec.rb b/spec/ruby/core/module/append_features_spec.rb index d960798eef..1724cde5d6 100644 --- a/spec/ruby/core/module/append_features_spec.rb +++ b/spec/ruby/core/module/append_features_spec.rb @@ -47,20 +47,6 @@ describe "Module#append_features" do end - ruby_version_is ''...'2.7' do - it "copies own tainted status to the given module" do - other = Module.new - Module.new.taint.send :append_features, other - other.tainted?.should be_true - end - - it "copies own untrusted status to the given module" do - other = Module.new - Module.new.untrust.send :append_features, other - other.untrusted?.should be_true - end - end - describe "when other is frozen" do before :each do @receiver = Module.new diff --git a/spec/ruby/core/module/autoload_spec.rb b/spec/ruby/core/module/autoload_spec.rb index 1d61646db5..7e7e7a2139 100644 --- a/spec/ruby/core/module/autoload_spec.rb +++ b/spec/ruby/core/module/autoload_spec.rb @@ -18,16 +18,14 @@ describe "Module#autoload?" do ModuleSpecs::Autoload::Child.autoload?(:AnotherAutoload).should == "another_autoload.rb" end - ruby_version_is "2.7" do - it "returns nil if an ancestor defined that autoload but recursion is disabled" do - ModuleSpecs::Autoload::Parent.autoload :InheritedAutoload, "inherited_autoload.rb" - ModuleSpecs::Autoload::Child.autoload?(:InheritedAutoload, false).should be_nil - end + it "returns nil if an ancestor defined that autoload but recursion is disabled" do + ModuleSpecs::Autoload::Parent.autoload :InheritedAutoload, "inherited_autoload.rb" + ModuleSpecs::Autoload::Child.autoload?(:InheritedAutoload, false).should be_nil + end - it "returns the name of the file that will be loaded if recursion is disabled but the autoload is defined on the class itself" do - ModuleSpecs::Autoload::Child.autoload :ChildAutoload, "child_autoload.rb" - ModuleSpecs::Autoload::Child.autoload?(:ChildAutoload, false).should == "child_autoload.rb" - end + it "returns the name of the file that will be loaded if recursion is disabled but the autoload is defined on the class itself" do + ModuleSpecs::Autoload::Child.autoload :ChildAutoload, "child_autoload.rb" + ModuleSpecs::Autoload::Child.autoload?(:ChildAutoload, false).should == "child_autoload.rb" end end @@ -514,9 +512,7 @@ describe "Module#autoload" do it "does not load the file when accessing the constants table of the module" do ModuleSpecs::Autoload.autoload :P, @non_existent ModuleSpecs::Autoload.const_defined?(:P).should be_true - ruby_bug "[Bug #15780]", ""..."2.7" do - ModuleSpecs::Autoload.const_defined?("P").should be_true - end + ModuleSpecs::Autoload.const_defined?("P").should be_true end it "loads the file when opening a module that is the autoloaded constant" do diff --git a/spec/ruby/core/module/const_source_location_spec.rb b/spec/ruby/core/module/const_source_location_spec.rb index 9e1f2c1c49..11a2e74756 100644 --- a/spec/ruby/core/module/const_source_location_spec.rb +++ b/spec/ruby/core/module/const_source_location_spec.rb @@ -6,215 +6,220 @@ describe "Module#const_source_location" do @constants_fixture_path = File.expand_path('../../fixtures/constants.rb', __dir__) end - ruby_version_is "2.7" do - describe "with dynamically assigned constants" do - it "searches a path in the immediate class or module first" do - ConstantSpecs::ClassA::CSL_CONST301 = :const301_1 - ConstantSpecs::ClassA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1] - - ConstantSpecs::ModuleA::CSL_CONST301 = :const301_2 - ConstantSpecs::ModuleA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1] + describe "with dynamically assigned constants" do + it "searches a path in the immediate class or module first" do + ConstantSpecs::ClassA::CSL_CONST301 = :const301_1 + ConstantSpecs::ClassA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1] - ConstantSpecs::ParentA::CSL_CONST301 = :const301_3 - ConstantSpecs::ParentA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1] + ConstantSpecs::ModuleA::CSL_CONST301 = :const301_2 + ConstantSpecs::ModuleA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1] - ConstantSpecs::ContainerA::ChildA::CSL_CONST301 = :const301_5 - ConstantSpecs::ContainerA::ChildA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1] - end + ConstantSpecs::ParentA::CSL_CONST301 = :const301_3 + ConstantSpecs::ParentA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1] - it "searches a path in a module included in the immediate class before the superclass" do - ConstantSpecs::ParentB::CSL_CONST302 = :const302_1 - ConstantSpecs::ModuleF::CSL_CONST302 = :const302_2 - ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST302).should == [__FILE__, __LINE__ - 1] - end - - it "searches a path in the superclass before a module included in the superclass" do - ConstantSpecs::ModuleE::CSL_CONST303 = :const303_1 - ConstantSpecs::ParentB::CSL_CONST303 = :const303_2 - ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST303).should == [__FILE__, __LINE__ - 1] - end - - it "searches a path in a module included in the superclass" do - ConstantSpecs::ModuleA::CSL_CONST304 = :const304_1 - ConstantSpecs::ModuleE::CSL_CONST304 = :const304_2 - ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST304).should == [__FILE__, __LINE__ - 1] - end - - it "searches a path in the superclass chain" do - ConstantSpecs::ModuleA::CSL_CONST305 = :const305 - ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST305).should == [__FILE__, __LINE__ - 1] - end - - it "returns path to a toplevel constant when the receiver is a Class" do - Object::CSL_CONST306 = :const306 - ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST306).should == [__FILE__, __LINE__ - 1] - end - - it "returns path to a toplevel constant when the receiver is a Module" do - Object::CSL_CONST308 = :const308 - ConstantSpecs.const_source_location(:CSL_CONST308).should == [__FILE__, __LINE__ - 1] - ConstantSpecs::ModuleA.const_source_location(:CSL_CONST308).should == [__FILE__, __LINE__ - 2] - end - - it "returns path to the updated value of a constant" do - ConstantSpecs::ClassB::CSL_CONST309 = :const309_1 - ConstantSpecs::ClassB.const_source_location(:CSL_CONST309).should == [__FILE__, __LINE__ - 1] + ConstantSpecs::ContainerA::ChildA::CSL_CONST301 = :const301_5 + ConstantSpecs::ContainerA::ChildA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1] + end - -> { - ConstantSpecs::ClassB::CSL_CONST309 = :const309_2 - }.should complain(/already initialized constant/) - ConstantSpecs::ClassB.const_source_location(:CSL_CONST309).should == [__FILE__, __LINE__ - 2] - end + it "searches a path in a module included in the immediate class before the superclass" do + ConstantSpecs::ParentB::CSL_CONST302 = :const302_1 + ConstantSpecs::ModuleF::CSL_CONST302 = :const302_2 + ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST302).should == [__FILE__, __LINE__ - 1] end - describe "with statically assigned constants" do - it "searches location path the immediate class or module first" do - ConstantSpecs::ClassA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CONST10_LINE] - ConstantSpecs::ModuleA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ModuleA::CS_CONST10_LINE] - ConstantSpecs::ParentA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST10_LINE] - ConstantSpecs::ContainerA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ContainerA::CS_CONST10_LINE] - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ContainerA::ChildA::CS_CONST10_LINE] - end + it "searches a path in the superclass before a module included in the superclass" do + ConstantSpecs::ModuleE::CSL_CONST303 = :const303_1 + ConstantSpecs::ParentB::CSL_CONST303 = :const303_2 + ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST303).should == [__FILE__, __LINE__ - 1] + end - it "searches location path a module included in the immediate class before the superclass" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST15).should == [@constants_fixture_path, ConstantSpecs::ModuleC::CS_CONST15_LINE] - end + it "searches a path in a module included in the superclass" do + ConstantSpecs::ModuleA::CSL_CONST304 = :const304_1 + ConstantSpecs::ModuleE::CSL_CONST304 = :const304_2 + ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST304).should == [__FILE__, __LINE__ - 1] + end - it "searches location path the superclass before a module included in the superclass" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST11).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST11_LINE] - end + it "searches a path in the superclass chain" do + ConstantSpecs::ModuleA::CSL_CONST305 = :const305 + ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST305).should == [__FILE__, __LINE__ - 1] + end - it "searches location path a module included in the superclass" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST12).should == [@constants_fixture_path, ConstantSpecs::ModuleB::CS_CONST12_LINE] - end + it "returns path to a toplevel constant when the receiver is a Class" do + Object::CSL_CONST306 = :const306 + ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST306).should == [__FILE__, __LINE__ - 1] + end - it "searches location path the superclass chain" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST13).should == [@constants_fixture_path, ConstantSpecs::ModuleA::CS_CONST13_LINE] - end + it "returns path to a toplevel constant when the receiver is a Module" do + Object::CSL_CONST308 = :const308 + ConstantSpecs.const_source_location(:CSL_CONST308).should == [__FILE__, __LINE__ - 1] + ConstantSpecs::ModuleA.const_source_location(:CSL_CONST308).should == [__FILE__, __LINE__ - 2] + end - it "returns location path a toplevel constant when the receiver is a Class" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE] - end + it "returns path to the updated value of a constant" do + ConstantSpecs::ClassB::CSL_CONST309 = :const309_1 + ConstantSpecs::ClassB.const_source_location(:CSL_CONST309).should == [__FILE__, __LINE__ - 1] - it "returns location path a toplevel constant when the receiver is a Module" do - ConstantSpecs.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE] - ConstantSpecs::ModuleA.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE] - end + -> { + ConstantSpecs::ClassB::CSL_CONST309 = :const309_2 + }.should complain(/already initialized constant/) + ConstantSpecs::ClassB.const_source_location(:CSL_CONST309).should == [__FILE__, __LINE__ - 2] end + end - it "return empty path if constant defined in C code" do - Object.const_source_location(:String).should == [] + describe "with statically assigned constants" do + it "searches location path the immediate class or module first" do + ConstantSpecs::ClassA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CONST10_LINE] + ConstantSpecs::ModuleA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ModuleA::CS_CONST10_LINE] + ConstantSpecs::ParentA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST10_LINE] + ConstantSpecs::ContainerA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ContainerA::CS_CONST10_LINE] + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ContainerA::ChildA::CS_CONST10_LINE] end - it "accepts a String or Symbol name" do - Object.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE] - Object.const_source_location("CS_CONST1").should == [@constants_fixture_path, CS_CONST1_LINE] + it "searches location path a module included in the immediate class before the superclass" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST15).should == [@constants_fixture_path, ConstantSpecs::ModuleC::CS_CONST15_LINE] end - it "returns nil if no constant is defined in the search path" do - ConstantSpecs.const_source_location(:CS_CONSTX).should == nil + it "searches location path the superclass before a module included in the superclass" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST11).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST11_LINE] end - it "raises a NameError if the name does not start with a capital letter" do - -> { ConstantSpecs.const_source_location "name" }.should raise_error(NameError) + it "searches location path a module included in the superclass" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST12).should == [@constants_fixture_path, ConstantSpecs::ModuleB::CS_CONST12_LINE] end - it "raises a NameError if the name starts with a non-alphabetic character" do - -> { ConstantSpecs.const_source_location "__CONSTX__" }.should raise_error(NameError) - -> { ConstantSpecs.const_source_location "@CS_CONST1" }.should raise_error(NameError) - -> { ConstantSpecs.const_source_location "!CS_CONST1" }.should raise_error(NameError) + it "searches location path the superclass chain" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST13).should == [@constants_fixture_path, ConstantSpecs::ModuleA::CS_CONST13_LINE] end - it "raises a NameError if the name contains non-alphabetic characters except '_'" do - Object.const_source_location("CS_CONST1").should == [@constants_fixture_path, CS_CONST1_LINE] - -> { ConstantSpecs.const_source_location "CS_CONST1=" }.should raise_error(NameError) - -> { ConstantSpecs.const_source_location "CS_CONST1?" }.should raise_error(NameError) + it "returns location path a toplevel constant when the receiver is a Class" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE] end - it "calls #to_str to convert the given name to a String" do - name = mock("ClassA") - name.should_receive(:to_str).and_return("ClassA") - ConstantSpecs.const_source_location(name).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CLASS_A_LINE] + it "returns location path a toplevel constant when the receiver is a Module" do + ConstantSpecs.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE] + ConstantSpecs::ModuleA.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE] end + end - it "raises a TypeError if conversion to a String by calling #to_str fails" do - name = mock('123') - -> { ConstantSpecs.const_source_location(name) }.should raise_error(TypeError) + it "return empty path if constant defined in C code" do + Object.const_source_location(:String).should == [] + end - name.should_receive(:to_str).and_return(123) - -> { ConstantSpecs.const_source_location(name) }.should raise_error(TypeError) - end + it "accepts a String or Symbol name" do + Object.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE] + Object.const_source_location("CS_CONST1").should == [@constants_fixture_path, CS_CONST1_LINE] + end - it "does not search the singleton class of a Class or Module" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST14).should == nil - ConstantSpecs.const_source_location(:CS_CONST14).should == nil - end + it "returns nil if no constant is defined in the search path" do + ConstantSpecs.const_source_location(:CS_CONSTX).should == nil + end - it "does not search the containing scope" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST20).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST20_LINE] - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST5) == nil - end + it "raises a NameError if the name does not start with a capital letter" do + -> { ConstantSpecs.const_source_location "name" }.should raise_error(NameError) + end - it "returns nil if the constant is defined in the receiver's superclass and the inherit flag is false" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST4, false).should == nil - end + it "raises a NameError if the name starts with a non-alphabetic character" do + -> { ConstantSpecs.const_source_location "__CONSTX__" }.should raise_error(NameError) + -> { ConstantSpecs.const_source_location "@CS_CONST1" }.should raise_error(NameError) + -> { ConstantSpecs.const_source_location "!CS_CONST1" }.should raise_error(NameError) + end - it "searches into the receiver superclasses if the inherit flag is true" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST4, true).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST4_LINE] - end + it "raises a NameError if the name contains non-alphabetic characters except '_'" do + Object.const_source_location("CS_CONST1").should == [@constants_fixture_path, CS_CONST1_LINE] + -> { ConstantSpecs.const_source_location "CS_CONST1=" }.should raise_error(NameError) + -> { ConstantSpecs.const_source_location "CS_CONST1?" }.should raise_error(NameError) + end - it "returns nil when the receiver is a Module, the constant is defined at toplevel and the inherit flag is false" do - ConstantSpecs::ModuleA.const_source_location(:CS_CONST1, false).should == nil - end + it "calls #to_str to convert the given name to a String" do + name = mock("ClassA") + name.should_receive(:to_str).and_return("ClassA") + ConstantSpecs.const_source_location(name).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CLASS_A_LINE] + end - it "returns nil when the receiver is a Class, the constant is defined at toplevel and the inherit flag is false" do - ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST1, false).should == nil - end + it "raises a TypeError if conversion to a String by calling #to_str fails" do + name = mock('123') + -> { ConstantSpecs.const_source_location(name) }.should raise_error(TypeError) - it "accepts a toplevel scope qualifier" do - ConstantSpecs.const_source_location("::CS_CONST1").should == [@constants_fixture_path, CS_CONST1_LINE] - end + name.should_receive(:to_str).and_return(123) + -> { ConstantSpecs.const_source_location(name) }.should raise_error(TypeError) + end - it "accepts a scoped constant name" do - ConstantSpecs.const_source_location("ClassA::CS_CONST10").should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CONST10_LINE] - end + it "does not search the singleton class of a Class or Module" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST14).should == nil + ConstantSpecs.const_source_location(:CS_CONST14).should == nil + end - it "raises a NameError if the name includes two successive scope separators" do - -> { ConstantSpecs.const_source_location("ClassA::::CS_CONST10") }.should raise_error(NameError) - end + it "does not search the containing scope" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST20).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST20_LINE] + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST5) == nil + end - it "raises a NameError if only '::' is passed" do - -> { ConstantSpecs.const_source_location("::") }.should raise_error(NameError) - end + it "returns nil if the constant is defined in the receiver's superclass and the inherit flag is false" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST4, false).should == nil + end - it "raises a NameError if a Symbol has a toplevel scope qualifier" do - -> { ConstantSpecs.const_source_location(:'::CS_CONST1') }.should raise_error(NameError) - end + it "searches into the receiver superclasses if the inherit flag is true" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST4, true).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST4_LINE] + end - it "raises a NameError if a Symbol is a scoped constant name" do - -> { ConstantSpecs.const_source_location(:'ClassA::CS_CONST10') }.should raise_error(NameError) - end + it "returns nil when the receiver is a Module, the constant is defined at toplevel and the inherit flag is false" do + ConstantSpecs::ModuleA.const_source_location(:CS_CONST1, false).should == nil + end - it "does search private constants path" do - ConstantSpecs.const_source_location(:CS_PRIVATE).should == [@constants_fixture_path, ConstantSpecs::CS_PRIVATE_LINE] - end + it "returns nil when the receiver is a Class, the constant is defined at toplevel and the inherit flag is false" do + ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST1, false).should == nil + end + + it "accepts a toplevel scope qualifier" do + ConstantSpecs.const_source_location("::CS_CONST1").should == [@constants_fixture_path, CS_CONST1_LINE] + end + + it "accepts a scoped constant name" do + ConstantSpecs.const_source_location("ClassA::CS_CONST10").should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CONST10_LINE] + end + + it "returns updated location from const_set" do + mod = Module.new + const_line = __LINE__ + 1 + mod.const_set :Foo, 1 + mod.const_source_location(:Foo).should == [__FILE__, const_line] + end + + it "raises a NameError if the name includes two successive scope separators" do + -> { ConstantSpecs.const_source_location("ClassA::::CS_CONST10") }.should raise_error(NameError) + end + + it "raises a NameError if only '::' is passed" do + -> { ConstantSpecs.const_source_location("::") }.should raise_error(NameError) + end - context 'autoload' do - before :all do - ConstantSpecs.autoload :CSL_CONST1, "#{__dir__}/notexisting.rb" - @line = __LINE__ - 1 - end + it "raises a NameError if a Symbol has a toplevel scope qualifier" do + -> { ConstantSpecs.const_source_location(:'::CS_CONST1') }.should raise_error(NameError) + end - it 'returns the autoload location while not resolved' do - ConstantSpecs.const_source_location('CSL_CONST1').should == [__FILE__, @line] - end + it "raises a NameError if a Symbol is a scoped constant name" do + -> { ConstantSpecs.const_source_location(:'ClassA::CS_CONST10') }.should raise_error(NameError) + end + + it "does search private constants path" do + ConstantSpecs.const_source_location(:CS_PRIVATE).should == [@constants_fixture_path, ConstantSpecs::CS_PRIVATE_LINE] + end + + context 'autoload' do + before :all do + ConstantSpecs.autoload :CSL_CONST1, "#{__dir__}/notexisting.rb" + @line = __LINE__ - 1 + end + + it 'returns the autoload location while not resolved' do + ConstantSpecs.const_source_location('CSL_CONST1').should == [__FILE__, @line] + end - it 'returns where the constant was resolved when resolved' do - file = fixture(__FILE__, 'autoload_location.rb') - ConstantSpecs.autoload :CONST_LOCATION, file - line = ConstantSpecs::CONST_LOCATION - ConstantSpecs.const_source_location('CONST_LOCATION').should == [file, line] - end + it 'returns where the constant was resolved when resolved' do + file = fixture(__FILE__, 'autoload_location.rb') + ConstantSpecs.autoload :CONST_LOCATION, file + line = ConstantSpecs::CONST_LOCATION + ConstantSpecs.const_source_location('CONST_LOCATION').should == [file, line] end end end diff --git a/spec/ruby/core/module/deprecate_constant_spec.rb b/spec/ruby/core/module/deprecate_constant_spec.rb index faacbea03e..aabef934c4 100644 --- a/spec/ruby/core/module/deprecate_constant_spec.rb +++ b/spec/ruby/core/module/deprecate_constant_spec.rb @@ -31,17 +31,15 @@ describe "Module#deprecate_constant" do -> { @module.const_get :PRIVATE }.should complain(/warning: constant .+::PRIVATE is deprecated/) end - ruby_version_is '2.7' do - it "does not warn if Warning[:deprecated] is false" do - @module.deprecate_constant :PUBLIC1 - - deprecated = Warning[:deprecated] - begin - Warning[:deprecated] = false - -> { @module::PUBLIC1 }.should_not complain - ensure - Warning[:deprecated] = deprecated - end + it "does not warn if Warning[:deprecated] is false" do + @module.deprecate_constant :PUBLIC1 + + deprecated = Warning[:deprecated] + begin + Warning[:deprecated] = false + -> { @module::PUBLIC1 }.should_not complain + ensure + Warning[:deprecated] = deprecated end end end diff --git a/spec/ruby/core/module/extend_object_spec.rb b/spec/ruby/core/module/extend_object_spec.rb index e66b87efef..1fd1abc0b5 100644 --- a/spec/ruby/core/module/extend_object_spec.rb +++ b/spec/ruby/core/module/extend_object_spec.rb @@ -42,20 +42,6 @@ describe "Module#extend_object" do ScratchPad.recorded.should == :extended end - ruby_version_is ''...'2.7' do - it "does not copy own tainted status to the given object" do - other = Object.new - Module.new.taint.send :extend_object, other - other.tainted?.should be_false - end - - it "does not copy own untrusted status to the given object" do - other = Object.new - Module.new.untrust.send :extend_object, other - other.untrusted?.should be_false - end - end - describe "when given a frozen object" do before :each do @receiver = Module.new diff --git a/spec/ruby/core/module/name_spec.rb b/spec/ruby/core/module/name_spec.rb index ca9106a973..b78bbfcc80 100644 --- a/spec/ruby/core/module/name_spec.rb +++ b/spec/ruby/core/module/name_spec.rb @@ -118,27 +118,13 @@ describe "Module#name" do m::N.name.should == "ModuleSpecs::Anonymous::E::N" end - ruby_version_is ""..."2.7" do - it "returns a mutable string" do - ModuleSpecs.name.frozen?.should be_false - end - - it "returns a mutable string that when mutated does not modify the original module name" do - ModuleSpecs.name << "foo" - - ModuleSpecs.name.should == "ModuleSpecs" - end + it "returns a frozen String" do + ModuleSpecs.name.should.frozen? end - ruby_version_is "2.7" do - 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 + it "always returns the same String for a given Module" do + s1 = ModuleSpecs.name + s2 = ModuleSpecs.name + s1.should equal(s2) end end diff --git a/spec/ruby/core/module/prepend_features_spec.rb b/spec/ruby/core/module/prepend_features_spec.rb index 2d1fa713b7..09c15c5c15 100644 --- a/spec/ruby/core/module/prepend_features_spec.rb +++ b/spec/ruby/core/module/prepend_features_spec.rb @@ -28,20 +28,6 @@ describe "Module#prepend_features" do }.should raise_error(ArgumentError) end - ruby_version_is ''...'2.7' do - it "copies own tainted status to the given module" do - other = Module.new - Module.new.taint.send :prepend_features, other - other.tainted?.should be_true - end - - it "copies own untrusted status to the given module" do - other = Module.new - Module.new.untrust.send :prepend_features, other - other.untrusted?.should be_true - end - end - it "clears caches of the given module" do parent = Class.new do def bar; :bar; end diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb index 56ffc7ead2..841900cf87 100644 --- a/spec/ruby/core/module/refine_spec.rb +++ b/spec/ruby/core/module/refine_spec.rb @@ -518,115 +518,55 @@ describe "Module#refine" do result.should == "hello from refinement" end - ruby_version_is "" ... "2.7" do - it "is not honored by Kernel#method" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end - end + it "is honored by Kernel#method" do + klass = Class.new + refinement = Module.new do + refine klass do + def foo; end end - - -> { - Module.new do - using refinement - klass.new.method(:foo) - end - }.should raise_error(NameError, /undefined method `foo'/) end - end - - ruby_version_is "2.7" do - it "is honored by Kernel#method" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end - end - end - - result = nil - Module.new do - using refinement - result = klass.new.method(:foo).class - end - result.should == Method + result = nil + Module.new do + using refinement + result = klass.new.method(:foo).class end - end - - ruby_version_is "" ... "2.7" do - it "is not honored by Kernel#public_method" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end - end - end - -> { - Module.new do - using refinement - klass.new.public_method(:foo) - end - }.should raise_error(NameError, /undefined method `foo'/) - end + result.should == Method end - ruby_version_is "2.7" do - it "is honored by Kernel#public_method" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end - end - end - - result = nil - Module.new do - using refinement - result = klass.new.public_method(:foo).class + it "is honored by Kernel#public_method" do + klass = Class.new + refinement = Module.new do + refine klass do + def foo; end end - - result.should == Method end - end - ruby_version_is "" ... "2.7" do - it "is not honored by Kernel#instance_method" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end - end - end - - -> { - Module.new do - using refinement - klass.instance_method(:foo) - end - }.should raise_error(NameError, /undefined method `foo'/) + result = nil + Module.new do + using refinement + result = klass.new.public_method(:foo).class end - end - ruby_version_is "2.7" do - it "is honored by Kernel#instance_method" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end - end - end + result.should == Method + end - result = nil - Module.new do - using refinement - result = klass.instance_method(:foo).class + it "is honored by Kernel#instance_method" do + klass = Class.new + refinement = Module.new do + refine klass do + def foo; end end + end - result.should == UnboundMethod + result = nil + Module.new do + using refinement + result = klass.instance_method(:foo).class end + + result.should == UnboundMethod end it "is honored by Kernel#respond_to?" do diff --git a/spec/ruby/core/module/ruby2_keywords_spec.rb b/spec/ruby/core/module/ruby2_keywords_spec.rb index 6de3fdec80..80a99e2624 100644 --- a/spec/ruby/core/module/ruby2_keywords_spec.rb +++ b/spec/ruby/core/module/ruby2_keywords_spec.rb @@ -1,215 +1,319 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' -ruby_version_is "2.7" do - describe "Module#ruby2_keywords" do - it "marks the final hash argument as keyword hash" do - obj = Object.new +describe "Module#ruby2_keywords" do + class << self + ruby2_keywords def mark(*args) + args + end + end - obj.singleton_class.class_exec do - def foo(*a) a.last end - ruby2_keywords :foo + it "marks the final hash argument as keyword hash" do + last = mark(1, 2, a: "a").last + Hash.ruby2_keywords_hash?(last).should == true + end + + it "makes a copy of the hash and only marks the copy as keyword hash" do + obj = Object.new + obj.singleton_class.class_exec do + def regular(*args) + args.last end + end - last = obj.foo(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + h = {a: 1} + ruby_version_is "3.0" do + obj.regular(**h).should.equal?(h) end - it "makes a copy of the hash and only marks the copy as keyword hash" do - obj = Object.new - obj.singleton_class.class_exec do - def regular(*args) - args.last - end + last = mark(**h).last + Hash.ruby2_keywords_hash?(last).should == true + Hash.ruby2_keywords_hash?(h).should == false - ruby2_keywords def foo(*args) - args.last - end - end + last2 = mark(**last).last # last is already marked + Hash.ruby2_keywords_hash?(last2).should == true + Hash.ruby2_keywords_hash?(last).should == true + last2.should_not.equal?(last) + Hash.ruby2_keywords_hash?(h).should == false + end - h = {a: 1} - ruby_version_is "3.0" do - obj.regular(**h).should.equal?(h) + it "makes a copy and unmark the Hash when calling a method taking (arg)" do + obj = Object.new + obj.singleton_class.class_exec do + def single(arg) + arg end + end - last = obj.foo(**h) - Hash.ruby2_keywords_hash?(last).should == true - Hash.ruby2_keywords_hash?(h).should == false + h = { a: 1 } + args = mark(**h) + marked = args.last + Hash.ruby2_keywords_hash?(marked).should == true + + after_usage = obj.single(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should_not.equal?(marked) + Hash.ruby2_keywords_hash?(after_usage).should == false + Hash.ruby2_keywords_hash?(marked).should == true + end - last2 = obj.foo(**last) # last is already marked - Hash.ruby2_keywords_hash?(last2).should == true - Hash.ruby2_keywords_hash?(last).should == true - last2.should_not.equal?(last) - Hash.ruby2_keywords_hash?(h).should == false + it "makes a copy and unmark the Hash when calling a method taking (**kw)" do + obj = Object.new + obj.singleton_class.class_exec do + def kwargs(**kw) + kw + end end - it "makes a copy and unmark at the call site when calling with marked *args" do + h = { a: 1 } + args = mark(**h) + marked = args.last + Hash.ruby2_keywords_hash?(marked).should == true + + after_usage = obj.kwargs(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should_not.equal?(marked) + Hash.ruby2_keywords_hash?(after_usage).should == false + Hash.ruby2_keywords_hash?(marked).should == true + end + + ruby_version_is "3.2" do + it "makes a copy and unmark the Hash when calling a method taking (*args)" do obj = Object.new obj.singleton_class.class_exec do - ruby2_keywords def foo(*args) - args - end - - def single(arg) - arg + def splat(*args) + args.last end - def splat(*args) + def splat1(arg, *args) args.last end - def kwargs(**kw) - kw + def proc_call(*args) + -> *a { a.last }.call(*args) end end h = { a: 1 } - args = obj.foo(**h) + args = mark(**h) marked = args.last Hash.ruby2_keywords_hash?(marked).should == true - after_usage = obj.single(*args) + after_usage = obj.splat(*args) after_usage.should == h after_usage.should_not.equal?(h) after_usage.should_not.equal?(marked) Hash.ruby2_keywords_hash?(after_usage).should == false Hash.ruby2_keywords_hash?(marked).should == true - after_usage = obj.splat(*args) + args = mark(1, **h) + marked = args.last + after_usage = obj.splat1(*args) after_usage.should == h after_usage.should_not.equal?(h) after_usage.should_not.equal?(marked) - ruby_bug "#18625", ""..."3.3" do # might be fixed in 3.2 - Hash.ruby2_keywords_hash?(after_usage).should == false - end + Hash.ruby2_keywords_hash?(after_usage).should == false Hash.ruby2_keywords_hash?(marked).should == true - after_usage = obj.kwargs(*args) + args = mark(**h) + marked = args.last + after_usage = obj.proc_call(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should_not.equal?(marked) + Hash.ruby2_keywords_hash?(after_usage).should == false + Hash.ruby2_keywords_hash?(marked).should == true + + args = mark(**h) + marked = args.last + after_usage = obj.send(:splat, *args) after_usage.should == h after_usage.should_not.equal?(h) after_usage.should_not.equal?(marked) Hash.ruby2_keywords_hash?(after_usage).should == false Hash.ruby2_keywords_hash?(marked).should == true end + end - it "applies to the underlying method and applies across aliasing" do + ruby_version_is ""..."3.2" do + # https://bugs.ruby-lang.org/issues/18625 + it "does NOT copy the Hash when calling a method taking (*args)" do obj = Object.new - obj.singleton_class.class_exec do - def foo(*a) a.last end - alias_method :bar, :foo - ruby2_keywords :foo + def splat(*args) + args.last + end - def baz(*a) a.last end - ruby2_keywords :baz - alias_method :bob, :baz + def splat1(arg, *args) + args.last + end + + def proc_call(*args) + -> *a { a.last }.call(*args) + end end - last = obj.foo(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + h = { a: 1 } + args = mark(**h) + marked = args.last + Hash.ruby2_keywords_hash?(marked).should == true - last = obj.bar(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + after_usage = obj.splat(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should.equal?(marked) # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(after_usage).should == true # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(marked).should == true - last = obj.baz(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + args = mark(1, **h) + marked = args.last + after_usage = obj.splat1(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should.equal?(marked) # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(after_usage).should == true # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(marked).should == true - last = obj.bob(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + args = mark(**h) + marked = args.last + after_usage = obj.proc_call(*args) + after_usage.should == h + after_usage.should_not.equal?(h) + after_usage.should.equal?(marked) # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(after_usage).should == true # https://bugs.ruby-lang.org/issues/18625 + Hash.ruby2_keywords_hash?(marked).should == true + + args = mark(**h) + marked = args.last + after_usage = obj.send(:splat, *args) + after_usage.should == h + after_usage.should_not.equal?(h) + send_copies = RUBY_ENGINE == "ruby" # inconsistent with Proc#call above for CRuby + after_usage.equal?(marked).should == !send_copies + Hash.ruby2_keywords_hash?(after_usage).should == !send_copies + Hash.ruby2_keywords_hash?(marked).should == true end + end - ruby_version_is "2.7" ... "3.0" do - it "fixes delegation warnings when calling a method accepting keywords" do - obj = Object.new + it "applies to the underlying method and applies across aliasing" do + obj = Object.new - obj.singleton_class.class_exec do - def foo(*a) bar(*a) end - def bar(*a, **b) end - end + obj.singleton_class.class_exec do + def foo(*a) a.last end + alias_method :bar, :foo + ruby2_keywords :foo - -> { obj.foo(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/) + def baz(*a) a.last end + ruby2_keywords :baz + alias_method :bob, :baz + end - obj.singleton_class.class_exec do - ruby2_keywords :foo - end + last = obj.foo(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true - -> { obj.foo(1, 2, {a: "a"}) }.should_not complain - end - end + last = obj.bar(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true - it "returns nil" do + last = obj.baz(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + + last = obj.bob(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + end + + ruby_version_is ""..."3.0" do + it "fixes delegation warnings when calling a method accepting keywords" do obj = Object.new obj.singleton_class.class_exec do - def foo(*a) end + def foo(*a) bar(*a) end + def bar(*a, **b) end + end - ruby2_keywords(:foo).should == nil + -> { obj.foo(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/) + + obj.singleton_class.class_exec do + ruby2_keywords :foo end + + -> { obj.foo(1, 2, {a: "a"}) }.should_not complain end + end - it "raises NameError when passed not existing method name" do - obj = Object.new + it "returns nil" do + obj = Object.new - -> { - obj.singleton_class.class_exec do - ruby2_keywords :not_existing - end - }.should raise_error(NameError, /undefined method `not_existing'/) + obj.singleton_class.class_exec do + def foo(*a) end + + ruby2_keywords(:foo).should == nil end + end - it "accepts String as well" do - obj = Object.new + it "raises NameError when passed not existing method name" do + obj = Object.new + -> { obj.singleton_class.class_exec do - def foo(*a) a.last end - ruby2_keywords "foo" + ruby2_keywords :not_existing end + }.should raise_error(NameError, /undefined method `not_existing'/) + end - last = obj.foo(1, 2, a: "a") - Hash.ruby2_keywords_hash?(last).should == true + it "accepts String as well" do + obj = Object.new + + obj.singleton_class.class_exec do + def foo(*a) a.last end + ruby2_keywords "foo" end - it "raises TypeError when passed not Symbol or String" do - obj = Object.new + last = obj.foo(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + end - -> { - obj.singleton_class.class_exec do - ruby2_keywords Object.new - end - }.should raise_error(TypeError, /is not a symbol nor a string/) - end + it "raises TypeError when passed not Symbol or String" do + obj = Object.new - it "prints warning when a method does not accept argument splat" do - obj = Object.new - def obj.foo(a, b, c) end + -> { + obj.singleton_class.class_exec do + ruby2_keywords Object.new + end + }.should raise_error(TypeError, /is not a symbol nor a string/) + end - -> { - obj.singleton_class.class_exec do - ruby2_keywords :foo - end - }.should complain(/Skipping set of ruby2_keywords flag for/) - end + it "prints warning when a method does not accept argument splat" do + obj = Object.new + def obj.foo(a, b, c) end - it "prints warning when a method accepts keywords" do - obj = Object.new - def obj.foo(a:, b:) end + -> { + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + }.should complain(/Skipping set of ruby2_keywords flag for/) + end - -> { - obj.singleton_class.class_exec do - ruby2_keywords :foo - end - }.should complain(/Skipping set of ruby2_keywords flag for/) - end + it "prints warning when a method accepts keywords" do + obj = Object.new + def obj.foo(a:, b:) end - it "prints warning when a method accepts keyword splat" do - obj = Object.new - def obj.foo(**a) end + -> { + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + }.should complain(/Skipping set of ruby2_keywords flag for/) + end - -> { - obj.singleton_class.class_exec do - ruby2_keywords :foo - end - }.should complain(/Skipping set of ruby2_keywords flag for/) - end + it "prints warning when a method accepts keyword splat" do + obj = Object.new + def obj.foo(**a) end + + -> { + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + }.should complain(/Skipping set of ruby2_keywords flag for/) end end |
