Store arguments in method stub

Needed for matching arguments (setting constraints).
This commit is contained in:
Michael Miller 2019-11-03 11:18:46 -07:00
parent 20b80cc85a
commit af9104dfe4
8 changed files with 52 additions and 35 deletions

View file

@ -1,26 +1,4 @@
module Spectator::Mocks
class Arguments(T, NT)
protected getter args
protected getter opts
def initialize(@args : T, @opts : NT)
end
def self.create(*args, **opts)
Arguments.new(args, opts)
end
def pass_to(dispatcher)
dispatcher.call(*@args, **@opts)
end
def ===(other : Arguments(U, NU)) : Bool forall U, NU
return false unless @args === other.args
return false unless @opts.size === other.opts.size
@opts.keys.all? do |key|
other.opts.has_key?(key) && @opts[key] === other.opts[key]
end
end
abstract class Arguments
end
end

View file

@ -37,7 +37,7 @@ module Spectator::Mocks
%}
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
%args = ::Spectator::Mocks::Arguments.create({{args.splat}})
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
@spectator_stub_calls << %call
if (%stub = @spectator_stubs.find(&.callable?(%call)))
@ -48,7 +48,7 @@ module Spectator::Mocks
end
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
%args = ::Spectator::Mocks::Arguments.create({{args.splat}})
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
@spectator_stub_calls << %call
if (%stub = @spectator_stubs.find(&.callable?(%call)))

View file

@ -0,0 +1,28 @@
require "./arguments"
module Spectator::Mocks
class GenericArguments(T, NT) < Arguments
protected getter args
protected getter opts
def initialize(@args : T, @opts : NT)
end
def self.create(*args, **opts)
GenericArguments.new(args, opts)
end
def pass_to(dispatcher)
dispatcher.call(*@args, **@opts)
end
def ===(other : Arguments(U, NU)) : Bool forall U, NU
return false unless @args === other.args
return false unless @opts.size === other.opts.size
@opts.keys.all? do |key|
other.opts.has_key?(key) && @opts[key] === other.opts[key]
end
end
end
end

View file

@ -1,11 +1,11 @@
require "./arguments"
require "./generic_arguments"
require "./method_call"
module Spectator::Mocks
class GenericMethodCall(T, NT) < MethodCall
getter args
def initialize(name : Symbol, @args : Arguments(T, NT))
def initialize(name : Symbol, @args : GenericArguments(T, NT))
super(name)
end
end

View file

@ -1,8 +1,18 @@
require "./arguments"
require "./generic_arguments"
require "./method_call"
require "./method_stub"
module Spectator::Mocks
abstract class GenericMethodStub(ReturnType) < MethodStub
abstract def call(args : Arguments(T, NT)) : ReturnType forall T, NT
def initialize(name, source, @args : Arguments? = nil)
super(name, source)
end
def callable?(call : GenericMethodCall(T, NT)) : Bool forall T, NT
super && (!@args || @args === call.args)
end
abstract def call(args : GenericArguments(T, NT)) : ReturnType forall T, NT
end
end

View file

@ -1,11 +1,12 @@
require "../source"
require "./generic_method_call"
module Spectator::Mocks
abstract class MethodStub
def initialize(@name : Symbol, @source : Source)
end
def callable?(call : MethodCall) : Bool
def callable?(call : GenericMethodCall(T, NT)) : Bool forall T, NT
@name == call.name
end
end

View file

@ -3,11 +3,11 @@ require "./generic_method_stub"
module Spectator::Mocks
class ProcMethodStub(ReturnType) < GenericMethodStub(ReturnType)
def initialize(name, source, @proc : -> ReturnType)
super(name, source)
def initialize(name, source, @proc : -> ReturnType, args = nil)
super(name, source, args)
end
def call(_args : Arguments(T, NT)) : ReturnType forall T, NT
def call(_args : GenericArguments(T, NT)) : ReturnType forall T, NT
@proc.call
end
end

View file

@ -3,11 +3,11 @@ require "./generic_method_stub"
module Spectator::Mocks
class ValueMethodStub(ReturnType) < GenericMethodStub(ReturnType)
def initialize(name, source, @value : ReturnType)
super(name, source)
def initialize(name, source, @value : ReturnType, args = nil)
super(name, source, args)
end
def call(_args : Arguments(T, NT)) : ReturnType forall T, NT
def call(_args : GenericArguments(T, NT)) : ReturnType forall T, NT
@value
end