diff --git a/src/spectator/builders/example_builder.cr b/src/spectator/builders/example_builder.cr new file mode 100644 index 0000000..a181216 --- /dev/null +++ b/src/spectator/builders/example_builder.cr @@ -0,0 +1,10 @@ +module Spectator::Builders + class ExampleBuilder + def initialize(@wrapper : TestWrapper) + end + + def build(group) + RunnableExample.new(group, @wrapper).as(ExampleComponent) + end + end +end diff --git a/src/spectator/builders/example_group_builder.cr b/src/spectator/builders/example_group_builder.cr new file mode 100644 index 0000000..159b9ac --- /dev/null +++ b/src/spectator/builders/example_group_builder.cr @@ -0,0 +1,13 @@ +require "./example_builder" + +module Spectator::Builders + abstract class ExampleGroupBuilder + alias Child = NestedExampleGroupBuilder | ExampleBuilder + + private getter children = [] of Child + + def add_child(child : Child) + @children << child + end + end +end diff --git a/src/spectator/builders/example_group_stack.cr b/src/spectator/builders/example_group_stack.cr index cf91a45..0a9b792 100644 --- a/src/spectator/builders/example_group_stack.cr +++ b/src/spectator/builders/example_group_stack.cr @@ -1,8 +1,14 @@ +require "./root_example_group_builder" +require "./nested_example_group_builder" + module Spectator::Builders struct ExampleGroupStack - getter root = RootExampleGroupBuilder.new + getter root - @stack = Deque(ExampleGroupBuilder).new(1, @root) + def initialize + @root = RootExampleGroupBuilder.new + @stack = Deque(ExampleGroupBuilder).new(1, @root) + end def current @stack.last diff --git a/src/spectator/builders/nested_example_group_builder.cr b/src/spectator/builders/nested_example_group_builder.cr new file mode 100644 index 0000000..d2c748b --- /dev/null +++ b/src/spectator/builders/nested_example_group_builder.cr @@ -0,0 +1,16 @@ +require "./example_group_builder" + +module Spectator::Builders + class NestedExampleGroupBuilder < ExampleGroupBuilder + def initialize(@what : String | Symbol) + end + + def build(group) + NestedExampleGroup.new(@what, group).tap do |group| + group.children = children.map do |child| + child.build(group).as(ExampleComponent) + end + end + end + end +end diff --git a/src/spectator/builders/root_example_group_builder.cr b/src/spectator/builders/root_example_group_builder.cr new file mode 100644 index 0000000..fb3e27f --- /dev/null +++ b/src/spectator/builders/root_example_group_builder.cr @@ -0,0 +1,13 @@ +require "./example_group_builder" + +module Spectator::Builders + class RootExampleGroupBuilder < ExampleGroupBuilder + def build + RootExampleGroup.new.tap do |group| + group.children = children.map do |child| + child.build(group).as(ExampleComponent) + end + end + end + end +end diff --git a/src/spectator/dsl/builder.cr b/src/spectator/dsl/builder.cr index b815dce..569bea5 100644 --- a/src/spectator/dsl/builder.cr +++ b/src/spectator/dsl/builder.cr @@ -1,3 +1,5 @@ +require "../builders/example_group_stack" + module Spectator::DSL # Global builder used to create the runtime instance of the spec. # The DSL methods call into this module to generate parts of the spec. @@ -14,7 +16,7 @@ module Spectator::DSL # 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) + group = Builders::NestedExampleGroupBuilder.new(*args) @@stack.push(group) end @@ -88,7 +90,7 @@ module Spectator::DSL # 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(Internals::SampleValues.empty) + group = @@stack.root.build TestSuite.new(group, filter) end end diff --git a/src/spectator/example.cr b/src/spectator/example.cr index 3b5cbb2..56af0c7 100644 --- a/src/spectator/example.cr +++ b/src/spectator/example.cr @@ -25,9 +25,11 @@ module Spectator def symbolic? description = @test_wrapper.description - description.start_with?('#') || description.start_with?('.') + description.starts_with?('#') || description.starts_with?('.') end + abstract def run_impl + # Runs the example code. # A result is returned, which represents the outcome of the test. # An example can be run only once. @@ -39,9 +41,6 @@ module Spectator @finished = true end - # Implementation-specific for running the example code. - private abstract def run_impl : Result - # Creates the base of the example. # The group should be the example group the example belongs to. def initialize(@group, @test_wrapper) diff --git a/src/spectator/example_group.cr b/src/spectator/example_group.cr index 2d6b28e..b703cd7 100644 --- a/src/spectator/example_group.cr +++ b/src/spectator/example_group.cr @@ -15,10 +15,6 @@ module Spectator include Enumerable(ExampleComponent) include Iterable(ExampleComponent) - # Creates the example group. - def initialize - end - # Retrieves the children in the group. # This only returns the direct descends (non-recursive). # The children must be set (with `#children=`) prior to calling this method. diff --git a/src/spectator/runnable_example.cr b/src/spectator/runnable_example.cr index 7964ff1..9dca2d1 100644 --- a/src/spectator/runnable_example.cr +++ b/src/spectator/runnable_example.cr @@ -16,28 +16,6 @@ module Spectator # A captured result is returned. private def capture_result ResultCapture.new.tap do |result| - # Get the proc that will call around-each hooks and the example. - wrapper = wrap_run_example(result) - - run_wrapper(wrapper) - end - end - - private def run_wrapper(wrapper) - wrapper.call - rescue ex - # If an error occurs calling the wrapper, - # it means it came from the "around-each" hooks. - # This is because the test code is completely wrapped with a begin/rescue block. - raise Exception.new("Error encountered while running around hooks", ex) - end - - # Creates a proc that runs the test code - # and captures the result. - private def wrap_run_example(result) - # Wrap the method that runs and captures - # the test code with the around-each hooks. - group.wrap_around_each_hooks do run_example(result) end end diff --git a/src/spectator/runner.cr b/src/spectator/runner.cr index 306f837..afd517c 100644 --- a/src/spectator/runner.cr +++ b/src/spectator/runner.cr @@ -35,7 +35,7 @@ module Spectator result = run_example(example).as(Result) results << result if @config.fail_fast? && result.is_a?(FailedResult) - example.group.run_after_all_hooks(ignore_unfinished: true) + # TODO: example.group.run_after_all_hooks(ignore_unfinished: true) break end end diff --git a/src/spectator/test_wrapper.cr b/src/spectator/test_wrapper.cr index 761d4f4..77c097b 100644 --- a/src/spectator/test_wrapper.cr +++ b/src/spectator/test_wrapper.cr @@ -2,6 +2,8 @@ require "../spectator_test" require "./source" module Spectator + alias TestMethod = ::SpectatorTest -> + # Stores information about a end-user test. # Used to instantiate tests and run them. struct TestWrapper @@ -14,7 +16,7 @@ module Spectator # Creates a wrapper for the test. # The *builder* creates an instance of the test. # The *runner* takes the test created by *builder* and runs it. - def initialize(@description, @source, @builder : -> SpectatorTest, @runner : SpectatorTest ->) + def initialize(@description, @source, @builder : -> ::SpectatorTest, @runner : TestMethod) end # Instantiates and runs the test.