mirror of
https://github.com/ruby/ruby.git
synced 2026-08-16 12:57:31 +08:00
The `too_` prefix wasn't consistently used and just make the thing longer for no benefit.
304 lines
7.1 KiB
Ruby
304 lines
7.1 KiB
Ruby
require 'test/unit'
|
|
require "securerandom"
|
|
|
|
class TestObjectId < Test::Unit::TestCase
|
|
def setup
|
|
@obj = Object.new
|
|
end
|
|
|
|
def test_dup_new_id
|
|
id = @obj.object_id
|
|
refute_equal id, @obj.dup.object_id
|
|
end
|
|
|
|
def test_dup_with_ivar_and_id
|
|
id = @obj.object_id
|
|
@obj.instance_variable_set(:@foo, 42)
|
|
|
|
copy = @obj.dup
|
|
refute_equal id, copy.object_id
|
|
assert_equal 42, copy.instance_variable_get(:@foo)
|
|
end
|
|
|
|
def test_dup_with_id_and_ivar
|
|
@obj.instance_variable_set(:@foo, 42)
|
|
id = @obj.object_id
|
|
|
|
copy = @obj.dup
|
|
refute_equal id, copy.object_id
|
|
assert_equal 42, copy.instance_variable_get(:@foo)
|
|
end
|
|
|
|
def test_dup_with_id_and_ivar_and_frozen
|
|
@obj.instance_variable_set(:@foo, 42)
|
|
@obj.freeze
|
|
id = @obj.object_id
|
|
|
|
copy = @obj.dup
|
|
refute_equal id, copy.object_id
|
|
assert_equal 42, copy.instance_variable_get(:@foo)
|
|
refute_predicate copy, :frozen?
|
|
end
|
|
|
|
def test_clone_new_id
|
|
id = @obj.object_id
|
|
refute_equal id, @obj.clone.object_id
|
|
end
|
|
|
|
def test_clone_with_ivar_and_id
|
|
id = @obj.object_id
|
|
@obj.instance_variable_set(:@foo, 42)
|
|
|
|
copy = @obj.clone
|
|
refute_equal id, copy.object_id
|
|
assert_equal 42, copy.instance_variable_get(:@foo)
|
|
end
|
|
|
|
def test_clone_with_id_and_ivar
|
|
@obj.instance_variable_set(:@foo, 42)
|
|
id = @obj.object_id
|
|
|
|
copy = @obj.clone
|
|
refute_equal id, copy.object_id
|
|
assert_equal 42, copy.instance_variable_get(:@foo)
|
|
end
|
|
|
|
def test_clone_with_id_and_ivar_and_frozen
|
|
@obj.instance_variable_set(:@foo, 42)
|
|
@obj.freeze
|
|
id = @obj.object_id
|
|
|
|
copy = @obj.clone
|
|
refute_equal id, copy.object_id
|
|
assert_equal 42, copy.instance_variable_get(:@foo)
|
|
assert_predicate copy, :frozen?
|
|
end
|
|
|
|
def test_marshal_new_id
|
|
return pass if @obj.is_a?(Module)
|
|
|
|
id = @obj.object_id
|
|
refute_equal id, Marshal.load(Marshal.dump(@obj)).object_id
|
|
end
|
|
|
|
def test_marshal_with_ivar_and_id
|
|
return pass if @obj.is_a?(Module)
|
|
|
|
id = @obj.object_id
|
|
@obj.instance_variable_set(:@foo, 42)
|
|
|
|
copy = Marshal.load(Marshal.dump(@obj))
|
|
refute_equal id, copy.object_id
|
|
assert_equal 42, copy.instance_variable_get(:@foo)
|
|
end
|
|
|
|
def test_marshal_with_id_and_ivar
|
|
return pass if @obj.is_a?(Module)
|
|
|
|
@obj.instance_variable_set(:@foo, 42)
|
|
id = @obj.object_id
|
|
|
|
copy = Marshal.load(Marshal.dump(@obj))
|
|
refute_equal id, copy.object_id
|
|
assert_equal 42, copy.instance_variable_get(:@foo)
|
|
end
|
|
|
|
def test_marshal_with_id_and_ivar_and_frozen
|
|
return pass if @obj.is_a?(Module)
|
|
|
|
@obj.instance_variable_set(:@foo, 42)
|
|
@obj.freeze
|
|
id = @obj.object_id
|
|
|
|
copy = Marshal.load(Marshal.dump(@obj))
|
|
refute_equal id, copy.object_id
|
|
assert_equal 42, copy.instance_variable_get(:@foo)
|
|
refute_predicate copy, :frozen?
|
|
end
|
|
|
|
def test_object_id_need_resize
|
|
(3 - @obj.instance_variables.size).times do |i|
|
|
@obj.instance_variable_set("@a_#{i}", "[Bug #21445]")
|
|
end
|
|
@obj.object_id
|
|
GC.start
|
|
end
|
|
end
|
|
|
|
class TestObjectIdClass < TestObjectId
|
|
def setup
|
|
@obj = Class.new
|
|
end
|
|
end
|
|
|
|
class TestObjectIdGeneric < TestObjectId
|
|
def setup
|
|
@obj = Array.new
|
|
end
|
|
end
|
|
|
|
class TestObjectIdTooComplex < TestObjectId
|
|
class TooComplex
|
|
def initialize
|
|
@complex_obj_id_test = 1
|
|
end
|
|
end
|
|
|
|
def setup
|
|
if defined?(RubyVM::Shape::SHAPE_MAX_VARIATIONS)
|
|
assert_equal 8, RubyVM::Shape::SHAPE_MAX_VARIATIONS
|
|
end
|
|
8.times do |i|
|
|
TooComplex.new.instance_variable_set("@TestObjectIdTooComplex#{i}", 1)
|
|
end
|
|
@obj = TooComplex.new
|
|
@obj.instance_variable_set("@a#{rand(10_000)}", 1)
|
|
|
|
if defined?(RubyVM::Shape)
|
|
assert_predicate(RubyVM::Shape.of(@obj), :complex?)
|
|
end
|
|
end
|
|
end
|
|
|
|
class TestObjectIdTooComplexClass < TestObjectId
|
|
class TooComplex < Module
|
|
end
|
|
|
|
def setup
|
|
if defined?(RubyVM::Shape::SHAPE_MAX_VARIATIONS)
|
|
assert_equal 8, RubyVM::Shape::SHAPE_MAX_VARIATIONS
|
|
end
|
|
|
|
@obj = TooComplex.new
|
|
|
|
@obj.instance_variable_set("@___#{SecureRandom.hex}", 1)
|
|
|
|
8.times do |i|
|
|
@obj.instance_variable_set("@TestObjectIdTooComplexClass#{i}", 1)
|
|
@obj.remove_instance_variable("@TestObjectIdTooComplexClass#{i}")
|
|
end
|
|
|
|
@obj.instance_variable_set("@test", 1)
|
|
|
|
if defined?(RubyVM::Shape)
|
|
assert_predicate(RubyVM::Shape.of(@obj), :complex?)
|
|
end
|
|
end
|
|
end
|
|
|
|
class TestObjectIdTooComplexGeneric < TestObjectId
|
|
class TooComplex < Array
|
|
end
|
|
|
|
def setup
|
|
if defined?(RubyVM::Shape::SHAPE_MAX_VARIATIONS)
|
|
assert_equal 8, RubyVM::Shape::SHAPE_MAX_VARIATIONS
|
|
end
|
|
8.times do |i|
|
|
TooComplex.new.instance_variable_set("@TestObjectIdTooComplexGeneric#{i}", 1)
|
|
end
|
|
@obj = TooComplex.new
|
|
@obj.instance_variable_set("@a#{rand(10_000)}", 1)
|
|
@obj.instance_variable_set("@a#{rand(10_000)}", 1)
|
|
|
|
if defined?(RubyVM::Shape)
|
|
assert_predicate(RubyVM::Shape.of(@obj), :complex?)
|
|
end
|
|
end
|
|
end
|
|
|
|
class TestObjectIdRactor < Test::Unit::TestCase
|
|
def test_object_id_race_free
|
|
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
|
begin;
|
|
Warning[:experimental] = false
|
|
class MyClass
|
|
attr_reader :a, :b, :c
|
|
def initialize
|
|
@a = @b = @c = nil
|
|
end
|
|
end
|
|
N = 10_000
|
|
objs = Ractor.make_shareable(N.times.map { MyClass.new })
|
|
results = 4.times.map{
|
|
Ractor.new(objs) { |objs|
|
|
vars = []
|
|
ids = []
|
|
objs.each do |obj|
|
|
vars << obj.a << obj.b << obj.c
|
|
ids << obj.object_id
|
|
end
|
|
[vars, ids]
|
|
}
|
|
}.map(&:value)
|
|
assert_equal 1, results.uniq.size
|
|
end;
|
|
end
|
|
|
|
def test_external_object_id_ractor_move
|
|
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
|
begin;
|
|
Warning[:experimental] = false
|
|
class MyClass
|
|
attr_reader :a, :b, :c
|
|
def initialize
|
|
@a = @b = @c = nil
|
|
end
|
|
end
|
|
obj = Ractor.make_shareable(MyClass.new)
|
|
object_id = obj.object_id
|
|
obj = Ractor.new { Ractor.receive }.send(obj, move: true).value
|
|
assert_equal object_id, obj.object_id
|
|
end;
|
|
end
|
|
end
|
|
|
|
class TestObjectIdStruct < TestObjectId
|
|
EmbeddedStruct = Struct.new(:embedded_field)
|
|
|
|
def setup
|
|
@obj = EmbeddedStruct.new
|
|
end
|
|
end
|
|
|
|
class TestObjectIdStructGenIvar < TestObjectId
|
|
GenIvarStruct = Struct.new(:a, :b, :c)
|
|
|
|
def setup
|
|
@obj = GenIvarStruct.new
|
|
end
|
|
end
|
|
|
|
class TestObjectIdStructNotEmbed < TestObjectId
|
|
MANY_IVS = 80
|
|
|
|
StructNotEmbed = Struct.new(*MANY_IVS.times.map { |i| :"field_#{i}" })
|
|
|
|
def setup
|
|
@obj = StructNotEmbed.new
|
|
end
|
|
end
|
|
|
|
class TestObjectIdStructTooComplex < TestObjectId
|
|
StructTooComplex = Struct.new(:a) do
|
|
def initialize
|
|
@complex_obj_id_test = 1
|
|
end
|
|
end
|
|
|
|
def setup
|
|
if defined?(RubyVM::Shape::SHAPE_MAX_VARIATIONS)
|
|
assert_equal 8, RubyVM::Shape::SHAPE_MAX_VARIATIONS
|
|
end
|
|
8.times do |i|
|
|
StructTooComplex.new.instance_variable_set("@TestObjectIdStructTooComplex#{i}", 1)
|
|
end
|
|
@obj = StructTooComplex.new
|
|
@obj.instance_variable_set("@a#{rand(10_000)}", 1)
|
|
|
|
if defined?(RubyVM::Shape)
|
|
assert_predicate(RubyVM::Shape.of(@obj), :complex?)
|
|
end
|
|
end
|
|
end
|