|
require 'test/unit'
|
|
require 'weakref'
|
|
|
|
class TestWeakRef < Test::Unit::TestCase
|
|
def test_can_get_non_garbage_collected_objects
|
|
obj = Object.new
|
|
ref = WeakRef.new(obj)
|
|
assert_equal obj, ref.__getobj__
|
|
assert_equal true, ref.weakref_alive?
|
|
end
|
|
|
|
def test_get_the_correct_object
|
|
# Since we can't reliably control the garbage collector, this is a brute force test.
|
|
# It might not always fail if the garbage collector and memory allocator don't
|
|
# cooperate, but it should fail often enough on continuous integration to
|
|
# hilite any problems.
|
|
id_to_ref = {}
|
|
50000.times do |i|
|
|
obj = Object.new
|
|
if id_to_ref.key?(obj.object_id)
|
|
ref = id_to_ref[obj.object_id]
|
|
refobj = ref.__getobj__ rescue nil
|
|
if refobj
|
|
flunk "weak reference found with a live reference to an object that was not the one it was created with"
|
|
break
|
|
end
|
|
end
|
|
%w(Here are a bunch of objects that are allocated and can then be cleaned up by the garbage collector)
|
|
id_to_ref[obj.object_id] = WeakRef.new(obj)
|
|
if i % 1000 == 0
|
|
GC.start
|
|
sleep(0.01)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
class TestWeakReference < Test::Unit::TestCase
|
|
def test_can_get_non_garbage_collected_objects
|
|
obj = Object.new
|
|
ref = WeakReference.new(obj)
|
|
assert_equal obj, ref.object
|
|
assert_equal obj.object_id, ref.referenced_object_id
|
|
end
|
|
|
|
def test_get_the_correct_object
|
|
# Since we can't reliably control the garbage collector, this is a brute force test.
|
|
# It might not always fail if the garbage collector and memory allocator don't
|
|
# cooperate, but it should fail often enough on continuous integration to
|
|
# hilite any problems.
|
|
id_to_ref = {}
|
|
50000.times do |i|
|
|
obj = Object.new
|
|
if id_to_ref.key?(obj.object_id)
|
|
ref = id_to_ref[obj.object_id]
|
|
if ref.object
|
|
flunk "weak reference found with a live reference to an object that was not the one it was created with"
|
|
break
|
|
end
|
|
end
|
|
%w(Here are a bunch of objects that are allocated and can then be cleaned up by the garbage collector)
|
|
id_to_ref[obj.object_id] = WeakReference.new(obj)
|
|
if i % 1000 == 0
|
|
GC.start
|
|
sleep(0.01)
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_inspect
|
|
ref = WeakReference.new(Object.new)
|
|
assert ref.inspect
|
|
GC.start
|
|
GC.start
|
|
assert ref.inspect
|
|
end
|
|
end
|