diff options
Diffstat (limited to 'spec/ruby/core/module/refine_spec.rb')
-rw-r--r-- | spec/ruby/core/module/refine_spec.rb | 700 |
1 files changed, 293 insertions, 407 deletions
diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb index e5f65f5f96..11085c325b 100644 --- a/spec/ruby/core/module/refine_spec.rb +++ b/spec/ruby/core/module/refine_spec.rb @@ -71,7 +71,7 @@ describe "Module#refine" do Module.new do refine("foo") {} end - end.should raise_error(TypeError) + end.should raise_error(TypeError, "wrong argument type String (expected Class or Module)") end it "accepts a module as argument" do @@ -243,28 +243,30 @@ describe "Module#refine" do result.should == "foo from singleton class" end - it "looks in the included modules for builtin methods" do - result = ruby_exe(<<-RUBY) - a = Module.new do - def /(other) quo(other) end - end + ruby_version_is ""..."3.2" do + it "looks in the included modules for builtin methods" do + result = ruby_exe(<<-RUBY) + a = Module.new do + def /(other) quo(other) end + end - refinement = Module.new do - refine Integer do - include a + refinement = Module.new do + refine Integer do + include a + end end - end - result = nil - Module.new do - using refinement - result = 1 / 2 - end + result = nil + Module.new do + using refinement + result = 1 / 2 + end - print result.class - RUBY + print result.class + RUBY - result.should == 'Rational' + result.should == 'Rational' + end end it "looks in later included modules of the refined module first" do @@ -298,63 +300,65 @@ describe "Module#refine" do result.should == "foo from IncludeMeLater" end - it "looks in prepended modules from the refinement first" do - refined_class = ModuleSpecs.build_refined_class + ruby_version_is ""..."3.1" do + it "looks in prepended modules from the refinement first" do + refined_class = ModuleSpecs.build_refined_class - refinement = Module.new do - refine refined_class do - include ModuleSpecs::IncludedModule - prepend ModuleSpecs::PrependedModule + refinement = Module.new do + refine refined_class do + include ModuleSpecs::IncludedModule + prepend ModuleSpecs::PrependedModule - def foo; "foo from refinement"; end + def foo; "foo from refinement"; end + end end - end - result = nil - Module.new do - using refinement - result = refined_class.new.foo + result = nil + Module.new do + using refinement + result = refined_class.new.foo + end + + result.should == "foo from prepended module" end - result.should == "foo from prepended module" - end + it "looks in refinement then" do + refined_class = ModuleSpecs.build_refined_class - it "looks in refinement then" do - refined_class = ModuleSpecs.build_refined_class + refinement = Module.new do + refine(refined_class) do + include ModuleSpecs::IncludedModule - refinement = Module.new do - refine(refined_class) do - include ModuleSpecs::IncludedModule + def foo; "foo from refinement"; end + end + end - def foo; "foo from refinement"; end + result = nil + Module.new do + using refinement + result = refined_class.new.foo end - end - result = nil - Module.new do - using refinement - result = refined_class.new.foo + result.should == "foo from refinement" end - result.should == "foo from refinement" - end + it "looks in included modules from the refinement then" do + refined_class = ModuleSpecs.build_refined_class - it "looks in included modules from the refinement then" do - refined_class = ModuleSpecs.build_refined_class + refinement = Module.new do + refine refined_class do + include ModuleSpecs::IncludedModule + end + end - refinement = Module.new do - refine refined_class do - include ModuleSpecs::IncludedModule + result = nil + Module.new do + using refinement + result = refined_class.new.foo end - end - result = nil - Module.new do - using refinement - result = refined_class.new.foo + result.should == "foo from included module" end - - result.should == "foo from included module" end it "looks in the class then" do @@ -453,44 +457,22 @@ describe "Module#refine" do result.should == ["(1)", "(2)", "(3)"] end - ruby_version_is "" ... "2.6" do - it "is not honored by Kernel#public_send" do - refined_class = ModuleSpecs.build_refined_class - - refinement = Module.new do - refine refined_class do - def foo; "foo from refinement"; end - end - end + it "is honored by Kernel#public_send" do + refined_class = ModuleSpecs.build_refined_class - result = nil - Module.new do - using refinement - result = refined_class.new.public_send :foo + refinement = Module.new do + refine refined_class do + def foo; "foo from refinement"; end end - - result.should == "foo" end - end - - ruby_version_is "2.6" do - it "is honored by Kernel#public_send" do - refined_class = ModuleSpecs.build_refined_class - - refinement = Module.new do - refine refined_class do - def foo; "foo from refinement"; end - end - end - result = nil - Module.new do - using refinement - result = refined_class.new.public_send :foo - end - - result.should == "foo from refinement" + result = nil + Module.new do + using refinement + result = refined_class.new.public_send :foo end + + result.should == "foo from refinement" end it "is honored by string interpolation" do @@ -536,180 +518,104 @@ 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 = nil - Module.new do - using refinement - result = klass.instance_method(:foo).class - end - - result.should == UnboundMethod - end + result.should == Method end - ruby_version_is "" ... "2.6" do - it "is not honored by Kernel#respond_to?" 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.respond_to?(:foo) + 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 == false + result = nil + Module.new do + using refinement + result = klass.instance_method(:foo).class end - end - ruby_version_is "2.6" do - it "is honored by Kernel#respond_to?" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end - end - end + result.should == UnboundMethod + end - result = nil - Module.new do - using refinement - result = klass.new.respond_to?(:foo) + it "is honored by Kernel#respond_to?" do + klass = Class.new + refinement = Module.new do + refine klass do + def foo; end end + end - result.should == true + result = nil + Module.new do + using refinement + result = klass.new.respond_to?(:foo) end + + result.should == true end - ruby_version_is ""..."2.6" do - it "is not honored by &" do - refinement = Module.new do - refine String do - def to_proc(*args) - -> * { 'foo' } - end + it "is honored by &" do + refinement = Module.new do + refine String do + def to_proc(*args) + -> * { 'foo' } end end + end - -> do - Module.new do - using refinement - ["hola"].map(&"upcase") - end - end.should raise_error(TypeError, /wrong argument type String \(expected Proc\)/) + result = nil + Module.new do + using refinement + result = ["hola"].map(&"upcase") end + + result.should == ['foo'] end + end + + context "when super is called in a refinement" do + ruby_version_is ""..."3.1" do + it "looks in the included to refinery module" do + refined_class = ModuleSpecs.build_refined_class - ruby_version_is "2.6" do - it "is honored by &" do refinement = Module.new do - refine String do - def to_proc(*args) - -> * { 'foo' } + refine refined_class do + include ModuleSpecs::IncludedModule + + def foo + super end end end @@ -717,22 +623,18 @@ describe "Module#refine" do result = nil Module.new do using refinement - result = ["hola"].map(&"upcase") + result = refined_class.new.foo end - result.should == ['foo'] + result.should == "foo from included module" end end - end - context "when super is called in a refinement" do - it "looks in the included to refinery module" do + it "looks in the refined class" do refined_class = ModuleSpecs.build_refined_class refinement = Module.new do refine refined_class do - include ModuleSpecs::IncludedModule - def foo super end @@ -745,78 +647,60 @@ describe "Module#refine" do result = refined_class.new.foo end - result.should == "foo from included module" + result.should == "foo" end - it "looks in the refined class" do - refined_class = ModuleSpecs.build_refined_class + ruby_version_is ""..."3.1" do + it "looks in the refined class from included module" do + refined_class = ModuleSpecs.build_refined_class(for_super: true) - refinement = Module.new do - refine refined_class do + a = Module.new do def foo - super + [:A] + super end end - end - - result = nil - Module.new do - using refinement - result = refined_class.new.foo - end - - result.should == "foo" - end - - it "looks in the refined class from included module" do - refined_class = ModuleSpecs.build_refined_class(for_super: true) - a = Module.new do - def foo - [:A] + super + refinement = Module.new do + refine refined_class do + include a + end end - end - refinement = Module.new do - refine refined_class do - include a - end - end + result = nil + Module.new do + using refinement - result = nil - Module.new do - using refinement + result = refined_class.new.foo + end - result = refined_class.new.foo + result.should == [:A, :C] end - result.should == [:A, :C] - end + it "looks in the refined ancestors from included module" do + refined_class = ModuleSpecs.build_refined_class(for_super: true) + subclass = Class.new(refined_class) - it "looks in the refined ancestors from included module" do - refined_class = ModuleSpecs.build_refined_class(for_super: true) - subclass = Class.new(refined_class) - - a = Module.new do - def foo - [:A] + super + a = Module.new do + def foo + [:A] + super + end end - end - refinement = Module.new do - refine refined_class do - include a + refinement = Module.new do + refine refined_class do + include a + end end - end - result = nil - Module.new do - using refinement + result = nil + Module.new do + using refinement - result = subclass.new.foo - end + result = subclass.new.foo + end - result.should == [:A, :C] + result.should == [:A, :C] + end end # super in a method of a refinement invokes the method in the refined @@ -880,175 +764,177 @@ describe "Module#refine" do end end - it "does't have access to active refinements for C from included module" do - refined_class = ModuleSpecs.build_refined_class + ruby_version_is ""..."3.1" do + it "does't have access to active refinements for C from included module" do + refined_class = ModuleSpecs.build_refined_class - a = Module.new do - def foo - super + bar + a = Module.new do + def foo + super + bar + end end - end - refinement = Module.new do - refine refined_class do - include a + refinement = Module.new do + refine refined_class do + include a - def bar - "bar is not seen from A methods" + def bar + "bar is not seen from A methods" + end end end - end - Module.new do - using refinement - -> { - refined_class.new.foo - }.should raise_error(NameError) { |e| e.name.should == :bar } + Module.new do + using refinement + -> { + refined_class.new.foo + }.should raise_error(NameError) { |e| e.name.should == :bar } + end end - end - it "does't have access to other active refinements from included module" do - refined_class = ModuleSpecs.build_refined_class + it "does't have access to other active refinements from included module" do + refined_class = ModuleSpecs.build_refined_class - refinement_integer = Module.new do - refine Integer do - def bar - "bar is not seen from A methods" + refinement_integer = Module.new do + refine Integer do + def bar + "bar is not seen from A methods" + end end end - end - a = Module.new do - def foo - super + 1.bar + a = Module.new do + def foo + super + 1.bar + end end - end - refinement = Module.new do - refine refined_class do - include a + refinement = Module.new do + refine refined_class do + include a + end end - end - Module.new do - using refinement - using refinement_integer - -> { - refined_class.new.foo - }.should raise_error(NameError) { |e| e.name.should == :bar } + Module.new do + using refinement + using refinement_integer + -> { + refined_class.new.foo + }.should raise_error(NameError) { |e| e.name.should == :bar } + end end - end - # https://bugs.ruby-lang.org/issues/16977 - it "looks in the another active refinement if super called from included modules" do - refined_class = ModuleSpecs.build_refined_class(for_super: true) + # https://bugs.ruby-lang.org/issues/16977 + it "looks in the another active refinement if super called from included modules" do + refined_class = ModuleSpecs.build_refined_class(for_super: true) - a = Module.new do - def foo - [:A] + super + a = Module.new do + def foo + [:A] + super + end end - end - b = Module.new do - def foo - [:B] + super + b = Module.new do + def foo + [:B] + super + end end - end - refinement_a = Module.new do - refine refined_class do - include a + refinement_a = Module.new do + refine refined_class do + include a + end end - end - refinement_b = Module.new do - refine refined_class do - include b + refinement_b = Module.new do + refine refined_class do + include b + end end - end - result = nil - Module.new do - using refinement_a - using refinement_b - result = refined_class.new.foo + result = nil + Module.new do + using refinement_a + using refinement_b + result = refined_class.new.foo + end + + result.should == [:B, :A, :C] end - result.should == [:B, :A, :C] - end + it "looks in the current active refinement from included modules" do + refined_class = ModuleSpecs.build_refined_class(for_super: true) - it "looks in the current active refinement from included modules" do - refined_class = ModuleSpecs.build_refined_class(for_super: true) + a = Module.new do + def foo + [:A] + super + end + end - a = Module.new do - def foo - [:A] + super + b = Module.new do + def foo + [:B] + super + end end - end - b = Module.new do - def foo - [:B] + super + refinement = Module.new do + refine refined_class do + def foo + [:LAST] + super + end + end end - end - refinement = Module.new do - refine refined_class do - def foo - [:LAST] + super + refinement_a_b = Module.new do + refine refined_class do + include a + include b end end - end - refinement_a_b = Module.new do - refine refined_class do - include a - include b + result = nil + Module.new do + using refinement + using refinement_a_b + result = refined_class.new.foo end - end - result = nil - Module.new do - using refinement - using refinement_a_b - result = refined_class.new.foo + result.should == [:B, :A, :LAST, :C] end - result.should == [:B, :A, :LAST, :C] - end + it "looks in the lexical scope refinements before other active refinements" do + refined_class = ModuleSpecs.build_refined_class(for_super: true) - it "looks in the lexical scope refinements before other active refinements" do - refined_class = ModuleSpecs.build_refined_class(for_super: true) + refinement_local = Module.new do + refine refined_class do + def foo + [:LOCAL] + super + end + end + end + + a = Module.new do + using refinement_local - refinement_local = Module.new do - refine refined_class do def foo - [:LOCAL] + super + [:A] + super end end - end - a = Module.new do - using refinement_local - - def foo - [:A] + super + refinement = Module.new do + refine refined_class do + include a + end end - end - refinement = Module.new do - refine refined_class do - include a + result = nil + Module.new do + using refinement + result = refined_class.new.foo end - end - result = nil - Module.new do - using refinement - result = refined_class.new.foo + result.should == [:A, :LOCAL, :C] end - - result.should == [:A, :LOCAL, :C] end end |