Replace stub value method with call method

Pass method call information to stub.
This commit is contained in:
Michael Miller 2022-03-31 23:07:55 -06:00
parent f00ea23c47
commit 17592287ad
No known key found for this signature in database
GPG key ID: 32B47AE8F388A1FF
7 changed files with 21 additions and 17 deletions

View file

@ -1,6 +1,7 @@
require "../../spec_helper"
Spectator.describe Spectator::ValueStub do
let(method_call) { Spectator::MethodCall.capture(:foo) }
subject(stub) { Spectator::ValueStub.new(:foo, 42) }
it "stores the method name" do
@ -8,7 +9,7 @@ Spectator.describe Spectator::ValueStub do
end
it "stores the return value" do
expect(stub.value).to eq(42)
expect(stub.call(method_call)).to eq(42)
end
describe "#===" do

View file

@ -57,13 +57,13 @@ module Spectator
_spectator_cast_stub_value(%stub, %call, \{{Messages[{{call.name.symbolize}}.id]}}, \{{Messages[{{call.name.symbolize}}.id].resolve >= Nil}})
\{% else %}
# A method that was not defined during initialization was stubbed.
# Even though all stubs will have a #value method, the compiler doesn't seem to agree.
# Even though all stubs will have a #call method, the compiler doesn't seem to agree.
# Assert that it will (this should never fail).
raise TypeCastError.new("Stub has no value") unless %stub.responds_to?(:value)
raise TypeCastError.new("Stub has no value") unless %stub.responds_to?(:call)
# Return the value of the stub as-is.
# Might want to give a warning here, as this may produce a "bloated" union of all known stub types.
%stub.value
%stub.call(%call)
\{% end %}
else
# A stub wasn't found, invoke the fallback logic.

View file

@ -60,13 +60,13 @@ module Spectator
# Attempt to find a stub that satisfies the method call and arguments.
if %stub = _spectator_find_stub(%call)
# A method that was not defined during initialization was stubbed.
# Even though all stubs will have a #value method, the compiler doesn't seem to agree.
# Even though all stubs will have a #call method, the compiler doesn't seem to agree.
# Assert that it will (this should never fail).
raise TypeCastError.new("Stub has no value") unless %stub.responds_to?(:value)
raise TypeCastError.new("Stub has no value") unless %stub.responds_to?(:call)
# Return the value of the stub as-is.
# Might want to give a warning here, as this may produce a "bloated" union of all known stub types.
%stub.value
%stub.call(%call)
else
# A stub wasn't found, invoke the fallback logic.
# Message received for a methods that isn't stubbed nor defined when initialized.

View file

@ -4,8 +4,8 @@ require "./value_stub"
module Spectator
# Stub that does nothing and returns nil.
class NullStub < TypedStub(Nil)
def value : Nil
nil
# Invokes the stubbed implementation.
def call(_call : MethodCall) : Nil
end
def and_return(value)

View file

@ -273,17 +273,17 @@ module Spectator
# If successful, return the value of the stub.
# This is a common usage where the return type is simple and matches the stub type exactly.
if %typed = {{stub}}.as?(::Spectator::TypedStub({{type}}))
%typed.value
%typed.call({{call}})
else
# The stub couldn't be easily cast to match the return type.
# Even though all stubs will have a #value method, the compiler doesn't seem to agree.
# Even though all stubs will have a #call method, the compiler doesn't seem to agree.
# Assert that it will (this should never fail).
raise TypeCastError.new("Stub has no value") unless {{stub}}.responds_to?(:value)
raise TypeCastError.new("Stub has no value") unless {{stub}}.responds_to?(:call)
# Get the value as-is from the stub.
# This will be compiled as a union of all known stubbed value types.
%value = {{stub}}.value
%value = {{stub}}.call({{call}})
# Attempt to cast the value to the method's return type.
# If successful, which it will be in most cases, return it.

View file

@ -1,3 +1,4 @@
require "./method_call"
require "./stub"
module Spectator
@ -6,7 +7,7 @@ module Spectator
# *T* is the type produced by the stub.
# How the stub produces this value is up to subclasses.
abstract class TypedStub(T) < Stub
# Return value.
abstract def value : T
# Invokes the stubbed implementation.
abstract def call(call : MethodCall) : T
end
end

View file

@ -4,8 +4,10 @@ require "./typed_stub"
module Spectator
# Stub that responds with a static value.
class ValueStub(T) < TypedStub(T)
# Return value.
getter value : T
# Invokes the stubbed implementation.
def call(_call : MethodCall) : T
@value
end
# Creates the stub.
def initialize(method : Symbol, @value : T, constraint : AbstractArguments? = nil)