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/helpers'
|
||||||
require 'shoulda/matchers/active_model/validation_matcher'
|
require 'shoulda/matchers/active_model/validation_matcher'
|
||||||
require 'shoulda/matchers/active_model/validation_message_finder'
|
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/allow_value_matcher'
|
||||||
require 'shoulda/matchers/active_model/ensure_length_of_matcher'
|
require 'shoulda/matchers/active_model/ensure_length_of_matcher'
|
||||||
require 'shoulda/matchers/active_model/ensure_inclusion_of_matcher'
|
require 'shoulda/matchers/active_model/ensure_inclusion_of_matcher'
|
||||||
|
|
|
@ -29,7 +29,7 @@ module Shoulda # :nodoc:
|
||||||
|
|
||||||
def initialize(*values)
|
def initialize(*values)
|
||||||
@values_to_match = values
|
@values_to_match = values
|
||||||
@strict = false
|
@message_finder_factory = ValidationMessageFinder
|
||||||
@options = {}
|
@options = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
def strict
|
def strict
|
||||||
@strict = true
|
@message_finder_factory = ExceptionMessageFinder
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -66,13 +66,7 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
def description
|
def description
|
||||||
base = "allow #{@attribute} to be set to #{allowed_values}"
|
message_finder.allow_description(allowed_values)
|
||||||
|
|
||||||
if strict?
|
|
||||||
"strictly #{base}"
|
|
||||||
else
|
|
||||||
message_finder.allow_description(allowed_values)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -82,19 +76,7 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_messages?
|
def has_messages?
|
||||||
if strict?
|
message_finder.has_messages?
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def errors_for_attribute_match?
|
def errors_for_attribute_match?
|
||||||
|
@ -106,19 +88,7 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
def errors_for_attribute
|
def errors_for_attribute
|
||||||
if strict?
|
message_finder.messages
|
||||||
[strict_exception_message]
|
|
||||||
else
|
|
||||||
message_finder.messages
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def strict_exception_message
|
|
||||||
@strict_exception.message
|
|
||||||
end
|
|
||||||
|
|
||||||
def strict?
|
|
||||||
@strict
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def errors_match_regexp?
|
def errors_match_regexp?
|
||||||
|
@ -139,27 +109,11 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
def error_source
|
def error_source
|
||||||
if strict?
|
message_finder.source_description
|
||||||
'exception'
|
|
||||||
else
|
|
||||||
message_finder.source_description
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def error_description
|
def error_description
|
||||||
if strict?
|
message_finder.messages_description
|
||||||
exception_description
|
|
||||||
else
|
|
||||||
message_finder.messages_description
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def exception_description
|
|
||||||
if @strict_exception
|
|
||||||
strict_exception_message
|
|
||||||
else
|
|
||||||
'no exception'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def allowed_values
|
def allowed_values
|
||||||
|
@ -181,19 +135,7 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_expected_message
|
def default_expected_message
|
||||||
if strict?
|
message_finder.expected_message_from(default_attribute_message)
|
||||||
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)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_attribute_message
|
def default_attribute_message
|
||||||
|
@ -209,7 +151,7 @@ module Shoulda # :nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
def message_finder
|
def message_finder
|
||||||
@message_finder ||= ValidationMessageFinder.new(@instance, @attribute)
|
@message_finder ||= @message_finder_factory.new(@instance, @attribute)
|
||||||
end
|
end
|
||||||
end
|
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
|
it "describes itself" do
|
||||||
allow_value("xyz").for(:attr).strict.description.
|
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
|
end
|
||||||
|
|
||||||
it "provides a useful negative failure message" do
|
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