Class: Matchi::BeAKindOf

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

Overview

Type matcher that checks if an object is an instance of a class or one of its subclasses.

This matcher provides a reliable way to verify object types while respecting Ruby’s inheritance hierarchy. It uses the case equality operator (===) which is Ruby’s built-in mechanism for type checking, ensuring consistent behavior with Ruby’s own type system.

Examples:

Basic usage with simple types

matcher = Matchi::BeAKindOf.new(Numeric)
matcher.match? { 42 }     # => true
matcher.match? { 42.0 }   # => true
matcher.match? { "42" }   # => false

Working with inheritance hierarchies

class Animal; end
class Dog < Animal; end
class GermanShepherd < Dog; end

matcher = Matchi::BeAKindOf.new(Animal)
matcher.match? { Dog.new }             # => true
matcher.match? { GermanShepherd.new }  # => true
matcher.match? { Object.new }          # => false

Using with modules and interfaces

module Swimmable
  def swim; end
end

class Duck
  include Swimmable
end

matcher = Matchi::BeAKindOf.new(Swimmable)
matcher.match? { Duck.new }     # => true
matcher.match? { Object.new }   # => false

Different ways to specify the class

# Using class directly
Matchi::BeAKindOf.new(String)

# Using class name as string
Matchi::BeAKindOf.new("String")

# Using class name as symbol
Matchi::BeAKindOf.new(:String)

# Using namespaced class
Matchi::BeAKindOf.new("MyModule::MyClass")

See Also:

Instance Method Summary collapse

Constructor Details

#initialize(expected) ⇒ BeAKindOf

Creates a new type matcher for the specified class.

Examples:

BeAKindOf.new(String)          # Using class
BeAKindOf.new("String")        # Using string
BeAKindOf.new(:String)         # Using symbol

Parameters:

  • expected (Class, #to_s)

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

Raises:

  • (ArgumentError)

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



71
72
73
74
75
76
77
# File 'lib/matchi/be_a_kind_of.rb', line 71

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 object is an instance of the expected class or its subclasses.

This method leverages Ruby’s case equality operator (===) which provides a reliable way to check class hierarchy relationships. When a class is the receiver of ===, it returns true if the argument is an instance of that class or one of its subclasses.

Examples:

Simple type check

matcher = BeAKindOf.new(Numeric)
matcher.match? { 42 }      # => true

With inheritance

matcher = BeAKindOf.new(Animal)
matcher.match? { Dog.new } # => true

Yields:

  • Block that returns the object to check

Yield Returns:

  • (Object)

    The object to verify the type of

Returns:

  • (Boolean)

    true if the object is an instance of the expected class or one of its subclasses

Raises:

  • (ArgumentError)

    if no block is provided

  • (NameError)

    if the expected class cannot be found



102
103
104
105
106
# File 'lib/matchi/be_a_kind_of.rb', line 102

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

  expected_class === yield # rubocop:disable Style/CaseEquality
end

#to_sString

Returns a human-readable description of the matcher.

Examples:

BeAKindOf.new(String).to_s # => "be a kind of String"

Returns:

  • (String)

    A string describing what this matcher verifies



116
117
118
# File 'lib/matchi/be_a_kind_of.rb', line 116

def to_s
  "be a kind of #{@expected}"
end