Skip to content

Commit 9d386bd

Browse files
committed
Improve refine+super tests: add more corner cases & check the whole super chain
1 parent 02fe5e5 commit 9d386bd

File tree

2 files changed

+173
-7
lines changed

2 files changed

+173
-7
lines changed

spec/ruby/core/module/fixtures/refine.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ class ClassWithFoo
33
def foo; "foo" end
44
end
55

6+
class ClassWithSuperFoo
7+
def foo; [:C] end
8+
end
9+
610
module PrependedModule
711
def foo; "foo from prepended module"; end
812
end
@@ -11,7 +15,9 @@ module IncludedModule
1115
def foo; "foo from included module"; end
1216
end
1317

14-
def self.build_refined_class
15-
Class.new(ClassWithFoo)
18+
def self.build_refined_class(for_super: false)
19+
return Class.new(ClassWithSuperFoo) if for_super
20+
21+
return Class.new(ClassWithFoo)
1622
end
1723
end

spec/ruby/core/module/refine_spec.rb

Lines changed: 165 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -731,24 +731,49 @@ def foo
731731
result.should == "foo"
732732
end
733733

734+
it "looks in the refined class from included module" do
735+
refined_class = ModuleSpecs.build_refined_class(for_super: true)
736+
737+
a = Module.new do
738+
def foo
739+
[:A] + super
740+
end
741+
end
742+
743+
refinement = Module.new do
744+
refine refined_class do
745+
include a
746+
end
747+
end
748+
749+
result = nil
750+
Module.new do
751+
using refinement
752+
753+
result = refined_class.new.foo
754+
end
755+
756+
result.should == [:A, :C]
757+
end
758+
734759
# super in a method of a refinement invokes the method in the refined
735760
# class even if there is another refinement which has been activated
736761
# in the same context.
737-
it "looks in the refined class even if there is another active refinement" do
738-
refined_class = ModuleSpecs.build_refined_class
762+
it "looks in the refined class first if called from refined method" do
763+
refined_class = ModuleSpecs.build_refined_class(for_super: true)
739764

740765
refinement = Module.new do
741766
refine refined_class do
742767
def foo
743-
"foo from refinement"
768+
[:R1]
744769
end
745770
end
746771
end
747772

748773
refinement_with_super = Module.new do
749774
refine refined_class do
750775
def foo
751-
super
776+
[:R2] + super
752777
end
753778
end
754779
end
@@ -760,7 +785,142 @@ def foo
760785
result = refined_class.new.foo
761786
end
762787

763-
result.should == "foo"
788+
result.should == [:R2, :C]
789+
end
790+
791+
it "looks only in the refined class even if there is another active refinement" do
792+
refined_class = ModuleSpecs.build_refined_class(for_super: true)
793+
794+
refinement = Module.new do
795+
refine refined_class do
796+
def bar
797+
"you cannot see me from super because I belongs to another active R"
798+
end
799+
end
800+
end
801+
802+
refinement_with_super = Module.new do
803+
refine refined_class do
804+
def bar
805+
super
806+
end
807+
end
808+
end
809+
810+
811+
Module.new do
812+
using refinement
813+
using refinement_with_super
814+
-> {
815+
refined_class.new.bar
816+
}.should raise_error(NoMethodError)
817+
end
818+
end
819+
820+
it "does't have access to refinement from included module" do
821+
refined_class = ModuleSpecs.build_refined_class
822+
823+
a = Module.new do
824+
def foo
825+
super + bar
826+
end
827+
end
828+
829+
refinement = Module.new do
830+
refine refined_class do
831+
include a
832+
833+
def bar
834+
"bar is not seen from A methods"
835+
end
836+
end
837+
end
838+
839+
840+
Module.new do
841+
using refinement
842+
-> {
843+
refined_class.new.foo
844+
}.should raise_error(NameError)
845+
end
846+
end
847+
848+
# https://bugs.ruby-lang.org/issues/16977
849+
it "looks in the another active refinement if super called from included modules" do
850+
refined_class = ModuleSpecs.build_refined_class(for_super: true)
851+
852+
a = Module.new do
853+
def foo
854+
[:A] + super
855+
end
856+
end
857+
858+
b = Module.new do
859+
def foo
860+
[:B] + super
861+
end
862+
end
863+
864+
refinement = Module.new do
865+
refine refined_class do
866+
include a
867+
end
868+
end
869+
870+
refinement1 = Module.new do
871+
refine refined_class do
872+
include b
873+
end
874+
end
875+
876+
result = nil
877+
Module.new do
878+
using refinement
879+
using refinement1
880+
result = refined_class.new.foo
881+
end
882+
883+
result.should == [:B, :A, :C]
884+
end
885+
886+
it "looks in the current active refinement from included modules" do
887+
refined_class = ModuleSpecs.build_refined_class(for_super: true)
888+
889+
a = Module.new do
890+
def foo
891+
[:A] + super
892+
end
893+
end
894+
895+
b = Module.new do
896+
def foo
897+
[:B] + super
898+
end
899+
end
900+
901+
refinement = Module.new do
902+
refine refined_class do
903+
def foo
904+
[:LAST] + super
905+
end
906+
end
907+
end
908+
909+
refinement1 = Module.new do
910+
refine refined_class do
911+
include a
912+
include b
913+
end
914+
end
915+
916+
result = nil
917+
Module.new do
918+
using refinement
919+
using refinement1
920+
result = refined_class.new.foo
921+
end
922+
923+
result.should == [:B, :A, :LAST, :C]
764924
end
765925
end
766926

0 commit comments

Comments
 (0)