mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Started playing around with method stubs
This commit is contained in:
parent
4b57ddab80
commit
0b6465e6bc
5 changed files with 80 additions and 3 deletions
|
@ -1,26 +1,50 @@
|
||||||
|
require "./method_stub"
|
||||||
|
|
||||||
module Spectator
|
module Spectator
|
||||||
abstract class Double
|
abstract class Double
|
||||||
|
@stubs = Deque(MethodStub).new
|
||||||
|
|
||||||
|
private macro delegate_internal(method, *args)
|
||||||
|
# Modified version of Object#delegate
|
||||||
|
{% if method.id.ends_with?('=') && method.id != "[]=" %}
|
||||||
|
@internal.{{method.id}} {{args.splat}}
|
||||||
|
{% else %}
|
||||||
|
@internal.{{method.id}}({{args.splat}})
|
||||||
|
{% end %}
|
||||||
|
end
|
||||||
|
|
||||||
macro stub(definition, &block)
|
macro stub(definition, &block)
|
||||||
{%
|
{%
|
||||||
name = nil
|
name = nil
|
||||||
|
params = nil
|
||||||
args = nil
|
args = nil
|
||||||
body = nil
|
body = nil
|
||||||
if definition.is_a?(Call) # stub foo { :bar }
|
if definition.is_a?(Call) # stub foo { :bar }
|
||||||
name = definition.name.id
|
name = definition.name.id
|
||||||
args = definition.args
|
params = definition.args
|
||||||
|
args = params.map { |p| p.is_a?(TypeDeclaration) ? p.var : p.id }
|
||||||
body = definition.block.is_a?(Nop) ? block : definition.block
|
body = definition.block.is_a?(Nop) ? block : definition.block
|
||||||
elsif definition.is_a?(TypeDeclaration) # stub foo : Symbol
|
elsif definition.is_a?(TypeDeclaration) # stub foo : Symbol
|
||||||
name = definition.var
|
name = definition.var
|
||||||
|
params = [] of MacroId
|
||||||
args = [] of MacroId
|
args = [] of MacroId
|
||||||
body = block
|
body = block
|
||||||
else
|
else
|
||||||
raise "Unrecognized stub format"
|
raise "Unrecognized stub format"
|
||||||
end
|
end
|
||||||
%}
|
%}
|
||||||
delegate {{name}}, to: @internal
|
|
||||||
|
def {{name}}({{params.splat}})
|
||||||
|
%stub = @stubs.find(&.callable?({{name.symbolize}}{% unless args.empty? %}, {{args.splat}}{% end %}))
|
||||||
|
if %stub
|
||||||
|
%stub.call({{args.splat}})
|
||||||
|
else
|
||||||
|
delegate_internal({{name}}{% unless args.empty? %}, {{args.splat}}{% end %})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private class Internal
|
private class Internal
|
||||||
def {{name}}({{args.splat}})
|
def {{name}}({{params.splat}})
|
||||||
{% if body && !body.is_a?(Nop) %}
|
{% if body && !body.is_a?(Nop) %}
|
||||||
{{body.body}}
|
{{body.body}}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -29,5 +53,9 @@ module Spectator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected def spectator_define_stub(stub : MethodStub) : Nil
|
||||||
|
@stubs << stub
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
require "../double"
|
require "../double"
|
||||||
|
require "../generic_method_stub"
|
||||||
|
require "../open_mock"
|
||||||
|
|
||||||
module Spectator::DSL
|
module Spectator::DSL
|
||||||
macro double(name, &block)
|
macro double(name, &block)
|
||||||
|
@ -21,4 +23,13 @@ module Spectator::DSL
|
||||||
end
|
end
|
||||||
{% end %}
|
{% end %}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def allow(double : ::Spectator::Double)
|
||||||
|
OpenMock.new(double)
|
||||||
|
end
|
||||||
|
|
||||||
|
macro receive(method_name, _source_file = __FILE__, _source_line = __LINE__)
|
||||||
|
%source = ::Spectator::Source.new({{_source_file}}, {{_source_line}})
|
||||||
|
::Spectator::GenericMethodStub(Nil).new({{method_name.symbolize}}, %source)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
13
src/spectator/generic_method_stub.cr
Normal file
13
src/spectator/generic_method_stub.cr
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
require "./method_stub"
|
||||||
|
require "./source"
|
||||||
|
|
||||||
|
module Spectator
|
||||||
|
class GenericMethodStub(ReturnType, *ArgumentTypes) < MethodStub
|
||||||
|
def callable?(name : Symbol, *args) : Bool
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(*args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
src/spectator/method_stub.cr
Normal file
15
src/spectator/method_stub.cr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require "./source"
|
||||||
|
|
||||||
|
module Spectator
|
||||||
|
abstract class MethodStub
|
||||||
|
def initialize(@name : Symbol, @source : Source)
|
||||||
|
end
|
||||||
|
|
||||||
|
def callable?(name : Symbol, *args) : Bool
|
||||||
|
name == @name
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(*args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
10
src/spectator/open_mock.cr
Normal file
10
src/spectator/open_mock.cr
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
module Spectator
|
||||||
|
struct OpenMock
|
||||||
|
def initialize(@mock : Double)
|
||||||
|
end
|
||||||
|
|
||||||
|
def to(stub : MethodStub) : Nil
|
||||||
|
@mock.spectator_define_stub(stub)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue