From af9104dfe4192f79dfdd491cd12e4caeb512f102 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Sun, 3 Nov 2019 11:18:46 -0700 Subject: [PATCH] Store arguments in method stub Needed for matching arguments (setting constraints). --- src/spectator/mocks/arguments.cr | 24 +------------------ src/spectator/mocks/double.cr | 4 ++-- src/spectator/mocks/generic_arguments.cr | 28 ++++++++++++++++++++++ src/spectator/mocks/generic_method_call.cr | 4 ++-- src/spectator/mocks/generic_method_stub.cr | 12 +++++++++- src/spectator/mocks/method_stub.cr | 3 ++- src/spectator/mocks/proc_method_stub.cr | 6 ++--- src/spectator/mocks/value_method_stub.cr | 6 ++--- 8 files changed, 52 insertions(+), 35 deletions(-) create mode 100644 src/spectator/mocks/generic_arguments.cr diff --git a/src/spectator/mocks/arguments.cr b/src/spectator/mocks/arguments.cr index 7d70a69..e909235 100644 --- a/src/spectator/mocks/arguments.cr +++ b/src/spectator/mocks/arguments.cr @@ -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 diff --git a/src/spectator/mocks/double.cr b/src/spectator/mocks/double.cr index 5af252c..806e3fc 100644 --- a/src/spectator/mocks/double.cr +++ b/src/spectator/mocks/double.cr @@ -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))) diff --git a/src/spectator/mocks/generic_arguments.cr b/src/spectator/mocks/generic_arguments.cr new file mode 100644 index 0000000..246c78d --- /dev/null +++ b/src/spectator/mocks/generic_arguments.cr @@ -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 diff --git a/src/spectator/mocks/generic_method_call.cr b/src/spectator/mocks/generic_method_call.cr index 639e825..628e40f 100644 --- a/src/spectator/mocks/generic_method_call.cr +++ b/src/spectator/mocks/generic_method_call.cr @@ -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 diff --git a/src/spectator/mocks/generic_method_stub.cr b/src/spectator/mocks/generic_method_stub.cr index e5f21ba..e29f4b5 100644 --- a/src/spectator/mocks/generic_method_stub.cr +++ b/src/spectator/mocks/generic_method_stub.cr @@ -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 diff --git a/src/spectator/mocks/method_stub.cr b/src/spectator/mocks/method_stub.cr index 3bc3790..acdc3d5 100644 --- a/src/spectator/mocks/method_stub.cr +++ b/src/spectator/mocks/method_stub.cr @@ -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 diff --git a/src/spectator/mocks/proc_method_stub.cr b/src/spectator/mocks/proc_method_stub.cr index e1b1956..f3141ed 100644 --- a/src/spectator/mocks/proc_method_stub.cr +++ b/src/spectator/mocks/proc_method_stub.cr @@ -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 diff --git a/src/spectator/mocks/value_method_stub.cr b/src/spectator/mocks/value_method_stub.cr index 3b02d33..0fa5b77 100644 --- a/src/spectator/mocks/value_method_stub.cr +++ b/src/spectator/mocks/value_method_stub.cr @@ -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