lib-opal/opal/rspec/async/hooks.rb
# await: *await*
require 'rspec/core/hooks'
module RSpec
module Core
module Hooks
class HookCollections
def run_example_hooks_for_await(example, position, each_method)
# WAS:
# owner_parent_groups.__send__(each_method) do |group|
# group.hooks.run_owned_hooks_for(position, :example, example)
# end
case each_method
when :each
groups = owner_parent_groups
when :reverse_each
groups = owner_parent_groups.reverse
else
raise "Unsupported each_method: #{each_method}"
end
groups.each_await do |group|
group.hooks.run_owned_hooks_for_await(position, :example, example)
end
end
def run_owned_hooks_for_await(position, scope, example_or_group)
# WAS:
# matching_hooks_for(position, scope, example_or_group).each do |hook|
# hook.run(example_or_group)
# end
matching_hooks_for(position, scope, example_or_group).each_await do |hook|
hook.run_await(example_or_group)
end
end
def run_await(position, scope, example_or_group)
return if RSpec.configuration.dry_run?
if scope == :context
unless example_or_group.class.metadata[:skip]
run_owned_hooks_for_await(position, :context, example_or_group)
end
else
case position
when :before then run_example_hooks_for_await(example_or_group, :before, :reverse_each)
when :after then run_example_hooks_for_await(example_or_group, :after, :each)
when :around then run_around_example_hooks_for_await(example_or_group) { yield.await }
end
end
end
def run_around_example_hooks_for_await(example)
hooks = FlatMap.flat_map(owner_parent_groups) do |group|
group.hooks.matching_hooks_for(:around, :example, example)
end
return yield if hooks.empty? # exit early to avoid the extra allocation cost of `Example::Procsy`
initial_procsy = Example::Procsy.new(example) { yield.await }
hooks.inject(initial_procsy) do |procsy, around_hook|
procsy.wrap { around_hook.execute_with_await(example, procsy) }
end.call.await
end
end
class BeforeHook < Hook
def run_await(example)
example.instance_exec_await(example, &block)
end
end
# @private
class AfterHook < Hook
def run_await(example)
example.instance_exec_await(example, &block)
rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex
example.set_exception(ex)
end
end
# @private
class AfterContextHook < Hook
def run_await(example)
example.instance_exec_await(example, &block)
rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e
RSpec.configuration.reporter.notify_non_example_exception(e, "An error occurred in an `after(:context)` hook.")
end
end
class AroundHook < Hook
def execute_with_await(example, procsy)
example.instance_exec_await(procsy, &block)
return if procsy.executed?
Pending.mark_skipped!(example,
"#{hook_description} did not execute the example")
end
end
end
end
end