class RSpec::Core::Hooks::HookCollections

Experimental RBS support (using type sampling data from the type_fusion project).

# sig/rspec/core/hooks.rbs

class RSpec::Core::Hooks::HookCollections
  def all_hooks_for: (Symbol position, Symbol scope) -> untyped
  def hooks_for: (Symbol position, Symbol scope) -> nil
  def matching_hooks_for: (Symbol position, Symbol scope, RSpec::Core::Example example_or_group) -> untyped
  def owner_parent_groups: () -> untyped
  def owner_parent_groups: () -> untyped
  def process: ((Class | RSpec::Core::Example) host, Array[Class] parent_groups, RSpec::Core::Hooks::HookCollections globals, Symbol position, Symbol scope) -> nil
  def processable_hooks_for: (Symbol position, Symbol scope, (Class | RSpec::Core::Example) host) -> untyped
  def run_example_hooks_for: (RSpec::Core::Example example, Symbol position, Symbol each_method) -> untyped
  def run_owned_hooks_for: (Symbol position, Symbol scope, RSpec::Core::Example example_or_group) -> untyped
end

asking this class for a list of hooks, and then doing something with them.
API, so that callers tell this class what to do with the hooks, rather than
This is only possible because this interface provides a “tell, don’t ask”-style
case of a group having no hooks.
a hook is added. This allows us to avoid many object allocations for the common
this, so that, for example, hook collection objects are only instantiated when
implementation details behind this facade, it’s allowed us to heavily optimize
This provides the primary API used by other parts of rspec-core. By hiding all
@private

def all_hooks_for(position, scope)

Experimental RBS support (using type sampling data from the type_fusion project).

def all_hooks_for: (Symbol position, Symbol scope) -> untyped

This signature was generated using 1 sample from 1 application.

def all_hooks_for(position, scope)
  hooks_for(position, scope) { return EMPTY_HOOK_ARRAY }.items_and_filters.map(&:first)
end

def ensure_hooks_initialized_for(position, scope)

def ensure_hooks_initialized_for(position, scope)
  if position == :before
    if scope == :example
      @before_example_hooks ||= @filterable_item_repo_class.new(:all?)
    else
      @before_context_hooks ||= @filterable_item_repo_class.new(:all?)
    end
  elsif position == :after
    if scope == :example
      @after_example_hooks ||= @filterable_item_repo_class.new(:all?)
    else
      @after_context_hooks ||= @filterable_item_repo_class.new(:all?)
    end
  else # around
    @around_example_hooks ||= @filterable_item_repo_class.new(:all?)
  end
end

def extract_scope_from(args)

def extract_scope_from(args)
  if known_scope?(args.first)
    normalized_scope_for(args.shift)
  elsif args.any? { |a| a.is_a?(Symbol) }
    error_message = "You must explicitly give a scope " \
      "(#{SCOPES.join(", ")}) or scope alias " \
      "(#{SCOPE_ALIASES.keys.join(", ")}) when using symbols as " \
      "metadata for a hook."
    raise ArgumentError.new error_message
  else
    :example
  end
end

def hooks_for(position, scope)

Experimental RBS support (using type sampling data from the type_fusion project).

def hooks_for: (Symbol position, Symbol scope) -> nil

This signature was generated using 5 samples from 1 application.

def hooks_for(position, scope)
  if position == :before
    scope == :example ? @before_example_hooks : @before_context_hooks
  elsif position == :after
    scope == :example ? @after_example_hooks : @after_context_hooks
  else # around
    @around_example_hooks
  end || yield
end

def initialize(owner, filterable_item_repo_class)

def initialize(owner, filterable_item_repo_class)
  @owner                      = owner
  @filterable_item_repo_class = filterable_item_repo_class
  @before_example_hooks       = nil
  @after_example_hooks        = nil
  @before_context_hooks       = nil
  @after_context_hooks        = nil
  @around_example_hooks       = nil
end

def known_scope?(scope)

def known_scope?(scope)
  SCOPES.include?(scope) || SCOPE_ALIASES.keys.include?(scope)
end

def matching_hooks_for(position, scope, example_or_group)

Experimental RBS support (using type sampling data from the type_fusion project).

def matching_hooks_for: (Symbol position, Symbol scope, RSpec::Core::Example example_or_group) -> untyped

This signature was generated using 3 samples from 1 application.

def matching_hooks_for(position, scope, example_or_group)
  repository = hooks_for(position, scope) { return EMPTY_HOOK_ARRAY }
  # It would be nice to not have to switch on type here, but
  # we don't want to define `ExampleGroup#metadata` because then
  # `metadata` from within an individual example would return the
  # group's metadata but the user would probably expect it to be
  # the example's metadata.
  metadata = case example_or_group
             when ExampleGroup then example_or_group.class.metadata
             else example_or_group.metadata
             end
  repository.items_for(metadata)
end

def normalized_scope_for(scope)

def normalized_scope_for(scope)
  SCOPE_ALIASES[scope] || scope
end

def owner_parent_groups

Experimental RBS support (using type sampling data from the type_fusion project).

def owner_parent_groups: () -> untyped

This signature was generated using 1 sample from 1 application.

def owner_parent_groups
  @owner.parent_groups
end

def owner_parent_groups

Experimental RBS support (using type sampling data from the type_fusion project).

def owner_parent_groups: () -> untyped

This signature was generated using 1 sample from 1 application.

:nocov:
Ruby < 2.1 (see https://bugs.ruby-lang.org/issues/8035)
def owner_parent_groups
  @owner_parent_groups ||= [@owner] + @owner.parent_groups
end

def process(host, parent_groups, globals, position, scope)

Experimental RBS support (using type sampling data from the type_fusion project).

def process: ((Class | RSpec::Core::Example) host, Class | Class parent_groups, RSpec::Core::Hooks::HookCollections globals, Symbol position, Symbol scope) -> nil

This signature was generated using 4 samples from 1 application.

def process(host, parent_groups, globals, position, scope)
  hooks_to_process = globals.processable_hooks_for(position, scope, host)
  return if hooks_to_process.empty?
  hooks_to_process -= FlatMap.flat_map(parent_groups) do |group|
    group.hooks.all_hooks_for(position, scope)
  end
  return if hooks_to_process.empty?
  repository = ensure_hooks_initialized_for(position, scope)
  hooks_to_process.each { |hook| repository.append hook, (yield hook) }
end

def processable_hooks_for(position, scope, host)

Experimental RBS support (using type sampling data from the type_fusion project).

def processable_hooks_for: (Symbol position, Symbol scope, (Class | RSpec::Core::Example) host) -> untyped

This signature was generated using 3 samples from 1 application.

def processable_hooks_for(position, scope, host)
  if scope == :example
    all_hooks_for(position, scope)
  else
    matching_hooks_for(position, scope, host)
  end
end

def register(prepend_or_append, position, *args, &block)

def register(prepend_or_append, position, *args, &block)
  scope, options = scope_and_options_from(*args)
  if scope == :suite
    # TODO: consider making this an error in RSpec 4. For SemVer reasons,
    # we are only warning in RSpec 3.
    RSpec.warn_with "WARNING: `#{position}(:suite)` hooks are only supported on " \
                    "the RSpec configuration object. This " \
                    "`#{position}(:suite)` hook, registered on an example " \
                    "group, will be ignored."
    return
  elsif scope == :context && position == :around
    # TODO: consider making this an error in RSpec 4. For SemVer reasons,
    # we are only warning in RSpec 3.
    RSpec.warn_with "WARNING: `around(:context)` hooks are not supported and " \
                    "behave like `around(:example)."
  end
  hook = HOOK_TYPES[position][scope].new(block, options)
  ensure_hooks_initialized_for(position, scope).__send__(prepend_or_append, hook, options)
end

def register_global_singleton_context_hooks(example, globals)

def register_global_singleton_context_hooks(example, globals)
  parent_groups = example.example_group.parent_groups
  process(example, parent_groups, globals, :before, :context) { {} }
  process(example, parent_groups, globals, :after,  :context) { {} }
end

def register_globals(host, globals)

def register_globals(host, globals)
  parent_groups = host.parent_groups
  process(host, parent_groups, globals, :before, :example, &:options)
  process(host, parent_groups, globals, :after,  :example, &:options)
  process(host, parent_groups, globals, :around, :example, &:options)
  process(host, parent_groups, globals, :before, :context, &:options)
  process(host, parent_groups, globals, :after,  :context, &:options)
end

def run(position, scope, example_or_group)

Other tags:
    Private: -
def run(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(position, :context, example_or_group)
    end
  else
    case position
    when :before then run_example_hooks_for(example_or_group, :before, :reverse_each)
    when :after  then run_example_hooks_for(example_or_group, :after,  :each)
    when :around then run_around_example_hooks_for(example_or_group) { yield }
    end
  end
end

def run_around_example_hooks_for(example)

def run_around_example_hooks_for(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 }
  hooks.inject(initial_procsy) do |procsy, around_hook|
    procsy.wrap { around_hook.execute_with(example, procsy) }
  end.call
end

def run_example_hooks_for(example, position, each_method)

Experimental RBS support (using type sampling data from the type_fusion project).

def run_example_hooks_for: (RSpec::Core::Example example, Symbol position, Symbol each_method) -> untyped

This signature was generated using 1 sample from 1 application.

def run_example_hooks_for(example, position, each_method)
  owner_parent_groups.__send__(each_method) do |group|
    group.hooks.run_owned_hooks_for(position, :example, example)
  end
end

def run_owned_hooks_for(position, scope, example_or_group)

Experimental RBS support (using type sampling data from the type_fusion project).

def run_owned_hooks_for: (Symbol position, Symbol scope, RSpec::Core::Example example_or_group) -> untyped

This signature was generated using 2 samples from 1 application.

def run_owned_hooks_for(position, scope, example_or_group)
  matching_hooks_for(position, scope, example_or_group).each do |hook|
    hook.run(example_or_group)
  end
end

def scope_and_options_from(*args)

def scope_and_options_from(*args)
  return :suite if args.first == :suite
  scope = extract_scope_from(args)
  meta  = Metadata.build_hash_from(args, :warn_about_example_group_filtering)
  return scope, meta
end