Extract ExceptionMessageFinder from AllowValueMatcher
* Replaces repeated conditional with polymorphism
This commit is contained in:
parent
3dbf5d4f0d
commit
87327c225a
|
@ -1,6 +1,7 @@
|
|||
require 'shoulda/matchers/active_model/helpers'
|
||||
require 'shoulda/matchers/active_model/validation_matcher'
|
||||
require 'shoulda/matchers/active_model/validation_message_finder'
|
||||
require 'shoulda/matchers/active_model/exception_message_finder'
|
||||
require 'shoulda/matchers/active_model/allow_value_matcher'
|
||||
require 'shoulda/matchers/active_model/ensure_length_of_matcher'
|
||||
require 'shoulda/matchers/active_model/ensure_inclusion_of_matcher'
|
||||
|
|
|
@ -29,7 +29,7 @@ module Shoulda # :nodoc:
|
|||
|
||||
def initialize(*values)
|
||||
@values_to_match = values
|
||||
@strict = false
|
||||
@message_finder_factory = ValidationMessageFinder
|
||||
@options = {}
|
||||
end
|
||||
|
||||
|
@ -44,7 +44,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def strict
|
||||
@strict = true
|
||||
@message_finder_factory = ExceptionMessageFinder
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -66,13 +66,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def description
|
||||
base = "allow #{@attribute} to be set to #{allowed_values}"
|
||||
|
||||
if strict?
|
||||
"strictly #{base}"
|
||||
else
|
||||
message_finder.allow_description(allowed_values)
|
||||
end
|
||||
message_finder.allow_description(allowed_values)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -82,19 +76,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def has_messages?
|
||||
if strict?
|
||||
has_exception_message?
|
||||
else
|
||||
message_finder.has_messages?
|
||||
end
|
||||
end
|
||||
|
||||
def has_exception_message?
|
||||
@instance.valid?
|
||||
false
|
||||
rescue ::ActiveModel::StrictValidationFailed => exception
|
||||
@strict_exception = exception
|
||||
true
|
||||
message_finder.has_messages?
|
||||
end
|
||||
|
||||
def errors_for_attribute_match?
|
||||
|
@ -106,19 +88,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def errors_for_attribute
|
||||
if strict?
|
||||
[strict_exception_message]
|
||||
else
|
||||
message_finder.messages
|
||||
end
|
||||
end
|
||||
|
||||
def strict_exception_message
|
||||
@strict_exception.message
|
||||
end
|
||||
|
||||
def strict?
|
||||
@strict
|
||||
message_finder.messages
|
||||
end
|
||||
|
||||
def errors_match_regexp?
|
||||
|
@ -139,27 +109,11 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def error_source
|
||||
if strict?
|
||||
'exception'
|
||||
else
|
||||
message_finder.source_description
|
||||
end
|
||||
message_finder.source_description
|
||||
end
|
||||
|
||||
def error_description
|
||||
if strict?
|
||||
exception_description
|
||||
else
|
||||
message_finder.messages_description
|
||||
end
|
||||
end
|
||||
|
||||
def exception_description
|
||||
if @strict_exception
|
||||
strict_exception_message
|
||||
else
|
||||
'no exception'
|
||||
end
|
||||
message_finder.messages_description
|
||||
end
|
||||
|
||||
def allowed_values
|
||||
|
@ -181,19 +135,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def default_expected_message
|
||||
if strict?
|
||||
default_full_message
|
||||
else
|
||||
message_finder.expected_message_from(default_attribute_message)
|
||||
end
|
||||
end
|
||||
|
||||
def default_full_message
|
||||
"#{human_attribute_name} #{default_attribute_message}"
|
||||
end
|
||||
|
||||
def human_attribute_name
|
||||
@instance.class.human_attribute_name(@attribute)
|
||||
message_finder.expected_message_from(default_attribute_message)
|
||||
end
|
||||
|
||||
def default_attribute_message
|
||||
|
@ -209,7 +151,7 @@ module Shoulda # :nodoc:
|
|||
end
|
||||
|
||||
def message_finder
|
||||
@message_finder ||= ValidationMessageFinder.new(@instance, @attribute)
|
||||
@message_finder ||= @message_finder_factory.new(@instance, @attribute)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
module Shoulda
|
||||
module Matchers
|
||||
module ActiveModel
|
||||
|
||||
# Finds message information from exceptions thrown by #valid?
|
||||
class ExceptionMessageFinder
|
||||
def initialize(instance, attribute)
|
||||
@instance = instance
|
||||
@attribute = attribute
|
||||
end
|
||||
|
||||
def allow_description(allowed_values)
|
||||
"doesn't raise when #{@attribute} is set to #{allowed_values}"
|
||||
end
|
||||
|
||||
def messages_description
|
||||
if has_messages?
|
||||
messages.join
|
||||
else
|
||||
'no exception'
|
||||
end
|
||||
end
|
||||
|
||||
def has_messages?
|
||||
messages.any?
|
||||
end
|
||||
|
||||
def messages
|
||||
@messages ||= validate_and_rescue
|
||||
end
|
||||
|
||||
def source_description
|
||||
'exception'
|
||||
end
|
||||
|
||||
def expected_message_from(attribute_message)
|
||||
"#{human_attribute_name} #{attribute_message}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_and_rescue
|
||||
@instance.valid?
|
||||
[]
|
||||
rescue ::ActiveModel::StrictValidationFailed => exception
|
||||
[exception.message]
|
||||
end
|
||||
|
||||
def human_attribute_name
|
||||
@instance.class.human_attribute_name(@attribute)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
|||
|
||||
it "describes itself" do
|
||||
allow_value("xyz").for(:attr).strict.description.
|
||||
should == 'strictly allow attr to be set to "xyz"'
|
||||
should == %{doesn't raise when attr is set to "xyz"}
|
||||
end
|
||||
|
||||
it "provides a useful negative failure message" do
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::ExceptionMessageFinder do
|
||||
if Rails::VERSION::STRING.to_f >= 3.2
|
||||
context '#allow_description' do
|
||||
it 'describes its attribute' do
|
||||
finder = build_finder(:attribute => :attr)
|
||||
|
||||
description = finder.allow_description('allowed values')
|
||||
|
||||
description.should == "doesn't raise when attr is set to allowed values"
|
||||
end
|
||||
end
|
||||
|
||||
context '#expected_message_from' do
|
||||
it 'returns the message with the attribute name prefixed' do
|
||||
finder = build_finder(:attribute => :attr)
|
||||
|
||||
message = finder.expected_message_from('some message')
|
||||
|
||||
message.should == 'Attr some message'
|
||||
end
|
||||
end
|
||||
|
||||
context '#has_messages?' do
|
||||
it 'has messages when some validations fail' do
|
||||
finder = build_finder(:format => /abc/, :value => 'xyz')
|
||||
|
||||
result = finder.has_messages?
|
||||
|
||||
result.should be_true
|
||||
end
|
||||
|
||||
it 'has no messages when all validations pass' do
|
||||
finder = build_finder(:format => /abc/, :value => 'abc')
|
||||
|
||||
result = finder.has_messages?
|
||||
|
||||
result.should be_false
|
||||
end
|
||||
end
|
||||
|
||||
context '#messages' do
|
||||
it 'returns errors for the given attribute' do
|
||||
finder = build_finder(
|
||||
:attribute => :attr,
|
||||
:format => /abc/,
|
||||
:value => 'xyz'
|
||||
)
|
||||
|
||||
messages = finder.messages
|
||||
|
||||
messages.should == ['Attr is invalid']
|
||||
end
|
||||
end
|
||||
|
||||
context '#messages_description' do
|
||||
it 'describes errors for the given attribute' do
|
||||
finder = build_finder(
|
||||
:attribute => :attr,
|
||||
:format => /abc/,
|
||||
:value => 'xyz'
|
||||
)
|
||||
|
||||
description = finder.messages_description
|
||||
|
||||
description.should == 'Attr is invalid'
|
||||
end
|
||||
|
||||
it 'describes errors when there are none' do
|
||||
finder = build_finder(:format => /abc/, :value => 'abc')
|
||||
|
||||
description = finder.messages_description
|
||||
|
||||
description.should == 'no exception'
|
||||
end
|
||||
end
|
||||
|
||||
context '#source_description' do
|
||||
it 'describes the source of its messages' do
|
||||
finder = build_finder
|
||||
|
||||
description = finder.source_description
|
||||
|
||||
description.should == 'exception'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def build_finder(arguments = {})
|
||||
arguments[:attribute] ||= :attr
|
||||
instance = build_instance_validating(
|
||||
arguments[:attribute],
|
||||
arguments[:format] || /abc/,
|
||||
arguments[:value] || 'abc'
|
||||
)
|
||||
Shoulda::Matchers::ActiveModel::ExceptionMessageFinder.new(
|
||||
instance,
|
||||
arguments[:attribute]
|
||||
)
|
||||
end
|
||||
|
||||
def build_instance_validating(attribute, format, value)
|
||||
model_class = define_model(:example, attribute => :string) do
|
||||
attr_accessible attribute
|
||||
validates_format_of attribute, :with => format, :strict => true
|
||||
end
|
||||
|
||||
model_class.new(attribute => value)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue