Initial code for example metadata

This commit is contained in:
Michael Miller 2021-01-30 00:40:59 -07:00
parent 8252d333fa
commit 466a388558
No known key found for this signature in database
GPG key ID: F9A0C5C65B162436
4 changed files with 38 additions and 5 deletions

View file

@ -21,11 +21,24 @@ module Spectator::DSL
# #
# The example will be marked as pending if the block is omitted. # The example will be marked as pending if the block is omitted.
# A block or name must be provided. # A block or name must be provided.
macro {{name.id}}(what = nil, &block) macro {{name.id}}(what = nil, *tags, **metadata, &block)
\{% raise "Cannot use '{{name.id}}' inside of a test block" if @def %} \{% raise "Cannot use '{{name.id}}' inside of a test block" if @def %}
\{% raise "A description or block must be provided. Cannot use '{{name.id}}' alone." unless what || block %} \{% raise "A description or block must be provided. Cannot use '{{name.id}}' alone." unless what || block %}
\{% raise "Block argument count '{{name.id}}' hook must be 0..1" if block.args.size > 1 %} \{% raise "Block argument count '{{name.id}}' hook must be 0..1" if block.args.size > 1 %}
def self.\%metadata
\{% if tags.empty? && metadata.empty? %}
_spectator_metadata
\{% else %}
_spectator_metadata.merge(
\{% for tag in tags %}
\{{tag.id.stringify}}: true,
\{% end %}
\{{metadata.double_splat}}
)
\{% end %}
end
def \%test(\{{block.args.splat}}) : Nil def \%test(\{{block.args.splat}}) : Nil
\{{block.body}} \{{block.body}}
end end
@ -33,7 +46,8 @@ module Spectator::DSL
::Spectator::DSL::Builder.add_example( ::Spectator::DSL::Builder.add_example(
_spectator_example_name(\{{what}}), _spectator_example_name(\{{what}}),
::Spectator::Source.new(\{{block.filename}}, \{{block.line_number}}), ::Spectator::Source.new(\{{block.filename}}, \{{block.line_number}}),
\{{@type.name}}.new.as(::Spectator::Context) \{{@type.name}}.new.as(::Spectator::Context),
\{{@type.name}}.\%metadata
) do |example| ) do |example|
example.with_context(\{{@type.name}}) do example.with_context(\{{@type.name}}) do
\{% if block.args.empty? %} \{% if block.args.empty? %}

View file

@ -10,12 +10,25 @@ module Spectator::DSL
# The *what* argument is a name or description of the group. # The *what* argument is a name or description of the group.
# #
# TODO: Handle string interpolation in example and group names. # TODO: Handle string interpolation in example and group names.
macro {{name.id}}(what, &block) macro {{name.id}}(what, *tags, **metadata, &block)
\{% raise "Cannot use '{{name.id}}' inside of a test block" if @def %} \{% raise "Cannot use '{{name.id}}' inside of a test block" if @def %}
class Group\%group < \{{@type.id}} class Group\%group < \{{@type.id}}
_spectator_group_subject(\{{what}}) _spectator_group_subject(\{{what}})
def self._spectator_metadata
\{% if tags.empty? && metadata.empty? %}
super
\{% else %}
super.merge(
\{% for tag in tags %}
\{{tag.id.stringify}}: true,
\{% end %}
\{{metadata.double_splat}}
)
\{% end %}
end
::Spectator::DSL::Builder.start_group( ::Spectator::DSL::Builder.start_group(
_spectator_group_name(\{{what}}), _spectator_group_name(\{{what}}),
::Spectator::Source.new(\{{block.filename}}, \{{block.line_number}}) ::Spectator::Source.new(\{{block.filename}}, \{{block.line_number}})

View file

@ -93,8 +93,8 @@ module Spectator
# It is expected that the test code runs when the block is called. # It is expected that the test code runs when the block is called.
# #
# The newly created example is returned. # The newly created example is returned.
def add_example(name, source, context, &block : Example -> _) : Example def add_example(name, source, context, metadata, &block : Example -> _) : Example
Log.trace { "Add example: #{name} @ #{source}" } Log.trace { "Add example: #{name} @ #{source}; metadata: #{metadata}" }
Example.new(context, block, name, source, current_group) Example.new(context, block, name, source, current_group)
# The example is added to the current group by `Example` initializer. # The example is added to the current group by `Example` initializer.
end end

View file

@ -27,4 +27,10 @@ class SpectatorTestContext < SpectatorContext
private def subject private def subject
@subject.get { _spectator_implicit_subject } @subject.get { _spectator_implicit_subject }
end end
# Initial metadata for tests.
# This method should be overridden by example groups and examples.
def self._spectator_metadata
NamedTuple.new
end
end end