Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Extract ValidationMessageFinder from AllowValueMatcher

  • Loading branch information...
commit 3dbf5d4f0d5943ae11f7c770a172c9c71f24ac87 1 parent 96d32c2
Joe Ferris jferris authored
1  lib/shoulda/matchers/active_model.rb
View
@@ -1,5 +1,6 @@
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/allow_value_matcher'
require 'shoulda/matchers/active_model/ensure_length_of_matcher'
require 'shoulda/matchers/active_model/ensure_inclusion_of_matcher'
51 lib/shoulda/matchers/active_model/allow_value_matcher.rb
View
@@ -71,34 +71,30 @@ def description
if strict?
"strictly #{base}"
else
- base
+ message_finder.allow_description(allowed_values)
end
end
private
def errors_match?
+ has_messages? && errors_for_attribute_match?
+ end
+
+ def has_messages?
if strict?
- exception_message_matches?
+ has_exception_message?
else
- validation_messages_match?
+ message_finder.has_messages?
end
end
- def exception_message_matches?
+ def has_exception_message?
@instance.valid?
false
rescue ::ActiveModel::StrictValidationFailed => exception
@strict_exception = exception
- errors_for_attribute_match?
- end
-
- def validation_messages_match?
- if @instance.valid?
- false
- else
- errors_for_attribute_match?
- end
+ true
end
def errors_for_attribute_match?
@@ -113,7 +109,7 @@ def errors_for_attribute
if strict?
[strict_exception_message]
else
- validation_messages_for_attribute
+ message_finder.messages
end
end
@@ -121,15 +117,6 @@ def strict_exception_message
@strict_exception.message
end
- def validation_messages_for_attribute
- if @instance.errors.respond_to?(:[])
- errors = @instance.errors[@attribute]
- else
- errors = @instance.errors.on(@attribute)
- end
- Array.wrap(errors)
- end
-
def strict?
@strict
end
@@ -155,7 +142,7 @@ def error_source
if strict?
'exception'
else
- 'errors'
+ message_finder.source_description
end
end
@@ -163,7 +150,7 @@ def error_description
if strict?
exception_description
else
- validation_error_description
+ message_finder.messages_description
end
end
@@ -175,14 +162,6 @@ def exception_description
end
end
- def validation_error_description
- if @instance.errors.empty?
- "no errors"
- else
- "errors: #{pretty_error_messages(@instance)}"
- end
- end
-
def allowed_values
if @values_to_match.length > 1
"any of [#{@values_to_match.map(&:inspect).join(', ')}]"
@@ -205,7 +184,7 @@ def default_expected_message
if strict?
default_full_message
else
- default_attribute_message
+ message_finder.expected_message_from(default_attribute_message)
end
end
@@ -228,6 +207,10 @@ def default_attribute_message
def model_name
@instance.class.to_s.underscore
end
+
+ def message_finder
+ @message_finder ||= ValidationMessageFinder.new(@instance, @attribute)
+ end
end
end
end
69 lib/shoulda/matchers/active_model/validation_message_finder.rb
View
@@ -0,0 +1,69 @@
+module Shoulda
+ module Matchers
+ module ActiveModel
+
+ # Finds message information from a model's #errors method.
+ class ValidationMessageFinder
+ include Helpers
+
+ def initialize(instance, attribute)
+ @instance = instance
+ @attribute = attribute
+ end
+
+ def allow_description(allowed_values)
+ "allow #{@attribute} to be set to #{allowed_values}"
+ end
+
+ def expected_message_from(attribute_message)
+ attribute_message
+ end
+
+ def has_messages?
+ errors.present?
+ end
+
+ def source_description
+ 'errors'
+ end
+
+ def messages_description
+ if errors.empty?
+ "no errors"
+ else
+ "errors: #{pretty_error_messages(validated_instance)}"
+ end
+ end
+
+ def messages
+ Array.wrap(messages_for_attribute)
+ end
+
+ private
+
+ def messages_for_attribute
+ if errors.respond_to?(:[])
+ errors[@attribute]
+ else
+ errors.on(@attribute)
+ end
+ end
+
+ def errors
+ validated_instance.errors
+ end
+
+ def validated_instance
+ @validated_instance ||= validate_instance
+ end
+
+ def validate_instance
+ @instance.valid?
+ @instance
+ end
+ end
+
+ end
+ end
+end
+
105 spec/shoulda/active_model/validation_message_finder_spec.rb
View
@@ -0,0 +1,105 @@
+require 'spec_helper'
+
+describe Shoulda::Matchers::ActiveModel::ValidationMessageFinder do
+ context '#allow_description' do
+ it 'describes its attribute' do
+ finder = build_finder(:attribute => :attr)
+
+ description = finder.allow_description('allowed values')
+
+ description.should == 'allow attr to be set to allowed values'
+ end
+ end
+
+ context '#expected_message_from' do
+ it 'returns the message as-is' do
+ finder = build_finder
+
+ message = finder.expected_message_from('some message')
+
+ message.should == '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(:format => /abc/, :value => 'xyz')
+
+ messages = finder.messages
+
+ messages.should == ['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 == 'errors: ["attr is invalid (\"xyz\")"]'
+ end
+
+ it 'describes errors when there are none' do
+ finder = build_finder(:format => /abc/, :value => 'abc')
+
+ description = finder.messages_description
+
+ description.should == 'no errors'
+ end
+ end
+
+ context '#source_description' do
+ it 'describes the source of its messages' do
+ finder = build_finder
+
+ description = finder.source_description
+
+ description.should == 'errors'
+ end
+ end
+
+ def build_finder(arguments = {})
+ arguments[:attribute] ||= :attr
+ instance = build_instance_validating(
+ arguments[:attribute],
+ arguments[:format] || /abc/,
+ arguments[:value] || 'abc'
+ )
+ Shoulda::Matchers::ActiveModel::ValidationMessageFinder.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
+ end
+
+ model_class.new(attribute => value)
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.