From 605b82c5323a7114181e41b0585c399ec54d36d5 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Sun, 8 Aug 2021 10:51:39 -0600 Subject: [PATCH] Add prepend and append variants of hooks to DSL --- src/spectator/dsl/builder.cr | 42 +++++++++++++++++++++++++++++++ src/spectator/dsl/hooks.cr | 47 +++++++++++++++++++++++++++++++++++ src/spectator/spec_builder.cr | 12 ++++++++- 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/spectator/dsl/builder.cr b/src/spectator/dsl/builder.cr index 16b1116..ddd659e 100644 --- a/src/spectator/dsl/builder.cr +++ b/src/spectator/dsl/builder.cr @@ -60,42 +60,84 @@ module Spectator::DSL @@builder.before_suite(hook) end + # Defines a block of code to execute before any and all examples in the test suite. + def prepend_before_suite(location = nil, label = "before_suite", &block) + hook = ExampleGroupHook.new(location: location, label: label, &block) + @@builder.prepend_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) @@builder.before_all(hook) end + # Defines a block of code to execute before any and all examples in the current group. + def prepend_before_all(location = nil, label = "before_all", &block) + hook = ExampleGroupHook.new(location: location, label: label, &block) + @@builder.prepend_before_all(hook) + end + # Defines a block of code to execute before every example in the current group def before_each(location = nil, label = "before_each", &block : Example -> _) hook = ExampleHook.new(location: location, label: label, &block) @@builder.before_each(hook) end + # Defines a block of code to execute before every example in the current group + def prepend_before_each(location = nil, label = "before_each", &block : Example -> _) + hook = ExampleHook.new(location: location, label: label, &block) + @@builder.prepend_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 test suite. + def append_after_suite(location = nil, label = "after_suite", &block) + hook = ExampleGroupHook.new(location: location, label: label, &block) + @@builder.append_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) @@builder.after_all(hook) end + # Defines a block of code to execute after any and all examples in the current group. + def append_after_all(location = nil, label = "after_all", &block) + hook = ExampleGroupHook.new(location: location, label: label, &block) + @@builder.append_after_all(hook) + end + # Defines a block of code to execute after every example in the current group. def after_each(location = nil, label = "after_each", &block : Example ->) hook = ExampleHook.new(location: location, label: label, &block) @@builder.after_each(hook) end + # Defines a block of code to execute after every example in the current group. + def append_after_each(location = nil, label = "after_each", &block : Example ->) + hook = ExampleHook.new(location: location, label: label, &block) + @@builder.append_after_each(hook) + end + # Defines a block of code to execute around every example in the current group. def around_each(location = nil, label = "around_each", &block : Example::Procsy ->) hook = ExampleProcsyHook.new(location: location, label: label, &block) @@builder.around_each(hook) end + # Defines a block of code to execute around every example in the current group. + def prepend_around_each(location = nil, label = "around_each", &block : Example::Procsy ->) + hook = ExampleProcsyHook.new(location: location, label: label, &block) + @@builder.prepend_around_each(hook) + end + # Sets the configuration of the spec. # # See `Spec::Builder#config=` for usage details. diff --git a/src/spectator/dsl/hooks.cr b/src/spectator/dsl/hooks.cr index d11ff08..0cae6ee 100644 --- a/src/spectator/dsl/hooks.cr +++ b/src/spectator/dsl/hooks.cr @@ -104,31 +104,67 @@ module Spectator::DSL # 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 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. + # The hook is added before all others others of the same type in this context. + define_example_group_hook :prepend_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 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. + # The hook is added after all others others of the same type in this context. + define_example_group_hook :append_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. define_example_group_hook :before_all + # 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. + # The hook is added before all others others of the same type in this context. + define_example_group_hook :prepend_before_all + # Defines a block of code that will be invoked once after all 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. define_example_group_hook :after_all + # Defines a block of code that will be invoked once after all 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. + # The hook is added after all others others of the same type in this context. + define_example_group_hook :append_after_all + # Defines a block of code that will be invoked before every example in the group. # The block will be run in the context of the current running example. # This means that values defined by `let` and `subject` are available. define_example_hook :before_each + # Defines a block of code that will be invoked before every example in the group. + # The block will be run in the context of the current running example. + # This means that values defined by `let` and `subject` are available. + # The hook is added before all others others of the same type in this context. + define_example_hook :prepend_before_each + # Defines a block of code that will be invoked after every example in the group. # The block will be run in the context of the current running example. # This means that values defined by `let` and `subject` are available. define_example_hook :after_each + # Defines a block of code that will be invoked after every example in the group. + # The block will be run in the context of the current running example. + # This means that values defined by `let` and `subject` are available. + # The hook is added after all others others of the same type in this context. + define_example_hook :append_after_each + # Defines a block of code that will be invoked around every example in the group. # The block will be run in the context of the current running example. # This means that values defined by `let` and `subject` are available. @@ -138,5 +174,16 @@ module Spectator::DSL # The `Example::Procsy#run` method should be called to ensure the example runs. # More code can run afterwards (in the block). define_example_hook :around_each + + # Defines a block of code that will be invoked around every example in the group. + # The block will be run in the context of the current running example. + # This means that values defined by `let` and `subject` are available. + # The hook is added before all others others of the same type in this context. + # + # The block will execute before the example. + # An `Example::Procsy` is passed to the block. + # The `Example::Procsy#run` method should be called to ensure the example runs. + # More code can run afterwards (in the block). + define_example_hook :prepend_around_each end end diff --git a/src/spectator/spec_builder.cr b/src/spectator/spec_builder.cr index 4e11611..57cd57a 100644 --- a/src/spectator/spec_builder.cr +++ b/src/spectator/spec_builder.cr @@ -18,7 +18,17 @@ module Spectator class SpecBuilder Log = ::Spectator::Log.for(self) - delegate before_all, after_all, before_each, after_each, around_each, to: current + delegate before_all, + prepend_before_all, + after_all, + append_after_all, + before_each, + prepend_before_each, + after_each, + append_after_each, + around_each, + prepend_around_each, + to: current # Stack tracking the current group. # The bottom of the stack (first element) is the root group.