diff --git a/src/spectator/events.cr b/src/spectator/events.cr index 847cc5c..86a6132 100644 --- a/src/spectator/events.cr +++ b/src/spectator/events.cr @@ -12,7 +12,7 @@ module Spectator # Three methods are defined - one to add a hook and the others to trigger the event which calls every hook. # One trigger method, prefixed with *call_* will always call the event hooks. # The other trigger method, prefixed with *call_once_* will only call the event hooks on the first invocation. - private macro group_event(name) + private macro group_event(name, &block) @{{name.id}}_hooks = Deque(->).new @{{name.id}}_called = Atomic::Flag.new @@ -25,7 +25,8 @@ module Spectator # Signals that the *{{name.id}}* event has occurred. # All hooks associated with the event will be called. def call_{{name.id}} : Nil - @{{name.id}}_hooks.each(&.call) + {{block.args.first}} = @{{name.id}}_hooks + {{yield}} end # Signals that the *{{name.id}}* event has occurred. @@ -45,7 +46,7 @@ module Spectator # This must be unique across all events. # Three methods are defined - two to add a hook and the other to trigger the event which calls every hook. # A hook can be added with an `ExampleContextDelegate` or a block that accepts an example (no context). - private macro example_event(name) + private macro example_event(name, &block) @{{name.id}}_hooks = Deque(Example ->).new # Defines a hook for the *{{name.id}}* event. @@ -58,8 +59,9 @@ module Spectator # Signals that the *{{name.id}}* event has occurred. # All hooks associated with the event will be called. # The *example* should be the current example. - def call_{{name.id}}(example) : Nil - @{{name.id}}_hooks.each(&.call(example)) + def call_{{name.id}}({{block.args[1]}}) : Nil + {{block.args.first}} = @{{name.id}}_hooks + {{yield}} end end end diff --git a/src/spectator/example_group.cr b/src/spectator/example_group.cr index cd5bb71..0f64801 100644 --- a/src/spectator/example_group.cr +++ b/src/spectator/example_group.cr @@ -8,10 +8,45 @@ module Spectator include Events include Iterable(ExampleNode) - group_event before_all - group_event after_all - example_event before_each - example_event after_each + group_event before_all do |hooks| + Log.trace { "Processing before_all hooks" } + + if (parent = group?) + parent.call_once_before_all + end + + hooks.each(&.call) + end + + group_event after_all do |hooks| + Log.trace { "Processing after_all hooks" } + + hooks.each(&.call) + + if (parent = group?) + parent.call_once_after_all + end + end + + example_event before_each do |hooks, example| + Log.trace { "Processing before_each hooks" } + + if (parent = group?) + parent.call_before_each(example) + end + + hooks.each(&.call(example)) + end + + example_event after_each do |hooks, example| + Log.trace { "Processing after_each hooks" } + + hooks.each(&.call(example)) + + if (parent = group?) + parent.call_after_each(example) + end + end @nodes = [] of ExampleNode