Expose running example to before-each and after-each hooks

This commit is contained in:
Michael Miller 2019-09-22 11:27:18 -06:00
parent 5f3c9d2f63
commit 24ccb77595
8 changed files with 51 additions and 31 deletions

View file

@ -1,19 +1,33 @@
module Spectator module Spectator
module DSL module DSL
macro before_each(&block) macro before_each(&block)
def %hook : Nil def %hook({{block.args.splat}}) : Nil
{{block.body}} {{block.body}}
end end
::Spectator::SpecBuilder.add_before_each_hook { |test| test.as({{@type.id}}).%hook } ::Spectator::SpecBuilder.add_before_each_hook do |test, example|
cast_test = test.as({{@type.id}})
{% if block.args.empty? %}
cast_test.%hook
{% else %}
cast_test.%hook(example)
{% end %}
end
end end
macro after_each(&block) macro after_each(&block)
def %hook : Nil def %hook({{block.args.splat}}) : Nil
{{block.body}} {{block.body}}
end end
::Spectator::SpecBuilder.add_after_each_hook { |test| test.as({{@type.id}}).%hook } ::Spectator::SpecBuilder.add_after_each_hook do |test, example|
cast_test = test.as({{@type.id}})
{% if block.args.empty? %}
cast_test.%hook
{% else %}
cast_test.%hook(example)
{% end %}
end
end end
macro before_all(&block) macro before_all(&block)

View file

@ -12,7 +12,7 @@ module Spectator
getter group : ExampleGroup getter group : ExampleGroup
# Retrieves the internal wrapped instance. # Retrieves the internal wrapped instance.
private getter test_wrapper : TestWrapper protected getter test_wrapper : TestWrapper
# Source where the example originated from. # Source where the example originated from.
def source def source

View file

@ -1,4 +1,6 @@
module Spectator module Spectator
alias TestMetaMethod = ::SpectatorTest, Example ->
# Collection of hooks that run at various times throughout testing. # Collection of hooks that run at various times throughout testing.
# A hook is just a `Proc` (code block) that runs at a specified time. # A hook is just a `Proc` (code block) that runs at a specified time.
class ExampleHooks class ExampleHooks
@ -7,9 +9,9 @@ module Spectator
def self.empty def self.empty
new( new(
[] of ->, [] of ->,
[] of TestMethod, [] of TestMetaMethod,
[] of ->, [] of ->,
[] of TestMethod, [] of TestMetaMethod,
[] of ::SpectatorTest, Proc(Nil) -> [] of ::SpectatorTest, Proc(Nil) ->
) )
end end
@ -17,9 +19,9 @@ module Spectator
# Creates a new set of hooks. # Creates a new set of hooks.
def initialize( def initialize(
@before_all : Array(->), @before_all : Array(->),
@before_each : Array(TestMethod), @before_each : Array(TestMetaMethod),
@after_all : Array(->), @after_all : Array(->),
@after_each : Array(TestMethod), @after_each : Array(TestMetaMethod),
@around_each : Array(::SpectatorTest, Proc(Nil) ->) @around_each : Array(::SpectatorTest, Proc(Nil) ->)
) )
end end
@ -32,9 +34,9 @@ module Spectator
# Runs all "before-each" hooks. # Runs all "before-each" hooks.
# These hooks should be run every time before each example in a group. # These hooks should be run every time before each example in a group.
def run_before_each(wrapper : TestWrapper) def run_before_each(wrapper : TestWrapper, example : Example)
@before_each.each do |hook| @before_each.each do |hook|
wrapper.call(hook) wrapper.call(hook, example)
end end
end end
@ -46,9 +48,9 @@ module Spectator
# Runs all "after-all" hooks. # Runs all "after-all" hooks.
# These hooks should be run every time after each example in a group. # These hooks should be run every time after each example in a group.
def run_after_each(wrapper : TestWrapper) def run_after_each(wrapper : TestWrapper, example : Example)
@after_each.each do |hook| @after_each.each do |hook|
wrapper.call(hook) wrapper.call(hook, example)
end end
end end

View file

@ -17,9 +17,9 @@ module Spectator
private def capture_result private def capture_result
context = group.context context = group.context
ResultCapture.new.tap do |result| ResultCapture.new.tap do |result|
context.run_before_hooks(test_wrapper) context.run_before_hooks(self)
run_example(result) run_example(result)
context.run_after_hooks(test_wrapper) context.run_after_hooks(self)
end end
end end

View file

@ -55,7 +55,7 @@ module Spectator
end end
# Adds a block of code to run before each example in the current group. # Adds a block of code to run before each example in the current group.
def add_before_each_hook(&block : TestMethod) : Nil def add_before_each_hook(&block : TestMetaMethod) : Nil
@@stack.current.add_before_each_hook(block) @@stack.current.add_before_each_hook(block)
end end
@ -65,7 +65,7 @@ module Spectator
end end
# Adds a block of code to run after each example in the current group. # Adds a block of code to run after each example in the current group.
def add_after_each_hook(&block : TestMethod) : Nil def add_after_each_hook(&block : TestMetaMethod) : Nil
@@stack.current.add_after_each_hook(block) @@stack.current.add_after_each_hook(block)
end end

View file

@ -7,8 +7,8 @@ module Spectator::SpecBuilder
private getter children = Deque(Child).new private getter children = Deque(Child).new
@before_each_hooks = Deque(TestMethod).new @before_each_hooks = Deque(TestMetaMethod).new
@after_each_hooks = Deque(TestMethod).new @after_each_hooks = Deque(TestMetaMethod).new
@before_all_hooks = Deque(->).new @before_all_hooks = Deque(->).new
@after_all_hooks = Deque(->).new @after_all_hooks = Deque(->).new
@around_each_hooks = Deque(::SpectatorTest, Proc(Nil) ->).new @around_each_hooks = Deque(::SpectatorTest, Proc(Nil) ->).new
@ -17,11 +17,11 @@ module Spectator::SpecBuilder
@children << child @children << child
end end
def add_before_each_hook(hook : TestMethod) def add_before_each_hook(hook : TestMetaMethod)
@before_each_hooks << hook @before_each_hooks << hook
end end
def add_after_each_hook(hook : TestMethod) def add_after_each_hook(hook : TestMetaMethod)
@after_each_hooks << hook @after_each_hooks << hook
end end

View file

@ -5,9 +5,9 @@ module Spectator
@after_all_hooks_run = false @after_all_hooks_run = false
end end
def run_before_hooks(wrapper : TestWrapper) def run_before_hooks(example : Example)
run_before_all_hooks run_before_all_hooks
run_before_each_hooks(wrapper) run_before_each_hooks(example)
end end
protected def run_before_all_hooks protected def run_before_all_hooks
@ -19,13 +19,13 @@ module Spectator
@before_all_hooks_run = true @before_all_hooks_run = true
end end
protected def run_before_each_hooks(wrapper : TestWrapper) protected def run_before_each_hooks(example : Example)
@parent.try &.run_before_each_hooks(wrapper) @parent.try &.run_before_each_hooks(example)
@hooks.run_before_each(wrapper) @hooks.run_before_each(example.test_wrapper, example)
end end
def run_after_hooks(wrapper : TestWrapper) def run_after_hooks(example : Example)
run_after_each_hooks(wrapper) run_after_each_hooks(example)
run_after_all_hooks run_after_all_hooks
end end
@ -38,9 +38,9 @@ module Spectator
@after_all_hooks_run = true @after_all_hooks_run = true
end end
protected def run_after_each_hooks(wrapper : TestWrapper) protected def run_after_each_hooks(example : Example)
@hooks.run_after_each(wrapper) @hooks.run_after_each(example.test_wrapper, example)
@parent.try &.run_after_each_hooks(wrapper) @parent.try &.run_after_each_hooks(example)
end end
def wrap_around_each_hooks(test, &block : ->) def wrap_around_each_hooks(test, &block : ->)

View file

@ -25,6 +25,10 @@ module Spectator
method.call(@test) method.call(@test)
end end
def call(method, *args) : Nil
method.call(@test, *args)
end
def around_hook(context : TestContext) def around_hook(context : TestContext)
context.wrap_around_each_hooks(@test) { run } context.wrap_around_each_hooks(@test) { run }
end end