class RSpec::SleepingKingStudios::Matchers::ActiveModel::HaveErrorsMatcher
Matcher for testing ActiveModel
object validations.
@since 1.0.0
Public Class Methods
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 16 def initialize super # The error and message expectations are set up through #on and # #with_message. @error_expectations = [] end
Public Instance Methods
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 25 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
(see BaseMatcher#description
)
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 61 def does_not_match? actual super @negative_expectation = true return false unless @validates = actual.respond_to?(:valid?) !matches?(actual) end
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.
@param [Object] actual The object to test against the matcher.
@return [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 matches?
RSpec::SleepingKingStudios::Matchers::BaseMatcher#does_not_match?
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 144 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
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 161 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
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 82 def matches? actual super return false unless @validates = actual.respond_to?(:valid?) !@actual.valid? && attributes_have_errors? end
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.
@param [Object] actual The object to test against the matcher.
@return [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 RSpec::SleepingKingStudios::Matchers::BaseMatcher#matches?
RSpec::SleepingKingStudios::Matchers::BaseMatcher#matches?
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 99 def on attribute @error_expectations << ErrorExpectation.new(attribute) self end
Adds an error expectation. If the actual object does not have an error on the specified attribute, matches?
will return false.
@param [String, Symbol] attribute
@return [HaveErrorsMatcher] self
@example Setting an error expectation
expect(actual).to have_errors.on(:foo)
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 121 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
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.
@param [String, Regexp] message 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.
@raise [ArgumentError] If no error attribute has been added.
@return [HaveErrorsMatcher] self
@example Setting an error and a message expectation
expect(actual).to have_errors.on(:foo).with("can't be blank")
@see on
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 136 def with_messages *messages messages.each do |message| self.with_message(message); end self end
Adds a set of message expectations for the most recently added error attribute.
@param [Array<String, Regexp>] messages
@see with_message
Private Instance Methods
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 182 def attributes_have_errors? # Iterate through the received errors and match them against the expected # errors and messages. @actual.errors.messages.each do |attribute, messages| # Find the matching error expectation, if any. error_expectation = @error_expectations.detect do |error_expectation| error_expectation.attribute == attribute end # detect if error_expectation error_expectation.received = true # If the error includes message expectations, iterate through the # received messages. unless error_expectation.messages.empty? messages.each do |message| # Find the matching message expectation, if any. message_expectation = error_expectation.messages.detect do |message_expectation| if Regexp === message_expectation.message message =~ message_expectation.message else message == message_expectation.message end # if-else end # detect if message_expectation message_expectation.received = true else error_expectation.messages << MessageExpectation.new(message, false, true) end # if-else end # each end # unless else error_expectation = ErrorExpectation.new attribute, false, true messages.each do |message| error_expectation.messages << MessageExpectation.new(message, false, true) end # each @error_expectations << error_expectation end # if-else end # each missing_errors.empty? && missing_messages.empty? end
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 227 def expected_errors @error_expectations.select do |error_expectation| error_expectation.expected end # select end
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 251 def expected_errors_message "\n expected errors:" + expected_errors.map do |error_expectation| "\n #{error_expectation.attribute}: " + (error_expectation.messages.empty? ? "(#{@negative_expectation ? 'none' : 'any'})" : error_expectation.messages.expected.map(&:message).map(&:inspect).join(", ")) end.join # map end
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 233 def missing_errors @error_expectations.select do |error_expectation| error_expectation.expected && !error_expectation.received end # select end
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 239 def missing_messages @error_expectations.select do |error_expectation| !error_expectation.messages.missing.empty? end # select end
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 259 def received_errors_message return "" unless @validates return "\n received errors:\n (none)" if @actual.errors.messages.empty? "\n received errors:" + @actual.errors.messages.map do |attr, ary| "\n #{attr}: " + ary.map(&:inspect).join(", ") end.join # map end
Source
# File lib/rspec/sleeping_king_studios/matchers/active_model/have_errors_matcher.rb, line 245 def unexpected_errors @error_expectations.select do |error_expectation| !error_expectation.expected && error_expectation.received end # select end