123456789_123456789_123456789_123456789_123456789_

Class: RSpec::Core::Example

Relationships & Source Files
Namespace Children
Classes:
Extension / Inclusion / Inheritance Descendants
Subclasses:
RSpec::Core::SuiteHookContext
Inherits: Object
Defined in: rspec-core/lib/rspec/core/example.rb

Overview

Note:

Example blocks are evaluated in the context of an instance of an ‘ExampleGroup`, not in the context of an instance of Example.

Wrapper for an instance of a subclass of ExampleGroup. An instance of ‘RSpec::Core::Example` is returned by example definition methods such as it and is yielded to the it, before, after, around, let and subject blocks.

This allows us to provide rich metadata about each individual example without adding tons of methods directly to the ExampleGroup that users may inadvertently redefine.

Useful for configuring logging and/or taking some action based on the state of an example’s metadata.

Examples:

RSpec.configure do |config|
  config.before do |example|
    log example.description
  end

  config.after do |example|
    log example.description
  end

  config.around do |example|
    log example.description
    example.run
  end
end

shared_examples "auditable" do
  it "does something" do
    log "#{example.full_description}: #{auditable.inspect}"
    auditable.should do_something
  end
end

See Also:

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Class Method Details

.delegate_to_metadata(key)

This method is for internal use only.

Used to define methods that delegate to this example’s metadata.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 48

def self.(key)
  define_method(key) { @metadata[key] }
end

.parse_id(id)

This method is for internal use only.
[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 122

def self.parse_id(id)
  # http://rubular.com/r/OMZSAPcAfn
  id.match(/\A(.*?)(?:\[([\d\s:,]+)\])?\z/).captures
end

Instance Attribute Details

#clock (rw)

This method is for internal use only.
[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 174

attr_accessor :clock

#display_exception (rw)

This method is for internal use only.

The exception that will be displayed to the user – either the failure of the example or the ‘pending_exception` if the example is pending.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 388

def display_exception
  @exception || execution_result.pending_exception
end

#display_exception=(ex) (rw)

This method is for internal use only.

Assigns the exception that will be displayed to the user – either the failure of the example or the ‘pending_exception` if the example is pending.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 396

def display_exception=(ex)
  if pending? && !(Pending::PendingExampleFixedError === ex)
    @exception = nil
    execution_result.pending_fixed = false
    execution_result.pending_exception = ex
  else
    @exception = ex
  end
end

#example_group_instance (readonly)

This method is for internal use only.

Returns the example_group_instance that provides the context for running this example.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 170

attr_reader :example_group_instance

#exception (readonly)

Returns the first exception raised in the context of running this example (nil if no exception is raised).

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 158

attr_reader :exception

#metadata (readonly)

Returns the metadata object associated with this example.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 163

attr_reader :

#mocks_need_verification?Boolean (readonly, private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 530

def mocks_need_verification?
  exception.nil? || execution_result.pending_fixed?
end

#pendingBoolean (readonly)

Returns:

  • (Boolean)

    flag that indicates that the example is not expected to pass. It will be run and will either have a pending result (if a failure occurs) or a failed result (if no failure occurs).

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 66

 :pending

#pending?Boolean (readonly)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 234

def pending?
  !!pending
end

#reporterRSpec::Core::Reporter (readonly)

Returns:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 226

attr_reader :reporter

#skipped?Boolean (readonly)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 238

def skipped?
  !!skip
end

Instance Method Details

#assign_generated_description (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 534

def assign_generated_description
  if [:description].empty? && (description = generate_description)
    [:description] = description
    [:full_description] += description
  end
ensure
  RSpec::Matchers.clear_generated_description
end

#description

Returns the string submitted to ‘example` or its aliases (e.g. specify, it, etc). If no string is submitted (e.g. `it { is_expected.to do_something }`) it returns the message generated by the matcher if there is one, otherwise returns a message including the location of the example.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 76

def description
  description = if [:description].to_s.empty?
                  location_description
                else
                  [:description]
                end

  RSpec.configuration.format_docstrings_block.call(description)
end

#duplicate_with(metadata_overrides = {}) ⇒ Example

Duplicates the example and overrides metadata with the provided hash.

Parameters:

  • metadata_overrides (Hash) (defaults to: {})

    the hash to override the example metadata

Returns:

  • (Example)

    a duplicate of the example with modified metadata

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 132

def duplicate_with(={})
   = .clone.merge()

  RSpec::Core::Metadata::RESERVED_KEYS.each do |reserved_key|
    .delete reserved_key
  end

  # don't clone the example group because the new example
  # must belong to the same example group (not a clone).
  #
  # block is nil in new_metadata so we have to get it from metadata.
  Example.new(example_group, description.clone,
              , [:block])
end

#example_group

Returns the example group class that provides the context for running this example.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 230

def example_group
  @example_group_class
end

#execution_resultExecutionResult

Returns:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 53

 :execution_result

#fail_with_exception(reporter, exception)

This method is for internal use only.

Used internally to set an exception and fail without actually executing the example when an exception is raised in before(:context).

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 439

def fail_with_exception(reporter, exception)
  start(reporter)
  set_exception(exception)
  finish(reporter)
end

#file_pathString

Returns:

  • (String)

    the relative path to the file where this example was defined.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 56

 :file_path

#finish(reporter) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 478

def finish(reporter)
  pending_message = execution_result.pending_message

  if @exception
    execution_result.exception = @exception
    record_finished :failed, reporter
    reporter.example_failed self
    false
  elsif pending_message
    execution_result.pending_message = pending_message
    record_finished :pending, reporter
    reporter.example_pending self
    true
  else
    record_finished :passed, reporter
    reporter.example_passed self
    true
  end
end

#full_descriptionString

Returns:

  • (String)

    the full description (including the docstrings of all parent example groups).

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 59

 :full_description

#generate_description (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 543

def generate_description
  RSpec::Matchers.generated_description
rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e
  location_description + " (Got an error when generating description " \
    "from matcher: #{e.class}: #{e.message} -- #{e.backtrace.first})"
end

#hooks (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 462

def hooks
  example_group_instance.singleton_class.hooks
end

#idString

Returns:

  • (String)

    the unique id of this example. Pass this at the command line to re-run this exact example.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 117

def id
  @id ||= Metadata.id_from()
end

#inspect Also known as: #to_s

Provide a human-readable representation of this class

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 220

def inspect
  "#<#{self.class.name} #{description.inspect}>"
end

#inspect_output

Returns a description of the example that always includes the location.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 87

def inspect_output
  inspect_output = "\"#{description}\""
  unless [:description].to_s.empty?
    inspect_output += " (#{location})"
  end
  inspect_output
end

#instance_exec(*args, &block)

This method is for internal use only.
[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 456

def instance_exec(*args, &block)
  @example_group_instance.instance_exec(*args, &block)
end

#locationString

Returns:

  • (String)

    the exact source location of this example in a form like ‘./path/to/spec.rb:17`

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 62

 :location

#location_description (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 550

def location_description
  "example at #{location}"
end

#location_rerun_argument

Returns the location-based argument that can be passed to the ‘rspec` command to rerun this example.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 96

def location_rerun_argument
  @location_rerun_argument ||= begin
    loaded_spec_files = RSpec.configuration.loaded_spec_files

    Metadata.ascending() do |meta|
      return meta[:location] if loaded_spec_files.include?(meta[:absolute_file_path])
    end
  end
end

#record_finished(status, reporter) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 498

def record_finished(status, reporter)
  execution_result.record_finished(status, clock.now)
  reporter.example_finished(self)
end

#rerun_argument

Deprecated.
Note:

If there are multiple examples identified by this location, they will use #id to rerun instead, but this method will still return the location (that’s why it is deprecated!).

Returns the location-based argument that can be passed to the ‘rspec` command to rerun this example.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 111

def rerun_argument
  location_rerun_argument
end

#run(example_group_instance, reporter)

This method is for internal use only.

instance_execs the block passed to the constructor in the context of the instance of ExampleGroup.

Parameters:

  • example_group_instance

    the instance of an ExampleGroup subclass

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 246

def run(example_group_instance, reporter)
  @example_group_instance = example_group_instance
  @reporter = reporter
  RSpec.configuration.configure_example(self, hooks)
  RSpec.current_example = self

  start(reporter)
  Pending.mark_pending!(self, pending) if pending?

  begin
    if skipped?
      Pending.mark_pending! self, skip
    elsif !RSpec.configuration.dry_run?
      with_around_and_singleton_context_hooks do
        begin
          run_before_example
          RSpec.current_scope = :example
          @example_group_instance.instance_exec(self, &@example_block)

          if pending?
            Pending.mark_fixed! self

            raise Pending::PendingExampleFixedError,
                  'Expected example to fail since it is pending, but it passed.',
                  [location]
          end
        rescue Pending::SkipDeclaredInExample => _
          # The "=> _" is normally useless but on JRuby it is a workaround
          # for a bug that prevents us from getting backtraces:
          # https://github.com/jruby/jruby/issues/4467
          #
          # no-op, required metadata has already been set by the `skip`
          # method.
        rescue AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt => e
          set_exception(e)
        ensure
          RSpec.current_scope = :after_example_hook
          run_after_example
        end
      end
    end
  rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e
    set_exception(e)
  ensure
    @example_group_instance = nil # if you love something... let it go
  end

  finish(reporter)
ensure
  execution_result.ensure_timing_set(clock)
  RSpec.current_example = nil
end

#run_after_example (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 516

def run_after_example
  assign_generated_description if defined?(::RSpec::Matchers)
  hooks.run(:after, :example, self)
  verify_mocks
ensure
  @example_group_instance.teardown_mocks_for_rspec
end

#run_before_example (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 503

def run_before_example
  @example_group_instance.setup_mocks_for_rspec
  hooks.run(:before, :example, self)
end

#set_aggregate_failures_exception(exception)

This method is for internal use only.

Used to set the exception when ‘aggregate_failures` fails.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 425

def set_aggregate_failures_exception(exception)
  return set_exception(exception) unless display_exception

  exception = RSpec::Core::MultipleExceptionError::InterfaceTag.for(exception)
  exception.add display_exception
  self.display_exception = exception
end

#set_exception(exception)

This method is for internal use only.

Used internally to set an exception in an after hook, which captures the exception but doesn’t raise it.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 412

def set_exception(exception)
  return self.display_exception = exception unless display_exception

  unless RSpec::Core::MultipleExceptionError === display_exception
    self.display_exception = RSpec::Core::MultipleExceptionError.new(display_exception)
  end

  display_exception.add exception
end

#skipBoolean

Returns:

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 69

 :skip

#skip_with_exception(reporter, exception)

This method is for internal use only.

Used internally to skip without actually executing the example when skip is used in before(:context).

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 449

def skip_with_exception(reporter, exception)
  start(reporter)
  Pending.mark_skipped! self, exception.argument
  finish(reporter)
end

#start(reporter) (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 473

def start(reporter)
  reporter.example_started(self)
  execution_result.started_at = clock.now
end

#to_s

Alias for #inspect.

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 223

alias to_s inspect

#update_inherited_metadata(updates)

This method is for internal use only.
[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 148

def (updates)
  .update(updates) do |_key, existing_example_value, _new_inherited_value|
    existing_example_value
  end
end

#verify_mocks (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 524

def verify_mocks
  @example_group_instance.verify_mocks_for_rspec if mocks_need_verification?
rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e
  set_exception(e)
end

#with_around_and_singleton_context_hooks (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 508

def with_around_and_singleton_context_hooks
  singleton_context_hooks_host = example_group_instance.singleton_class
  singleton_context_hooks_host.run_before_context_hooks(example_group_instance)
  with_around_example_hooks { yield }
ensure
  singleton_context_hooks_host.run_after_context_hooks(example_group_instance)
end

#with_around_example_hooks (private)

[ GitHub ]

  
# File 'rspec-core/lib/rspec/core/example.rb', line 466

def with_around_example_hooks
  RSpec.current_scope = :before_example_hook
  hooks.run(:around, :example, self) { yield }
rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e
  set_exception(e)
end