shard-spectator/src/spectator/config.cr

121 lines
4.2 KiB
Crystal
Raw Normal View History

require "./config/*"
require "./node_filter"
require "./example_group"
require "./filtered_example_iterator"
require "./formatting/formatter"
require "./node_iterator"
2021-05-09 04:51:54 +00:00
require "./run_flags"
2020-09-12 21:58:54 +00:00
module Spectator
# Provides customization and describes specifics for how Spectator will run and report tests.
class Config
# Primary formatter all events will be sent to.
getter formatter : Formatting::Formatter
2018-12-13 21:16:49 +00:00
2021-05-09 04:51:54 +00:00
# Flags indicating how the spec should run.
getter run_flags : RunFlags
2019-03-24 01:43:41 +00:00
2020-10-18 03:39:41 +00:00
# Seed used for random number generation.
2020-10-18 04:11:04 +00:00
getter random_seed : UInt64
2020-07-27 16:36:53 +00:00
# Filter used to select which examples to run.
getter node_filter : NodeFilter
# 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)
# List of hooks to run before each top-level example group.
protected getter before_all_hooks : Deque(ExampleGroupHook)
# List of hooks to run before every example.
protected getter before_each_hooks : Deque(ExampleHook)
# List of hooks to run after all examples in the test suite.
protected getter after_suite_hooks : Deque(ExampleGroupHook)
# List of hooks to run after each top-level example group.
protected getter after_all_hooks : Deque(ExampleGroupHook)
# List of hooks to run after every example.
protected getter after_each_hooks : Deque(ExampleHook)
# List of hooks to run around every example.
protected getter around_each_hooks : Deque(ExampleProcsyHook)
2018-12-13 21:16:49 +00:00
# Creates a new configuration.
2020-10-18 04:11:04 +00:00
# Properties are pulled from *source*.
# Typically, *source* is a `Config::Builder`.
2020-10-18 04:12:47 +00:00
def initialize(source)
@formatter = source.formatter
2021-05-09 04:51:54 +00:00
@run_flags = source.run_flags
2020-10-18 04:12:47 +00:00
@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
@before_each_hooks = source.before_each_hooks
@after_suite_hooks = source.after_suite_hooks
@after_all_hooks = source.after_all_hooks
@after_each_hooks = source.after_each_hooks
@around_each_hooks = source.around_each_hooks
2018-12-13 21:16:49 +00:00
end
2019-03-23 23:00:21 +00:00
# Produces the default configuration.
def self.default : self
Builder.new.build
end
2020-10-18 04:11:04 +00:00
# Shuffles the items in an array using the configured random settings.
# If `#randomize?` is true, the *items* are shuffled and returned as a new array.
# Otherwise, the items are left alone and returned as-is.
# The array of *items* is never modified.
def shuffle(items)
2021-05-09 04:51:54 +00:00
return items unless run_flags.randomize?
2020-10-18 04:11:04 +00:00
items.shuffle(random)
end
# Shuffles the items in an array using the configured random settings.
# If `#randomize?` is true, the *items* are shuffled and returned.
# Otherwise, the items are left alone and returned as-is.
# The array of *items* is modified, the items are shuffled in-place.
def shuffle!(items)
2021-05-09 04:51:54 +00:00
return items unless run_flags.randomize?
2020-10-18 04:11:04 +00:00
items.shuffle!(random)
end
# Creates an iterator configured to select the filtered examples.
def iterator(group : ExampleGroup)
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?
2019-03-23 23:00:21 +00:00
end
2020-10-18 04:11:04 +00:00
# Retrieves the configured random number generator.
# This will produce the same generator with the same seed every time.
2021-07-17 19:05:03 +00:00
def random
2020-10-18 04:11:04 +00:00
Random.new(random_seed)
end
end
end