mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
WIP
This commit is contained in:
parent
fd372226ab
commit
7db863254d
7 changed files with 2 additions and 188 deletions
1
specs.cr
Normal file
1
specs.cr
Normal file
|
@ -0,0 +1 @@
|
||||||
|
require "./spec/**"
|
|
@ -1,38 +0,0 @@
|
||||||
require "./context"
|
|
||||||
require "./example"
|
|
||||||
require "./location"
|
|
||||||
require "./metadata"
|
|
||||||
require "./node_builder"
|
|
||||||
|
|
||||||
module Spectator
|
|
||||||
# Constructs examples.
|
|
||||||
# Call `#build` to produce an `Example`.
|
|
||||||
class ExampleBuilder < NodeBuilder
|
|
||||||
@name : Proc(Example, String) | String?
|
|
||||||
|
|
||||||
# Creates the builder.
|
|
||||||
# A proc provided by *context_builder* is used to create a unique `Context` for each example produced by `#build`.
|
|
||||||
# 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? = nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Creates the builder.
|
|
||||||
# A proc provided by *context_builder* is used to create a unique `Context` for each example produced by `#build`.
|
|
||||||
# The *entrypoint* indicates the proc used to invoke the test code in the example.
|
|
||||||
# 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? = nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Constructs an example with previously defined attributes and context.
|
|
||||||
# The *parent* is an already constructed example group to nest the new example under.
|
|
||||||
# It can be nil if the new example won't have a parent.
|
|
||||||
def build(parent = nil)
|
|
||||||
context = @context_builder.call
|
|
||||||
Example.new(context, @entrypoint, @name, @location, parent, @metadata)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,62 +0,0 @@
|
||||||
require "./example_group"
|
|
||||||
require "./example_group_hook"
|
|
||||||
require "./example_hook"
|
|
||||||
require "./example_procsy_hook"
|
|
||||||
require "./hooks"
|
|
||||||
require "./label"
|
|
||||||
require "./location"
|
|
||||||
require "./metadata"
|
|
||||||
require "./node_builder"
|
|
||||||
|
|
||||||
module Spectator
|
|
||||||
# Progressively constructs an example group.
|
|
||||||
# Hooks and builders for child nodes can be added over time to this builder.
|
|
||||||
# When done, call `#build` to produce an `ExampleGroup`.
|
|
||||||
class ExampleGroupBuilder < NodeBuilder
|
|
||||||
include Hooks
|
|
||||||
|
|
||||||
define_hook before_all : ExampleGroupHook
|
|
||||||
define_hook after_all : ExampleGroupHook, :prepend
|
|
||||||
define_hook before_each : ExampleHook
|
|
||||||
define_hook after_each : ExampleHook, :prepend
|
|
||||||
define_hook pre_condition : ExampleHook
|
|
||||||
define_hook post_condition : ExampleHook, :prepend
|
|
||||||
define_hook around_each : ExampleProcsyHook
|
|
||||||
|
|
||||||
@children = [] of NodeBuilder
|
|
||||||
|
|
||||||
# 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? = nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Constructs an example group with previously defined attributes, children, and hooks.
|
|
||||||
# The *parent* is an already constructed example group to nest the new example group under.
|
|
||||||
# It can be nil if the new example group won't have a parent.
|
|
||||||
def build(parent = nil)
|
|
||||||
ExampleGroup.new(@name, @location, parent, @metadata).tap do |group|
|
|
||||||
apply_hooks(group)
|
|
||||||
@children.each(&.build(group))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Adds a child builder to the group.
|
|
||||||
# The *builder* will have `NodeBuilder#build` called on it from within `#build`.
|
|
||||||
# The new example group will be passed to it.
|
|
||||||
def <<(builder)
|
|
||||||
@children << builder
|
|
||||||
end
|
|
||||||
|
|
||||||
# Adds all previously configured hooks to an example group.
|
|
||||||
private def apply_hooks(group)
|
|
||||||
before_all_hooks.each { |hook| group.before_all(hook) }
|
|
||||||
before_each_hooks.each { |hook| group.before_each(hook) }
|
|
||||||
after_all_hooks.reverse_each { |hook| group.after_all(hook) }
|
|
||||||
after_each_hooks.reverse_each { |hook| group.after_each(hook) }
|
|
||||||
around_each_hooks.each { |hook| group.around_each(hook) }
|
|
||||||
pre_condition_hooks.each { |hook| group.pre_condition(hook) }
|
|
||||||
post_condition_hooks.reverse_each { |hook| group.post_condition(hook) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,58 +0,0 @@
|
||||||
require "./example_group"
|
|
||||||
require "./example_group_builder"
|
|
||||||
require "./example_group_iteration"
|
|
||||||
require "./location"
|
|
||||||
require "./metadata"
|
|
||||||
|
|
||||||
module Spectator
|
|
||||||
# Progressively constructs an iterative example group.
|
|
||||||
# Hooks and builders for child nodes can be added over time to this builder.
|
|
||||||
# When done, call `#build` to produce an `ExampleGroup` with nested `ExampleGroupIteration` instances.
|
|
||||||
class IterativeExampleGroupBuilder(T) < ExampleGroupBuilder
|
|
||||||
# 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`.
|
|
||||||
# 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? = nil)
|
|
||||||
super(name, location, metadata)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Constructs an iterative example group with previously defined attributes, children, and hooks.
|
|
||||||
# The *parent* is an already constructed example group to nest the new example group under.
|
|
||||||
# It can be nil if the new example group won't have a parent.
|
|
||||||
def build(parent = nil)
|
|
||||||
ExampleGroup.new(@name, @location, parent, @metadata).tap do |group|
|
|
||||||
# Hooks are applied once to the outer group,
|
|
||||||
# instead of multiple times for each inner group (iteration).
|
|
||||||
apply_hooks(group)
|
|
||||||
|
|
||||||
@collection.each do |item|
|
|
||||||
ExampleGroupIteration.new(item, iteration_name(item), @location, group).tap do |iteration|
|
|
||||||
@children.each(&.build(iteration))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Constructs the name of an example group iteration.
|
|
||||||
private def iteration_name(item)
|
|
||||||
if item.is_a?(Tuple) && @iterators.size > 1
|
|
||||||
item.zip?(@iterators).map do |(subitem, iterator)|
|
|
||||||
if iterator
|
|
||||||
"#{iterator}: #{subitem.inspect}"
|
|
||||||
else
|
|
||||||
subitem.inspect
|
|
||||||
end
|
|
||||||
end.join("; ")
|
|
||||||
else
|
|
||||||
if iterator = @iterators.first?
|
|
||||||
"#{iterator}: #{item.inspect}"
|
|
||||||
else
|
|
||||||
item.inspect
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -8,6 +8,7 @@ module Spectator
|
||||||
# but can be anything that should be iterated over when running the spec.
|
# but can be anything that should be iterated over when running the spec.
|
||||||
abstract class Node
|
abstract class Node
|
||||||
# Default text used if none was given by the user for skipping a node.
|
# Default text used if none was given by the user for skipping a node.
|
||||||
|
# TODO: Move out of Node.
|
||||||
DEFAULT_PENDING_REASON = "No reason given"
|
DEFAULT_PENDING_REASON = "No reason given"
|
||||||
|
|
||||||
# Location of the node in source code.
|
# Location of the node in source code.
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
module Spectator
|
|
||||||
abstract class NodeBuilder
|
|
||||||
# Produces a node for a spec.
|
|
||||||
abstract def build(parent = nil)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,24 +0,0 @@
|
||||||
require "./example"
|
|
||||||
require "./location"
|
|
||||||
require "./metadata"
|
|
||||||
require "./node_builder"
|
|
||||||
|
|
||||||
module Spectator
|
|
||||||
# Constructs pending examples.
|
|
||||||
# Call `#build` to produce an `Example`.
|
|
||||||
class PendingExampleBuilder < NodeBuilder
|
|
||||||
# Creates the builder.
|
|
||||||
# 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? = nil, @reason : String? = nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Constructs an example with previously defined attributes.
|
|
||||||
# The *parent* is an already constructed example group to nest the new example under.
|
|
||||||
# It can be nil if the new example won't have a parent.
|
|
||||||
def build(parent = nil)
|
|
||||||
Example.pending(@name, @location, parent, @metadata, @reason)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Add table
Add a link
Reference in a new issue