Move mocks to their own module

This commit is contained in:
Michael Miller 2019-11-03 09:44:32 -07:00
parent 541dc661ca
commit c95e228bde
12 changed files with 56 additions and 52 deletions

View File

@ -703,33 +703,33 @@ module Spectator
# # Is equivalent to: # # Is equivalent to:
# expect("foobar".has_back_references?).to_not be_true # expect("foobar".has_back_references?).to_not be_true
# ``` # ```
macro method_missing(call) # macro method_missing(call)
{% if call.name.starts_with?("be_") %} # {% if call.name.starts_with?("be_") %}
# Remove `be_` prefix. # # Remove `be_` prefix.
{% method_name = call.name[3..-1] %} # {% method_name = call.name[3..-1] %}
{% matcher = "PredicateMatcher" %} # {% matcher = "PredicateMatcher" %}
{% elsif call.name.starts_with?("have_") %} # {% elsif call.name.starts_with?("have_") %}
# Remove `have_` prefix. # # Remove `have_` prefix.
{% method_name = call.name[5..-1] %} # {% method_name = call.name[5..-1] %}
{% matcher = "HavePredicateMatcher" %} # {% matcher = "HavePredicateMatcher" %}
{% else %} # {% else %}
{% raise "Undefined local variable or method '#{call}'" %} # {% raise "Undefined local variable or method '#{call}'" %}
{% end %} # {% end %}
#
descriptor = { {{method_name}}: Tuple.new({{call.args.splat}}) } # descriptor = { {{method_name}}: Tuple.new({{call.args.splat}}) }
label = String::Builder.new({{method_name.stringify}}) # label = String::Builder.new({{method_name.stringify}})
{% unless call.args.empty? %} # {% unless call.args.empty? %}
label << '(' # label << '('
{% for arg, index in call.args %} # {% for arg, index in call.args %}
label << {{arg}} # label << {{arg}}
{% if index < call.args.size - 1 %} # {% if index < call.args.size - 1 %}
label << ", " # label << ", "
{% end %} # {% end %}
{% end %} # {% end %}
label << ')' # label << ')'
{% end %} # {% end %}
test_value = ::Spectator::TestValue.new(descriptor, label.to_s) # test_value = ::Spectator::TestValue.new(descriptor, label.to_s)
::Spectator::Matchers::{{matcher.id}}.new(test_value) # ::Spectator::Matchers::{{matcher.id}}.new(test_value)
end # end
end end
end end

View File

@ -1,13 +1,11 @@
require "../double" require "../mocks"
require "../generic_method_stub"
require "../open_mock"
module Spectator::DSL module Spectator::DSL
macro double(name, &block) macro double(name, &block)
{% if block.is_a?(Nop) %} {% if block.is_a?(Nop) %}
Double{{name.id}}.new(self) Double{{name.id}}.new(self)
{% else %} {% else %}
class Double{{name.id}} < ::Spectator::Double class Double{{name.id}} < ::Spectator::Mocks::Double
def initialize(@spectator_test : {{@type.id}}) def initialize(@spectator_test : {{@type.id}})
super({{name.id.symbolize}}) super({{name.id.symbolize}})
end end
@ -19,12 +17,12 @@ module Spectator::DSL
{% end %} {% end %}
end end
def allow(double : ::Spectator::Double) def allow(double : ::Spectator::Mocks::Double)
OpenMock.new(double) Mocks::OpenMock.new(double)
end end
macro receive(method_name, _source_file = __FILE__, _source_line = __LINE__) macro receive(method_name, _source_file = __FILE__, _source_line = __LINE__)
%source = ::Spectator::Source.new({{_source_file}}, {{_source_line}}) %source = ::Spectator::Source.new({{_source_file}}, {{_source_line}})
::Spectator::GenericMethodStub(Nil).new({{method_name.symbolize}}, %source, ->{ nil }) ::Spectator::Mocks::GenericMethodStub(Nil).new({{method_name.symbolize}}, %source, ->{ nil })
end end
end end

View File

@ -29,8 +29,7 @@ require "./example_group"
require "./nested_example_group" require "./nested_example_group"
require "./root_example_group" require "./root_example_group"
require "./mock" require "./mocks"
require "./double"
require "./config" require "./config"
require "./config_builder" require "./config_builder"

View File

@ -1,4 +1,4 @@
require "../double" require "../mocks/double"
require "./standard_matcher" require "./standard_matcher"
module Spectator::Matchers module Spectator::Matchers
@ -11,7 +11,7 @@ module Spectator::Matchers
end end
def match?(actual : TestExpression(T)) : Bool forall T def match?(actual : TestExpression(T)) : Bool forall T
double = actual.value.as(Double) double = actual.value.as(Mocks::Double)
calls = double.spectator_stub_calls(@expected.value) calls = double.spectator_stub_calls(@expected.value)
!calls.empty? !calls.empty?
end end

7
src/spectator/mocks.cr Normal file
View File

@ -0,0 +1,7 @@
require "./mocks/*"
module Spectator
# Functionality for mocking existing types.
module Mocks
end
end

View File

@ -1,7 +1,7 @@
require "./generic_method_call" require "./generic_method_call"
require "./generic_method_stub" require "./generic_method_stub"
module Spectator module Spectator::Mocks
abstract class Double abstract class Double
@spectator_stubs = Deque(MethodStub).new @spectator_stubs = Deque(MethodStub).new
@spectator_stub_calls = Deque(MethodCall).new @spectator_stub_calls = Deque(MethodCall).new
@ -37,20 +37,20 @@ module Spectator
%} %}
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %} def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
%call = ::Spectator::GenericMethodCall.create({{name.symbolize}}{% unless args.empty? %}, {{args.splat}}{% end %}) %call = ::Spectator::Mocks::GenericMethodCall.create({{name.symbolize}}{% unless args.empty? %}, {{args.splat}}{% end %})
@spectator_stub_calls << %call @spectator_stub_calls << %call
if (%stub = @spectator_stubs.find(&.callable?(%call))) if (%stub = @spectator_stubs.find(&.callable?(%call)))
%stub.as(::Spectator::GenericMethodStub(typeof(%method({{args.splat}})))).call(%call) %stub.as(::Spectator::Mocks::GenericMethodStub(typeof(%method({{args.splat}})))).call(%call)
else else
%method({{args.splat}}) %method({{args.splat}})
end end
end end
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %} def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
%call = ::Spectator::GenericMethodCall.create({{name.symbolize}}{% unless args.empty? %}, {{args.splat}}{% end %}) %call = ::Spectator::Mocks::GenericMethodCall.create({{name.symbolize}}{% unless args.empty? %}, {{args.splat}}{% end %})
@spectator_stub_calls << %call @spectator_stub_calls << %call
if (%stub = @spectator_stubs.find(&.callable?(%call))) if (%stub = @spectator_stubs.find(&.callable?(%call)))
%stub.as(::Spectator::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(%call)
else else
%method({{args.splat}}) do |*%yield_args| %method({{args.splat}}) do |*%yield_args|
yield *%yield_args yield *%yield_args

View File

@ -1,6 +1,6 @@
require "./method_call" require "./method_call"
module Spectator module Spectator::Mocks
class GenericMethodCall(T, NT) < MethodCall class GenericMethodCall(T, NT) < MethodCall
getter args : T getter args : T

View File

@ -1,8 +1,8 @@
require "../source"
require "./method_call" require "./method_call"
require "./method_stub" require "./method_stub"
require "./source"
module Spectator module Spectator::Mocks
class GenericMethodStub(ReturnType) < MethodStub class GenericMethodStub(ReturnType) < MethodStub
def initialize(name : Symbol, source : Source, @proc : -> ReturnType) def initialize(name : Symbol, source : Source, @proc : -> ReturnType)
super(name, source) super(name, source)

View File

@ -1,4 +1,4 @@
module Spectator module Spectator::Mocks
abstract class MethodCall abstract class MethodCall
getter name : Symbol getter name : Symbol

View File

@ -1,6 +1,6 @@
require "./source" require "../source"
module Spectator module Spectator::Mocks
abstract class MethodStub abstract class MethodStub
def initialize(@name : Symbol, @source : Source) def initialize(@name : Symbol, @source : Source)
end end

View File

@ -1,4 +1,4 @@
module Spectator module Spectator::Mocks
module Mock module Mock
macro included macro included
{% for meth in @type.methods %} {% for meth in @type.methods %}

View File

@ -1,4 +1,4 @@
module Spectator module Spectator::Mocks
struct OpenMock struct OpenMock
def initialize(@mock : Double) def initialize(@mock : Double)
end end