2010-12-15 22:34:19 +00:00
|
|
|
module Shoulda # :nodoc:
|
|
|
|
module Matchers
|
2011-05-06 11:51:12 +00:00
|
|
|
module ActiveModel # :nodoc:
|
2010-12-15 22:34:19 +00:00
|
|
|
|
2010-09-05 15:33:32 +00:00
|
|
|
# Ensures that the attribute can be set to the given value or values. If
|
|
|
|
# multiple values are given the match succeeds only if all given values
|
|
|
|
# are allowed. Otherwise, the matcher fails at the first bad value in the
|
|
|
|
# argument list (the remaining arguments are not processed then).
|
2010-12-15 22:34:19 +00:00
|
|
|
#
|
|
|
|
# Options:
|
|
|
|
# * <tt>with_message</tt> - value the test expects to find in
|
|
|
|
# <tt>errors.on(:attribute)</tt>. Regexp or string. If omitted,
|
|
|
|
# the test looks for any errors in <tt>errors.on(:attribute)</tt>.
|
2012-09-14 13:59:24 +00:00
|
|
|
# * <tt>strict</tt> - expects the model to raise an exception when the
|
|
|
|
# validation fails rather than adding to the errors collection. Used for
|
|
|
|
# testing `validates!` and the `:strict => true` validation options.
|
2010-12-15 22:34:19 +00:00
|
|
|
#
|
|
|
|
# Example:
|
|
|
|
# it { should_not allow_value('bad').for(:isbn) }
|
2012-12-20 05:04:27 +00:00
|
|
|
# it { should allow_value('isbn 1 2345 6789 0').for(:isbn) }
|
2010-12-15 22:34:19 +00:00
|
|
|
#
|
2010-09-05 15:33:32 +00:00
|
|
|
def allow_value(*values)
|
2012-03-23 14:10:08 +00:00
|
|
|
if values.empty?
|
2012-12-20 05:04:27 +00:00
|
|
|
raise ArgumentError, 'need at least one argument'
|
2012-03-23 14:10:08 +00:00
|
|
|
else
|
|
|
|
AllowValueMatcher.new(*values)
|
|
|
|
end
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
class AllowValueMatcher # :nodoc:
|
|
|
|
include Helpers
|
|
|
|
|
2013-07-24 21:46:01 +00:00
|
|
|
attr_accessor :attribute_with_message
|
2013-03-28 18:48:45 +00:00
|
|
|
attr_accessor :options
|
|
|
|
|
2010-09-05 15:33:32 +00:00
|
|
|
def initialize(*values)
|
2013-03-28 18:48:45 +00:00
|
|
|
self.values_to_match = values
|
|
|
|
self.message_finder_factory = ValidationMessageFinder
|
|
|
|
self.options = {}
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def for(attribute)
|
2013-07-24 21:46:01 +00:00
|
|
|
self.attribute_to_set = attribute
|
|
|
|
self.attribute_to_check_message_against = attribute
|
2010-12-15 22:34:19 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2013-03-04 03:34:38 +00:00
|
|
|
def on(context)
|
|
|
|
@context = context
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2013-07-24 21:46:01 +00:00
|
|
|
def with_message(message, options={})
|
2013-03-28 18:48:45 +00:00
|
|
|
self.options[:expected_message] = message
|
2013-07-24 21:46:01 +00:00
|
|
|
if options.key?(:against)
|
|
|
|
self.attribute_to_check_message_against = options[:against]
|
|
|
|
end
|
2010-12-15 22:34:19 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2012-09-11 22:40:39 +00:00
|
|
|
def strict
|
2013-03-28 18:48:45 +00:00
|
|
|
self.message_finder_factory = ExceptionMessageFinder
|
2012-09-11 22:40:39 +00:00
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2010-12-15 22:34:19 +00:00
|
|
|
def matches?(instance)
|
2013-03-28 18:48:45 +00:00
|
|
|
self.instance = instance
|
2013-03-26 22:16:04 +00:00
|
|
|
|
2013-03-29 20:10:01 +00:00
|
|
|
values_to_match.none? do |value|
|
|
|
|
self.value = value
|
2013-07-24 21:46:01 +00:00
|
|
|
instance.send("#{attribute_to_set}=", value)
|
2013-03-29 20:10:01 +00:00
|
|
|
errors_match?
|
2010-09-05 15:33:32 +00:00
|
|
|
end
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
|
2013-12-24 11:24:27 +00:00
|
|
|
def failure_message
|
2013-03-28 18:48:45 +00:00
|
|
|
"Did not expect #{expectation}, got error: #{matched_error}"
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
2013-12-24 11:24:27 +00:00
|
|
|
alias failure_message_for_should failure_message
|
2010-12-15 22:34:19 +00:00
|
|
|
|
2013-12-24 11:24:27 +00:00
|
|
|
def failure_message_when_negated
|
2010-12-15 22:34:19 +00:00
|
|
|
"Expected #{expectation}, got #{error_description}"
|
|
|
|
end
|
2013-12-24 11:24:27 +00:00
|
|
|
alias failure_message_for_should_not failure_message_when_negated
|
2010-12-15 22:34:19 +00:00
|
|
|
|
|
|
|
def description
|
2012-09-13 00:41:43 +00:00
|
|
|
message_finder.allow_description(allowed_values)
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2013-03-28 18:48:45 +00:00
|
|
|
attr_accessor :values_to_match, :message_finder_factory,
|
2013-07-24 21:46:01 +00:00
|
|
|
:instance, :attribute_to_set, :attribute_to_check_message_against,
|
|
|
|
:context, :value, :matched_error
|
2013-03-26 22:16:04 +00:00
|
|
|
|
2013-03-29 20:10:01 +00:00
|
|
|
def errors_match?
|
|
|
|
has_messages? && errors_for_attribute_match?
|
2013-03-26 22:16:04 +00:00
|
|
|
end
|
|
|
|
|
2013-03-29 20:10:01 +00:00
|
|
|
def has_messages?
|
|
|
|
message_finder.has_messages?
|
2012-09-11 22:40:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def errors_for_attribute_match?
|
|
|
|
if expected_message
|
2013-03-28 18:48:45 +00:00
|
|
|
self.matched_error = errors_match_regexp? || errors_match_string?
|
2012-09-11 22:40:39 +00:00
|
|
|
else
|
|
|
|
errors_for_attribute.compact.any?
|
2010-09-05 15:23:09 +00:00
|
|
|
end
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
|
2012-03-23 14:10:08 +00:00
|
|
|
def errors_for_attribute
|
2012-09-13 00:41:43 +00:00
|
|
|
message_finder.messages
|
2012-09-11 22:40:39 +00:00
|
|
|
end
|
|
|
|
|
2010-12-15 22:34:19 +00:00
|
|
|
def errors_match_regexp?
|
2012-03-23 14:10:08 +00:00
|
|
|
if Regexp === expected_message
|
2012-05-07 14:25:46 +00:00
|
|
|
errors_for_attribute.detect { |e| e =~ expected_message }
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def errors_match_string?
|
2012-03-23 14:10:08 +00:00
|
|
|
if errors_for_attribute.include?(expected_message)
|
2012-05-07 14:25:46 +00:00
|
|
|
expected_message
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def expectation
|
2012-03-23 14:10:08 +00:00
|
|
|
includes_expected_message = expected_message ? "to include #{expected_message.inspect}" : ''
|
2013-07-24 21:46:01 +00:00
|
|
|
[error_source, includes_expected_message, "when #{attribute_to_set} is set to #{value.inspect}"].join(' ')
|
2012-09-11 22:40:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def error_source
|
2012-09-13 00:41:43 +00:00
|
|
|
message_finder.source_description
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def error_description
|
2012-09-13 00:41:43 +00:00
|
|
|
message_finder.messages_description
|
2012-09-11 22:40:39 +00:00
|
|
|
end
|
|
|
|
|
2012-03-23 14:10:08 +00:00
|
|
|
def allowed_values
|
2013-03-28 18:48:45 +00:00
|
|
|
if values_to_match.length > 1
|
|
|
|
"any of [#{values_to_match.map(&:inspect).join(', ')}]"
|
2012-03-23 14:10:08 +00:00
|
|
|
else
|
2013-03-28 18:48:45 +00:00
|
|
|
values_to_match.first.inspect
|
2012-03-23 14:10:08 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def expected_message
|
2013-03-28 18:48:45 +00:00
|
|
|
if options.key?(:expected_message)
|
|
|
|
if Symbol === options[:expected_message]
|
2012-09-12 00:53:21 +00:00
|
|
|
default_expected_message
|
2012-03-23 14:10:08 +00:00
|
|
|
else
|
2013-03-28 18:48:45 +00:00
|
|
|
options[:expected_message]
|
2012-03-23 14:10:08 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-09-12 00:53:21 +00:00
|
|
|
def default_expected_message
|
2012-09-13 00:41:43 +00:00
|
|
|
message_finder.expected_message_from(default_attribute_message)
|
2012-09-12 00:53:21 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def default_attribute_message
|
2013-02-14 22:25:46 +00:00
|
|
|
default_error_message(
|
2013-03-28 18:48:45 +00:00
|
|
|
options[:expected_message],
|
2013-02-14 22:25:46 +00:00
|
|
|
:model_name => model_name,
|
2013-03-28 18:48:45 +00:00
|
|
|
:instance => instance,
|
2013-07-24 21:46:01 +00:00
|
|
|
:attribute => attribute_to_set
|
2013-02-14 22:25:46 +00:00
|
|
|
)
|
2012-09-12 00:53:21 +00:00
|
|
|
end
|
|
|
|
|
2012-03-23 14:10:08 +00:00
|
|
|
def model_name
|
2013-03-28 18:48:45 +00:00
|
|
|
instance.class.to_s.underscore
|
2012-03-23 14:10:08 +00:00
|
|
|
end
|
2012-09-13 00:23:18 +00:00
|
|
|
|
|
|
|
def message_finder
|
2013-07-24 21:46:01 +00:00
|
|
|
message_finder_factory.new(instance, attribute_to_check_message_against, context)
|
2012-09-13 00:23:18 +00:00
|
|
|
end
|
2012-03-23 14:10:08 +00:00
|
|
|
end
|
2010-12-15 22:34:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|