From 5b143cb72cd09e6fe4399edc1ad1eda2dcf293ed Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Sun, 3 Nov 2019 10:02:53 -0700 Subject: [PATCH] Change structure around --- src/spectator/dsl/mocks.cr | 2 +- src/spectator/mocks/arguments.cr | 26 ++++++++++++++++++++++ src/spectator/mocks/double.cr | 10 +++++---- src/spectator/mocks/generic_method_call.cr | 22 +++--------------- src/spectator/mocks/generic_method_stub.cr | 21 +++-------------- src/spectator/mocks/proc_method_stub.cr | 14 ++++++++++++ src/spectator/mocks/value_method_stub.cr | 18 +++++++++++++++ 7 files changed, 71 insertions(+), 42 deletions(-) create mode 100644 src/spectator/mocks/arguments.cr create mode 100644 src/spectator/mocks/proc_method_stub.cr create mode 100644 src/spectator/mocks/value_method_stub.cr diff --git a/src/spectator/dsl/mocks.cr b/src/spectator/dsl/mocks.cr index be05616..4ccafe9 100644 --- a/src/spectator/dsl/mocks.cr +++ b/src/spectator/dsl/mocks.cr @@ -23,6 +23,6 @@ module Spectator::DSL macro receive(method_name, _source_file = __FILE__, _source_line = __LINE__) %source = ::Spectator::Source.new({{_source_file}}, {{_source_line}}) - ::Spectator::Mocks::GenericMethodStub(Nil).new({{method_name.symbolize}}, %source, ->{ nil }) + ::Spectator::Mocks::ValueMethodStub.new({{method_name.symbolize}}, %source, nil) end end diff --git a/src/spectator/mocks/arguments.cr b/src/spectator/mocks/arguments.cr new file mode 100644 index 0000000..7d70a69 --- /dev/null +++ b/src/spectator/mocks/arguments.cr @@ -0,0 +1,26 @@ +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 + end +end diff --git a/src/spectator/mocks/double.cr b/src/spectator/mocks/double.cr index 83c3679..5af252c 100644 --- a/src/spectator/mocks/double.cr +++ b/src/spectator/mocks/double.cr @@ -37,20 +37,22 @@ module Spectator::Mocks %} def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %} - %call = ::Spectator::Mocks::GenericMethodCall.create({{name.symbolize}}{% unless args.empty? %}, {{args.splat}}{% end %}) + %args = ::Spectator::Mocks::Arguments.create({{args.splat}}) + %call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args) @spectator_stub_calls << %call if (%stub = @spectator_stubs.find(&.callable?(%call))) - %stub.as(::Spectator::Mocks::GenericMethodStub(typeof(%method({{args.splat}})))).call(%call) + %stub.as(::Spectator::Mocks::GenericMethodStub(typeof(%method({{args.splat}})))).call(%args) else %method({{args.splat}}) end end def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %} - %call = ::Spectator::Mocks::GenericMethodCall.create({{name.symbolize}}{% unless args.empty? %}, {{args.splat}}{% end %}) + %args = ::Spectator::Mocks::Arguments.create({{args.splat}}) + %call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args) @spectator_stub_calls << %call if (%stub = @spectator_stubs.find(&.callable?(%call))) - %stub.as(::Spectator::Mocks::GenericMethodStub(typeof(%method({{args.splat}}) { |*%yield_args| yield *%yield_args }))).call(%call) + %stub.as(::Spectator::Mocks::GenericMethodStub(typeof(%method({{args.splat}}) { |*%yield_args| yield *%yield_args }))).call(%args) else %method({{args.splat}}) do |*%yield_args| yield *%yield_args diff --git a/src/spectator/mocks/generic_method_call.cr b/src/spectator/mocks/generic_method_call.cr index f413537..639e825 100644 --- a/src/spectator/mocks/generic_method_call.cr +++ b/src/spectator/mocks/generic_method_call.cr @@ -1,28 +1,12 @@ +require "./arguments" require "./method_call" module Spectator::Mocks class GenericMethodCall(T, NT) < MethodCall - getter args : T + getter args - getter options : NT - - def initialize(name : Symbol, @args : T, @options : NT) + def initialize(name : Symbol, @args : Arguments(T, NT)) super(name) end - - def self.create(name : Symbol, *args, **options) - GenericMethodCall.new(name, args, options) - end - - def to_s(io) - io << name - return if @args.empty? && @options.empty? - - io << '(' - io << @args - io << ", " if @args.any? - io << @options - io << ')' - end end end diff --git a/src/spectator/mocks/generic_method_stub.cr b/src/spectator/mocks/generic_method_stub.cr index c3349ae..e5f21ba 100644 --- a/src/spectator/mocks/generic_method_stub.cr +++ b/src/spectator/mocks/generic_method_stub.cr @@ -1,23 +1,8 @@ -require "../source" -require "./method_call" +require "./arguments" require "./method_stub" module Spectator::Mocks - class GenericMethodStub(ReturnType) < MethodStub - def initialize(name : Symbol, source : Source, @proc : -> ReturnType) - super(name, source) - end - - def callable?(call : MethodCall) : Bool - super - end - - def call(call : MethodCall) : ReturnType - @proc.call - end - - def and_return(value : T) forall T - GenericMethodStub(T).new(@name, @source, ->{ value }) - end + abstract class GenericMethodStub(ReturnType) < MethodStub + abstract def call(args : Arguments(T, NT)) : ReturnType forall T, NT end end diff --git a/src/spectator/mocks/proc_method_stub.cr b/src/spectator/mocks/proc_method_stub.cr new file mode 100644 index 0000000..e1b1956 --- /dev/null +++ b/src/spectator/mocks/proc_method_stub.cr @@ -0,0 +1,14 @@ +require "./arguments" +require "./generic_method_stub" + +module Spectator::Mocks + class ProcMethodStub(ReturnType) < GenericMethodStub(ReturnType) + def initialize(name, source, @proc : -> ReturnType) + super(name, source) + end + + def call(_args : Arguments(T, NT)) : ReturnType forall T, NT + @proc.call + end + end +end diff --git a/src/spectator/mocks/value_method_stub.cr b/src/spectator/mocks/value_method_stub.cr new file mode 100644 index 0000000..3b02d33 --- /dev/null +++ b/src/spectator/mocks/value_method_stub.cr @@ -0,0 +1,18 @@ +require "./arguments" +require "./generic_method_stub" + +module Spectator::Mocks + class ValueMethodStub(ReturnType) < GenericMethodStub(ReturnType) + def initialize(name, source, @value : ReturnType) + super(name, source) + end + + def call(_args : Arguments(T, NT)) : ReturnType forall T, NT + @value + end + + def and_return(value : T) forall T + ValueMethodStub.new(@name, @source, value) + end + end +end