Specify contents of event trigger method with macro block

Implement calling parent group hooks.
This commit is contained in:
Michael Miller 2020-11-15 11:22:52 -07:00
parent 0279606a1c
commit 2f4cbd9c33
No known key found for this signature in database
GPG key ID: FB9F12F7C646A4AD
2 changed files with 46 additions and 9 deletions

View file

@ -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

View file

@ -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