-
-
Notifications
You must be signed in to change notification settings - Fork 912
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract ExceptionMessageFinder from AllowValueMatcher
* Replaces repeated conditional with polymorphism
- Loading branch information
Showing
5 changed files
with
181 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
lib/shoulda/matchers/active_model/exception_message_finder.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
spec/shoulda/active_model/exception_message_finder_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|