mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Initial code for StubbedType
This commit is contained in:
parent
20c9da75a8
commit
cecd2464de
3 changed files with 103 additions and 0 deletions
|
@ -270,6 +270,35 @@ Spectator.describe Spectator::Double do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "class method stubs" do
|
||||||
|
Spectator::Double.define(ClassDouble) do
|
||||||
|
stub def self.foo
|
||||||
|
:stub
|
||||||
|
end
|
||||||
|
|
||||||
|
stub def self.bar(arg)
|
||||||
|
arg
|
||||||
|
end
|
||||||
|
|
||||||
|
stub def self.baz
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
subject(dbl) { ClassDouble }
|
||||||
|
let(foo_stub) { Spectator::ValueStub.new(:foo, :override) }
|
||||||
|
|
||||||
|
after_each { dbl._spectator_clear_stubs }
|
||||||
|
|
||||||
|
it "overrides an existing method" do
|
||||||
|
expect { dbl._spectator_define_stub(foo_stub) }.to change { dbl.foo }.from(:stub).to(:override)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't affect other methods" do
|
||||||
|
expect { dbl._spectator_define_stub(foo_stub) }.to_not change { dbl.bar(42) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#_spectator_define_stub" do
|
describe "#_spectator_define_stub" do
|
||||||
subject(dbl) { FooBarDouble.new }
|
subject(dbl) { FooBarDouble.new }
|
||||||
let(stub3) { Spectator::ValueStub.new(:foo, 3) }
|
let(stub3) { Spectator::ValueStub.new(:foo, 3) }
|
||||||
|
|
|
@ -2,6 +2,7 @@ require "../dsl/reserved"
|
||||||
require "./arguments"
|
require "./arguments"
|
||||||
require "./method_call"
|
require "./method_call"
|
||||||
require "./stub"
|
require "./stub"
|
||||||
|
require "./stubbed_type"
|
||||||
require "./typed_stub"
|
require "./typed_stub"
|
||||||
|
|
||||||
module Spectator
|
module Spectator
|
||||||
|
@ -380,5 +381,12 @@ module Spectator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Automatically extend `StubbedType` when a type is made stubbable.
|
||||||
|
macro included
|
||||||
|
extend StubbedType
|
||||||
|
|
||||||
|
private class_getter _spectator_stubs : Array(::Spectator::Stub) = [] of ::Spectator::Stub
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
66
src/spectator/mocks/stubbed_type.cr
Normal file
66
src/spectator/mocks/stubbed_type.cr
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
require "./method_call"
|
||||||
|
require "./stub"
|
||||||
|
|
||||||
|
module Spectator
|
||||||
|
# Defines stubbing functionality at the type level (classes and structs).
|
||||||
|
#
|
||||||
|
# This module is intended to be extended from when a type includes `Stubbable`.
|
||||||
|
module StubbedType
|
||||||
|
private abstract def _spectator_stubs : Array(Stub)
|
||||||
|
|
||||||
|
def _spectator_find_stub(call : MethodCall) : Stub?
|
||||||
|
_spectator_stubs.find &.===(call)
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_stub_for_method?(method : Symbol) : Bool
|
||||||
|
_spectator_stubs.any? { |stub| stub.method == method }
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_define_stub(stub : Stub) : Nil
|
||||||
|
_spectator_stubs.unshift(stub)
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_clear_stubs : Nil
|
||||||
|
_spectator_stubs.clear
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_record_call(call : MethodCall) : Nil
|
||||||
|
_spectator_calls << call
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_calls
|
||||||
|
[] of MethodCall
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_stub_fallback(call : MethodCall, &)
|
||||||
|
Log.trace { "Fallback for #{call} - call original" }
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_stub_fallback(call : MethodCall, type, &)
|
||||||
|
_spectator_stub_fallback(call) { yield }
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_abstract_stub_fallback(call : MethodCall)
|
||||||
|
Log.info do
|
||||||
|
break unless _spectator_stub_for_method?(call.method)
|
||||||
|
|
||||||
|
"Stubs are defined for #{call.method.inspect}, but none matched (no argument constraints met)."
|
||||||
|
end
|
||||||
|
|
||||||
|
raise UnexpectedMessage.new("#{_spectator_stubbed_name} received unexpected message #{call}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_abstract_stub_fallback(call : MethodCall, type)
|
||||||
|
_spectator_abstract_stub_fallback(call)
|
||||||
|
end
|
||||||
|
|
||||||
|
def _spectator_stubbed_name : String
|
||||||
|
{% if anno = @type.annotation(StubbedName) %}
|
||||||
|
"#<Stubbed " + {{(anno[0] || :Anonymous.id).stringify}} + ">"
|
||||||
|
{% else %}
|
||||||
|
"#<Stubbed " + {{@type.name.stringify}} + ">"
|
||||||
|
{% end %}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue