mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Some initial spec builder code
This commit is contained in:
parent
0190cc7260
commit
67ac06e4d6
5 changed files with 84 additions and 111 deletions
17
src/spectator/dsl/builder.cr
Normal file
17
src/spectator/dsl/builder.cr
Normal file
|
@ -0,0 +1,17 @@
|
|||
require "../spec/builder"
|
||||
|
||||
module Spectator::DSL
|
||||
module Builder
|
||||
extend self
|
||||
|
||||
@@builder = Spec::Builder.new
|
||||
|
||||
def start_group(*args)
|
||||
@@builder.start_group(*args)
|
||||
end
|
||||
|
||||
def end_group(*args)
|
||||
@@builder.end_group(*args)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,4 +7,3 @@
|
|||
require "./config"
|
||||
require "./config_builder"
|
||||
require "./dsl"
|
||||
require "./spec_builder"
|
||||
|
|
6
src/spectator/spec.cr
Normal file
6
src/spectator/spec.cr
Normal file
|
@ -0,0 +1,6 @@
|
|||
require "./spec/*"
|
||||
|
||||
module Spectator
|
||||
class Spec
|
||||
end
|
||||
end
|
61
src/spectator/spec/builder.cr
Normal file
61
src/spectator/spec/builder.cr
Normal file
|
@ -0,0 +1,61 @@
|
|||
require "../example"
|
||||
require "../example_group"
|
||||
|
||||
module Spectator
|
||||
class Spec::Builder
|
||||
# Stack tracking the current group.
|
||||
# The bottom of the stack (first element) is the root group.
|
||||
# The root group should never be removed.
|
||||
# The top of the stack (last element) is the current group.
|
||||
# New examples should be added to the current group.
|
||||
@group_stack : Deque(ExampleGroup)
|
||||
|
||||
def initialize
|
||||
root_group = ExampleGroup.new
|
||||
@group_stack = Deque(ExampleGroup).new
|
||||
@group_stack.push(root_group)
|
||||
end
|
||||
|
||||
def add_example
|
||||
raise NotImplementedError.new("#add_example")
|
||||
end
|
||||
|
||||
def start_group(name, source = nil) : ExampleGroup
|
||||
{% if flag?(:spectator_debug) %}
|
||||
puts "Start group: #{name.inspect} @ #{source}"
|
||||
{% end %}
|
||||
ExampleGroup.new(name, source, current_group).tap do |group|
|
||||
@group_stack << group
|
||||
end
|
||||
end
|
||||
|
||||
def end_group
|
||||
{% if flag?(:spectator_debug) %}
|
||||
puts "End group: #{current_group}"
|
||||
{% end %}
|
||||
raise "Can't pop root group" if root?
|
||||
|
||||
@group_stack.pop
|
||||
end
|
||||
|
||||
def build
|
||||
raise NotImplementedError.new("#build")
|
||||
end
|
||||
|
||||
# Checks if the current group is the root group.
|
||||
private def root?
|
||||
@group_stack.size == 1
|
||||
end
|
||||
|
||||
# Retrieves the root group.
|
||||
private def root_group
|
||||
@group_stack.first
|
||||
end
|
||||
|
||||
# Retrieves the current group.
|
||||
# This is the group that new examples should be added to.
|
||||
private def current_group
|
||||
@group_stack.last
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,110 +0,0 @@
|
|||
require "./spec_builder/*"
|
||||
|
||||
module Spectator
|
||||
# Global builder used to create the runtime instance of the spec.
|
||||
# The DSL methods call into this module to generate parts of the spec.
|
||||
# Once the DSL is done, the `#build` method can be invoked
|
||||
# to create the entire spec as a runtime instance.
|
||||
module SpecBuilder
|
||||
extend self
|
||||
|
||||
@@stack = ExampleGroupStack.new
|
||||
|
||||
# Begins a new nested group in the spec.
|
||||
# A corresponding `#end_group` call must be made
|
||||
# when the group being started is finished.
|
||||
# See `NestedExampleGroupBuilder#initialize` for the arguments
|
||||
# as arguments to this method are passed directly to it.
|
||||
def start_group(*args) : Nil
|
||||
group = NestedExampleGroupBuilder.new(*args)
|
||||
@@stack.push(group)
|
||||
end
|
||||
|
||||
# Begins a new sample group in the spec -
|
||||
# that is, a group defined by the `StructureDSL#sample` macro in the DSL.
|
||||
# A corresponding `#end_group` call must be made
|
||||
# when the group being started is finished.
|
||||
# See `SampleExampleGroupBuilder#initialize` for the arguments
|
||||
# as arguments to this method are passed directly to it.
|
||||
def start_sample_group(*args, &block : TestValues -> Array(T)) : Nil forall T
|
||||
group = SampleExampleGroupBuilder(T).new(*args, block)
|
||||
@@stack.push(group)
|
||||
end
|
||||
|
||||
# Marks the end of a group in the spec.
|
||||
# This must be called for every `#start_group` and `#start_sample_group` call.
|
||||
# It is also important to line up the start and end calls.
|
||||
# Otherwise examples might get placed into wrong groups.
|
||||
def end_group : Nil
|
||||
@@stack.pop
|
||||
end
|
||||
|
||||
# Adds an example type to the current group.
|
||||
# The class name of the example should be passed as an argument.
|
||||
# The example will be instantiated later.
|
||||
def add_example(description : String?, source : Source,
|
||||
example_type : ::SpectatorTest.class, &runner : ::SpectatorTest ->) : Nil
|
||||
builder = ->(values : TestValues) { example_type.new(values).as(::SpectatorTest) }
|
||||
factory = RunnableExampleBuilder.new(description, source, builder, runner)
|
||||
@@stack.current.add_child(factory)
|
||||
end
|
||||
|
||||
# Adds an example type to the current group.
|
||||
# The class name of the example should be passed as an argument.
|
||||
# The example will be instantiated later.
|
||||
def add_pending_example(description : String?, source : Source,
|
||||
example_type : ::SpectatorTest.class, &runner : ::SpectatorTest ->) : Nil
|
||||
builder = ->(values : TestValues) { example_type.new(values).as(::SpectatorTest) }
|
||||
factory = PendingExampleBuilder.new(description, source, builder, runner)
|
||||
@@stack.current.add_child(factory)
|
||||
end
|
||||
|
||||
# Adds a block of code to run before all examples in the current group.
|
||||
def add_before_all_hook(&block : ->) : Nil
|
||||
@@stack.current.add_before_all_hook(block)
|
||||
end
|
||||
|
||||
# Adds a block of code to run before each example in the current group.
|
||||
def add_before_each_hook(&block : TestMetaMethod) : Nil
|
||||
@@stack.current.add_before_each_hook(block)
|
||||
end
|
||||
|
||||
# Adds a block of code to run after all examples in the current group.
|
||||
def add_after_all_hook(&block : ->) : Nil
|
||||
@@stack.current.add_after_all_hook(block)
|
||||
end
|
||||
|
||||
# Adds a block of code to run after each example in the current group.
|
||||
def add_after_each_hook(&block : TestMetaMethod) : Nil
|
||||
@@stack.current.add_after_each_hook(block)
|
||||
end
|
||||
|
||||
# Adds a block of code to run before and after each example in the current group.
|
||||
# The block of code will be given another hook as an argument.
|
||||
# It is expected that the block will call the hook.
|
||||
def add_around_each_hook(&block : ::SpectatorTest, Proc(Nil) ->) : Nil
|
||||
@@stack.current.add_around_each_hook(block)
|
||||
end
|
||||
|
||||
# Adds a pre-condition to run at the start of every example in the current group.
|
||||
def add_pre_condition(&block : TestMetaMethod) : Nil
|
||||
@@stack.current.add_pre_condition(block)
|
||||
end
|
||||
|
||||
# Adds a post-condition to run at the end of every example in the current group.
|
||||
def add_post_condition(&block : TestMetaMethod) : Nil
|
||||
@@stack.current.add_post_condition(block)
|
||||
end
|
||||
|
||||
def add_default_stub(*args) : Nil
|
||||
@@stack.current.add_default_stub(*args)
|
||||
end
|
||||
|
||||
# Builds the entire spec and returns it as a test suite.
|
||||
# This should be called only once after the entire spec has been defined.
|
||||
protected def build(filter : ExampleFilter) : TestSuite
|
||||
group = @@stack.root.build
|
||||
TestSuite.new(group, filter)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue