Support custom handling of hooks

This commit is contained in:
Michael Miller 2021-07-31 14:16:39 -06:00
parent f53ffabf6b
commit 868aa1d00a
No known key found for this signature in database
GPG key ID: FB9F12F7C646A4AD

View file

@ -6,42 +6,94 @@ module Spectator::DSL
module Hooks module Hooks
# Defines a macro to create an example group hook. # Defines a macro to create an example group hook.
# The *type* indicates when the hook runs and must be a method on `Spectator::DSL::Builder`. # The *type* indicates when the hook runs and must be a method on `Spectator::DSL::Builder`.
macro define_example_group_hook(type) # A custom *name* can be used for the hook method.
macro {{type.id}}(&block) # If not provided, *type* will be used instead.
\{% raise "Missing block for '{{type.id}}' hook" unless block %} # Additionally, a block can be provided.
\{% raise "Cannot use '{{type.id}}' inside of a test block" if @def %} # The block can perform any operations necessary and yield to invoke the end-user hook.
macro define_example_group_hook(type, name = nil, &block)
macro {{(name ||= type).id}}(&block)
\{% raise "Missing block for '{{name.id}}' hook" unless block %}
\{% raise "Cannot use '{{name.id}}' inside of a test block" if @def %}
private def self.\%hook : Nil private def self.\%hook : Nil
\{{block.body}} \{{block.body}}
end end
{% if block %}
private def self.%wrapper : Nil
{{block.body}}
end
{% end %}
::Spectator::DSL::Builder.{{type.id}}( ::Spectator::DSL::Builder.{{type.id}}(
::Spectator::Location.new(\{{block.filename}}, \{{block.line_number}}) ::Spectator::Location.new(\{{block.filename}}, \{{block.line_number}})
) { \%hook } ) do
{% if block %}
%wrapper do |*args|
\{% if block.args.empty? %}
\%hook
\{% else %}
\%hook(*args)
\{% end %}
end
{% else %}
\%hook
{% end %}
end
end end
end end
# Defines a macro to create an example hook. # Defines a macro to create an example hook.
# The *type* indicates when the hook runs and must be a method on `Spectator::DSL::Builder`. # The *type* indicates when the hook runs and must be a method on `Spectator::DSL::Builder`.
macro define_example_hook(type) # A custom *name* can be used for the hook method.
macro {{type.id}}(&block) # If not provided, *type* will be used instead.
\{% raise "Missing block for '{{type.id}}' hook" unless block %} # Additionally, a block can be provided that takes the current example as an argument.
\{% raise "Block argument count '{{type.id}}' hook must be 0..1" if block.args.size > 1 %} # The block can perform any operations necessary and yield to invoke the end-user hook.
\{% raise "Cannot use '{{type.id}}' inside of a test block" if @def %} macro define_example_hook(type, name = nil, &block)
macro {{(name ||= type).id}}(&block)
\{% raise "Missing block for '{{name.id}}' hook" unless block %}
\{% raise "Block argument count '{{name.id}}' hook must be 0..1" if block.args.size > 1 %}
\{% raise "Cannot use '{{name.id}}' inside of a test block" if @def %}
private def \%hook(\{{block.args.splat}}) : Nil private def \%hook(\{{block.args.splat}}) : Nil
\{{block.body}} \{{block.body}}
end end
{% if block %}
private def %wrapper({{block.args.splat}}) : Nil
{{block.body}}
end
{% end %}
::Spectator::DSL::Builder.{{type.id}}( ::Spectator::DSL::Builder.{{type.id}}(
::Spectator::Location.new(\{{block.filename}}, \{{block.line_number}}) ::Spectator::Location.new(\{{block.filename}}, \{{block.line_number}})
) do |example| ) do |example|
example.with_context(\{{@type.name}}) do example.with_context(\{{@type.name}}) do
{% if block %}
{% if block.args.empty? %}
%wrapper do |*args|
\{% if block.args.empty? %}
\%hook
\{% else %}
\%hook(*args)
\{% end %}
end
{% else %}
%wrapper(example) do |*args|
\{% if block.args.empty? %}
\%hook
\{% else %}
\%hook(*args)
\{% end %}
end
{% end %}
{% else %}
\{% if block.args.empty? %} \{% if block.args.empty? %}
\%hook \%hook
\{% else %} \{% else %}
\%hook(example) \%hook(example)
\{% end %} \{% end %}
{% end %}
end end
end end
end end