mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Move method redefinition for stub to Stubable
Require stub or raise UnexpectedMessage for all double methods. Expose abstract_stub macro to require a stub.
This commit is contained in:
parent
9b94245bd8
commit
12eeb02a8d
2 changed files with 34 additions and 28 deletions
|
@ -25,7 +25,6 @@ module Spectator
|
|||
{% end %}
|
||||
{% if block %}{{block.body}}{% end %}
|
||||
end
|
||||
{% debug %}
|
||||
end
|
||||
|
||||
# Stores responses to messages (method calls).
|
||||
|
@ -47,37 +46,14 @@ module Spectator
|
|||
# Redefines all methods on a type to conditionally respond to messages.
|
||||
# Methods will raise `UnexpectedMessage` if they're called when they shouldn't be.
|
||||
# Otherwise, they'll return the configured response.
|
||||
# TODO: Better error for type mismatch
|
||||
private macro _spectator_mask_methods(type_name)
|
||||
{% type = type_name.resolve %}
|
||||
{% if type.superclass %}
|
||||
_spectator_mask_methods({{type.superclass}})
|
||||
{% end %}
|
||||
|
||||
{% for meth in type.methods %}
|
||||
{% if !meth.abstract? && !DSL::RESERVED_KEYWORDS.includes?(meth.name.symbolize) %}
|
||||
{% if meth.visibility != :public %}{{meth.visibility.id}}{% end %} def {{meth.receiver}}{{meth.name}}(
|
||||
{{meth.args.splat(",")}}
|
||||
{% if meth.double_splat %}**{{meth.double_splat}}, {% end %}
|
||||
{% if meth.block_arg %}&{{meth.block_arg}}{% elsif meth.accepts_block? %}&{% end %}
|
||||
){% if meth.return_type %} : {{meth.return_type}}{% end %}{% if !meth.free_vars.empty? %} forall {{meth.free_vars.splat}}{% end %}
|
||||
# Capture call information.
|
||||
%args = Arguments.capture(
|
||||
{{meth.args.map(&.internal_name).splat}}{% if !meth.args.empty? %}, {% end %}
|
||||
{% if meth.double_splat %}**{{meth.double_splat}}, {% end %}
|
||||
)
|
||||
%call = MethodCall.new({{meth.name.symbolize}}, %args)
|
||||
|
||||
# Find a suitable stub.
|
||||
if %stub = @stubs.find &.===(%call)
|
||||
# Return configured response.
|
||||
%stub.value
|
||||
else
|
||||
# Response not configured for this method/message.
|
||||
raise UnexpectedMessage.new("#{_spectator_double_name} received unexpected message :{{meth.name}} (masking ancestor) with #{%args}")
|
||||
end
|
||||
end
|
||||
{% end %}
|
||||
{% for meth in type.methods.reject { |m| DSL::RESERVED_KEYWORDS.includes?(m.name.symbolize) } %}
|
||||
abstract_stub {{meth}}
|
||||
{% end %}
|
||||
end
|
||||
|
||||
|
@ -92,7 +68,6 @@ module Spectator
|
|||
arguments = ::Spectator::Arguments.capture({{call.args.splat(", ")}}{% if call.named_args %}{{call.named_args.splat}}{% end %})
|
||||
call = ::Spectator::MethodCall.new({{call.name.symbolize}}, arguments)
|
||||
raise ::Spectator::UnexpectedMessage.new("#{_spectator_double_name} received unexpected message :{{call.name}} with #{arguments}")
|
||||
{% debug %}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,7 +40,38 @@ module Spectator
|
|||
{% end %}
|
||||
end
|
||||
end
|
||||
{% debug %}
|
||||
end
|
||||
|
||||
private macro abstract_stub(method)
|
||||
{% raise "abstract_stub requires a method definition" if !method.is_a?(Def) %}
|
||||
{% raise "Cannot stub method with reserved keyword as name - #{method.name}" if ::Spectator::DSL::RESERVED_KEYWORDS.includes?(method.name.symbolize) %}
|
||||
|
||||
{% if method.visibility != :public %}{{method.visibility.id}}{% end %} def {{method.receiver}}{{method.name}}(
|
||||
{{method.args.splat(",")}}
|
||||
{% if method.double_splat %}**{{method.double_splat}}, {% end %}
|
||||
{% if method.block_arg %}&{{method.block_arg}}{% elsif method.accepts_block? %}&{% end %}
|
||||
){% if method.return_type %} : {{method.return_type}}{% end %}{% if !method.free_vars.empty? %} forall {{method.free_vars.splat}}{% end %}
|
||||
%args = ::Spectator::Arguments.capture(
|
||||
{{method.args.map(&.internal_name).splat(",")}}
|
||||
{% if method.double_splat %}**{{method.double_splat}}{% end %}
|
||||
)
|
||||
%call = ::Spectator::MethodCall.new({{method.name.symbolize}}, %args)
|
||||
|
||||
if %stub = _spectator_find_stub(%call)
|
||||
{% if method.return_type %}
|
||||
if %cast = %stub.as?(::Spectator::ValueStub({{method.return_type}}))
|
||||
%cast.value
|
||||
else
|
||||
%stub.value.as({{method.return_type}})
|
||||
end
|
||||
{% else %}
|
||||
%stub.value
|
||||
{% end %}
|
||||
else
|
||||
# Response not configured for this method/message.
|
||||
raise ::Spectator::UnexpectedMessage.new("#{_spectator_double_name} received unexpected message :{{method.name}} with #{%args}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue