class RSpec::Core::ExampleGroup

your examples defined in {MemoizedHelpers} and {Pending}.
{SharedExampleGroup}. There are additional instance methods available to
defined in {Hooks}, {MemoizedHelpers::ClassMethods} and
Besides the class methods defined here, there are other interesting macros
subclass to which they belong.
evaluated in the context of an instance of the specific ExampleGroup
in the context of a new subclass of ExampleGroup. Individual examples are
Example group bodies (e.g. ‘describe` or `context` blocks) are evaluated
is declared.
which serves as a wrapper for an instance of the ExampleGroup in which it
The object returned by `it “does something”` is an instance of Example,
The object returned by `describe Thing` is a subclass of ExampleGroup.
end
end
it “does something” do
RSpec.describe Thing do
rspec-core. Consider this example:
ExampleGroup and {Example} are the main structural elements of

def self.add_example(example)

Adds an example to the example group
def self.add_example(example)
  reset_memoized
  examples << example
end

def self.before_context_ivars

Other tags:
    Private: -
def self.before_context_ivars
  @before_context_ivars ||= {}
end

def self.children

Other tags:
    Private: -
def self.children
  @children ||= []
end

def self.currently_executing_a_context_hook?

hook is currently executing.
Returns true if a `before(:context)` or `after(:context)`
def self.currently_executing_a_context_hook?
  @currently_executing_a_context_hook
end

def self.declaration_locations

Other tags:
    Private: -
def self.declaration_locations
  @declaration_locations ||= [Metadata.location_tuple_from(metadata)] +
    examples.map { |e| Metadata.location_tuple_from(e.metadata) } +
    FlatMap.flat_map(children, &:declaration_locations)
end

def self.define_example_group_method(name, metadata={})

Other tags:
    See: DSL#describe -

Parameters:
  • example_group_definition (Block) -- The definition of the example group.
  • metadata (Array, Hash) -- Metadata for the group.
  • doc_string (String) -- The group's doc string.
  • example_group_definition (Block) -- The definition of the example group.

Overloads:
  • $1(doc_string, *metadata, &example_implementation)
  • $1(&example_group_definition)
  • $1

Other tags:
    Private: -
def self.define_example_group_method(name, metadata={})
  idempotently_define_singleton_method(name) do |*args, &example_group_block|
    thread_data = RSpec::Support.thread_local_data
    top_level   = self == ExampleGroup
    registration_collection =
      if top_level
        if thread_data[:in_example_group]
          raise "Creating an isolated context from within a context is " \
                "not allowed. Change `RSpec.#{name}` to `#{name}` or " \
                "move this to a top-level scope."
        end
        thread_data[:in_example_group] = true
        RSpec.world.example_groups
      else
        children
      end
    begin
      description = args.shift
      combined_metadata = metadata.dup
      combined_metadata.merge!(args.pop) if args.last.is_a? Hash
      args << combined_metadata
      subclass(self, description, args, registration_collection, &example_group_block)
    ensure
      thread_data.delete(:in_example_group) if top_level
    end
  end
  RSpec::Core::DSL.expose_example_group_alias(name)
end

def self.define_example_method(name, extra_options={})

Other tags:
    Yield: - the example object

Parameters:
  • example_implementation (Block) -- The implementation of the example.
  • metadata (Array, Hash) -- Metadata for the example.
  • doc_string (String) -- The example's doc string.
  • metadata (Array, Hash) -- Metadata for the example.
  • doc_string (String) -- The example's doc string.
  • example_implementation (Block) -- The implementation of the example.

Overloads:
  • $1(doc_string, *metadata, &example_implementation)
  • $1(doc_string, *metadata)
  • $1(&example_implementation)
  • $1

Other tags:
    Private: -
def self.define_example_method(name, extra_options={})
  idempotently_define_singleton_method(name) do |*all_args, &block|
    desc, *args = *all_args
    options = Metadata.build_hash_from(args)
    options.update(:skip => RSpec::Core::Pending::NOT_YET_IMPLEMENTED) unless block
    options.update(extra_options)
    RSpec::Core::Example.new(self, desc, options, block)
  end
end

def self.define_nested_shared_group_method(new_name, report_label="it should behave like")

Other tags:
    See: SharedExampleGroup -

Other tags:
    Private: -
def self.define_nested_shared_group_method(new_name, report_label="it should behave like")
  idempotently_define_singleton_method(new_name) do |name, *args, &customization_block|
    # Pass :caller so the :location metadata is set properly.
    # Otherwise, it'll be set to the next line because that's
    # the block's source_location.
    group = example_group("#{report_label} #{name}", :caller => (the_caller = caller)) do
      find_and_eval_shared("examples", name, the_caller.first, *args, &customization_block)
    end
    group.metadata[:shared_group_name] = name
    group
  end
end

def self.delegate_to_metadata(*names)

Other tags:
    Private: -
def self.delegate_to_metadata(*names)
  names.each do |name|
    idempotently_define_singleton_method(name) { metadata.fetch(name) }
  end
end

def self.descendant_filtered_examples

Other tags:
    Private: -
def self.descendant_filtered_examples
  @descendant_filtered_examples ||= filtered_examples +
    FlatMap.flat_map(children, &:descendant_filtered_examples)
end

def self.descendants

Other tags:
    Private: -
def self.descendants
  @_descendants ||= [self] + FlatMap.flat_map(children, &:descendants)
end

def self.description

Returns:
  • (String) - the current example group description
def self.description
  description = metadata[:description]
  RSpec.configuration.format_docstrings_block.call(description)
end

def self.each_instance_variable_for_example(group)

Other tags:
    Private: -
def self.each_instance_variable_for_example(group)
  group.instance_variables.each do |ivar|
    yield ivar unless ivar == INSTANCE_VARIABLE_TO_IGNORE
  end
end

def self.ensure_example_groups_are_configured

Other tags:
    Private: -
def self.ensure_example_groups_are_configured
  unless defined?(@@example_groups_configured)
    RSpec.configuration.configure_mock_framework
    RSpec.configuration.configure_expectation_framework
    # rubocop:disable Style/ClassVars
    @@example_groups_configured = true
    # rubocop:enable Style/ClassVars
  end
end

def self.examples

Other tags:
    Private: -
def self.examples
  @examples ||= []
end

def self.filtered_examples

Other tags:
    Private: -
def self.filtered_examples
  RSpec.world.filtered_examples[self]
end

def self.find_and_eval_shared(label, name, inclusion_location, *args, &customization_block)

Other tags:
    Private: -
def self.find_and_eval_shared(label, name, inclusion_location, *args, &customization_block)
  shared_module = RSpec.world.shared_example_group_registry.find(parent_groups, name)
  unless shared_module
    raise ArgumentError, "Could not find shared #{label} #{name.inspect}"
  end
  shared_module.include_in(
    self, Metadata.relative_path(inclusion_location),
    args, customization_block
  )
end

def self.for_filtered_examples(reporter, &block)

Other tags:
    Private: -
def self.for_filtered_examples(reporter, &block)
  filtered_examples.each(&block)
  children.each do |child|
    reporter.example_group_started(child)
    child.for_filtered_examples(reporter, &block)
    reporter.example_group_finished(child)
  end
  false
end

def self.id

Returns:
  • (String) - the unique id of this example group. Pass
def self.id
  Metadata.id_from(metadata)
end

def self.idempotently_define_singleton_method(name, &definition)

Other tags:
    Private: -
def self.idempotently_define_singleton_method(name, &definition)
  (class << self; self; end).module_exec do
    remove_method(name) if method_defined?(name) && instance_method(name).owner == self
    define_method(name, &definition)
  end
end

def self.include_context(name, *args, &block)

Other tags:
    See: SharedExampleGroup -
def self.include_context(name, *args, &block)
  find_and_eval_shared("context", name, caller.first, *args, &block)
end

def self.include_examples(name, *args, &block)

Other tags:
    See: SharedExampleGroup -
def self.include_examples(name, *args, &block)
  find_and_eval_shared("examples", name, caller.first, *args, &block)
end

def self.metadata

Other tags:
    See: Metadata -
def self.metadata
  @metadata ||= nil
end

def self.method_missing(name, *args)

def self.method_missing(name, *args)
  if method_defined?(name)
    raise WrongScopeError,
          "`#{name}` is not available on an example group (e.g. a " \
          "`describe` or `context` block). It is only available from " \
          "within individual examples (e.g. `it` blocks) or from " \
          "constructs that run in the scope of an example (e.g. " \
          "`before`, `let`, etc)."
  end
  super
end

def self.next_runnable_index_for(file)

Other tags:
    Private: -
def self.next_runnable_index_for(file)
  if self == ExampleGroup
    # We add 1 so the ids start at 1 instead of 0. This is
    # necessary for this branch (but not for the other one)
    # because we register examples and groups with the
    # `children` and `examples` collection BEFORE this
    # method is called as part of metadata hash creation,
    # but the example group is recorded with
    # `RSpec.world.example_group_counts_by_spec_file` AFTER
    # the metadata hash is created and the group is returned
    # to the caller.
    RSpec.world.num_example_groups_defined_in(file) + 1
  else
    children.count + examples.count
  end
end

def self.ordering_strategy

Other tags:
    Private: -
def self.ordering_strategy
  order = metadata.fetch(:order, :global)
  registry = RSpec.configuration.ordering_registry
  registry.fetch(order) do
    warn <<-WARNING.gsub(/^ +\|/, '')
      |WARNING: Ignoring unknown ordering specified using `:order => #{order.inspect}` metadata.
      |         Falling back to configured global ordering.
      |         Unrecognized ordering specified at: #{location}
    WARNING
    registry.fetch(:global)
  end
end

def self.parent_groups

# @private
def self.parent_groups
  @parent_groups ||= ancestors.select { |a| a < RSpec::Core::ExampleGroup }
end

def self.remove_example(example)

Removes an example from the example group
def self.remove_example(example)
  reset_memoized
  examples.delete example
end

def self.reset_memoized

Other tags:
    Private: -
def self.reset_memoized
  @descendant_filtered_examples = nil
  @_descendants = nil
  @parent_groups = nil
  @declaration_locations = nil
end

def self.run(reporter=RSpec::Core::NullReporter)

Runs all the examples in this group.
def self.run(reporter=RSpec::Core::NullReporter)
  return if RSpec.world.wants_to_quit
  reporter.example_group_started(self)
  should_run_context_hooks = descendant_filtered_examples.any?
  begin
    RSpec.current_scope = :before_context_hook
    run_before_context_hooks(new('before(:context) hook')) if should_run_context_hooks
    result_for_this_group = run_examples(reporter)
    results_for_descendants = ordering_strategy.order(children).map { |child| child.run(reporter) }.all?
    result_for_this_group && results_for_descendants
  rescue Pending::SkipDeclaredInExample => ex
    for_filtered_examples(reporter) { |example| example.skip_with_exception(reporter, ex) }
    true
  rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex
    for_filtered_examples(reporter) { |example| example.fail_with_exception(reporter, ex) }
    RSpec.world.wants_to_quit = true if reporter.fail_fast_limit_met?
    false
  ensure
    RSpec.current_scope = :after_context_hook
    run_after_context_hooks(new('after(:context) hook')) if should_run_context_hooks
    reporter.example_group_finished(self)
  end
end

def self.run_after_context_hooks(example_group_instance)

Other tags:
    Private: -
def self.run_after_context_hooks(example_group_instance)
  set_ivars(example_group_instance, before_context_ivars)
  @currently_executing_a_context_hook = true
  ContextHookMemoized::After.isolate_for_context_hook(example_group_instance) do
    hooks.run(:after, :context, example_group_instance)
  end
ensure
  before_context_ivars.clear
  @currently_executing_a_context_hook = false
end

def self.run_before_context_hooks(example_group_instance)

Other tags:
    Private: -
def self.run_before_context_hooks(example_group_instance)
  set_ivars(example_group_instance, superclass_before_context_ivars)
  @currently_executing_a_context_hook = true
  ContextHookMemoized::Before.isolate_for_context_hook(example_group_instance) do
    hooks.run(:before, :context, example_group_instance)
  end
ensure
  store_before_context_ivars(example_group_instance)
  @currently_executing_a_context_hook = false
end

def self.run_examples(reporter)

Other tags:
    Private: -
def self.run_examples(reporter)
  ordering_strategy.order(filtered_examples).map do |example|
    next if RSpec.world.wants_to_quit
    instance = new(example.inspect_output)
    set_ivars(instance, before_context_ivars)
    succeeded = example.run(instance, reporter)
    if !succeeded && reporter.fail_fast_limit_met?
      RSpec.world.wants_to_quit = true
    end
    succeeded
  end.all?
end

def self.set_it_up(description, args, registration_collection, &example_group_block)

Other tags:
    Private: -
def self.set_it_up(description, args, registration_collection, &example_group_block)
  # Ruby 1.9 has a bug that can lead to infinite recursion and a
  # SystemStackError if you include a module in a superclass after
  # including it in a subclass: https://gist.github.com/845896
  # To prevent this, we must include any modules in
  # RSpec::Core::ExampleGroup before users create example groups and have
  # a chance to include the same module in a subclass of
  # RSpec::Core::ExampleGroup. So we need to configure example groups
  # here.
  ensure_example_groups_are_configured
  # Register the example with the group before creating the metadata hash.
  # This is necessary since creating the metadata hash triggers
  # `when_first_matching_example_defined` callbacks, in which users can
  # load RSpec support code which defines hooks. For that to work, the
  # examples and example groups must be registered at the time the
  # support code is called or be defined afterwards.
  # Begin defined beforehand but registered afterwards causes hooks to
  # not be applied where they should.
  registration_collection << self
  @user_metadata = Metadata.build_hash_from(args)
  @metadata = Metadata::ExampleGroupHash.create(
    superclass_metadata, @user_metadata,
    superclass.method(:next_runnable_index_for),
    description, *args, &example_group_block
  )
  config = RSpec.configuration
  config.apply_derived_metadata_to(@metadata)
  ExampleGroups.assign_const(self)
  @currently_executing_a_context_hook = false
  config.configure_group(self)
end

def self.set_ivars(instance, ivars)

Other tags:
    Private: -
def self.set_ivars(instance, ivars)
  ivars.each { |name, value| instance.instance_variable_set(name, value) }
end

def self.store_before_context_ivars(example_group_instance)

Other tags:
    Private: -
def self.store_before_context_ivars(example_group_instance)
  each_instance_variable_for_example(example_group_instance) do |ivar|
    before_context_ivars[ivar] = example_group_instance.instance_variable_get(ivar)
  end
end

def self.subclass(parent, description, args, registration_collection, &example_group_block)

Other tags:
    Private: -
def self.subclass(parent, description, args, registration_collection, &example_group_block)
  subclass = Class.new(parent)
  subclass.set_it_up(description, args, registration_collection, &example_group_block)
  subclass.module_exec(&example_group_block) if example_group_block
  # The LetDefinitions module must be included _after_ other modules
  # to ensure that it takes precedence when there are name collisions.
  # Thus, we delay including it until after the example group block
  # has been eval'd.
  MemoizedHelpers.define_helpers_on(subclass)
  subclass
end

def self.superclass_before_context_ivars

Other tags:
    Private: -
def self.superclass_before_context_ivars
  superclass.before_context_ivars
end

def self.superclass_before_context_ivars

Other tags:
    Private: -
def self.superclass_before_context_ivars
  if superclass.respond_to?(:before_context_ivars)
    superclass.before_context_ivars
  else
    # `self` must be the singleton class of an ExampleGroup instance.
    # On 1.8.7, the superclass of a singleton class of an instance of A
    # is A's singleton class. On 1.9+, it's A. On 1.8.7, the first ancestor
    # is A, so we can mirror 1.8.7's behavior here. Note that we have to
    # search for the first that responds to `before_context_ivars`
    # in case a module has been included in the singleton class.
    ancestors.find { |a| a.respond_to?(:before_context_ivars) }.before_context_ivars
  end
end

def self.superclass_metadata

Returns:
  • (Metadata) - belonging to the parent of a nested {ExampleGroup}

Other tags:
    Private: -
def self.superclass_metadata
  @superclass_metadata ||= superclass.respond_to?(:metadata) ? superclass.metadata : nil
end

def self.top_level?

Other tags:
    Private: -
def self.top_level?
  superclass == ExampleGroup
end

def self.top_level_description

Other tags:
    Private: -
def self.top_level_description
  parent_groups.last.description
end

def self.traverse_tree_until(&block)

Other tags:
    Private: -
def self.traverse_tree_until(&block)
  return if yield self
  children.each do |child|
    child.traverse_tree_until(&block)
  end
end

def self.update_inherited_metadata(updates)

Other tags:
    Private: -
def self.update_inherited_metadata(updates)
  metadata.update(updates) do |key, existing_group_value, new_inherited_value|
    @user_metadata.key?(key) ? existing_group_value : new_inherited_value
  end
  RSpec.configuration.configure_group(self)
  examples.each { |ex| ex.update_inherited_metadata(updates) }
  children.each { |group| group.update_inherited_metadata(updates) }
end

def self.with_replaced_metadata(meta)

Other tags:
    Private: -
def self.with_replaced_metadata(meta)
  orig_metadata = metadata
  @metadata = meta
  yield
ensure
  @metadata = orig_metadata
end

def described_class


end
end
described_class == Thing
it "does something" do
RSpec.describe Thing do
@example
Returns nil if the subject is not a class or module.
Returns the class or module passed to the `describe` method (or alias).
def described_class
  self.class.described_class
end

def initialize(inspect_output=nil)

Other tags:
    Private: -
def initialize(inspect_output=nil)
  @__inspect_output = inspect_output || '(no description provided)'
  super() # no args get passed
end

def inspect

Other tags:
    Private: -
def inspect
  "#<#{self.class} #{@__inspect_output}>"
end

def method_missing(name, *args)

def method_missing(name, *args)
  if self.class.respond_to?(name)
    raise WrongScopeError,
          "`#{name}` is not available from within an example (e.g. an " \
          "`it` block) or from constructs that run in the scope of an " \
          "example (e.g. `before`, `let`, etc). It is only available " \
          "on an example group (e.g. a `describe` or `context` block)."
  end
  super(name, *args)
end

def singleton_class

Other tags:
    Private: -
def singleton_class
  class << self; self; end
end