Class: RSpec::SleepingKingStudios::Matchers::ActiveModel::HaveErrorsMatcher

Inherits:
BaseMatcher
  • Object
show all
Includes:
HaveErrors
Defined in:
lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb

Overview

Matcher for testing ActiveModel object validations.

Since:

  • 1.0.0

Constant Summary

Constants included from Description

Description::DEFAULT_EXPECTED_ITEMS

Instance Attribute Summary

Attributes inherited from BaseMatcher

#actual

Instance Method Summary collapse

Constructor Details

#initializeHaveErrorsMatcher

Returns a new instance of HaveErrorsMatcher.

Since:

  • 1.0.0



15
16
17
18
19
20
21
# File 'lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb', line 15

def initialize
  super

  # The error and message expectations are set up through #on and
  # #with_message.
  @error_expectations = []
end

Instance Method Details

#descriptionObject

Since:

  • 1.0.0



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb', line 24

def description
  message = 'have errors'

  attribute_messages = @error_expectations.select(&:expected).map do |expectation|
    attribute_message = ":#{expectation.attribute}"

    error_messages = expectation.messages.select(&:expected).map do |message_expectation|
      %{"#{message_expectation.message}"}
    end # map

    unless error_messages.empty?
      tools = ::SleepingKingStudios::Tools::ArrayTools

      attribute_message <<
        " with message#{error_messages.count == 1 ? '' : 's'} "\
        "#{tools.humanize_list error_messages}"
    end # unless

    attribute_message
  end # each
  message << " on #{attribute_messages.join(", and on ")}" unless attribute_messages.empty?

  message
end

#does_not_match?(actual) ⇒ Boolean

Checks if the object can be validated, whether the object is valid, and checks the errors on the object against the expected errors and messages from #on and #with_message, if any.

Parameters:

  • actual (Object)

    The object to test against the matcher.

Returns:

  • (Boolean)

    True if the object responds to :valid? and is valid or object.errors does not match the specified errors and messages (if any); otherwise false.

See Also:

Since:

  • 1.0.0



60
61
62
63
64
65
66
67
68
# File 'lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb', line 60

def does_not_match? actual
  super

  @negative_expectation = true

  return false unless @validates = actual.respond_to?(:valid?)

  !matches?(actual)
end

#failure_messageObject

Message for when the object does not match, but was expected to. Make sure to always call #matches? first to set up the matcher state.

Since:

  • 1.0.0



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb', line 143

def failure_message
  # Failure cases:
  # * object is not a model ("to respond to valid")
  # * expected one or more errors, but received none ("to have errors")
  # * expected one or more messages on :attribute, but received none or a
  #   subset ("to have errors on")

  if !@validates
    "expected #{@actual.inspect} to respond to :valid?"
  elsif expected_errors.empty?
    "expected #{@actual.inspect} to have errors"
  else
    "expected #{@actual.inspect} to have errors#{expected_errors_message}#{received_errors_message}"
  end # if-elsif-else
end

#failure_message_when_negatedObject

Message for when the object matches, but was expected not to. Make sure to always call #matches? first to set up the matcher state.

Since:

  • 1.0.0



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb', line 160

def failure_message_when_negated
  # Failure cases:
  # * object is not a model ("to respond to valid")
  # * expected one or more errors, received one or more ("not to have
  #   errors")
  # * expected one or more messages on attribute, received one or more
  #   ("not to have errors on")
  # * expected specific messages on attribute, received all ("not to have
  #   errors on")

  if !@validates
    "expected #{@actual.inspect} to respond to :valid?"
  elsif expected_errors.empty?
    return "expected #{@actual.inspect} not to have errors#{received_errors_message}"
  else
    return "expected #{@actual.inspect} not to have errors#{expected_errors_message}#{received_errors_message}"
  end # if-else
end

#matches?(actual) ⇒ Boolean

Checks if the object can be validated, whether the object is valid, and checks the errors on the object against the expected errors and messages from #on and #with_message, if any.

Parameters:

  • actual (Object)

    The object to test against the matcher.

Returns:

  • (Boolean)

    True if the object responds to :valid?, is not valid, and object.errors matches the specified errors and messages (if any); otherwise false.

See Also:

Since:

  • 1.0.0



81
82
83
84
85
86
87
# File 'lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb', line 81

def matches? actual
  super

  return false unless @validates = actual.respond_to?(:valid?)

  !@actual.valid? && attributes_have_errors?
end

#on(attribute) ⇒ HaveErrorsMatcher

Adds an error expectation. If the actual object does not have an error on the specified attribute, #matches? will return false.

Examples:

Setting an error expectation

expect(actual).to have_errors.on(:foo)

Parameters:

  • attribute (String, Symbol)

Returns:

Since:

  • 1.0.0



98
99
100
101
102
# File 'lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb', line 98

def on attribute
  @error_expectations << ErrorExpectation.new(attribute)

  self
end

#with_message(message) ⇒ HaveErrorsMatcher

Adds a message expectation for the most recently added error attribute. If the actual object does not have an error on the that attribute with the specified message, #matches? will return false.

Examples:

Setting an error and a message expectation

expect(actual).to have_errors.on(:foo).with("can't be blank")

Parameters:

  • message (String, Regexp)

    The expected error message. If a string, matcher will check for an exact match; if a regular expression, matcher will check if the message matches the regexp.

Returns:

Raises:

  • (ArgumentError)

    If no error attribute has been added.

See Also:

Since:

  • 1.0.0



120
121
122
123
124
125
126
127
# File 'lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb', line 120

def with_message message
  raise ArgumentError.new "no attribute specified for error message" if
    @error_expectations.empty?

  @error_expectations.last.messages << MessageExpectation.new(message)

  self
end

#with_messages(*messages) ⇒ Object Also known as: with

Adds a set of message expectations for the most recently added error attribute.

Parameters:

  • messages (Array<String, Regexp>)

See Also:

Since:

  • 1.0.0



135
136
137
138
139
# File 'lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb', line 135

def with_messages *messages
  messages.each do |message| self.with_message(message); end

  self
end