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 db028738..1e34447b 100644 --- a/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +++ b/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb @@ -7,15 +7,23 @@ module Shoulda # :nodoc: # * with_message - value the test expects to find in # errors.on(:attribute). Regexp or string. Defaults to the # translation for :not_a_number. + # * only_integer - allows only integer values # - # Example: - # it { should validate_numericality_of(:age) } + # Examples: + # it { should validate_numericality_of(:price) } + # it { should validate_numericality_of(:age).only_integer } # def validate_numericality_of(attr) ValidateNumericalityOfMatcher.new(attr) end class ValidateNumericalityOfMatcher < ValidationMatcher # :nodoc: + + def only_integer + @only_integer = true + self + end + def with_message(message) if message @expected_message = message @@ -25,17 +33,30 @@ module Shoulda # :nodoc: def matches?(subject) super(subject) - disallows_value_of('abcd', expected_message) + disallows_double_if_only_integer && + disallows_text end def description - "only allow numeric values for #{@attribute}" + type = if @only_integer then "integer" else "numeric" end + description = "only allow #{type} values for #{@attribute}" + description end private - def expected_message - @expected_message || :not_a_number + def disallows_double_if_only_integer + if @only_integer + message = @expected_message || :not_an_integer + disallows_value_of(0.1, message) && disallows_value_of('0.1', message) + else + true + end + end + + def disallows_text + message = @expected_message || :not_a_number + disallows_value_of('abcd', message) end end end 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 f39f7410..9b1a0bb5 100644 --- a/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb +++ b/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb @@ -19,6 +19,19 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do end end + context "a numeric attribute which must be integer" do + before do + define_model :example, :attr => :string do + validates_numericality_of :attr, { :only_integer => true } + end + @model = Example.new + end + + it "should only allow integer values for that attribute" do + @model.should validate_numericality_of(:attr).only_integer + end + end + context "a numeric attribute with a custom validation message" do before do define_model :example, :attr => :string do