Fix validates_confirmation_of matcher so that it works under Rails 4
Rails 4 changed how validates_confirmation_of works so that the error message is applied to the confirmation attribute, not the original attribute.
This commit is contained in:
parent
34c2219b8a
commit
a026afb800
|
@ -30,6 +30,7 @@ module Shoulda # :nodoc:
|
|||
class AllowValueMatcher # :nodoc:
|
||||
include Helpers
|
||||
|
||||
attr_accessor :attribute_with_message
|
||||
attr_accessor :options
|
||||
|
||||
def initialize(*values)
|
||||
|
@ -39,7 +40,8 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def for(attribute)
|
||||
self.attribute = attribute
|
||||
self.attribute_to_set = attribute
|
||||
self.attribute_to_check_message_against = attribute
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -48,8 +50,11 @@ module Shoulda # :nodoc:
|
|||
self
|
||||
end
|
||||
|
||||
def with_message(message)
|
||||
def with_message(message, options={})
|
||||
self.options[:expected_message] = message
|
||||
if options.key?(:against)
|
||||
self.attribute_to_check_message_against = options[:against]
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -63,7 +68,7 @@ module Shoulda # :nodoc:
|
|||
|
||||
values_to_match.none? do |value|
|
||||
self.value = value
|
||||
instance.send("#{attribute}=", value)
|
||||
instance.send("#{attribute_to_set}=", value)
|
||||
errors_match?
|
||||
end
|
||||
end
|
||||
|
@ -83,7 +88,8 @@ module Shoulda # :nodoc:
|
|||
private
|
||||
|
||||
attr_accessor :values_to_match, :message_finder_factory,
|
||||
:instance, :attribute, :context, :value, :matched_error
|
||||
:instance, :attribute_to_set, :attribute_to_check_message_against,
|
||||
:context, :value, :matched_error
|
||||
|
||||
def errors_match?
|
||||
has_messages? && errors_for_attribute_match?
|
||||
|
@ -119,7 +125,7 @@ module Shoulda # :nodoc:
|
|||
|
||||
def expectation
|
||||
includes_expected_message = expected_message ? "to include #{expected_message.inspect}" : ''
|
||||
[error_source, includes_expected_message, "when #{attribute} is set to #{value.inspect}"].join(' ')
|
||||
[error_source, includes_expected_message, "when #{attribute_to_set} is set to #{value.inspect}"].join(' ')
|
||||
end
|
||||
|
||||
def error_source
|
||||
|
@ -157,7 +163,7 @@ module Shoulda # :nodoc:
|
|||
options[:expected_message],
|
||||
:model_name => model_name,
|
||||
:instance => instance,
|
||||
:attribute => attribute
|
||||
:attribute => attribute_to_set
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -166,7 +172,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def message_finder
|
||||
message_finder_factory.new(instance, attribute, context)
|
||||
message_finder_factory.new(instance, attribute_to_check_message_against, context)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,8 +20,8 @@ module Shoulda # :nodoc:
|
|||
self
|
||||
end
|
||||
|
||||
def with_message(message)
|
||||
@allow_matcher.with_message(message)
|
||||
def with_message(message, options={})
|
||||
@allow_matcher.with_message(message, options)
|
||||
self
|
||||
end
|
||||
|
||||
|
|
|
@ -13,9 +13,11 @@ module Shoulda # :nodoc:
|
|||
class ValidateConfirmationOfMatcher < ValidationMatcher # :nodoc:
|
||||
include Helpers
|
||||
|
||||
attr_reader :attribute, :confirmation_attribute
|
||||
|
||||
def initialize(attribute)
|
||||
@attribute = attribute
|
||||
@confirmation = "#{attribute}_confirmation"
|
||||
@confirmation_attribute = "#{attribute}_confirmation"
|
||||
end
|
||||
|
||||
def with_message(message)
|
||||
|
@ -24,7 +26,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def description
|
||||
"require #{@confirmation} to match #{@attribute}"
|
||||
"require #{@confirmation_attribute} to match #{@attribute}"
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
|
@ -40,25 +42,35 @@ module Shoulda # :nodoc:
|
|||
|
||||
def disallows_different_value
|
||||
set_confirmation('some value')
|
||||
disallows_value_of('different value', @message)
|
||||
disallows_value_of('different value') do |matcher|
|
||||
matcher.with_message(@message, against: error_attribute)
|
||||
end
|
||||
end
|
||||
|
||||
def allows_same_value
|
||||
set_confirmation('same value')
|
||||
allows_value_of('same value', @message)
|
||||
allows_value_of('same value') do |matcher|
|
||||
matcher.with_message(@message, against: error_attribute)
|
||||
end
|
||||
end
|
||||
|
||||
def allows_missing_confirmation
|
||||
set_confirmation(nil)
|
||||
allows_value_of('any value', @message)
|
||||
allows_value_of('any value') do |matcher|
|
||||
matcher.with_message(@message, against: error_attribute)
|
||||
end
|
||||
end
|
||||
|
||||
def set_confirmation(val)
|
||||
setter = :"#{@confirmation}="
|
||||
setter = :"#{@confirmation_attribute}="
|
||||
if @subject.respond_to?(setter)
|
||||
@subject.send(setter, val)
|
||||
end
|
||||
end
|
||||
|
||||
def error_attribute
|
||||
RailsShim.validates_confirmation_of_error_attribute(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,8 +30,9 @@ module Shoulda # :nodoc:
|
|||
|
||||
private
|
||||
|
||||
def allows_value_of(value, message = nil)
|
||||
def allows_value_of(value, message = nil, &block)
|
||||
allow = allow_value_matcher(value, message)
|
||||
yield allow if block_given?
|
||||
|
||||
if allow.matches?(@subject)
|
||||
@failure_message_for_should_not = allow.failure_message_for_should_not
|
||||
|
@ -42,8 +43,9 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
def disallows_value_of(value, message = nil)
|
||||
def disallows_value_of(value, message = nil, &block)
|
||||
disallow = disallow_value_matcher(value, message)
|
||||
yield disallow if block_given?
|
||||
|
||||
if disallow.matches?(@subject)
|
||||
@failure_message_for_should_not = disallow.failure_message_for_should_not
|
||||
|
|
|
@ -25,6 +25,14 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
end
|
||||
|
||||
def self.validates_confirmation_of_error_attribute(matcher)
|
||||
if rails_major_version == 4
|
||||
matcher.confirmation_attribute
|
||||
else
|
||||
matcher.attribute
|
||||
end
|
||||
end
|
||||
|
||||
def self.rails_major_version
|
||||
Rails::VERSION::MAJOR
|
||||
end
|
||||
|
|
|
@ -56,6 +56,30 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
|||
end
|
||||
end
|
||||
|
||||
context 'an attribute where the message occurs on another attribute' do
|
||||
it 'allows a good value' do
|
||||
record_with_custom_validation.should \
|
||||
allow_value('good value').for(:attr).with_message(/some message/, :against => :attr2)
|
||||
end
|
||||
|
||||
it 'rejects a bad value' do
|
||||
record_with_custom_validation.should_not \
|
||||
allow_value('bad value').for(:attr).with_message(/some message/, :against => :attr2)
|
||||
end
|
||||
|
||||
def record_with_custom_validation
|
||||
define_model :example, :attr => :string, :attr2 => :string do
|
||||
validate :custom_validation
|
||||
|
||||
def custom_validation
|
||||
if self[:attr] != 'good value'
|
||||
self.errors[:attr2] << 'some message'
|
||||
end
|
||||
end
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
||||
context "an attribute with a context-dependent validation" do
|
||||
context "without the validation context" do
|
||||
it "allows a bad value" do
|
||||
|
|
|
@ -55,6 +55,30 @@ describe Shoulda::Matchers::ActiveModel::DisallowValueMatcher do
|
|||
end
|
||||
end
|
||||
|
||||
context 'an attribute where the message occurs on another attribute' do
|
||||
it 'matches if the message is correct but the value is not' do
|
||||
record_with_custom_validation.should \
|
||||
matcher('bad value').for(:attr).with_message(/some message/, :against => :attr2)
|
||||
end
|
||||
|
||||
it 'does not match if the value and message are both correct' do
|
||||
record_with_custom_validation.should_not \
|
||||
matcher('good value').for(:attr).with_message(/some message/, :against => :attr2)
|
||||
end
|
||||
|
||||
def record_with_custom_validation
|
||||
define_model :example, :attr => :string, :attr2 => :string do
|
||||
validate :custom_validation
|
||||
|
||||
def custom_validation
|
||||
if self[:attr] != 'good value'
|
||||
self.errors[:attr2] << 'some message'
|
||||
end
|
||||
end
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
||||
def matcher(value)
|
||||
described_class.new(value)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue