123456789_123456789_123456789_123456789_123456789_

Class: RSpec::Matchers::BuiltIn::RaiseError Private

Do not use. This class is for internal use only.
Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
Inherits: Object
Defined in: rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb

Overview

Provides the implementation for ‘raise_error`. Not intended to be instantiated directly.

rubocop:disable Lint/RescueException

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

::RSpec::Matchers::Composable - Included

#&

Alias for Composable#and.

#===

Delegates to ‘#matches?`.

#and

Creates a compound ‘and` expectation.

#description_of

Returns the description of the given object in a way that is aware of composed matchers.

#or

Creates a compound ‘or` expectation.

#values_match?

This provides a generic way to fuzzy-match an expected value against an actual value.

#|

Alias for Composable#or.

#should_enumerate?

We should enumerate arrays as long as they are not recursive.

#surface_descriptions_in

Transforms the given data structure (typically a hash or array) into a new data structure that, when ‘#inspect` is called on it, will provide descriptions of any contained matchers rather than the normal #inspect output.

#unreadable_io?,
#with_matchers_cloned

Historically, a single matcher instance was only checked against a single value.

Instance Attribute Details

#block_matches?Boolean (readonly, private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 133

def block_matches?
  @eval_block ? @eval_block_passed : true
end

#error_and_message_match?Boolean (readonly, private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 129

def error_and_message_match?
  @raised_expected_error && @with_expected_message
end

#expectation_matched?Boolean (readonly, private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 125

def expectation_matched?
  error_and_message_match? && block_matches?
end

#expecting_specific_exception?Boolean (readonly, private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 253

def expecting_specific_exception?
  @expected_error != Exception
end

#expects_call_stack_jump?Boolean (readonly)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 95

def expects_call_stack_jump?
  true
end

#ready_to_eval_block?Boolean (readonly, private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 137

def ready_to_eval_block?
  @raised_expected_error && @with_expected_message && @block
end

#supports_block_expectations?Boolean (readonly)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 85

def supports_block_expectations?
  true
end

#supports_value_expectations?Boolean (readonly)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 90

def supports_value_expectations?
  false
end

#warn_about_bare_error?Boolean (readonly, private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 176

def warn_about_bare_error?
  @warn_about_bare_error && @block.nil?
end

#warn_about_nil_error?Boolean (readonly, private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 180

def warn_about_nil_error?
  @warn_about_nil_error
end

Instance Method Details

#actual_error_message (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 119

def actual_error_message
  return nil unless @actual_error

  @actual_error.respond_to?(:original_message) ? @actual_error.original_message : @actual_error.message
end

#descriptionString

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 113

def description
  "raise #{expected_error}"
end

#does_not_match?(given_proc) ⇒ Boolean

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 79

def does_not_match?(given_proc)
  warn_for_negative_false_positives!
  !matches?(given_proc, :negative_expectation) && Proc === given_proc
end

#eval_block (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 141

def eval_block
  @eval_block = true
  begin
    @block[@actual_error]
    @eval_block_passed = true
  rescue Exception => err
    @actual_error = err
  end
end

#expected_error (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 222

def expected_error
  case @expected_message
  when nil
    if RSpec::Support.is_a_matcher?(@expected_error)
      "Exception with #{description_of(@expected_error)}"
    else
      description_of(@expected_error)
    end
  when Regexp
    "#{@expected_error} with message matching #{description_of(@expected_message)}"
  else
    "#{@expected_error} with #{description_of(@expected_message)}"
  end
end

#failure_messageString

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 101

def failure_message
  @eval_block ? actual_error_message : "expected #{expected_error}#{given_error}"
end

#failure_message_when_negatedString

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 107

def failure_message_when_negated
  "expected no #{expected_error}#{given_error}"
end

#format_backtrace(backtrace) (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 237

def format_backtrace(backtrace)
  formatter = Matchers.configuration.backtrace_formatter
  formatter.format_backtrace(backtrace)
end

#given_error (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 242

def given_error
  return " but was not given a block" unless Proc === @given_proc
  return " but nothing was raised" unless @actual_error

  backtrace = format_backtrace(@actual_error.backtrace)
  [
    ", got #{description_of(@actual_error)} with backtrace:",
    *backtrace
  ].join("\n  # ")
end

#handle_warning(message) (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 172

def handle_warning(message)
  RSpec::Expectations.configuration.false_positives_handler.call(message)
end

#matches?(given_proc, negative_expectation = false, &block) ⇒ Boolean

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 48

def matches?(given_proc, negative_expectation=false, &block)
  @given_proc = given_proc
  @block ||= block
  @raised_expected_error = false
  @with_expected_message = false
  @eval_block = false
  @eval_block_passed = false

  return false unless Proc === given_proc

  begin
    given_proc.call
  rescue Exception => @actual_error
    if values_match?(@expected_error, @actual_error) ||
       values_match?(@expected_error, actual_error_message)
      @raised_expected_error = true
      @with_expected_message = verify_message
    end
  end

  unless negative_expectation
    warn_about_bare_error! if warn_about_bare_error?
    warn_about_nil_error! if warn_about_nil_error?
    eval_block if ready_to_eval_block?
  end

  expectation_matched?
end

#raise_message_already_set (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 257

def raise_message_already_set
  raise "`expect { }.to raise_error(message).with_message(message)` is not valid. " \
        'The matcher only allows the expected message to be specified once'
end

#verify_message (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 151

def verify_message
  return true if @expected_message.nil?
  values_match?(@expected_message, actual_error_message.to_s)
end

#warn_about_bare_error! (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 184

def warn_about_bare_error!
  handle_warning("Using the `raise_error` matcher without providing a specific " \
                 "error or message risks false positives, since `raise_error` " \
                 "will match when Ruby raises a `NoMethodError`, `NameError` or " \
                 "`ArgumentError`, potentially allowing the expectation to pass " \
                 "without even executing the method you are intending to call. " \
                 "#{warning}"\
                 "Instead consider providing a specific error class or message. " \
                 "This message can be suppressed by setting: " \
                 "`RSpec::Expectations.configuration.on_potential_false" \
                 "_positives = :nothing`")
end

#warn_about_negative_false_positive!(expression) (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 210

def warn_about_negative_false_positive!(expression)
  handle_warning("Using #{expression} risks false positives, since literally " \
                 "any other error would cause the expectation to pass, " \
                 "including those raised by Ruby (e.g. `NoMethodError`, `NameError` " \
                 "and `ArgumentError`), meaning the code you are intending to test " \
                 "may not even get reached. Instead consider using " \
                 "`expect { }.not_to raise_error` or `expect { }.to raise_error" \
                 "(DifferentSpecificErrorClass)`. This message can be suppressed by " \
                 "setting: `RSpec::Expectations.configuration.on_potential_false" \
                 "_positives = :nothing`")
end

#warn_about_nil_error! (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 197

def warn_about_nil_error!
  handle_warning("Using the `raise_error` matcher with a `nil` error is probably " \
                 "unintentional, it risks false positives, since `raise_error` " \
                 "will match when Ruby raises a `NoMethodError`, `NameError` or " \
                 "`ArgumentError`, potentially allowing the expectation to pass " \
                 "without even executing the method you are intending to call. " \
                 "#{warning}"\
                 "Instead consider providing a specific error class or message. " \
                 "This message can be suppressed by setting: " \
                 "`RSpec::Expectations.configuration.on_potential_false" \
                 "_positives = :nothing`")
end

#warn_for_negative_false_positives! (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 156

def warn_for_negative_false_positives!
  expression = if expecting_specific_exception? && @expected_message
                 "`expect { }.not_to raise_error(SpecificErrorClass, message)`"
               elsif expecting_specific_exception?
                 "`expect { }.not_to raise_error(SpecificErrorClass)`"
               elsif @expected_message
                 "`expect { }.not_to raise_error(message)`"
               elsif @warn_about_nil_error
                 "`expect { }.not_to raise_error(nil)`"
               end

  return unless expression

  warn_about_negative_false_positive! expression
end

#warning (private)

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 262

def warning
  warning = "Actual error raised was #{description_of(@actual_error)}. "
  warning if @actual_error
end

#with_message(expected_message)

Specifies the expected error message.

[ GitHub ]

  
# File 'rspec-expectations/lib/rspec/matchers/built_in/raise_error.rb', line 39

def with_message(expected_message)
  raise_message_already_set if @expected_message
  @warn_about_bare_error = false
  @expected_message = expected_message
  self
end