mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Allow metadata to be stored as nil
This commit is contained in:
parent
fbe877690d
commit
275b217c6c
13 changed files with 41 additions and 24 deletions
|
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Changed
|
||||
- Simplify string representation of mock-related types.
|
||||
- Remove unnecessary redefinitions of methods when adding stub functionality to a type.
|
||||
- Allow metadata to be stored as nil to reduce overhead when tracking nodes without tags.
|
||||
|
||||
## [0.11.4]
|
||||
### Added
|
||||
|
|
|
@ -6,6 +6,9 @@ module Spectator::DSL
|
|||
private macro _spectator_metadata(name, source, *tags, **metadata)
|
||||
private def self.{{name.id}}
|
||||
%metadata = {{source.id}}.dup
|
||||
{% unless tags.empty? && metadata.empty? %}
|
||||
%metadata ||= ::Spectator::Metadata.new
|
||||
{% end %}
|
||||
{% for k in tags %}
|
||||
%metadata[{{k.id.symbolize}}] = nil
|
||||
{% end %}
|
||||
|
|
|
@ -40,7 +40,7 @@ module Spectator
|
|||
# Note: The metadata will not be merged with the parent metadata.
|
||||
def initialize(@context : Context, @entrypoint : self ->,
|
||||
name : String? = nil, location : Location? = nil,
|
||||
@group : ExampleGroup? = nil, metadata = Metadata.new)
|
||||
@group : ExampleGroup? = nil, metadata = nil)
|
||||
super(name, location, metadata)
|
||||
|
||||
# Ensure group is linked.
|
||||
|
@ -58,7 +58,7 @@ module Spectator
|
|||
# Note: The metadata will not be merged with the parent metadata.
|
||||
def initialize(@context : Context, @entrypoint : self ->,
|
||||
@name_proc : Example -> String, location : Location? = nil,
|
||||
@group : ExampleGroup? = nil, metadata = Metadata.new)
|
||||
@group : ExampleGroup? = nil, metadata = nil)
|
||||
super(nil, location, metadata)
|
||||
|
||||
# Ensure group is linked.
|
||||
|
@ -75,7 +75,7 @@ module Spectator
|
|||
# A set of *metadata* can be used for filtering and modifying example behavior.
|
||||
# Note: The metadata will not be merged with the parent metadata.
|
||||
def initialize(name : String? = nil, location : Location? = nil,
|
||||
@group : ExampleGroup? = nil, metadata = Metadata.new, &block : self ->)
|
||||
@group : ExampleGroup? = nil, metadata = nil, &block : self ->)
|
||||
super(name, location, metadata)
|
||||
|
||||
@context = NullContext.new
|
||||
|
@ -93,9 +93,10 @@ module Spectator
|
|||
# A set of *metadata* can be used for filtering and modifying example behavior.
|
||||
# Note: The metadata will not be merged with the parent metadata.
|
||||
def self.pending(name : String? = nil, location : Location? = nil,
|
||||
group : ExampleGroup? = nil, metadata = Metadata.new, reason = nil)
|
||||
group : ExampleGroup? = nil, metadata = nil, reason = nil)
|
||||
# Add pending tag and reason if they don't exist.
|
||||
metadata = metadata.merge({:pending => nil, :reason => reason}) { |_, v, _| v }
|
||||
tags = {:pending => nil, :reason => reason}
|
||||
metadata = metadata ? metadata.merge(tags) { |_, v, _| v } : tags
|
||||
new(name, location, group, metadata) { nil }
|
||||
end
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ module Spectator
|
|||
# The *entrypoint* indicates the proc used to invoke the test code in the example.
|
||||
# The *name*, *location*, and *metadata* will be applied to the `Example` produced by `#build`.
|
||||
def initialize(@context_builder : -> Context, @entrypoint : Example ->,
|
||||
@name : String? = nil, @location : Location? = nil, @metadata : Metadata = Metadata.new)
|
||||
@name : String? = nil, @location : Location? = nil, @metadata : Metadata? = nil)
|
||||
end
|
||||
|
||||
# Creates the builder.
|
||||
|
@ -24,7 +24,7 @@ module Spectator
|
|||
# The *name* is an interpolated string that runs in the context of the example.
|
||||
# *location*, and *metadata* will be applied to the `Example` produced by `#build`.
|
||||
def initialize(@context_builder : -> Context, @entrypoint : Example ->,
|
||||
@name : Example -> String, @location : Location? = nil, @metadata : Metadata = Metadata.new)
|
||||
@name : Example -> String, @location : Location? = nil, @metadata : Metadata? = nil)
|
||||
end
|
||||
|
||||
# Constructs an example with previously defined attributes and context.
|
||||
|
|
|
@ -79,7 +79,7 @@ module Spectator
|
|||
# This group will be assigned to the parent *group* if it is provided.
|
||||
# A set of *metadata* can be used for filtering and modifying example behavior.
|
||||
def initialize(@name : Label = nil, @location : Location? = nil,
|
||||
@group : ExampleGroup? = nil, @metadata : Metadata = Metadata.new)
|
||||
@group : ExampleGroup? = nil, @metadata : Metadata? = nil)
|
||||
# Ensure group is linked.
|
||||
group << self if group
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ module Spectator
|
|||
# Creates the builder.
|
||||
# Initially, the builder will have no children and no hooks.
|
||||
# The *name*, *location*, and *metadata* will be applied to the `ExampleGroup` produced by `#build`.
|
||||
def initialize(@name : Label = nil, @location : Location? = nil, @metadata : Metadata = Metadata.new)
|
||||
def initialize(@name : Label = nil, @location : Location? = nil, @metadata : Metadata? = nil)
|
||||
end
|
||||
|
||||
# Constructs an example group with previously defined attributes, children, and hooks.
|
||||
|
|
|
@ -18,7 +18,7 @@ module Spectator
|
|||
# This group will be assigned to the parent *group* if it is provided.
|
||||
# A set of *metadata* can be used for filtering and modifying example behavior.
|
||||
def initialize(@item : T, name : Label = nil, location : Location? = nil,
|
||||
group : ExampleGroup? = nil, metadata : Metadata = Metadata.new)
|
||||
group : ExampleGroup? = nil, metadata : Metadata? = nil)
|
||||
super(name, location, group, metadata)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ module Spectator
|
|||
# The *collection* is the set of items to create sub-nodes for.
|
||||
# The *iterators* is a list of optional names given to items in the collection.
|
||||
def initialize(@collection : Enumerable(T), name : String? = nil, @iterators : Array(String) = [] of String,
|
||||
location : Location? = nil, metadata : Metadata = Metadata.new)
|
||||
location : Location? = nil, metadata : Metadata? = nil)
|
||||
super(name, location, metadata)
|
||||
end
|
||||
|
||||
|
|
|
@ -30,14 +30,16 @@ module Spectator
|
|||
end
|
||||
|
||||
# User-defined tags and values used for filtering and behavior modification.
|
||||
getter metadata : Metadata
|
||||
def metadata : Metadata
|
||||
@metadata ||= Metadata.new
|
||||
end
|
||||
|
||||
# Creates the node.
|
||||
# The *name* describes the purpose of the node.
|
||||
# It can be a `Symbol` to describe a type.
|
||||
# The *location* tracks where the node exists in source code.
|
||||
# A set of *metadata* can be used for filtering and modifying example behavior.
|
||||
def initialize(@name : Label = nil, @location : Location? = nil, @metadata : Metadata = Metadata.new)
|
||||
def initialize(@name : Label = nil, @location : Location? = nil, @metadata : Metadata? = nil)
|
||||
end
|
||||
|
||||
# Indicates whether the node has completed.
|
||||
|
@ -46,17 +48,25 @@ module Spectator
|
|||
# Checks if the node has been marked as pending.
|
||||
# Pending items should be skipped during execution.
|
||||
def pending?
|
||||
metadata.has_key?(:pending) || metadata.has_key?(:skip)
|
||||
return false unless md = @metadata
|
||||
|
||||
md.has_key?(:pending) || md.has_key?(:skip)
|
||||
end
|
||||
|
||||
# Gets the reason the node has been marked as pending.
|
||||
def pending_reason
|
||||
metadata[:pending]? || metadata[:skip]? || metadata[:reason]? || DEFAULT_PENDING_REASON
|
||||
return DEFAULT_PENDING_REASON unless md = @metadata
|
||||
|
||||
md[:pending]? || md[:skip]? || md[:reason]? || DEFAULT_PENDING_REASON
|
||||
end
|
||||
|
||||
# Retrieves just the tag names applied to the node.
|
||||
def tags
|
||||
Tags.new(metadata.keys)
|
||||
if md = @metadata
|
||||
Tags.new(md.keys)
|
||||
else
|
||||
Tags.new
|
||||
end
|
||||
end
|
||||
|
||||
# Non-nil name used to show the node name.
|
||||
|
|
|
@ -11,7 +11,7 @@ module Spectator
|
|||
# The *name*, *location*, and *metadata* will be applied to the `Example` produced by `#build`.
|
||||
# A default *reason* can be given in case the user didn't provide one.
|
||||
def initialize(@name : String? = nil, @location : Location? = nil,
|
||||
@metadata : Metadata = Metadata.new, @reason : String? = nil)
|
||||
@metadata : Metadata? = nil, @reason : String? = nil)
|
||||
end
|
||||
|
||||
# Constructs an example with previously defined attributes.
|
||||
|
|
|
@ -60,7 +60,7 @@ module Spectator
|
|||
#
|
||||
# A set of *metadata* can be used for filtering and modifying example behavior.
|
||||
# For instance, adding a "pending" tag will mark tests as pending and skip execution.
|
||||
def start_group(name, location = nil, metadata = Metadata.new) : Nil
|
||||
def start_group(name, location = nil, metadata = nil) : Nil
|
||||
Log.trace { "Start group: #{name.inspect} @ #{location}; metadata: #{metadata}" }
|
||||
builder = ExampleGroupBuilder.new(name, location, metadata)
|
||||
|
||||
|
@ -86,7 +86,7 @@ module Spectator
|
|||
#
|
||||
# A set of *metadata* can be used for filtering and modifying example behavior.
|
||||
# For instance, adding a "pending" tag will mark tests as pending and skip execution.
|
||||
def start_iterative_group(collection, name, iterator = nil, location = nil, metadata = Metadata.new) : Nil
|
||||
def start_iterative_group(collection, name, iterator = nil, location = nil, metadata = nil) : Nil
|
||||
Log.trace { "Start iterative group: #{name} (#{typeof(collection)}) @ #{location}; metadata: #{metadata}" }
|
||||
builder = IterativeExampleGroupBuilder.new(collection, name, iterator, location, metadata)
|
||||
|
||||
|
@ -127,7 +127,7 @@ module Spectator
|
|||
# It will be yielded two arguments - the example created by this method, and the *context* argument.
|
||||
# The return value of the block is ignored.
|
||||
# It is expected that the test code runs when the block is called.
|
||||
def add_example(name, location, context_builder, metadata = Metadata.new, &block : Example -> _) : Nil
|
||||
def add_example(name, location, context_builder, metadata = nil, &block : Example -> _) : Nil
|
||||
Log.trace { "Add example: #{name} @ #{location}; metadata: #{metadata}" }
|
||||
current << ExampleBuilder.new(context_builder, block, name, location, metadata)
|
||||
end
|
||||
|
@ -144,7 +144,7 @@ module Spectator
|
|||
# A set of *metadata* can be used for filtering and modifying example behavior.
|
||||
# For instance, adding a "pending" tag will mark the test as pending and skip execution.
|
||||
# A default *reason* can be given in case the user didn't provide one.
|
||||
def add_pending_example(name, location, metadata = Metadata.new, reason = nil) : Nil
|
||||
def add_pending_example(name, location, metadata = nil, reason = nil) : Nil
|
||||
Log.trace { "Add pending example: #{name} @ #{location}; metadata: #{metadata}" }
|
||||
current << PendingExampleBuilder.new(name, location, metadata, reason)
|
||||
end
|
||||
|
|
|
@ -10,7 +10,9 @@ module Spectator
|
|||
|
||||
# Checks whether the node satisfies the filter.
|
||||
def includes?(node) : Bool
|
||||
node.metadata.any? { |key, value| key.to_s == @tag && (!@value || value == @value) }
|
||||
return false unless metadata = node.metadata
|
||||
|
||||
metadata.any? { |key, value| key.to_s == @tag && (!@value || value == @value) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,7 +34,7 @@ class SpectatorTestContext < SpectatorContext
|
|||
|
||||
# Initial metadata for tests.
|
||||
# This method should be overridden by example groups and examples.
|
||||
private def self.metadata
|
||||
::Spectator::Metadata.new
|
||||
private def self.metadata : ::Spectator::Metadata?
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue