refactored parsing and conversion with timezones. removed some cruft

This commit is contained in:
Adam Meehan 2010-09-17 08:32:56 +10:00
parent 3530e3a58c
commit 3f0e430eab
3 changed files with 31 additions and 28 deletions

View File

@ -2,6 +2,9 @@ module ValidatesTimeliness
module Conversion module Conversion
def type_cast_value(value, type) def type_cast_value(value, type)
return nil if value.nil?
value.in_time_zone if value.acts_like?(:time) && @timezone_aware
value = case type value = case type
when :time when :time
dummy_time(value) dummy_time(value)
@ -10,8 +13,6 @@ module ValidatesTimeliness
when :datetime when :datetime
value.to_time value.to_time
end end
rescue
nil
end end
def dummy_time(value) def dummy_time(value)
@ -20,30 +21,25 @@ module ValidatesTimeliness
else else
[0,0,0] [0,0,0]
end end
Time.send(ValidatesTimeliness.default_timezone, *(ValidatesTimeliness.dummy_date_for_time_type + time)) values = ValidatesTimeliness.dummy_date_for_time_type + time
@timezone_aware ? Time.zone.local(*values) : Time.send(ValidatesTimeliness.default_timezone, *values)
end end
def evaluate_option_value(value, record, timezone_aware=false) def evaluate_option_value(value, record)
case value case value
when Time when Time, Date
timezone_aware ? value.in_time_zone : value
when Date
value value
when String when String
if ValidatesTimeliness.use_plugin_parser parse(value)
ValidatesTimeliness::Parser.parse(value, :datetime, :timezone_aware => timezone_aware, :strict => false)
else
timezone_aware ? Time.zone.parse(value) : value.to_time(ValidatesTimeliness.default_timezone)
end
when Symbol when Symbol
if !record.respond_to?(value) && restriction_shorthand?(value) if !record.respond_to?(value) && restriction_shorthand?(value)
ValidatesTimeliness.restriction_shorthand_symbols[value].call ValidatesTimeliness.restriction_shorthand_symbols[value].call
else else
evaluate_option_value(record.send(value), record, timezone_aware) evaluate_option_value(record.send(value), record)
end end
when Proc when Proc
result = value.arity > 0 ? value.call(record) : value.call result = value.arity > 0 ? value.call(record) : value.call
evaluate_option_value(result, record, timezone_aware) evaluate_option_value(result, record)
else else
value value
end end
@ -53,5 +49,15 @@ module ValidatesTimeliness
ValidatesTimeliness.restriction_shorthand_symbols.keys.include?(symbol) ValidatesTimeliness.restriction_shorthand_symbols.keys.include?(symbol)
end end
def parse(value)
if ValidatesTimeliness.use_plugin_parser
ValidatesTimeliness::Parser.parse(value, @type, :timezone_aware => @timezone_aware, :strict => false)
else
@timezone_aware ? Time.zone.parse(value) : value.to_time(ValidatesTimeliness.default_timezone)
end
rescue ArgumentError, TypeError
nil
end
end end
end end

View File

@ -38,17 +38,19 @@ module ValidatesTimeliness
end end
def validate_each(record, attr_name, value) def validate_each(record, attr_name, value)
raw_value = attribute_raw_value(record, attr_name) || value raw_value = record._timeliness_raw_value_for(attr_name) || value
return if (@allow_nil && raw_value.nil?) || (@allow_blank && raw_value.blank?) return if (@allow_nil && raw_value.nil?) || (@allow_blank && raw_value.blank?)
timezone_aware = record.class.timeliness_attribute_timezone_aware?(attr_name) @timezone_aware = record.class.timeliness_attribute_timezone_aware?(attr_name)
value = type_cast(value) value = parse(value) if value.is_a?(String)
value = type_cast_value(value, @type)
return record.errors.add(attr_name, :"invalid_#{@type}") if value.blank? return record.errors.add(attr_name, :"invalid_#{@type}") if value.blank?
@restrictions_to_check.each do |restriction| @restrictions_to_check.each do |restriction|
begin begin
restriction_value = type_cast(evaluate_option_value(options[restriction], record, timezone_aware)) restriction_value = type_cast_value(evaluate_option_value(options[restriction], record), @type)
unless value.send(RESTRICTIONS[restriction], restriction_value) unless value.send(RESTRICTIONS[restriction], restriction_value)
return record.errors.add(attr_name, restriction, :message => options[:"#{restriction}_message"], :restriction => format_error_value(restriction_value)) return record.errors.add(attr_name, restriction, :message => options[:"#{restriction}_message"], :restriction => format_error_value(restriction_value))
end end
@ -60,18 +62,11 @@ module ValidatesTimeliness
end end
end end
def attribute_raw_value(record, attr_name)
record._timeliness_raw_value_for(attr_name)
end
def type_cast(value)
type_cast_value(value, @type)
end
def format_error_value(value) def format_error_value(value)
format = I18n.t(@type, :scope => 'validates_timeliness.error_value_formats') format = I18n.t(@type, :scope => 'validates_timeliness.error_value_formats')
value.strftime(format) value.strftime(format)
end end
end end
end end

View File

@ -126,8 +126,9 @@ describe ValidatesTimeliness::Conversion do
end end
it 'should return Time value is current zone from string time value if timezone aware' do it 'should return Time value is current zone from string time value if timezone aware' do
@timezone_aware = true
value = '2010-01-01 12:00:00' value = '2010-01-01 12:00:00'
evaluate_option_value(value, person, true).should == Time.zone.local(2010,1,1,12,0,0) evaluate_option_value(value, person).should == Time.zone.local(2010,1,1,12,0,0)
end end
it 'should return Time value in default zone from proc which returns string time' do it 'should return Time value in default zone from proc which returns string time' do
@ -142,9 +143,10 @@ describe ValidatesTimeliness::Conversion do
end end
it 'should return Time value in current zone attribute method symbol which returns string time value if timezone aware' do it 'should return Time value in current zone attribute method symbol which returns string time value if timezone aware' do
@timezone_aware = true
value = '2010-01-01 12:00:00' value = '2010-01-01 12:00:00'
person.birth_time = value person.birth_time = value
evaluate_option_value(:birth_time, person, true).should == Time.zone.local(2010,1,1,12,0,0) evaluate_option_value(:birth_time, person).should == Time.zone.local(2010,1,1,12,0,0)
end end
context "restriction shorthand" do context "restriction shorthand" do