Record calls on injected mocks

This commit is contained in:
Michael Miller 2022-06-28 23:36:24 -06:00
parent 8aed5027aa
commit c8ec0ad02a
No known key found for this signature in database
GPG key ID: AC78B32D30CE34A2
6 changed files with 146 additions and 55 deletions

View file

@ -113,15 +113,10 @@ module Spectator
{% end %}
private def _spectator_stubs
@@_spectator_mock_registry.fetch(self) do
{% begin %}
[
{% for key, value in value_methods %}
::Spectator::ValueStub.new({{key.id.symbolize}}, {{value}}),
{% end %}
] of ::Spectator::Stub
{% end %}
entry = @@_spectator_mock_registry.fetch(self) do
_spectator_default_stubs
end
entry.stubs
end
def _spectator_clear_stubs : Nil
@ -129,7 +124,20 @@ module Spectator
end
def _spectator_calls
[] of ::Spectator::MethodCall
entry = @@_spectator_mock_registry.fetch(self) do
_spectator_default_stubs
end
entry.calls
end
private def _spectator_default_stubs
{% begin %}
[
{% for key, value in value_methods %}
::Spectator::ValueStub.new({{key.id.symbolize}}, {{value}}),
{% end %}
] of ::Spectator::Stub
{% end %}
end
# Returns the mock's name formatted for user output.

View file

@ -0,0 +1,13 @@
require "./method_call"
require "./stub"
module Spectator
# Stubs and calls for a mock.
private struct MockRegistryEntry
# Retrieves all stubs defined for a mock.
property stubs = [] of Stub
# Retrieves all calls to stubbed methods.
getter calls = [] of MethodCall
end
end

View file

@ -1,3 +1,4 @@
require "./mock_registry_entry"
require "./stub"
module Spectator
@ -9,19 +10,19 @@ module Spectator
# This registry works around that by mapping mocks (via their memory address) to a collection of stubs.
# Doing so prevents adding data to the mocked type.
class ReferenceMockRegistry
@object_stubs : Hash(Void*, Array(Stub))
@entries : Hash(Void*, MockRegistryEntry)
# Creates an empty registry.
def initialize
@object_stubs = Hash(Void*, Array(Stub)).new do |hash, key|
hash[key] = [] of Stub
@entries = Hash(Void*, MockRegistryEntry).new do |hash, key|
hash[key] = MockRegistryEntry.new
end
end
# Retrieves all stubs defined for a mocked object.
def [](object : Reference) : Array(Stub)
def [](object : Reference)
key = Box.box(object)
@object_stubs[key]
@entries[key]
end
# Retrieves all stubs defined for a mocked object.
@ -30,15 +31,17 @@ module Spectator
# This allows a mock to populate the registry with initial stubs.
def fetch(object : Reference, & : -> Array(Stub))
key = Box.box(object)
@object_stubs.fetch(key) do
@object_stubs[key] = yield
@entries.fetch(key) do
entry = MockRegistryEntry.new
entry.stubs = yield
@entries[key] = entry
end
end
# Clears all stubs defined for a mocked object.
def delete(object : Reference) : Nil
key = Box.box(object)
@object_stubs.delete(key)
@entries.delete(key)
end
end
end

View file

@ -1,4 +1,5 @@
require "string_pool"
require "./mock_registry_entry"
require "./stub"
module Spectator
@ -13,19 +14,19 @@ module Spectator
# Doing so prevents adding data to the mocked type.
class ValueMockRegistry(T)
@pool = StringPool.new # Used to de-dup values.
@object_stubs : Hash(String, Array(Stub))
@entries : Hash(String, MockRegistryEntry)
# Creates an empty registry.
def initialize
@object_stubs = Hash(String, Array(Stub)).new do |hash, key|
hash[key] = [] of Stub
@entries = Hash(String, MockRegistryEntry).new do |hash, key|
hash[key] = MockRegistryEntry.new
end
end
# Retrieves all stubs defined for a mocked object.
def [](object : T) : Array(Stub)
def [](object : T)
key = value_bytes(object)
@object_stubs[key]
@entries[key]
end
# Retrieves all stubs defined for a mocked object.
@ -34,15 +35,17 @@ module Spectator
# This allows a mock to populate the registry with initial stubs.
def fetch(object : T, & : -> Array(Stub))
key = value_bytes(object)
@object_stubs.fetch(key) do
@object_stubs[key] = yield
@entries.fetch(key) do
entry = MockRegistryEntry.new
entry.stubs = yield
@entries[key] = entry
end
end
# Clears all stubs defined for a mocked object.
def delete(object : T) : Nil
key = value_bytes(object)
@object_stubs.delete(key)
@entries.delete(key)
end
# Extracts heap-managed bytes for a value.