Class: Matchi::RaiseException

Inherits:
Object
  • Object
show all
Defined in:
lib/matchi/raise_exception.rb

Overview

Exception matcher that verifies if a block of code raises a specific exception.

This matcher ensures that code raises an expected exception by executing it within a controlled environment. It supports matching against specific exception classes and their subclasses, providing a reliable way to test error handling.

Examples:

Basic usage with standard exceptions

matcher = Matchi::RaiseException.new(ArgumentError)
matcher.match? { raise ArgumentError }    # => true
matcher.match? { raise RuntimeError }     # => false
matcher.match? { "no error" }             # => false

Working with inheritance hierarchy

class CustomError < StandardError; end
class SpecificError < CustomError; end

matcher = Matchi::RaiseException.new(CustomError)
matcher.match? { raise CustomError }      # => true
matcher.match? { raise SpecificError }    # => true
matcher.match? { raise StandardError }    # => false

Using string class names

matcher = Matchi::RaiseException.new("ArgumentError")
matcher.match? { raise ArgumentError }    # => true

With custom exception hierarchies

module Api
  class Error < StandardError; end
  class AuthenticationError < Error; end
end

matcher = Matchi::RaiseException.new("Api::Error")
matcher.match? { raise Api::AuthenticationError } # => true

See Also:

Instance Method Summary collapse

Constructor Details

#initialize(expected) ⇒ RaiseException

Initialize the matcher with an exception class.

Examples:

RaiseException.new(ArgumentError)         # Using class
RaiseException.new("ArgumentError")       # Using string
RaiseException.new(:ArgumentError)        # Using symbol
RaiseException.new("Api::CustomError")    # Using namespaced class

Parameters:

  • expected (Exception, #to_s)

    The expected exception class or its name Can be provided as a Class, String, or Symbol

Raises:

  • (ArgumentError)

    if the class name doesn’t start with an uppercase letter



57
58
59
60
61
62
63
# File 'lib/matchi/raise_exception.rb', line 57

def initialize(expected)
  @expected = String(expected)
  return if /\A[A-Z]/.match?(@expected)

  raise ::ArgumentError,
        "expected must start with an uppercase letter (got: #{@expected})"
end

Instance Method Details

#match? { ... } ⇒ Boolean

Checks if the yielded block raises the expected exception.

This method executes the provided block within a begin/rescue clause and verifies that it raises an exception of the expected type. It also handles inheritance, allowing subclasses of the expected exception to match.

Examples:

Standard usage

matcher = RaiseException.new(ArgumentError)
matcher.match? { raise ArgumentError }     # => true

With inheritance

matcher = RaiseException.new(StandardError)
matcher.match? { raise ArgumentError }     # => true

Without exception

matcher = RaiseException.new(StandardError)
matcher.match? { "no error" }             # => false

Yields:

  • Block that should raise an exception

Yield Returns:

  • (Object)

    The result of the block (if it doesn’t raise)

Returns:

  • (Boolean)

    true if the block raises the expected exception

Raises:

  • (ArgumentError)

    if no block is provided

  • (ArgumentError)

    if expected exception class doesn’t inherit from Exception

  • (NameError)

    if the expected exception class cannot be found



93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/matchi/raise_exception.rb', line 93

def match?
  raise ::ArgumentError, "a block must be provided" unless block_given?

  klass = expected_class
  raise ::ArgumentError, "expected exception class must inherit from Exception" unless klass <= ::Exception

  begin
    yield
    false
  rescue ::Exception => e # rubocop:disable Lint/RescueException
    e.class <= klass
  end
end

#to_sString

Returns a human-readable description of the matcher.

Examples:

RaiseException.new(ArgumentError).to_s  # => "raise exception ArgumentError"

Returns:

  • (String)

    A string describing what this matcher verifies



115
116
117
# File 'lib/matchi/raise_exception.rb', line 115

def to_s
  "raise exception #{@expected}"
end