mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Merge branch 'mocks-and-doubles'
This commit is contained in:
commit
a9ac48e12c
15 changed files with 38 additions and 47 deletions
|
@ -1,5 +1,5 @@
|
||||||
name: spectator
|
name: spectator
|
||||||
version: 0.9.0
|
version: 0.9.1
|
||||||
description: |
|
description: |
|
||||||
A feature-rich spec testing framework for Crystal with similarities to RSpec.
|
A feature-rich spec testing framework for Crystal with similarities to RSpec.
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Spectator
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
# Current version of the Spectator library.
|
# Current version of the Spectator library.
|
||||||
VERSION = "0.9.0"
|
VERSION = "0.9.1"
|
||||||
|
|
||||||
# Top-level describe method.
|
# Top-level describe method.
|
||||||
# All specs in a file must be wrapped in this call.
|
# All specs in a file must be wrapped in this call.
|
||||||
|
|
|
@ -9,7 +9,7 @@ module Spectator::Mocks
|
||||||
|
|
||||||
macro method_missing(call)
|
macro method_missing(call)
|
||||||
args = ::Spectator::Mocks::GenericArguments.create({{call.args.splat}})
|
args = ::Spectator::Mocks::GenericArguments.create({{call.args.splat}})
|
||||||
call = ::Spectator::Mocks::GenericMethodCall.new({{call.name.symbolize}}, args)
|
call = ::Spectator::Mocks::MethodCall.new({{call.name.symbolize}}, args)
|
||||||
::Spectator::Harness.current.mocks.record_call(self, call)
|
::Spectator::Harness.current.mocks.record_call(self, call)
|
||||||
if (stub = ::Spectator::Harness.current.mocks.find_stub(self, call))
|
if (stub = ::Spectator::Harness.current.mocks.find_stub(self, call))
|
||||||
stub.call!(args) do
|
stub.call!(args) do
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Spectator::Mocks
|
||||||
|
|
||||||
macro method_missing(call)
|
macro method_missing(call)
|
||||||
args = ::Spectator::Mocks::GenericArguments.create({{call.args.splat}})
|
args = ::Spectator::Mocks::GenericArguments.create({{call.args.splat}})
|
||||||
call = ::Spectator::Mocks::GenericMethodCall.new({{call.name.symbolize}}, args)
|
call = ::Spectator::Mocks::MethodCall.new({{call.name.symbolize}}, args)
|
||||||
::Spectator::Harness.current.mocks.record_call(self, call)
|
::Spectator::Harness.current.mocks.record_call(self, call)
|
||||||
if (stub = ::Spectator::Harness.current.mocks.find_stub(self, call))
|
if (stub = ::Spectator::Harness.current.mocks.find_stub(self, call))
|
||||||
stub.call!(args) { @values.fetch({{call.name.symbolize}}) { self } }
|
stub.call!(args) { @values.fetch({{call.name.symbolize}}) { self } }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require "./generic_method_call"
|
|
||||||
require "./generic_method_stub"
|
require "./generic_method_stub"
|
||||||
|
require "./method_call"
|
||||||
require "./unexpected_message_error"
|
require "./unexpected_message_error"
|
||||||
|
|
||||||
module Spectator::Mocks
|
module Spectator::Mocks
|
||||||
|
@ -36,7 +36,7 @@ module Spectator::Mocks
|
||||||
|
|
||||||
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
||||||
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
||||||
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
|
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
|
||||||
::Spectator::Harness.current.mocks.record_call(self, %call)
|
::Spectator::Harness.current.mocks.record_call(self, %call)
|
||||||
if (%stub = ::Spectator::Harness.current.mocks.find_stub(self, %call))
|
if (%stub = ::Spectator::Harness.current.mocks.find_stub(self, %call))
|
||||||
%stub.call!(%args) { %method({{args.splat}}) }
|
%stub.call!(%args) { %method({{args.splat}}) }
|
||||||
|
@ -47,7 +47,7 @@ module Spectator::Mocks
|
||||||
|
|
||||||
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
||||||
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
||||||
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
|
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
|
||||||
::Spectator::Harness.current.mocks.record_call(self, %call)
|
::Spectator::Harness.current.mocks.record_call(self, %call)
|
||||||
if (%stub = ::Spectator::Harness.current.mocks.find_stub(self, %call))
|
if (%stub = ::Spectator::Harness.current.mocks.find_stub(self, %call))
|
||||||
%stub.call!(%args) { %method({{args.splat}}) { |*%ya| yield *%ya } }
|
%stub.call!(%args) { %method({{args.splat}}) { |*%ya| yield *%ya } }
|
||||||
|
@ -62,8 +62,8 @@ module Spectator::Mocks
|
||||||
{% if body && !body.is_a?(Nop) %}
|
{% if body && !body.is_a?(Nop) %}
|
||||||
{{body.body}}
|
{{body.body}}
|
||||||
{% else %}
|
{% else %}
|
||||||
%args = ::Spectator::Mocks::GenericArguments.create({{params.splat}})
|
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
||||||
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
|
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
|
||||||
unless ::Spectator::Harness.current.mocks.expected?(self, %call)
|
unless ::Spectator::Harness.current.mocks.expected?(self, %call)
|
||||||
raise ::Spectator::Mocks::UnexpectedMessageError.new("#{self} received unexpected message {{name}}")
|
raise ::Spectator::Mocks::UnexpectedMessageError.new("#{self} received unexpected message {{name}}")
|
||||||
end
|
end
|
||||||
|
@ -80,7 +80,7 @@ module Spectator::Mocks
|
||||||
|
|
||||||
macro method_missing(call)
|
macro method_missing(call)
|
||||||
args = ::Spectator::Mocks::GenericArguments.create({{call.args.splat}})
|
args = ::Spectator::Mocks::GenericArguments.create({{call.args.splat}})
|
||||||
call = ::Spectator::Mocks::GenericMethodCall.new({{call.name.symbolize}}, args)
|
call = ::Spectator::Mocks::MethodCall.new({{call.name.symbolize}}, args)
|
||||||
::Spectator::Harness.current.mocks.record_call(self, call)
|
::Spectator::Harness.current.mocks.record_call(self, call)
|
||||||
|
|
||||||
return self if @null
|
return self if @null
|
||||||
|
|
|
@ -7,7 +7,7 @@ module Spectator::Mocks
|
||||||
|
|
||||||
def to(stub : MethodStub) : Nil
|
def to(stub : MethodStub) : Nil
|
||||||
actual = TestValue.new(T)
|
actual = TestValue.new(T)
|
||||||
Harness.current.mocks.expect(T, stub.name)
|
Harness.current.mocks.expect(T, stub)
|
||||||
value = TestValue.new(stub.name, stub.to_s)
|
value = TestValue.new(stub.name, stub.to_s)
|
||||||
matcher = Matchers::ReceiveTypeMatcher.new(value, stub.arguments?)
|
matcher = Matchers::ReceiveTypeMatcher.new(value, stub.arguments?)
|
||||||
partial = Expectations::ExpectationPartial.new(actual, @source)
|
partial = Expectations::ExpectationPartial.new(actual, @source)
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
require "./generic_arguments"
|
|
||||||
require "./method_call"
|
|
||||||
|
|
||||||
module Spectator::Mocks
|
|
||||||
class GenericMethodCall(T, NT) < MethodCall
|
|
||||||
getter args
|
|
||||||
|
|
||||||
def initialize(name : Symbol, @args : GenericArguments(T, NT))
|
|
||||||
super(name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s(io)
|
|
||||||
super
|
|
||||||
io << '('
|
|
||||||
io << @args
|
|
||||||
io << ')'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -11,7 +11,7 @@ module Spectator::Mocks
|
||||||
super(name, source)
|
super(name, source)
|
||||||
end
|
end
|
||||||
|
|
||||||
def callable?(call : GenericMethodCall(T, NT)) : Bool forall T, NT
|
def callable?(call : MethodCall) : Bool
|
||||||
super && (!@args || @args === call.args)
|
super && (!@args || @args === call.args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
module Spectator::Mocks
|
module Spectator::Mocks
|
||||||
abstract class MethodCall
|
class MethodCall
|
||||||
getter name : Symbol
|
getter name : Symbol
|
||||||
|
getter args : Arguments
|
||||||
|
|
||||||
def initialize(@name : Symbol)
|
def initialize(@name : Symbol, @args : Arguments)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s(io)
|
def to_s(io)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
require "../source"
|
require "../source"
|
||||||
require "./generic_method_call"
|
require "./method_call"
|
||||||
|
|
||||||
module Spectator::Mocks
|
module Spectator::Mocks
|
||||||
abstract class MethodStub
|
abstract class MethodStub
|
||||||
|
@ -10,7 +10,7 @@ module Spectator::Mocks
|
||||||
def initialize(@name, @source)
|
def initialize(@name, @source)
|
||||||
end
|
end
|
||||||
|
|
||||||
def callable?(call : GenericMethodCall(T, NT)) : Bool forall T, NT
|
def callable?(call : MethodCall) : Bool
|
||||||
@name == call.name
|
@name == call.name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,19 @@ module Spectator::Mocks
|
||||||
%source = ::Spectator::Source.new({{meth.filename}}, {{meth.line_number}})
|
%source = ::Spectator::Source.new({{meth.filename}}, {{meth.line_number}})
|
||||||
%args = ::Spectator::Mocks::GenericArguments.create(
|
%args = ::Spectator::Mocks::GenericArguments.create(
|
||||||
{% for arg, i in meth.args %}
|
{% for arg, i in meth.args %}
|
||||||
|
{% matcher = if arg.restriction
|
||||||
|
if arg.restriction == :self.id
|
||||||
|
@type.id
|
||||||
|
else
|
||||||
|
arg.restriction
|
||||||
|
end
|
||||||
|
else
|
||||||
|
"::Spectator::Anything.new".id
|
||||||
|
end %}
|
||||||
{% if meth.splat_index && i == meth.splat_index %}
|
{% if meth.splat_index && i == meth.splat_index %}
|
||||||
*{{arg.restriction || "::Spectator::Anything.new".id}}{% if i < meth.args.size %},{% end %}
|
*{{matcher}}{% if i < meth.args.size %},{% end %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{arg.restriction || "::Spectator::Anything.new".id}}{% if i < meth.args.size %},{% end %}
|
{{matcher}}{% if i < meth.args.size %},{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
)
|
)
|
||||||
|
|
|
@ -47,7 +47,7 @@ module Spectator::Mocks
|
||||||
fetch_type(object.class).stubs.any? { |stub| stub.name == method_name }
|
fetch_type(object.class).stubs.any? { |stub| stub.name == method_name }
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_stub(object, call : GenericMethodCall(T, NT)) forall T, NT
|
def find_stub(object, call : MethodCall)
|
||||||
fetch_instance(object).stubs.find(&.callable?(call)) ||
|
fetch_instance(object).stubs.find(&.callable?(call)) ||
|
||||||
fetch_type(object.class).stubs.find(&.callable?(call))
|
fetch_type(object.class).stubs.find(&.callable?(call))
|
||||||
end
|
end
|
||||||
|
@ -65,7 +65,7 @@ module Spectator::Mocks
|
||||||
fetch_type(type).calls.select { |call| call.name == method_name }
|
fetch_type(type).calls.select { |call| call.name == method_name }
|
||||||
end
|
end
|
||||||
|
|
||||||
def expected?(object, call : GenericMethodCall(T, NT)) : Bool forall T, NT
|
def expected?(object, call : MethodCall) : Bool
|
||||||
fetch_instance(object).expected.any?(&.callable?(call)) ||
|
fetch_instance(object).expected.any?(&.callable?(call)) ||
|
||||||
fetch_type(object.class).expected.any?(&.callable?(call))
|
fetch_type(object.class).expected.any?(&.callable?(call))
|
||||||
end
|
end
|
||||||
|
|
|
@ -53,7 +53,7 @@ module Spectator::Mocks
|
||||||
def {{receiver}}{{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
def {{receiver}}{{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
||||||
if (%harness = ::Spectator::Harness.current?)
|
if (%harness = ::Spectator::Harness.current?)
|
||||||
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
||||||
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
|
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
|
||||||
%harness.mocks.record_call(self, %call)
|
%harness.mocks.record_call(self, %call)
|
||||||
if (%stub = %harness.mocks.find_stub(self, %call))
|
if (%stub = %harness.mocks.find_stub(self, %call))
|
||||||
return %stub.call!(%args) { {{original}}({{args.splat}}) }
|
return %stub.call!(%args) { {{original}}({{args.splat}}) }
|
||||||
|
@ -65,7 +65,7 @@ module Spectator::Mocks
|
||||||
def {{receiver}}{{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
def {{receiver}}{{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
||||||
if (%harness = ::Spectator::Harness.current?)
|
if (%harness = ::Spectator::Harness.current?)
|
||||||
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
||||||
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
|
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
|
||||||
%harness.mocks.record_call(self, %call)
|
%harness.mocks.record_call(self, %call)
|
||||||
if (%stub = %harness.mocks.find_stub(self, %call))
|
if (%stub = %harness.mocks.find_stub(self, %call))
|
||||||
return %stub.call!(%args) { {{original}}({{args.splat}}) { |*%ya| yield *%ya } }
|
return %stub.call!(%args) { {{original}}({{args.splat}}) { |*%ya| yield *%ya } }
|
||||||
|
|
|
@ -16,7 +16,7 @@ module Spectator::Mocks
|
||||||
list << NilMethodStub.new(method_name, source, args)
|
list << NilMethodStub.new(method_name, source, args)
|
||||||
end
|
end
|
||||||
|
|
||||||
def exists?(type_name : String, call : GenericMethodCall(T, NT)) : Bool forall T, NT
|
def exists?(type_name : String, call : MethodCall) : Bool
|
||||||
key = {type_name, call.name}
|
key = {type_name, call.name}
|
||||||
list = @@entries.fetch(key) { return false }
|
list = @@entries.fetch(key) { return false }
|
||||||
list.any?(&.callable?(call))
|
list.any?(&.callable?(call))
|
||||||
|
|
|
@ -32,7 +32,7 @@ module Spectator::Mocks
|
||||||
|
|
||||||
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
||||||
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
||||||
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
|
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
|
||||||
::Spectator::Harness.current.mocks.record_call(self, %call)
|
::Spectator::Harness.current.mocks.record_call(self, %call)
|
||||||
|
|
||||||
unless ::Spectator::Mocks::TypeRegistry.exists?(T.to_s, %call)
|
unless ::Spectator::Mocks::TypeRegistry.exists?(T.to_s, %call)
|
||||||
|
@ -48,7 +48,7 @@ module Spectator::Mocks
|
||||||
|
|
||||||
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
def {{name}}({{params.splat}}){% if definition.is_a?(TypeDeclaration) %} : {{definition.type}}{% end %}
|
||||||
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
||||||
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
|
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
|
||||||
::Spectator::Harness.current.mocks.record_call(self, %call)
|
::Spectator::Harness.current.mocks.record_call(self, %call)
|
||||||
|
|
||||||
unless ::Spectator::Mocks::TypeRegistry.exists?(T.to_s, %call)
|
unless ::Spectator::Mocks::TypeRegistry.exists?(T.to_s, %call)
|
||||||
|
@ -68,8 +68,8 @@ module Spectator::Mocks
|
||||||
{% if body && !body.is_a?(Nop) %}
|
{% if body && !body.is_a?(Nop) %}
|
||||||
{{body.body}}
|
{{body.body}}
|
||||||
{% else %}
|
{% else %}
|
||||||
%args = ::Spectator::Mocks::GenericArguments.create({{params.splat}})
|
%args = ::Spectator::Mocks::GenericArguments.create({{args.splat}})
|
||||||
%call = ::Spectator::Mocks::GenericMethodCall.new({{name.symbolize}}, %args)
|
%call = ::Spectator::Mocks::MethodCall.new({{name.symbolize}}, %args)
|
||||||
unless ::Spectator::Harness.current.mocks.expected?(self, %call)
|
unless ::Spectator::Harness.current.mocks.expected?(self, %call)
|
||||||
raise ::Spectator::Mocks::UnexpectedMessageError.new("#{self} received unexpected message {{name}}")
|
raise ::Spectator::Mocks::UnexpectedMessageError.new("#{self} received unexpected message {{name}}")
|
||||||
end
|
end
|
||||||
|
@ -86,7 +86,7 @@ module Spectator::Mocks
|
||||||
|
|
||||||
macro method_missing(call)
|
macro method_missing(call)
|
||||||
args = ::Spectator::Mocks::GenericArguments.create({{call.args.splat}})
|
args = ::Spectator::Mocks::GenericArguments.create({{call.args.splat}})
|
||||||
call = ::Spectator::Mocks::GenericMethodCall.new({{call.name.symbolize}}, args)
|
call = ::Spectator::Mocks::MethodCall.new({{call.name.symbolize}}, args)
|
||||||
::Spectator::Harness.current.mocks.record_call(self, call)
|
::Spectator::Harness.current.mocks.record_call(self, call)
|
||||||
|
|
||||||
unless ::Spectator::Mocks::TypeRegistry.exists?(T.to_s, call)
|
unless ::Spectator::Mocks::TypeRegistry.exists?(T.to_s, call)
|
||||||
|
|
Loading…
Reference in a new issue