diff --git a/src/spectator.cr b/src/spectator.cr index 1bf9099..6540dae 100644 --- a/src/spectator.cr +++ b/src/spectator.cr @@ -13,6 +13,6 @@ module Spectator end at_exit do - Runner.new(Context::ROOT).run + Runner.new(ExampleGroup::ROOT).run end end diff --git a/src/spectator/context.cr b/src/spectator/context.cr deleted file mode 100644 index 2863c75..0000000 --- a/src/spectator/context.cr +++ /dev/null @@ -1,97 +0,0 @@ -require "./example" - -module Spectator - class Context - ROOT = Context.new("ROOT") - - getter what : String - getter parent : Context? - getter examples = [] of Example - getter contexts = [] of Context - getter before_all_hooks = [] of -> - getter before_each_hooks = [] of -> - getter after_all_hooks = [] of -> - getter after_each_hooks = [] of -> - getter around_each_hooks = [] of Proc(Nil) -> - - @before_all_hooks_run = false - @after_all_hooks_run = false - - def initialize(@what, @parent = nil) - if (parent = @parent) - parent.contexts << self - end - end - - def all_examples - add_examples - end - - def run_before_all_hooks - if (parent = @parent) - parent.run_before_all_hooks - end - unless @before_all_hooks_run - @before_all_hooks.each do |hook| - hook.call - end - @before_all_hooks_run = true - end - end - - def run_before_each_hooks - if (parent = @parent) - parent.run_before_each_hooks - end - @before_each_hooks.each do |hook| - hook.call - end - end - - def run_after_all_hooks - unless @after_all_hooks_run - if all_examples.all?(&.finished?) - @after_all_hooks.each do |hook| - hook.call - end - @after_all_hooks_run = true - end - end - if (parent = @parent) - parent.run_after_all_hooks - end - end - - def run_after_each_hooks - @after_each_hooks.each do |hook| - hook.call - end - if (parent = @parent) - parent.run_after_each_hooks - end - end - - def wrap_around_each_hooks(&block : ->) - wrapper = block - @around_each_hooks.reverse_each do |hook| - wrapper = wrap_proc(hook, wrapper) - end - if (parent = @parent) - wrapper = parent.wrap_around_each_hooks(&wrapper) - end - wrapper - end - - private def wrap_proc(inner : Proc(Nil) ->, wrapper : ->) - -> { inner.call(wrapper) } - end - - protected def add_examples(array = [] of Example) - array.concat(@examples) - contexts.each do |context| - context.add_examples(array) - end - array - end - end -end diff --git a/src/spectator/context_definitions.cr b/src/spectator/context_definitions.cr index 9a3ddac..3382d4d 100644 --- a/src/spectator/context_definitions.cr +++ b/src/spectator/context_definitions.cr @@ -1,7 +1,7 @@ module Spectator module ContextDefinitions ALL = {} of Path => Object - MAPPING = {} of String => Context + MAPPING = {} of String => ExampleGroup SPECIAL_CHARS = { '~' => "Tilde", diff --git a/src/spectator/dsl.cr b/src/spectator/dsl.cr index 840c707..be8694b 100644 --- a/src/spectator/dsl.cr +++ b/src/spectator/dsl.cr @@ -24,7 +24,7 @@ module Spectator %} ::Spectator::ContextDefinitions::MAPPING[{{absolute_module_name.stringify}}] = - Context.new({{what_arg}}, ::Spectator::ContextDefinitions::MAPPING[{{parent_module.stringify}}]) + ExampleGroup.new({{what_arg}}, ::Spectator::ContextDefinitions::MAPPING[{{parent_module.stringify}}]) module {{module_name.id}} include {{parent_module}} diff --git a/src/spectator/example.cr b/src/spectator/example.cr index 07f37eb..b9fa017 100644 --- a/src/spectator/example.cr +++ b/src/spectator/example.cr @@ -2,10 +2,10 @@ require "./source" module Spectator abstract class Example - getter context : Context + getter group : ExampleGroup getter? finished = false - def initialize(@context) + def initialize(@group) end abstract def run : ExampleResult diff --git a/src/spectator/example_group.cr b/src/spectator/example_group.cr index bbccd4b..54a241a 100644 --- a/src/spectator/example_group.cr +++ b/src/spectator/example_group.cr @@ -2,9 +2,96 @@ require "./example" module Spectator class ExampleGroup - protected getter examples : Array(Example) + ROOT = ExampleGroup.new("ROOT") - def initialize(@examples) + getter what : String + getter parent : ExampleGroup? + getter examples = [] of Example + getter groups = [] of ExampleGroup + getter before_all_hooks = [] of -> + getter before_each_hooks = [] of -> + getter after_all_hooks = [] of -> + getter after_each_hooks = [] of -> + getter around_each_hooks = [] of Proc(Nil) -> + + @before_all_hooks_run = false + @after_all_hooks_run = false + + def initialize(@what, @parent = nil) + if (parent = @parent) + parent.groups << self + end + end + + def all_examples + add_examples + end + + def run_before_all_hooks + if (parent = @parent) + parent.run_before_all_hooks + end + unless @before_all_hooks_run + @before_all_hooks.each do |hook| + hook.call + end + @before_all_hooks_run = true + end + end + + def run_before_each_hooks + if (parent = @parent) + parent.run_before_each_hooks + end + @before_each_hooks.each do |hook| + hook.call + end + end + + def run_after_all_hooks + unless @after_all_hooks_run + if all_examples.all?(&.finished?) + @after_all_hooks.each do |hook| + hook.call + end + @after_all_hooks_run = true + end + end + if (parent = @parent) + parent.run_after_all_hooks + end + end + + def run_after_each_hooks + @after_each_hooks.each do |hook| + hook.call + end + if (parent = @parent) + parent.run_after_each_hooks + end + end + + def wrap_around_each_hooks(&block : ->) + wrapper = block + @around_each_hooks.reverse_each do |hook| + wrapper = wrap_proc(hook, wrapper) + end + if (parent = @parent) + wrapper = parent.wrap_around_each_hooks(&wrapper) + end + wrapper + end + + private def wrap_proc(inner : Proc(Nil) ->, wrapper : ->) + -> { inner.call(wrapper) } + end + + protected def add_examples(array = [] of Example) + array.concat(@examples) + groups.each do |group| + group.add_examples(array) + end + array end end end diff --git a/src/spectator/examples.cr b/src/spectator/examples.cr index 85cfe0e..5c79985 100644 --- a/src/spectator/examples.cr +++ b/src/spectator/examples.cr @@ -9,6 +9,6 @@ module Spectator parent: nil, given: [] of Object } %} - ::Spectator::ContextDefinitions::MAPPING[{{@type.stringify}}] = ::Spectator::Context::ROOT + ::Spectator::ContextDefinitions::MAPPING[{{@type.stringify}}] = ::Spectator::ExampleGroup::ROOT end end diff --git a/src/spectator/runnable_example.cr b/src/spectator/runnable_example.cr index 9b7baae..4b838e6 100644 --- a/src/spectator/runnable_example.cr +++ b/src/spectator/runnable_example.cr @@ -5,20 +5,20 @@ module Spectator def run result = ResultCapture.new - context.run_before_all_hooks - context.run_before_each_hooks + group.run_before_all_hooks + group.run_before_each_hooks begin wrapped_capture_result(result).call ensure @finished = true - context.run_after_each_hooks - context.run_after_all_hooks + group.run_after_each_hooks + group.run_after_all_hooks end translate_result(result) end private def wrapped_capture_result(result) - context.wrap_around_each_hooks do + group.wrap_around_each_hooks do capture_result(result) end end diff --git a/src/spectator/runner.cr b/src/spectator/runner.cr index ece79f2..913a405 100644 --- a/src/spectator/runner.cr +++ b/src/spectator/runner.cr @@ -3,7 +3,7 @@ require "./successful_example_result" module Spectator class Runner - def initialize(@context : Context, + def initialize(@group : ExampleGroup, @reporter : Reporters::Reporter = Reporters::StandardReporter.new) end @@ -11,7 +11,7 @@ module Spectator results = [] of ExampleResult elapsed = Time.measure do @reporter.start_suite - results = @context.all_examples.map do |example| + results = @group.all_examples.map do |example| @reporter.start_example(example) example.run.tap do |result| @reporter.end_example(result)