added :equal_to and :ignore_usec options. the later is for ignore microsecond value in datetime restrictions

This commit is contained in:
Adam Meehan 2009-03-19 20:49:06 +11:00
parent eecef62de4
commit d1ee94248b
4 changed files with 81 additions and 7 deletions

View File

@ -63,6 +63,7 @@ The validation methods take the usual options plus some specific ones to restric
the valid range of dates or times allowed
Temporal options (or restrictions):
:equal_to - Attribute must be equal to value to be valid
:before - Attribute must be before this value to be valid
:on_or_before - Attribute must be equal to or before this value to be valid
:after - Attribute must be after this value to be valid
@ -78,11 +79,13 @@ Regular validation options:
Special options:
:with_time - Validate a date attribute value combined with a time value against any temporal restrictions
:with_date - Validate a time attribute value combined with a date value against any temporal restrictions
:ignore_usec - Ignores microsecond value on datetime restrictions
Message options: - Use these to override the default error messages
:invalid_date_message
:invalid_time_message
:invalid_datetime_message
:equal_to_message
:before_message
:on_or_before_message
:after_message

View File

@ -5,6 +5,7 @@ en:
invalid_date: "is not a valid date"
invalid_time: "is not a valid time"
invalid_datetime: "is not a valid datetime"
equal_to: "must be equal to {{restriction}}"
before: "must be before {{restriction}}"
on_or_before: "must be on or before {{restriction}}"
after: "must be after {{restriction}}"

View File

@ -12,6 +12,7 @@ module ValidatesTimeliness
}
RESTRICTION_METHODS = {
:equal_to => :==,
:before => :<,
:after => :>,
:on_or_before => :<=,
@ -20,14 +21,15 @@ module ValidatesTimeliness
}
VALID_OPTIONS = [
:on, :if, :unless, :allow_nil, :empty, :allow_blank, :blank, :with_time, :with_date,
:on, :if, :unless, :allow_nil, :empty, :allow_blank, :blank,
:with_time, :with_date, :ignore_usec,
:invalid_time_message, :invalid_date_message, :invalid_datetime_message
] + RESTRICTION_METHODS.keys.map {|option| [option, "#{option}_message".to_sym] }.flatten
attr_reader :configuration, :type
def initialize(configuration)
defaults = { :on => :save, :type => :datetime, :allow_nil => false, :allow_blank => false }
defaults = { :on => :save, :type => :datetime, :allow_nil => false, :allow_blank => false, :ignore_usec => false }
@configuration = defaults.merge(configuration)
@type = @configuration.delete(:type)
validate_options(@configuration)
@ -58,7 +60,7 @@ module ValidatesTimeliness
combine_date_and_time(value, record)
else
restriction_type = type
self.class.type_cast_value(value, type)
self.class.type_cast_value(value, type, @configuration[:ignore_usec])
end
return if value.nil?
@ -67,7 +69,7 @@ module ValidatesTimeliness
begin
restriction = self.class.evaluate_option_value(restriction, restriction_type, record)
next if restriction.nil?
restriction = self.class.type_cast_value(restriction, restriction_type)
restriction = self.class.type_cast_value(restriction, restriction_type, @configuration[:ignore_usec])
unless evaluate_restriction(restriction, value, method)
add_error(record, attr_name, option, interpolation_values(option, restriction))
@ -171,11 +173,11 @@ module ValidatesTimeliness
end
end
def type_cast_value(value, type)
def type_cast_value(value, type, ignore_usec=false)
if value.is_a?(Array)
value.map {|v| type_cast_value(v, type) }
value.map {|v| type_cast_value(v, type, ignore_usec) }
else
case type
value = case type
when :time
value.to_dummy_time
when :date
@ -189,6 +191,11 @@ module ValidatesTimeliness
else
nil
end
if ignore_usec && value.is_a?(Time)
::ActiveRecord::Base.send(:make_time, Array(value).reverse[4..9])
else
value
end
end
end

View File

@ -346,6 +346,69 @@ describe ValidatesTimeliness::Validator do
end
end
describe "instance with :equal_to restriction" do
describe "for datetime type" do
before do
configure_validator(:equal_to => Time.now)
end
it "should have error when value not equal to :equal_to restriction" do
validate_with(:birth_date_and_time, Time.now + 1)
should_have_error(:birth_date_and_time, :equal_to)
end
it "should have error when value is equal to :equal_to restriction for all values except microscond, and microsecond is not ignored" do
configure_validator(:equal_to => Time.utc(2000, 1, 1, 0, 0, 0, 0), :ignore_usec => false)
validate_with(:birth_date_and_time, Time.utc(2000, 1, 1, 0, 0, 0, 500))
should_have_error(:birth_date_and_time, :equal_to)
end
it "should be valid when value is equal to :equal_to restriction for all values except microscond, and microsecond is ignored" do
configure_validator(:equal_to => Time.utc(2000, 1, 1, 0, 0, 0, 0), :ignore_usec => true)
validate_with(:birth_date_and_time, Time.utc(2000, 1, 1, 0, 0, 0, 500))
should_have_no_error(:birth_date_and_time, :equal_to)
end
it "should be valid when value is equal to :equal_to restriction" do
validate_with(:birth_date_and_time, Time.now)
should_have_no_error(:birth_date_and_time, :equal_to)
end
end
describe "for date type" do
before do
configure_validator(:type => :date, :equal_to => Date.today)
end
it "should have error when value is not equal to :equal_to restriction" do
validate_with(:birth_date, Date.today + 1)
should_have_error(:birth_date, :equal_to)
end
it "should be valid when value is equal to :equal_to restriction" do
validate_with(:birth_date, Date.today)
should_have_no_error(:birth_date, :equal_to)
end
end
describe "for time type" do
before do
configure_validator(:type => :time, :equal_to => "09:00:00")
end
it "should have error when value is not equal to :equal_to restriction" do
validate_with(:birth_time, "09:00:01")
should_have_error(:birth_time, :equal_to)
end
it "should be valid when value is equal to :equal_to restriction" do
validate_with(:birth_time, "09:00:00")
should_have_no_error(:birth_time, :equal_to)
end
end
end
describe "instance with :with_time option" do
it "should validate date attribute as datetime combining value of :with_time against restrictions " do