Change structure around

This commit is contained in:
Michael Miller 2019-11-03 10:02:53 -07:00
parent c95e228bde
commit 5b143cb72c
7 changed files with 71 additions and 42 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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