From 8cf498c9e904cc85e8351783dda3e86501e8de76 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Sat, 30 Jan 2021 11:13:30 -0700 Subject: [PATCH] Switch to using tags instead of metadata --- src/spectator/dsl/examples.cr | 24 +++++++++++++++--------- src/spectator/example.cr | 18 ++++++++---------- src/spectator/metadata_example.cr | 12 ------------ src/spectator/spec/builder.cr | 4 ++-- src/spectator/test_context.cr | 6 +++--- 5 files changed, 28 insertions(+), 36 deletions(-) delete mode 100644 src/spectator/metadata_example.cr diff --git a/src/spectator/dsl/examples.cr b/src/spectator/dsl/examples.cr index 7c68053..e41bea7 100644 --- a/src/spectator/dsl/examples.cr +++ b/src/spectator/dsl/examples.cr @@ -26,16 +26,22 @@ module Spectator::DSL \{% 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 %} - def self.\%metadata + def self.\%tags \{% if tags.empty? && metadata.empty? %} - _spectator_metadata + _spectator_tags \{% else %} - _spectator_metadata.merge( - \{% for tag in tags %} - \{{tag.id.stringify}}: true, + _spectator_tags.concat({\{{tags.map(&.id.stringify).splat}}}).tap do |tags| + \{% for k, v in metadata %} + cond = begin + \{{v}} + end + if cond + tags.add(\{{k.id.stringify}}) + else + tags.remove(\{{k.id.stringify}}) + end \{% end %} - \{{metadata.double_splat}} - ) + end \{% end %} end @@ -47,13 +53,13 @@ module Spectator::DSL _spectator_example_name(\{{what}}), ::Spectator::Source.new(\{{block.filename}}, \{{block.line_number}}), \{{@type.name}}.new.as(::Spectator::Context), - \{{@type.name}}.\%metadata + \{{@type.name}}.\%tags ) do |example| example.with_context(\{{@type.name}}) do \{% if block.args.empty? %} \%test \{% else %} - \%test(example.unwrap_metadata(typeof(\{{@type.name}}.\%metadata))) + \%test(example) \{% end %} end end diff --git a/src/spectator/example.cr b/src/spectator/example.cr index 1c3e654..d5390ab 100644 --- a/src/spectator/example.cr +++ b/src/spectator/example.cr @@ -1,7 +1,6 @@ require "./example_context_delegate" require "./example_group" require "./harness" -require "./metadata_example" require "./pending_result" require "./result" require "./source" @@ -10,6 +9,9 @@ require "./spec/node" module Spectator # Standard example that runs a test case. class Example < Spec::Node + # User-defined keywords used for filtering and behavior modification. + alias Tags = Set(String) + # Currently running example. class_getter! current : Example @@ -19,6 +21,9 @@ module Spectator # Retrieves the result of the last time the example ran. getter result : Result = PendingResult.new + # User-defined keywords used for filtering and behavior modification. + getter tags : Set(String) + # Creates the example. # An instance to run the test code in is given by *context*. # The *entrypoint* defines the test code (typically inside *context*). @@ -27,9 +32,8 @@ module Spectator # The *source* tracks where the example exists in source code. # The example will be assigned to *group* if it is provided. def initialize(@context : Context, @entrypoint : self ->, - name : String? = nil, source : Source? = nil, group : ExampleGroup? = nil, metadata = NamedTuple.new) + name : String? = nil, source : Source? = nil, group : ExampleGroup? = nil, @tags = Tags.new) super(name, source, group) - @metadata = Wrapper.new(metadata) end # Creates a dynamic example. @@ -40,11 +44,10 @@ module Spectator # The *source* tracks where the example exists in source code. # The example will be assigned to *group* if it is provided. def initialize(name : String? = nil, source : Source? = nil, group : ExampleGroup? = nil, - metadata = NamedTuple.new, &block : self ->) + @tags = Tags.new, &block : self ->) super(name, source, group) @context = NullContext.new @entrypoint = block - @metadata = Wrapper.new(metadata) end # Executes the test case. @@ -98,11 +101,6 @@ module Spectator with context yield end - protected def unwrap_metadata(klass) - metadata = @metadata.get(klass) - MetadataExample.new(self, metadata) - end - # Casts the example's test context to a specific type. # This is an advanced method intended for internal usage only. # diff --git a/src/spectator/metadata_example.cr b/src/spectator/metadata_example.cr deleted file mode 100644 index 6365d82..0000000 --- a/src/spectator/metadata_example.cr +++ /dev/null @@ -1,12 +0,0 @@ -require "./example" - -module Spectator - class MetadataExample(Metadata) - getter metadata : Metadata - - def initialize(@example : Example, @metadata : Metadata) - end - - forward_missing_to @example - end -end diff --git a/src/spectator/spec/builder.cr b/src/spectator/spec/builder.cr index 42f4e11..3836a61 100644 --- a/src/spectator/spec/builder.cr +++ b/src/spectator/spec/builder.cr @@ -93,8 +93,8 @@ module Spectator # It is expected that the test code runs when the block is called. # # The newly created example is returned. - def add_example(name, source, context, metadata, &block : Example -> _) : Example - Log.trace { "Add example: #{name} @ #{source}; metadata: #{metadata}" } + def add_example(name, source, context, tags, &block : Example -> _) : Example + Log.trace { "Add example: #{name} @ #{source}; tags: #{tags}" } Example.new(context, block, name, source, current_group) # The example is added to the current group by `Example` initializer. end diff --git a/src/spectator/test_context.cr b/src/spectator/test_context.cr index caa77af..60bf451 100644 --- a/src/spectator/test_context.cr +++ b/src/spectator/test_context.cr @@ -28,9 +28,9 @@ class SpectatorTestContext < SpectatorContext @subject.get { _spectator_implicit_subject } end - # Initial metadata for tests. + # Initial tags for tests. # This method should be overridden by example groups and examples. - def self._spectator_metadata - NamedTuple.new + def self._spectator_tags + ::Spectator::Example::Tags.new end end