summaryrefslogtreecommitdiff
path: root/test/ruby/test_enum.rb
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2020-05-23 20:16:27 -0700
committerJeremy Evans <code@jeremyevans.net>2020-06-03 09:50:37 -0700
commit98286e9850936e27e8ae5e4f20858cc9c13d2dde (patch)
treebb8dc151858b6e415d0c264af70467354cdf89e7 /test/ruby/test_enum.rb
parentee35a4dad30eaf74064d5c38bfdfb3550998bb8f (diff)
Ensure origins for all included, prepended, and refined modules
This fixes various issues when a module is included in or prepended to a module or class, and then refined, or refined and then included or prepended to a module or class. Implement by renaming ensure_origin to rb_ensure_origin, making it non-static, and calling it when refining a module. Fix Module#initialize_copy to handle origins correctly. Previously, Module#initialize_copy did not handle origins correctly. For example, this code: ```ruby module B; end class A def b; 2 end prepend B end a = A.dup.new class A def b; 1 end end p a.b ``` Printed 1 instead of 2. This is because the super chain for a.singleton_class was: ``` a.singleton_class A.dup B(iclass) B(iclass origin) A(origin) # not A.dup(origin) ``` The B iclasses would not be modified, so the includer entry would be still be set to A and not A.dup. This modifies things so that if the class/module has an origin, all iclasses between the class/module and the origin are duplicated and have the correct includer entry set, and the correct origin is created. This requires other changes to make sure all tests still pass: * rb_undef_methods_from doesn't automatically handle classes with origins, so pass it the origin for Comparable when undefing methods in Complex. This fixed a failure in the Complex tests. * When adding a method, the method cache was not cleared correctly if klass has an origin. Clear the method cache for the klass before switching to the origin of klass. This fixed failures in the autoload tests related to overridding require, without breaking the optimization tests. Also clear the method cache for both the module and origin when removing a method. * Module#include? is fixed to skip origin iclasses. * Refinements are fixed to use the origin class of the module that has an origin. * RCLASS_REFINED_BY_ANY is removed as it was only used in a single place and is no longer needed. * Marshal#dump is fixed to skip iclass origins. * rb_method_entry_make is fixed to handled overridden optimized methods for modules that have origins. Fixes [Bug #16852]
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3140
Diffstat (limited to 'test/ruby/test_enum.rb')
-rw-r--r--test/ruby/test_enum.rb19
1 files changed, 19 insertions, 0 deletions
diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb
index 7b647231c8..809db31c2c 100644
--- a/test/ruby/test_enum.rb
+++ b/test/ruby/test_enum.rb
@@ -279,6 +279,25 @@ class TestEnumerable < Test::Unit::TestCase
end;
end
+ def test_refine_Enumerable_then_include
+ assert_separately([], "#{<<~"end;"}\n")
+ module RefinementBug
+ refine Enumerable do
+ def refined_method
+ :rm
+ end
+ end
+ end
+ using RefinementBug
+
+ class A
+ include Enumerable
+ end
+
+ assert_equal(:rm, [].refined_method)
+ end;
+ end
+
def test_partition
assert_equal([[1, 3, 1], [2, 2]], @obj.partition {|x| x % 2 == 1 })
cond = ->(x, i) { x % 2 == 1 }