Class: Minicrest::HasAttribute

Inherits:
Matcher
  • Object
show all
Defined in:
lib/minicrest/has_attribute.rb

Overview

Matcher that checks if an object has a specific attribute.

Works with: - Objects with attr_reader methods - Hashes (with symbol keys)

Examples:

Check attribute exists

has_attribute(:name).matches?(user)  # => true if user responds to :name

Check attribute value

has_attribute(:name, equals('Alice')).matches?(user)
has_attribute(:age, is_greater_than(18)).matches?(user)

Instance Method Summary collapse

Methods inherited from Matcher

#&, #|

Constructor Details

#initialize(name, value_matcher = nil) ⇒ HasAttribute

Creates a new has_attribute matcher.

Parameters:

  • name (Symbol)

    the attribute name to check

  • value_matcher (Matcher, nil) (defaults to: nil)

    optional matcher for the attribute value



21
22
23
24
25
# File 'lib/minicrest/has_attribute.rb', line 21

def initialize(name, value_matcher = nil)
  super()
  @name = name
  @value_matcher = value_matcher
end

Instance Method Details

#descriptionString

Returns a description of what this matcher expects.

Returns:

  • (String)

    description



41
42
43
44
45
46
47
# File 'lib/minicrest/has_attribute.rb', line 41

def description
  if @value_matcher
    "has attribute #{@name.inspect} #{@value_matcher.description}"
  else
    "has attribute #{@name.inspect}"
  end
end

#failure_message(actual) ⇒ String

Returns the failure message when the match fails.

Parameters:

  • actual (Object)

    the object that was checked

Returns:

  • (String)

    failure message



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/minicrest/has_attribute.rb', line 53

def failure_message(actual)
  unless has_attribute?(actual)
    return <<~MSG.chomp
      expected #{actual.inspect} to have attribute #{@name.inspect}
      but it does not respond to #{@name.inspect}
    MSG
  end

  value = get_attribute(actual)
  <<~MSG.chomp
    expected #{actual.inspect} to have attribute #{@name.inspect} #{@value_matcher.description}
    but #{@name.inspect} was #{value.inspect}
  MSG
end

#matches?(actual) ⇒ Boolean

Checks if actual has the attribute and optionally matches the value.

Parameters:

  • actual (Object)

    the object to check

Returns:

  • (Boolean)

    true if attribute exists (and value matches if specified)



31
32
33
34
35
36
# File 'lib/minicrest/has_attribute.rb', line 31

def matches?(actual)
  return false unless has_attribute?(actual)
  return true if @value_matcher.nil?

  @value_matcher.matches?(get_attribute(actual))
end

#negated_failure_message(actual) ⇒ String

Returns the failure message when a negated match fails.

Parameters:

  • actual (Object)

    the object that was checked

Returns:

  • (String)

    message indicating unexpected attribute



72
73
74
75
76
# File 'lib/minicrest/has_attribute.rb', line 72

def negated_failure_message(actual)
  <<~MSG.chomp
    expected #{actual.inspect} not to have attribute #{@name.inspect}, but it did
  MSG
end