validates_numericality_of uses \A \Z to ensure the entire string matches rather than ^ $ which may match one valid line of a multiline string. Closes #5716.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5589 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
88bd86e8bc
commit
9594832a8d
|
@ -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]
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue