Quick implementation of iterative group builder

This commit is contained in:
Michael Miller 2021-07-17 12:06:53 -06:00
parent c24c2cb5e1
commit c79cb62a61
No known key found for this signature in database
GPG key ID: FB9F12F7C646A4AD
4 changed files with 38 additions and 46 deletions

View file

@ -0,0 +1,10 @@
require "./example_group"
module Spectator
class ExampleGroupIteration(T) < ExampleGroup
def initialize(@item : T, name : Label = nil, location : Location? = nil,
group : ExampleGroup? = nil, metadata : Metadata = Metadata.new)
super(name, location, group, metadata)
end
end
end

View file

@ -1,44 +0,0 @@
require "./example_group"
require "./node"
module Spectator
# Collection of examples and sub-groups executed multiple times.
# Each sub-node is executed once for each item in a given collection.
class IterativeExampleGroup(T) < ExampleGroup
# Creates the iterative example group.
# The *collection* is a list of items to iterative over each sub-node over.
# The *location* tracks where the group exists in source code.
# 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(collection : Enumerable(T), location : Location? = nil,
group : ExampleGroup? = nil, metadata : Metadata = Metadata.new)
super()
@nodes = collection.map do |item|
Iteration.new(item, location, group, metadata).as(Node)
end
end
# Creates a child that is attched to the group.
# Yields zero or more times to create the child.
# The group the child should be attached to is provided as a block argument.
def create_child
@nodes.each { |child| yield child.as(Iteration(T)) }
end
# Adds the specified *node* to the group.
# Assigns the node to this group.
# If the node already belongs to a group,
# it will be removed from the previous group before adding it to this group.
def <<(node : Node)
@nodes.each { |child| child.as(Iteration(T)) << node.dup }
end
private class Iteration(T) < ExampleGroup
def initialize(@item : T, location : Location? = nil,
group : ExampleGroup? = nil, metadata : Metadata = Metadata.new)
super(@item.inspect, location, group, metadata)
end
end
end
end

View file

@ -0,0 +1,26 @@
require "./example_group_builder"
require "./example_group_iteration"
module Spectator
class IterativeExampleGroupBuilder(T) < ExampleGroupBuilder
def initialize(@collection : Enumerable(T),
location : Location? = nil, metadata : Metadata = Metadata.new)
super(nil, location, metadata)
end
def build(parent = nil)
ExampleGroup.new(@name, @location, parent, @metadata).tap do |group|
@before_all_hooks.each { |hook| group.add_before_all_hook(hook) }
@before_each_hooks.each { |hook| group.add_before_each_hook(hook) }
@after_all_hooks.each { |hook| group.add_after_all_hook(hook) }
@after_each_hooks.each { |hook| group.add_after_each_hook(hook) }
@around_each_hooks.each { |hook| group.add_around_each_hook(hook) }
@collection.each do |item|
ExampleGroupIteration.new(item, item.inspect, @location, group).tap do |iteration|
@children.each(&.build(iteration))
end
end
end
end
end
end

View file

@ -4,7 +4,7 @@ require "./example_builder"
require "./example_context_method" require "./example_context_method"
require "./example_group" require "./example_group"
require "./example_group_builder" require "./example_group_builder"
require "./iterative_example_group" require "./iterative_example_group_builder"
require "./pending_example_builder" require "./pending_example_builder"
require "./spec" require "./spec"
require "./metadata" require "./metadata"
@ -78,7 +78,7 @@ module Spectator
# For instance, adding a "pending" tag will mark tests as pending and skip execution. # For instance, adding a "pending" tag will mark tests as pending and skip execution.
def start_iterative_group(collection, location = nil, metadata = Metadata.new) : Nil def start_iterative_group(collection, location = nil, metadata = Metadata.new) : Nil
Log.trace { "Start iterative group: #{typeof(collection)} @ #{location}; metadata: #{metadata}" } Log.trace { "Start iterative group: #{typeof(collection)} @ #{location}; metadata: #{metadata}" }
builder = ExampleGroupBuilder.new(collection, location, metadata) # TODO: IterativeExampleGroupBuilder builder = IterativeExampleGroupBuilder.new(collection, location, metadata)
current << builder current << builder
@stack.push(builder) @stack.push(builder)
end end