diff --git a/CHANGELOG.md b/CHANGELOG.md index 0755b5e..828b451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Examples can be skipped by using a `:pending` tag. A reason method can be specified: `pending: "Some excuse"` - Examples can be skipped during execution by using `skip` or `pending` in the example block. - Sample blocks can be temporarily skipped by using `xsample` or `xrandom_sample`. +- Add `before_suite` and `after_suite` hooks. ### Changed - Simplify and reduce defined types and generics. Should speed up compilation times. diff --git a/src/spectator/dsl/builder.cr b/src/spectator/dsl/builder.cr index e0b724d..16b1116 100644 --- a/src/spectator/dsl/builder.cr +++ b/src/spectator/dsl/builder.cr @@ -54,6 +54,12 @@ module Spectator::DSL @@builder.add_pending_example(*args) end + # Defines a block of code to execute before any and all examples in the test suite. + def before_suite(location = nil, label = "before_suite", &block) + hook = ExampleGroupHook.new(location: location, label: label, &block) + @@builder.before_suite(hook) + end + # Defines a block of code to execute before any and all examples in the current group. def before_all(location = nil, label = "before_all", &block) hook = ExampleGroupHook.new(location: location, label: label, &block) @@ -66,6 +72,12 @@ module Spectator::DSL @@builder.before_each(hook) end + # Defines a block of code to execute after any and all examples in the test suite. + def after_suite(location = nil, label = "after_suite", &block) + hook = ExampleGroupHook.new(location: location, label: label, &block) + @@builder.after_suite(hook) + end + # Defines a block of code to execute after any and all examples in the current group. def after_all(location = nil, label = "after_all", &block) hook = ExampleGroupHook.new(location: location, label: label, &block) diff --git a/src/spectator/dsl/hooks.cr b/src/spectator/dsl/hooks.cr index 61fa15f..1e990fd 100644 --- a/src/spectator/dsl/hooks.cr +++ b/src/spectator/dsl/hooks.cr @@ -47,6 +47,16 @@ module Spectator::DSL end end + # Defines a block of code that will be invoked once before any examples in the suite. + # The block will not run in the context of the current running example. + # This means that values defined by `let` and `subject` are not available. + define_example_group_hook :before_suite + + # Defines a block of code that will be invoked once after all examples in the suite. + # The block will not run in the context of the current running example. + # This means that values defined by `let` and `subject` are not available. + define_example_group_hook :after_suite + # Defines a block of code that will be invoked once before any examples in the group. # The block will not run in the context of the current running example. # This means that values defined by `let` and `subject` are not available. diff --git a/src/spectator/spec_builder.cr b/src/spectator/spec_builder.cr index 1e03c79..579d922 100644 --- a/src/spectator/spec_builder.cr +++ b/src/spectator/spec_builder.cr @@ -135,6 +135,18 @@ module Spectator current << PendingExampleBuilder.new(name, location, metadata, reason) end + # Attaches a hook to be invoked before any and all examples in the test suite. + def before_suite(hook) + Log.trace { "Add before_suite hook #{hook}" } + root.add_before_all_hook(hook) + end + + # Defines a block of code to execute before any and all examples in the test suite. + def before_suite(&block) + Log.trace { "Add before_suite hook" } + root.before_all(&block) + end + # Attaches a hook to be invoked before any and all examples in the current group. def before_all(hook) Log.trace { "Add before_all hook #{hook}" } @@ -161,6 +173,18 @@ module Spectator current.before_each(&block) end + # Attaches a hook to be invoked after any and all examples in the test suite. + def after_suite(hook) + Log.trace { "Add after_suite hook #{hook}" } + root.add_after_all_hook(hook) + end + + # Defines a block of code to execute after any and all examples in the test suite. + def after_suite(&block) + Log.trace { "Add after_suite hook" } + root.after_all(&block) + end + # Attaches a hook to be invoked after any and all examples in the current group. def after_all(hook) Log.trace { "Add after_all hook #{hook}" }