module Ref::Mock
This module provides mock weak and strong references that are designed to be used in tests. You can define a block where all weak and soft references created will be mock references. You can then mimic running the garbage collector on the objects pointed to by the references.
Example usage:
Ref::Mock.use do obj = Object.new ref = Ref::WeakReference.new(obj) ref.object # obj Ref::Mock.gc(obj) # mimics the garbage collector reclaiming the referenced object ref.object # nil end
Public Class Methods
cleanup()
click to toggle source
Stop using mock references.
# File lib/ref/mock.rb, line 85 def cleanup @object_space = nil class << ObjectSpace alias_method :define_finalizer_with_mock_reference, :define_finalizer alias_method :define_finalizer, :define_finalizer_without_mock_reference end class << WeakReference alias_method :new_with_mock_reference, :new alias_method :new, :new_without_mock_reference end class << SoftReference alias_method :new_with_mock_reference, :new alias_method :new, :new_without_mock_reference end end
gc(*objects)
click to toggle source
Simulate garbage collection of the objects passed in as arguments. If no objects are specified, all objects will be reclaimed.
# File lib/ref/mock.rb, line 109 def gc(*objects) objects = if objects.empty? object_space.keys else objects.map { |obj| obj.__id__ } end objects.each do |id| finalizers = object_space.delete(id) if finalizers finalizers.each{|finalizer| finalizer.call(id)} end end end
setup()
click to toggle source
Start using mock references.
# File lib/ref/mock.rb, line 33 def setup raise "Ref::Mock already setup" if object_space @object_space = {} class << ObjectSpace unless method_defined?(:define_finalizer_with_mock_reference) def define_finalizer_with_mock_reference(obj, finalizer) if ::Ref::Mock.object_space.include?(obj.__id__) ::Ref::Mock.object_space[obj.__id__] << finalizer else define_finalizer_without_mock_reference(obj, finalizer) end end end alias_method :define_finalizer_without_mock_reference, :define_finalizer alias_method :define_finalizer, :define_finalizer_with_mock_reference end class << WeakReference unless method_defined?(:new_with_mock_reference) def new_with_mock_reference(obj) if self == Mock::MockWeakReference new_without_mock_reference(obj) else Mock::MockWeakReference.new(obj) end end end alias_method :new_without_mock_reference, :new alias_method :new, :new_with_mock_reference end class << SoftReference unless method_defined?(:new_with_mock_reference) def new_with_mock_reference(obj) if self == Mock::MockSoftReference new_without_mock_reference(obj) else Mock::MockSoftReference.new(obj) end end end alias_method :new_without_mock_reference, :new alias_method :new, :new_with_mock_reference end end
use() { || ... }
click to toggle source
Use the mock implementation inside a block and then restore the original implementation.
# File lib/ref/mock.rb, line 19 def use if object_space yield else setup begin yield ensure cleanup end end end