diff options
-rw-r--r-- | activerecord/CHANGELOG | 2 | ||||
-rwxr-xr-x | activerecord/lib/active_record/validations.rb | 8 | ||||
-rwxr-xr-x | activerecord/test/validations_test.rb | 31 |
3 files changed, 26 insertions, 15 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index 269d58a70d..5f6daf66ff 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* validates_numericality_of uses \A \Z to ensure the entire string matches rather than ^ $ which may match one valid line of a multiline string. #5716 [Andreas Schwarz] + * Run validations in the order they were declared. #6657 [obrie] * MySQL: detect when a NOT NULL column without a default value is misreported as default ''. Can't detect for string, text, and binary columns since '' is a legitimate default. #6156 [simon@redhillconsulting.com.au, obrie, Jeremy Kemper] diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index d7a425701b..3bc0e8fa37 100755 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -559,9 +559,11 @@ module ActiveRecord # provided. # # class Person < ActiveRecord::Base - # validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :on => :create + # validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create # end # + # Note: use \A and \Z to match the start and end of the string, ^ and $ match the start/end of a line. + # # A regular expression must be provided or else an exception will be raised. # # Configuration options: @@ -675,7 +677,7 @@ module ActiveRecord # Validates whether the value of the specified attribute is numeric by trying to convert it to # a float with Kernel.Float (if <tt>integer</tt> is false) or applying it to the regular expression - # <tt>/^[\+\-]?\d+$/</tt> (if <tt>integer</tt> is set to true). + # <tt>/\A[\+\-]?\d+\Z/</tt> (if <tt>integer</tt> is set to true). # # class Person < ActiveRecord::Base # validates_numericality_of :value, :on => :create @@ -696,7 +698,7 @@ module ActiveRecord if configuration[:only_integer] validates_each(attr_names,configuration) do |record, attr_name,value| - record.errors.add(attr_name, configuration[:message]) unless record.send("#{attr_name}_before_type_cast").to_s =~ /^[+-]?\d+$/ + record.errors.add(attr_name, configuration[:message]) unless record.send("#{attr_name}_before_type_cast").to_s =~ /\A[+-]?\d+\Z/ end else validates_each(attr_names,configuration) do |record, attr_name,value| diff --git a/activerecord/test/validations_test.rb b/activerecord/test/validations_test.rb index df1b400096..92a11778ef 100755 --- a/activerecord/test/validations_test.rb +++ b/activerecord/test/validations_test.rb @@ -1037,15 +1037,16 @@ class ValidationsTest < Test::Unit::TestCase end -class ValidatesNumericalityTest - NIL = [nil, "", " ", " \t \r \n"] +class ValidatesNumericalityTest < Test::Unit::TestCase + NIL = [nil] + BLANK = ["", " ", " \t \r \n"] BIGDECIMAL_STRINGS = %w(12345678901234567890.1234567890) # 30 significent digits FLOAT_STRINGS = %w(0.0 +0.0 -0.0 10.0 10.5 -10.5 -0.0001 -090.1 90.1e1 -90.1e5 -90.1e-5 90e-5) INTEGER_STRINGS = %w(0 +0 -0 10 +10 -10 0090 -090) FLOATS = [0.0, 10.0, 10.5, -10.5, -0.0001] + FLOAT_STRINGS INTEGERS = [0, 10, -10] + INTEGER_STRINGS BIGDECIMAL = BIGDECIMAL_STRINGS.collect! { |bd| BigDecimal.new(bd) } - JUNK = ["not a number", "42 not a number", "0xdeadbeef", "00-1", "--3", "+-3", "+3-1", "-+019.0", "12.12.13.12"] + JUNK = ["not a number", "42 not a number", "0xdeadbeef", "00-1", "--3", "+-3", "+3-1", "-+019.0", "12.12.13.12", "123\nnot a number"] def setup Topic.write_inheritable_attribute(:validate, nil) @@ -1056,44 +1057,50 @@ class ValidatesNumericalityTest def test_default_validates_numericality_of Topic.validates_numericality_of :approved - invalid!(NIL + JUNK) + invalid!(NIL + BLANK + JUNK) valid!(FLOATS + INTEGERS + BIGDECIMAL) end def test_validates_numericality_of_with_nil_allowed Topic.validates_numericality_of :approved, :allow_nil => true - invalid!(JUNK) + invalid!(BLANK + JUNK) valid!(NIL + FLOATS + INTEGERS + BIGDECIMAL) end def test_validates_numericality_of_with_integer_only Topic.validates_numericality_of :approved, :only_integer => true - invalid!(NIL + JUNK + FLOATS + BIGDECIMAL) + invalid!(NIL + BLANK + JUNK + FLOATS + BIGDECIMAL) valid!(INTEGERS) end def test_validates_numericality_of_with_integer_only_and_nil_allowed Topic.validates_numericality_of :approved, :only_integer => true, :allow_nil => true - invalid!(JUNK + FLOATS + BIGDECIMAL) + invalid!(BLANK + JUNK + FLOATS + BIGDECIMAL) valid!(NIL + INTEGERS) end private def invalid!(values) - values.each do |value| - topic = Topic.create("title" => "numeric test", "content" => "whatever", "approved" => value) - assert !topic.valid?, "#{value} not rejected as a number" + with_each_topic_approved_value(values) do |topic, value| + assert !topic.valid?, "#{value.inspect} not rejected as a number" assert topic.errors.on(:approved) end end def valid!(values) + with_each_topic_approved_value(values) do |topic, value| + assert topic.valid?, "#{value.inspect} not accepted as a number" + end + end + + def with_each_topic_approved_value(values) + topic = Topic.new("title" => "numeric test", "content" => "whatever") values.each do |value| - topic = Topic.create("title" => "numeric test", "content" => "whatever", "approved" => value) - assert topic.valid?, "#{value} not accepted as a number" + topic.approved = value + yield topic, value end end end |