diff --git a/lib/shoulda/matchers/active_model/disallow_value_matcher.rb b/lib/shoulda/matchers/active_model/disallow_value_matcher.rb index 81127636..72326d10 100644 --- a/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +++ b/lib/shoulda/matchers/active_model/disallow_value_matcher.rb @@ -3,7 +3,7 @@ module Shoulda # :nodoc: module ActiveModel # :nodoc: class DisallowValueMatcher # :nodoc: def initialize(value) - @allow_matcher = Shoulda::Matchers::ActiveModel::AllowValueMatcher.new(value) + @allow_matcher = AllowValueMatcher.new(value) end def matches?(subject) diff --git a/lib/shoulda/matchers/active_model/only_integer_matcher.rb b/lib/shoulda/matchers/active_model/only_integer_matcher.rb index 1827a522..220b56cc 100644 --- a/lib/shoulda/matchers/active_model/only_integer_matcher.rb +++ b/lib/shoulda/matchers/active_model/only_integer_matcher.rb @@ -2,22 +2,31 @@ module Shoulda # :nodoc: module Matchers module ActiveModel # :nodoc: class OnlyIntegerMatcher # :nodoc: + NON_INTEGER_VALUE = 0.1 + def initialize(attribute) @attribute = attribute + @disallow_value_matcher = DisallowValueMatcher.new(NON_INTEGER_VALUE). + for(attribute). + with_message(:not_an_integer) end def matches?(subject) - matcher = AllowValueMatcher.new(0.1).for(@attribute) - !matcher.matches?(subject) + @disallow_value_matcher.matches?(subject) end def with_message(message) + @disallow_value_matcher.with_message(message) self end def allowed_types "integer" end + + def failure_message + @disallow_value_matcher.failure_message + end end end end diff --git a/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb b/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb index 39d0e913..33a93b11 100644 --- a/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +++ b/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb @@ -18,6 +18,8 @@ module Shoulda # :nodoc: end class ValidateNumericalityOfMatcher + NON_NUMERIC_VALUE = 'abcd' + def initialize(attribute) @attribute = attribute @options = {} @@ -29,18 +31,16 @@ module Shoulda # :nodoc: def only_integer only_integer_matcher = OnlyIntegerMatcher.new(@attribute) add_submatcher(only_integer_matcher) - self end def with_message(message) - @expected_message = message + @submatchers.each { |matcher| matcher.with_message(message) } self end def matches?(subject) @subject = subject - set_expected_message_on_submatchers submatchers_match? end @@ -49,27 +49,33 @@ module Shoulda # :nodoc: end def failure_message - @disallow_value_matcher.failure_message + submatcher_failure_messages.last end private def add_disallow_value_matcher - @disallow_value_matcher = DisallowValueMatcher.new('abcd').for(@attribute) - add_submatcher(@disallow_value_matcher) + disallow_value_matcher = DisallowValueMatcher.new(NON_NUMERIC_VALUE). + for(@attribute). + with_message(:not_a_number) + + add_submatcher(disallow_value_matcher) end def add_submatcher(submatcher) @submatchers << submatcher end - def set_expected_message_on_submatchers - message = @expected_message || :not_a_number - @submatchers.each { |matcher| matcher.with_message(message) } + def submatchers_match? + failing_submatchers.empty? end - def submatchers_match? - @submatchers.all? { |matcher| matcher.matches?(@subject) } + def submatcher_failure_messages + failing_submatchers.map(&:failure_message) + end + + def failing_submatchers + @failing_submatchers ||= @submatchers.select { |matcher| !matcher.matches?(@subject) } end def allowed_types @@ -78,7 +84,7 @@ module Shoulda # :nodoc: end def submatcher_allowed_types - @submatchers.map(&:allowed_types).reject { |type| type.empty? } + @submatchers.map(&:allowed_types).reject(&:empty?) end end end diff --git a/spec/shoulda/active_model/disallow_value_matcher_spec.rb b/spec/shoulda/active_model/disallow_value_matcher_spec.rb index f5d02b98..5c4bcba6 100644 --- a/spec/shoulda/active_model/disallow_value_matcher_spec.rb +++ b/spec/shoulda/active_model/disallow_value_matcher_spec.rb @@ -42,7 +42,7 @@ describe Shoulda::Matchers::ActiveModel::DisallowValueMatcher do end it "delegates its failure message to its allow matcher's negative failure message" do - allow_matcher = stub_everything(negative_failure_message: "allow matcher failure") + allow_matcher = stub_everything(:negative_failure_message => "allow matcher failure") Shoulda::Matchers::ActiveModel::AllowValueMatcher.stubs(:new).returns(allow_matcher) matcher = new_matcher("abcde") diff --git a/spec/shoulda/active_model/only_integer_matcher_spec.rb b/spec/shoulda/active_model/only_integer_matcher_spec.rb index fe097b55..3d45dc73 100644 --- a/spec/shoulda/active_model/only_integer_matcher_spec.rb +++ b/spec/shoulda/active_model/only_integer_matcher_spec.rb @@ -25,6 +25,27 @@ describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do end end + context "given an attribute that only allows integer values with a custom validation message" do + before do + define_model :example, :attr => :string do + validates_numericality_of :attr, { :only_integer => true, :message => 'custom' } + end + @model = Example.new + end + + it "should only allow integer values for that attribute with that message" do + matcher = new_matcher(:attr) + matcher.with_message(/custom/) + matcher.matches?(@model).should be_true + end + + it "should not allow integer values for that attribute with another message" do + matcher = new_matcher(:attr) + matcher.with_message(/wrong/) + matcher.matches?(@model).should be_false + end + end + context "given an attribute that allows values other than integers" do before do @model = define_model(:example, :attr => :string).new @@ -34,6 +55,12 @@ describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do matcher = new_matcher(:attr) matcher.matches?(@model).should be_false end + + it "should fail with the ActiveRecord :not_an_integer message" do + matcher = new_matcher(:attr) + matcher.matches?(@model) + matcher.failure_message.should include 'Expected errors to include "must be an integer"' + end end def new_matcher(attribute) diff --git a/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb b/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb index 899c0659..f031f39a 100644 --- a/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb +++ b/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb @@ -25,10 +25,19 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do matcher.matches?(@model).should be_true end - it "should not enforce integer values for that attribute" do - matcher = new_matcher(:attr) - matcher.only_integer - matcher.matches?(@model).should be_false + context "when asked to enforce integer values for that attribute" do + it "should not match" do + matcher = new_matcher(:attr) + matcher.only_integer + matcher.matches?(@model).should be_false + end + + it "should fail with the ActiveRecord :not_an_integer message" do + matcher = new_matcher(:attr) + matcher.only_integer + matcher.matches?(@model) + matcher.failure_message.should include 'Expected errors to include "must be an integer"' + end end end