Quick implementation of `filter_run_when_matching`

Needed for focus tests.
This commit is contained in:
Michael Miller 2021-08-18 13:46:54 -06:00
parent fd4812207a
commit 2b27ea5a01
No known key found for this signature in database
GPG Key ID: F9A0C5C65B162436
2 changed files with 28 additions and 1 deletions

View File

@ -3,6 +3,7 @@ require "./node_filter"
require "./example_group"
require "./filtered_example_iterator"
require "./formatting/formatter"
require "./node_iterator"
require "./run_flags"
module Spectator
@ -23,6 +24,9 @@ module Spectator
# Filter used to select which examples to _not_ run.
getter node_reject : NodeFilter
# Tags to filter on if they're present in a spec.
protected getter match_filters : Metadata
# List of hooks to run before all examples in the test suite.
protected getter before_suite_hooks : Deque(ExampleGroupHook)
@ -53,6 +57,7 @@ module Spectator
@random_seed = source.random_seed
@node_filter = source.node_filter
@node_reject = source.node_reject
@match_filters = source.match_filters
@before_suite_hooks = source.before_suite_hooks
@before_all_hooks = source.before_all_hooks
@ -90,7 +95,20 @@ module Spectator
# Creates an iterator configured to select the filtered examples.
def iterator(group : ExampleGroup)
FilteredExampleIterator.new(group, @node_filter).reject(@node_reject)
match_filter = match_filter(group)
iterator = FilteredExampleIterator.new(group, @node_filter)
iterator = iterator.select(match_filter) if match_filter
iterator.reject(@node_reject)
end
# Creates a node filter if any conditionally matching filters apply to an example group.
private def match_filter(group : ExampleGroup) : NodeFilter?
iterator = NodeIterator.new(group)
filters = @match_filters.compact_map do |key, value|
filter = TagNodeFilter.new(key.to_s, value)
filter.as(NodeFilter) if iterator.rewind.any?(filter)
end
CompositeNodeFilter.new(filters) unless filters.empty?
end
# Retrieves the configured random number generator.

View File

@ -1,6 +1,7 @@
require "../composite_node_filter"
require "../node_filter"
require "../formatting"
require "../metadata"
require "../null_node_filter"
require "../run_flags"
require "../tag_node_filter"
@ -17,6 +18,8 @@ module Spectator
# Toggles indicating how the test spec should execute.
property run_flags = RunFlags::None
protected getter match_filters : Metadata = {:focus => nil.as(String?)}
@primary_formatter : Formatting::Formatter?
@additional_formatters = [] of Formatting::Formatter
@filters = [] of NodeFilter
@ -282,6 +285,12 @@ module Spectator
values.each { |tag, value| @rejects << TagNodeFilter.new(tag, value.to_s) }
end
# Specifies one or more tags to filter on only if they're present in the spec.
def filter_run_when_matching(*tags : Symbol, **values)
tags.each { |tag| @match_filters[tag] = nil }
values.each { |tag, value| @match_filters[tag] = value.to_s }
end
# Retrieves a filter that determines which examples can run.
# If no filters were added with `#add_node_filter`,
# then the returned filter will allow all examples to be run.