mirror of
https://github.com/ditkrg/validates_timeliness.git
synced 2026-01-23 06:16:44 +00:00
Merge branch '2.0.0'
This commit is contained in:
commit
e1d23d0f2b
24
README.rdoc
24
README.rdoc
@ -266,6 +266,20 @@ corner cases a little harder to test. In general if you are using procs or
|
|||||||
model methods and you only care when they return a value, then they should
|
model methods and you only care when they return a value, then they should
|
||||||
return nil in all other situations. Restrictions are skipped if they are nil.
|
return nil in all other situations. Restrictions are skipped if they are nil.
|
||||||
|
|
||||||
|
|
||||||
|
=== DISPLAY INVALID VALUES IN DATE HELPERS:
|
||||||
|
|
||||||
|
The plugin has some extensions to ActionView and ActiveRecord by allowing invalid
|
||||||
|
date and time values to be redisplayed to the user as feedback, instead of
|
||||||
|
a blank field which happens by default in Rails. Though the date helpers make this a
|
||||||
|
pretty rare occurence, given the select dropdowns for each date/time component, but
|
||||||
|
it may be something of interest.
|
||||||
|
|
||||||
|
To activate it, put this in an initializer:
|
||||||
|
|
||||||
|
ValidatesTimeliness.enable_datetime_select_extension!
|
||||||
|
|
||||||
|
|
||||||
=== OTHER CUSTOMISATION:
|
=== OTHER CUSTOMISATION:
|
||||||
|
|
||||||
The error messages for each temporal restrictions can also be globally overridden by
|
The error messages for each temporal restrictions can also be globally overridden by
|
||||||
@ -302,12 +316,22 @@ will be inserted.
|
|||||||
And for something a little more specific you can override the format of the interpolation
|
And for something a little more specific you can override the format of the interpolation
|
||||||
values inserted in the error messages for temporal restrictions like so
|
values inserted in the error messages for temporal restrictions like so
|
||||||
|
|
||||||
|
For Rails 2.0/2.1:
|
||||||
|
|
||||||
ValidatesTimeliness::Validator.error_value_formats.update(
|
ValidatesTimeliness::Validator.error_value_formats.update(
|
||||||
:time => '%H:%M:%S',
|
:time => '%H:%M:%S',
|
||||||
:date => '%Y-%m-%d',
|
:date => '%Y-%m-%d',
|
||||||
:datetime => '%Y-%m-%d %H:%M:%S'
|
:datetime => '%Y-%m-%d %H:%M:%S'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Rails 2.2+ using the I18n system to define new defaults:
|
||||||
|
|
||||||
|
validates_timeliness:
|
||||||
|
error_value_formats:
|
||||||
|
date: '%Y-%m-%d'
|
||||||
|
time: '%H:%M:%S'
|
||||||
|
datetime: '%Y-%m-%d %H:%M:%S'
|
||||||
|
|
||||||
Those are Ruby strftime formats not the plugin formats.
|
Those are Ruby strftime formats not the plugin formats.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
require 'validates_timeliness/formats'
|
require 'validates_timeliness/formats'
|
||||||
|
require 'validates_timeliness/parser'
|
||||||
require 'validates_timeliness/validator'
|
require 'validates_timeliness/validator'
|
||||||
require 'validates_timeliness/validation_methods'
|
require 'validates_timeliness/validation_methods'
|
||||||
require 'validates_timeliness/spec/rails/matchers/validate_timeliness' if ENV['RAILS_ENV'] == 'test'
|
require 'validates_timeliness/spec/rails/matchers/validate_timeliness' if ENV['RAILS_ENV'] == 'test'
|
||||||
@ -14,9 +15,11 @@ require 'validates_timeliness/core_ext/date_time'
|
|||||||
module ValidatesTimeliness
|
module ValidatesTimeliness
|
||||||
|
|
||||||
mattr_accessor :default_timezone
|
mattr_accessor :default_timezone
|
||||||
|
|
||||||
self.default_timezone = :utc
|
self.default_timezone = :utc
|
||||||
|
|
||||||
|
mattr_accessor :use_time_zones
|
||||||
|
self.use_time_zones = false
|
||||||
|
|
||||||
LOCALE_PATH = File.expand_path(File.dirname(__FILE__) + '/validates_timeliness/locale/en.yml')
|
LOCALE_PATH = File.expand_path(File.dirname(__FILE__) + '/validates_timeliness/locale/en.yml')
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
@ -31,25 +34,18 @@ module ValidatesTimeliness
|
|||||||
I18n.load_path += [ LOCALE_PATH ]
|
I18n.load_path += [ LOCALE_PATH ]
|
||||||
I18n.reload!
|
I18n.reload!
|
||||||
else
|
else
|
||||||
messages = YAML::load(IO.read(LOCALE_PATH))
|
defaults = YAML::load(IO.read(LOCALE_PATH))['en']
|
||||||
errors = messages['en']['activerecord']['errors']['messages'].inject({}) {|h,(k,v)| h[k.to_sym] = v.gsub(/\{\{\w*\}\}/, '%s');h }
|
errors = defaults['activerecord']['errors']['messages'].inject({}) {|h,(k,v)| h[k.to_sym] = v.gsub(/\{\{\w*\}\}/, '%s');h }
|
||||||
::ActiveRecord::Errors.default_error_messages.update(errors)
|
::ActiveRecord::Errors.default_error_messages.update(errors)
|
||||||
|
|
||||||
|
ValidatesTimeliness::Validator.error_value_formats = defaults['validates_timeliness']['error_value_formats'].symbolize_keys
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_error_messages
|
|
||||||
if Rails::VERSION::STRING < '2.2'
|
|
||||||
::ActiveRecord::Errors.default_error_messages
|
|
||||||
else
|
|
||||||
I18n.translate('activerecord.errors.messages')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def setup_for_rails
|
def setup_for_rails
|
||||||
major, minor = Rails::VERSION::MAJOR, Rails::VERSION::MINOR
|
|
||||||
self.default_timezone = ::ActiveRecord::Base.default_timezone
|
self.default_timezone = ::ActiveRecord::Base.default_timezone
|
||||||
self.enable_datetime_select_extension!
|
self.use_time_zones = ::ActiveRecord::Base.time_zone_aware_attributes rescue false
|
||||||
self.load_error_messages
|
load_error_messages
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -37,7 +37,7 @@ module ValidatesTimeliness
|
|||||||
return value_without_timeliness(object)
|
return value_without_timeliness(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
time_array = ParseDate.parsedate(raw_value)
|
time_array = ValidatesTimeliness::Formats.parse(raw_value, :datetime)
|
||||||
|
|
||||||
TimelinessDateTime.new(*time_array[0..5])
|
TimelinessDateTime.new(*time_array[0..5])
|
||||||
end
|
end
|
||||||
|
|||||||
@ -46,7 +46,7 @@ module ValidatesTimeliness
|
|||||||
# implementation as it chains the write_attribute method which deletes
|
# implementation as it chains the write_attribute method which deletes
|
||||||
# the attribute from the cache.
|
# the attribute from the cache.
|
||||||
def write_date_time_attribute(attr_name, value, type, time_zone_aware)
|
def write_date_time_attribute(attr_name, value, type, time_zone_aware)
|
||||||
new = self.class.parse_date_time(value, type)
|
new = ValidatesTimeliness::Parser.parse(value, type)
|
||||||
|
|
||||||
if new && type != :date
|
if new && type != :date
|
||||||
new = new.to_time
|
new = new.to_time
|
||||||
@ -73,7 +73,7 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
if @attributes_cache.has_key?(attr_name)
|
if @attributes_cache.has_key?(attr_name)
|
||||||
time = read_attribute_before_type_cast(attr_name)
|
time = read_attribute_before_type_cast(attr_name)
|
||||||
time = self.class.parse_date_time(time, type)
|
time = ValidatesTimeliness::Parser.parse(time, type)
|
||||||
else
|
else
|
||||||
time = read_attribute(attr_name)
|
time = read_attribute(attr_name)
|
||||||
@attributes[attr_name] = (time && time_zone_aware ? time.in_time_zone : time) unless frozen?
|
@attributes[attr_name] = (time && time_zone_aware ? time.in_time_zone : time) unless frozen?
|
||||||
@ -83,8 +83,6 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
|
|
||||||
# Define attribute reader and writer method for date, time and
|
|
||||||
# datetime attributes to use plugin parser.
|
|
||||||
def define_attribute_methods_with_timeliness
|
def define_attribute_methods_with_timeliness
|
||||||
return if generated_methods?
|
return if generated_methods?
|
||||||
columns_hash.each do |name, column|
|
columns_hash.each do |name, column|
|
||||||
@ -105,7 +103,6 @@ module ValidatesTimeliness
|
|||||||
define_attribute_methods_without_timeliness
|
define_attribute_methods_without_timeliness
|
||||||
end
|
end
|
||||||
|
|
||||||
# Define write method for date, time and datetime columns
|
|
||||||
def define_write_method_for_dates_and_times(attr_name, type, time_zone_aware)
|
def define_write_method_for_dates_and_times(attr_name, type, time_zone_aware)
|
||||||
method_body = <<-EOV
|
method_body = <<-EOV
|
||||||
def #{attr_name}=(value)
|
def #{attr_name}=(value)
|
||||||
|
|||||||
@ -38,7 +38,7 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
def time_array_to_string(values, type)
|
def time_array_to_string(values, type)
|
||||||
values = values.map {|v| v.to_s }
|
values.collect! {|v| v.to_s }
|
||||||
|
|
||||||
case type
|
case type
|
||||||
when :date
|
when :date
|
||||||
|
|||||||
@ -124,13 +124,13 @@ module ValidatesTimeliness
|
|||||||
{ 's' => [ /s{1}/, '(\d{1,2})', :sec ] },
|
{ 's' => [ /s{1}/, '(\d{1,2})', :sec ] },
|
||||||
{ 'u' => [ /u{1,}/, '(\d{1,6})', :usec ] },
|
{ 'u' => [ /u{1,}/, '(\d{1,6})', :usec ] },
|
||||||
{ 'ampm' => [ /ampm/, '((?:[aApP])\.?[mM]\.?)', :meridian ] },
|
{ 'ampm' => [ /ampm/, '((?:[aApP])\.?[mM]\.?)', :meridian ] },
|
||||||
{ 'zo' => [ /zo/, '(?:[+-]\d{2}:?\d{2})'] },
|
{ 'zo' => [ /zo/, '([+-]\d{2}:?\d{2})', :offset ] },
|
||||||
{ 'tz' => [ /tz/, '(?:[A-Z]{1,4})' ] },
|
{ 'tz' => [ /tz/, '(?:[A-Z]{1,4})' ] },
|
||||||
{ '_' => [ /_/, '\s?' ] }
|
{ '_' => [ /_/, '\s?' ] }
|
||||||
]
|
]
|
||||||
|
|
||||||
# Arguments whichs will be passed to the format proc if matched in the
|
# Arguments which will be passed to the format proc if matched in the
|
||||||
# time string. The key must should the key from the format tokens. The array
|
# time string. The key must be the key from the format tokens. The array
|
||||||
# consists of the arry position of the arg, the arg name, and the code to
|
# consists of the arry position of the arg, the arg name, and the code to
|
||||||
# place in the time array slot. The position can be nil which means the arg
|
# place in the time array slot. The position can be nil which means the arg
|
||||||
# won't be placed in the array.
|
# won't be placed in the array.
|
||||||
@ -146,6 +146,7 @@ module ValidatesTimeliness
|
|||||||
:min => [4, 'n', 'n'],
|
:min => [4, 'n', 'n'],
|
||||||
:sec => [5, 's', 's'],
|
:sec => [5, 's', 's'],
|
||||||
:usec => [6, 'u', 'microseconds(u)'],
|
:usec => [6, 'u', 'microseconds(u)'],
|
||||||
|
:offset => [7, 'z', 'offset_in_seconds(z)'],
|
||||||
:meridian => [nil, 'md', nil]
|
:meridian => [nil, 'md', nil]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,12 +162,13 @@ module ValidatesTimeliness
|
|||||||
# pre or post match strings to exist if strict is false. Otherwise wrap
|
# pre or post match strings to exist if strict is false. Otherwise wrap
|
||||||
# regexp in start and end anchors.
|
# regexp in start and end anchors.
|
||||||
# Returns 7 part time array.
|
# Returns 7 part time array.
|
||||||
def parse(string, type, strict=true)
|
def parse(string, type, options={})
|
||||||
return string unless string.is_a?(String)
|
return string unless string.is_a?(String)
|
||||||
|
options.reverse_merge!(:strict => true)
|
||||||
|
|
||||||
matches = nil
|
matches = nil
|
||||||
exp, processor = expression_set(type, string).find do |regexp, proc|
|
exp, processor = expression_set(type, string).find do |regexp, proc|
|
||||||
full = /\A#{regexp}\Z/ if strict
|
full = /\A#{regexp}\Z/ if options[:strict]
|
||||||
full ||= case type
|
full ||= case type
|
||||||
when :date then /\A#{regexp}/
|
when :date then /\A#{regexp}/
|
||||||
when :time then /#{regexp}\Z/
|
when :time then /#{regexp}\Z/
|
||||||
@ -174,7 +176,8 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
matches = full.match(string.strip)
|
matches = full.match(string.strip)
|
||||||
end
|
end
|
||||||
processor.call(*matches[1..7]) if matches
|
last = options[:include_offset] ? 8 : 7
|
||||||
|
processor.call(*matches[1..last]) if matches
|
||||||
end
|
end
|
||||||
|
|
||||||
# Delete formats of specified type. Error raised if format not found.
|
# Delete formats of specified type. Error raised if format not found.
|
||||||
@ -206,8 +209,7 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
compile_format_expressions
|
compile_format_expressions
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# Removes formats where the 1 or 2 digit month comes first, to eliminate
|
# Removes formats where the 1 or 2 digit month comes first, to eliminate
|
||||||
# formats which are ambiguous with the European style of day then month.
|
# formats which are ambiguous with the European style of day then month.
|
||||||
# The mmm token is ignored as its not ambigous.
|
# The mmm token is ignored as its not ambigous.
|
||||||
@ -246,17 +248,12 @@ module ValidatesTimeliness
|
|||||||
# argument in the position indicated by the first element of the proc arg
|
# argument in the position indicated by the first element of the proc arg
|
||||||
# array.
|
# array.
|
||||||
#
|
#
|
||||||
# Examples:
|
|
||||||
#
|
|
||||||
# 'yyyy-mm-dd hh:nn' => lambda {|y,m,d,h,n| md||=0; [unambiguous_year(y),month_index(m),d,full_hour(h,md),n,nil,nil].map {|i| i.to_i } }
|
|
||||||
# 'dd/mm/yyyy h:nn_ampm' => lambda {|d,m,y,h,n,md| md||=0; [unambiguous_year(y),month_index(m),d,full_hour(h,md),n,nil,nil].map {|i| i.to_i } }
|
|
||||||
#
|
|
||||||
def format_proc(order)
|
def format_proc(order)
|
||||||
arg_map = format_proc_args
|
arg_map = format_proc_args
|
||||||
args = order.invert.sort.map {|p| arg_map[p[1]][1] }
|
args = order.invert.sort.map {|p| arg_map[p[1]][1] }
|
||||||
arr = [nil] * 7
|
arr = [nil] * 7
|
||||||
order.keys.each {|k| i = arg_map[k][0]; arr[i] = arg_map[k][2] unless i.nil? }
|
order.keys.each {|k| i = arg_map[k][0]; arr[i] = arg_map[k][2] unless i.nil? }
|
||||||
proc_string = "lambda {|#{args.join(',')}| md||=nil; [#{arr.map {|i| i.nil? ? 'nil' : i }.join(',')}].map {|i| i.to_i } }"
|
proc_string = "lambda {|#{args.join(',')}| md||=nil; [#{arr.map {|i| i.nil? ? 'nil' : i }.join(',')}].map {|i| i.is_a?(Float) ? i : i.to_i } }"
|
||||||
eval proc_string
|
eval proc_string
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -313,6 +310,13 @@ module ValidatesTimeliness
|
|||||||
def microseconds(usec)
|
def microseconds(usec)
|
||||||
(".#{usec}".to_f * 1_000_000).to_i
|
(".#{usec}".to_f * 1_000_000).to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def offset_in_seconds(offset)
|
||||||
|
sign = offset =~ /^-/ ? -1 : 1
|
||||||
|
parts = offset.scan(/\d\d/).map {|p| p.to_f }
|
||||||
|
parts[1] = parts[1].to_f / 60
|
||||||
|
(parts[0] + parts[1]) * sign * 3600
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -11,3 +11,8 @@ en:
|
|||||||
after: "must be after {{restriction}}"
|
after: "must be after {{restriction}}"
|
||||||
on_or_after: "must be on or after {{restriction}}"
|
on_or_after: "must be on or after {{restriction}}"
|
||||||
between: "must be between {{earliest}} and {{latest}}"
|
between: "must be between {{earliest}} and {{latest}}"
|
||||||
|
validates_timeliness:
|
||||||
|
error_value_formats:
|
||||||
|
date: '%Y-%m-%d'
|
||||||
|
time: '%H:%M:%S'
|
||||||
|
datetime: '%Y-%m-%d %H:%M:%S'
|
||||||
|
|||||||
46
lib/validates_timeliness/parser.rb
Normal file
46
lib/validates_timeliness/parser.rb
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
module ValidatesTimeliness
|
||||||
|
module Parser
|
||||||
|
|
||||||
|
class << self
|
||||||
|
|
||||||
|
def parse(raw_value, type, options={})
|
||||||
|
return nil if raw_value.blank?
|
||||||
|
return raw_value if raw_value.acts_like?(:time) || raw_value.is_a?(Date)
|
||||||
|
|
||||||
|
options.reverse_merge!(:strict => true)
|
||||||
|
|
||||||
|
time_array = ValidatesTimeliness::Formats.parse(raw_value, type, options)
|
||||||
|
raise if time_array.nil?
|
||||||
|
|
||||||
|
# Rails dummy time date part is defined as 2000-01-01
|
||||||
|
time_array[0..2] = 2000, 1, 1 if type == :time
|
||||||
|
|
||||||
|
# Date.new enforces days per month, unlike Time
|
||||||
|
date = Date.new(*time_array[0..2]) unless type == :time
|
||||||
|
|
||||||
|
return date if type == :date
|
||||||
|
|
||||||
|
make_time(time_array[0..7])
|
||||||
|
rescue
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_time(time_array)
|
||||||
|
if Time.respond_to?(:zone) && ValidatesTimeliness.use_time_zones
|
||||||
|
Time.zone.local(*time_array)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
time_zone = ValidatesTimeliness.default_timezone
|
||||||
|
Time.send(time_zone, *time_array)
|
||||||
|
rescue ArgumentError, TypeError
|
||||||
|
zone_offset = time_zone == :local ? DateTime.local_offset : 0
|
||||||
|
time_array.pop # remove microseconds
|
||||||
|
DateTime.civil(*(time_array << zone_offset))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -116,7 +116,7 @@ module Spec
|
|||||||
end
|
end
|
||||||
|
|
||||||
def error_message_for(option)
|
def error_message_for(option)
|
||||||
msg = @validator.send(:error_messages)[option]
|
msg = @validator.error_messages[option]
|
||||||
restriction = @validator.class.send(:evaluate_option_value, @validator.configuration[option], @type, @record)
|
restriction = @validator.class.send(:evaluate_option_value, @validator.configuration[option], @type, @record)
|
||||||
|
|
||||||
if restriction
|
if restriction
|
||||||
@ -135,7 +135,7 @@ module Spec
|
|||||||
|
|
||||||
def format_value(value)
|
def format_value(value)
|
||||||
return value if value.is_a?(String)
|
return value if value.is_a?(String)
|
||||||
value.strftime(ValidatesTimeliness::Validator.error_value_formats[@type])
|
value.strftime(@validator.class.error_value_formats[@type])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -7,27 +7,6 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
|
|
||||||
def parse_date_time(raw_value, type, strict=true)
|
|
||||||
return nil if raw_value.blank?
|
|
||||||
return raw_value if raw_value.acts_like?(:time) || raw_value.is_a?(Date)
|
|
||||||
|
|
||||||
time_array = ValidatesTimeliness::Formats.parse(raw_value, type, strict)
|
|
||||||
raise if time_array.nil?
|
|
||||||
|
|
||||||
# Rails dummy time date part is defined as 2000-01-01
|
|
||||||
time_array[0..2] = 2000, 1, 1 if type == :time
|
|
||||||
|
|
||||||
# Date.new enforces days per month, unlike Time
|
|
||||||
date = Date.new(*time_array[0..2]) unless type == :time
|
|
||||||
|
|
||||||
return date if type == :date
|
|
||||||
|
|
||||||
# Create time object which checks time part, and return time object
|
|
||||||
make_time(time_array)
|
|
||||||
rescue
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def validates_time(*attr_names)
|
def validates_time(*attr_names)
|
||||||
configuration = attr_names.extract_options!
|
configuration = attr_names.extract_options!
|
||||||
configuration[:type] = :time
|
configuration[:type] = :time
|
||||||
@ -59,21 +38,6 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Time.zone. Rails 2.0 should be default_timezone.
|
|
||||||
def make_time(time_array)
|
|
||||||
if Time.respond_to?(:zone) && time_zone_aware_attributes
|
|
||||||
Time.zone.local(*time_array)
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
Time.send(::ActiveRecord::Base.default_timezone, *time_array)
|
|
||||||
rescue ArgumentError, TypeError
|
|
||||||
zone_offset = ::ActiveRecord::Base.default_timezone == :local ? DateTime.local_offset : 0
|
|
||||||
time_array.pop # remove microseconds
|
|
||||||
DateTime.civil(*(time_array << zone_offset))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -2,14 +2,7 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
class Validator
|
class Validator
|
||||||
cattr_accessor :ignore_restriction_errors
|
cattr_accessor :ignore_restriction_errors
|
||||||
cattr_accessor :error_value_formats
|
|
||||||
|
|
||||||
self.ignore_restriction_errors = false
|
self.ignore_restriction_errors = false
|
||||||
self.error_value_formats = {
|
|
||||||
:time => '%H:%M:%S',
|
|
||||||
:date => '%Y-%m-%d',
|
|
||||||
:datetime => '%Y-%m-%d %H:%M:%S'
|
|
||||||
}
|
|
||||||
|
|
||||||
RESTRICTION_METHODS = {
|
RESTRICTION_METHODS = {
|
||||||
:equal_to => :==,
|
:equal_to => :==,
|
||||||
@ -36,7 +29,7 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
def call(record, attr_name, value)
|
def call(record, attr_name, value)
|
||||||
value = record.class.parse_date_time(value, type, false) if value.is_a?(String)
|
value = ValidatesTimeliness::Parser.parse(value, type, :strict => false) if value.is_a?(String)
|
||||||
raw_value = raw_value(record, attr_name) || value
|
raw_value = raw_value(record, attr_name) || value
|
||||||
|
|
||||||
return if (raw_value.nil? && configuration[:allow_nil]) || (raw_value.blank? && configuration[:allow_blank])
|
return if (raw_value.nil? && configuration[:allow_nil]) || (raw_value.blank? && configuration[:allow_blank])
|
||||||
@ -47,7 +40,11 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
validate_restrictions(record, attr_name, value)
|
validate_restrictions(record, attr_name, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def error_messages
|
||||||
|
@error_messages ||= self.class.default_error_messages.merge(custom_error_messages)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def raw_value(record, attr_name)
|
def raw_value(record, attr_name)
|
||||||
@ -87,7 +84,7 @@ module ValidatesTimeliness
|
|||||||
restriction = [restriction] unless restriction.is_a?(Array)
|
restriction = [restriction] unless restriction.is_a?(Array)
|
||||||
|
|
||||||
if defined?(I18n)
|
if defined?(I18n)
|
||||||
message = custom_error_messages[option] || I18n.translate('activerecord.errors.messages')[option]
|
message = custom_error_messages[option] || I18n.t('activerecord.errors.messages')[option]
|
||||||
subs = message.scan(/\{\{([^\}]*)\}\}/)
|
subs = message.scan(/\{\{([^\}]*)\}\}/)
|
||||||
interpolations = {}
|
interpolations = {}
|
||||||
subs.each_with_index {|s, i| interpolations[s[0].to_sym] = restriction[i].strftime(format) }
|
subs.each_with_index {|s, i| interpolations[s[0].to_sym] = restriction[i].strftime(format) }
|
||||||
@ -120,10 +117,6 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def error_messages
|
|
||||||
@error_messages ||= ValidatesTimeliness.default_error_messages.merge(custom_error_messages)
|
|
||||||
end
|
|
||||||
|
|
||||||
def custom_error_messages
|
def custom_error_messages
|
||||||
@custom_error_messages ||= configuration.inject({}) {|msgs, (k, v)|
|
@custom_error_messages ||= configuration.inject({}) {|msgs, (k, v)|
|
||||||
if md = /(.*)_message$/.match(k.to_s)
|
if md = /(.*)_message$/.match(k.to_s)
|
||||||
@ -132,7 +125,7 @@ module ValidatesTimeliness
|
|||||||
msgs
|
msgs
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def combine_date_and_time(value, record)
|
def combine_date_and_time(value, record)
|
||||||
if type == :date
|
if type == :date
|
||||||
date = value
|
date = value
|
||||||
@ -143,7 +136,7 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
date, time = self.class.evaluate_option_value(date, :date, record), self.class.evaluate_option_value(time, :time, record)
|
date, time = self.class.evaluate_option_value(date, :date, record), self.class.evaluate_option_value(time, :time, record)
|
||||||
return if date.nil? || time.nil?
|
return if date.nil? || time.nil?
|
||||||
record.class.send(:make_time, [date.year, date.month, date.day, time.hour, time.min, time.sec, time.usec])
|
ValidatesTimeliness::Parser.make_time([date.year, date.month, date.day, time.hour, time.min, time.sec, time.usec])
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_options(options)
|
def validate_options(options)
|
||||||
@ -156,9 +149,29 @@ module ValidatesTimeliness
|
|||||||
# class methods
|
# class methods
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
|
def default_error_messages
|
||||||
|
if defined?(I18n)
|
||||||
|
I18n.t('activerecord.errors.messages')
|
||||||
|
else
|
||||||
|
::ActiveRecord::Errors.default_error_messages
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def error_value_formats
|
||||||
|
if defined?(I18n)
|
||||||
|
I18n.t('validates_timeliness.error_value_formats')
|
||||||
|
else
|
||||||
|
@@error_value_formats
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def error_value_formats=(formats)
|
||||||
|
@@error_value_formats = formats
|
||||||
|
end
|
||||||
|
|
||||||
def evaluate_option_value(value, type, record)
|
def evaluate_option_value(value, type, record)
|
||||||
case value
|
case value
|
||||||
when Time, Date, DateTime
|
when Time, Date
|
||||||
value
|
value
|
||||||
when Symbol
|
when Symbol
|
||||||
evaluate_option_value(record.send(value), type, record)
|
evaluate_option_value(record.send(value), type, record)
|
||||||
@ -169,7 +182,7 @@ module ValidatesTimeliness
|
|||||||
when Range
|
when Range
|
||||||
evaluate_option_value([value.first, value.last], type, record)
|
evaluate_option_value([value.first, value.last], type, record)
|
||||||
else
|
else
|
||||||
record.class.parse_date_time(value, type, false)
|
ValidatesTimeliness::Parser.parse(value, type, :strict => false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -192,7 +205,7 @@ module ValidatesTimeliness
|
|||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
if ignore_usec && value.is_a?(Time)
|
if ignore_usec && value.is_a?(Time)
|
||||||
::ActiveRecord::Base.send(:make_time, Array(value).reverse[4..9])
|
ValidatesTimeliness::Parser.make_time(Array(value).reverse[4..9])
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
|||||||
@ -39,17 +39,17 @@ describe ValidatesTimeliness::ActiveRecord::AttributeMethods do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should call parser on write for datetime attribute" do
|
it "should call parser on write for datetime attribute" do
|
||||||
@person.class.should_receive(:parse_date_time).once
|
ValidatesTimeliness::Parser.should_receive(:parse).once
|
||||||
@person.birth_date_and_time = "2000-01-01 02:03:04"
|
@person.birth_date_and_time = "2000-01-01 02:03:04"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should call parser on write for date attribute" do
|
it "should call parser on write for date attribute" do
|
||||||
@person.class.should_receive(:parse_date_time).once
|
ValidatesTimeliness::Parser.should_receive(:parse).once
|
||||||
@person.birth_date = "2000-01-01"
|
@person.birth_date = "2000-01-01"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should call parser on write for time attribute" do
|
it "should call parser on write for time attribute" do
|
||||||
@person.class.should_receive(:parse_date_time).once
|
ValidatesTimeliness::Parser.should_receive(:parse).once
|
||||||
@person.birth_time = "12:00"
|
@person.birth_time = "12:00"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -6,46 +6,6 @@ describe ValidatesTimeliness::Formats do
|
|||||||
before do
|
before do
|
||||||
@formats = ValidatesTimeliness::Formats
|
@formats = ValidatesTimeliness::Formats
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "expression generator" do
|
|
||||||
it "should generate regexp for time" do
|
|
||||||
generate_regexp_str('hh:nn:ss').should == '/(\d{2}):(\d{2}):(\d{2})/'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should generate regexp for time with meridian" do
|
|
||||||
generate_regexp_str('hh:nn:ss ampm').should == '/(\d{2}):(\d{2}):(\d{2}) ((?:[aApP])\.?[mM]\.?)/'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should generate regexp for time with meridian and optional space between" do
|
|
||||||
generate_regexp_str('hh:nn:ss_ampm').should == '/(\d{2}):(\d{2}):(\d{2})\s?((?:[aApP])\.?[mM]\.?)/'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should generate regexp for time with single or double digits" do
|
|
||||||
generate_regexp_str('h:n:s').should == '/(\d{1,2}):(\d{1,2}):(\d{1,2})/'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should generate regexp for date" do
|
|
||||||
generate_regexp_str('yyyy-mm-dd').should == '/(\d{4})-(\d{2})-(\d{2})/'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should generate regexp for date with slashes" do
|
|
||||||
generate_regexp_str('dd/mm/yyyy').should == '/(\d{2})\/(\d{2})\/(\d{4})/'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should generate regexp for date with dots" do
|
|
||||||
generate_regexp_str('dd.mm.yyyy').should == '/(\d{2})\.(\d{2})\.(\d{4})/'
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should generate regexp for Ruby time string" do
|
|
||||||
expected = '/(\w{3,9}) (\w{3,9}) (\d{2}):(\d{2}):(\d{2}) (?:[+-]\d{2}:?\d{2}) (\d{4})/'
|
|
||||||
generate_regexp_str('ddd mmm hh:nn:ss zo yyyy').should == expected
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should generate regexp for iso8601 datetime" do
|
|
||||||
expected = '/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:Z|(?:[+-]\d{2}:?\d{2}))/'
|
|
||||||
generate_regexp_str('yyyy-mm-ddThh:nn:ss(?:Z|zo)').should == expected
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "format proc generator" do
|
describe "format proc generator" do
|
||||||
it "should generate proc which outputs date array with values in correct order" do
|
it "should generate proc which outputs date array with values in correct order" do
|
||||||
@ -71,6 +31,10 @@ describe ValidatesTimeliness::Formats do
|
|||||||
it "should generate proc which outputs time array with microseconds" do
|
it "should generate proc which outputs time array with microseconds" do
|
||||||
generate_proc('hh:nn:ss.u').call('01', '02', '03', '99').should == [0,0,0,1,2,3,990000]
|
generate_proc('hh:nn:ss.u').call('01', '02', '03', '99').should == [0,0,0,1,2,3,990000]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should generate proc which outputs datetime array with zone offset" do
|
||||||
|
generate_proc('yyyy-mm-dd hh:nn:ss.u zo').call('2001', '02', '03', '04', '05', '06', '99', '+10:00').should == [2001,2,3,4,5,6,990000,36000]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "validation regexps" do
|
describe "validation regexps" do
|
||||||
@ -139,38 +103,43 @@ describe ValidatesTimeliness::Formats do
|
|||||||
describe "extracting values" do
|
describe "extracting values" do
|
||||||
|
|
||||||
it "should return time array from date string" do
|
it "should return time array from date string" do
|
||||||
time_array = formats.parse('12:13:14', :time, true)
|
time_array = formats.parse('12:13:14', :time, :strict => true)
|
||||||
time_array.should == [0,0,0,12,13,14,0]
|
time_array.should == [0,0,0,12,13,14,0]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return date array from time string" do
|
it "should return date array from time string" do
|
||||||
time_array = formats.parse('2000-02-01', :date, true)
|
time_array = formats.parse('2000-02-01', :date, :strict => true)
|
||||||
time_array.should == [2000,2,1,0,0,0,0]
|
time_array.should == [2000,2,1,0,0,0,0]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return datetime array from string value" do
|
it "should return datetime array from string value" do
|
||||||
time_array = formats.parse('2000-02-01 12:13:14', :datetime, true)
|
time_array = formats.parse('2000-02-01 12:13:14', :datetime, :strict => true)
|
||||||
time_array.should == [2000,2,1,12,13,14,0]
|
time_array.should == [2000,2,1,12,13,14,0]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should parse date string when type is datetime" do
|
it "should parse date string when type is datetime" do
|
||||||
time_array = formats.parse('2000-02-01', :datetime, false)
|
time_array = formats.parse('2000-02-01', :datetime, :strict => false)
|
||||||
time_array.should == [2000,2,1,0,0,0,0]
|
time_array.should == [2000,2,1,0,0,0,0]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should ignore time when extracting date and strict is false" do
|
it "should ignore time when extracting date and strict is false" do
|
||||||
time_array = formats.parse('2000-02-01 12:12', :date, false)
|
time_array = formats.parse('2000-02-01 12:13', :date, :strict => false)
|
||||||
time_array.should == [2000,2,1,0,0,0,0]
|
time_array.should == [2000,2,1,0,0,0,0]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should ignore time when extracting date from format with trailing year and strict is false" do
|
it "should ignore time when extracting date from format with trailing year and strict is false" do
|
||||||
time_array = formats.parse('01-02-2000 12:12', :date, false)
|
time_array = formats.parse('01-02-2000 12:13', :date, :strict => false)
|
||||||
time_array.should == [2000,2,1,0,0,0,0]
|
time_array.should == [2000,2,1,0,0,0,0]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should ignore date when extracting time and strict is false" do
|
it "should ignore date when extracting time and strict is false" do
|
||||||
time_array = formats.parse('2000-02-01 12:12', :time, false)
|
time_array = formats.parse('2000-02-01 12:13', :time, :strict => false)
|
||||||
time_array.should == [0,0,0,12,12,0,0]
|
time_array.should == [0,0,0,12,13,0,0]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return zone offset when :include_offset options is true" do
|
||||||
|
time_array = formats.parse('2000-02-01T12:13:14-10:30', :datetime, :include_offset => true)
|
||||||
|
time_array.should == [2000,2,1,12,13,14,0,-37800]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1,39 +1,39 @@
|
|||||||
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
||||||
|
|
||||||
describe ValidatesTimeliness::ValidationMethods do
|
describe ValidatesTimeliness::Parser do
|
||||||
attr_accessor :person
|
attr_accessor :person
|
||||||
|
|
||||||
describe "parse_date_time" do
|
describe "parse" do
|
||||||
it "should return time object for valid time string" do
|
it "should return time object for valid time string" do
|
||||||
parse_method("2000-01-01 12:13:14", :datetime).should be_kind_of(Time)
|
parse("2000-01-01 12:13:14", :datetime).should be_kind_of(Time)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil for time string with invalid date part" do
|
it "should return nil for time string with invalid date part" do
|
||||||
parse_method("2000-02-30 12:13:14", :datetime).should be_nil
|
parse("2000-02-30 12:13:14", :datetime).should be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil for time string with invalid time part" do
|
it "should return nil for time string with invalid time part" do
|
||||||
parse_method("2000-02-01 25:13:14", :datetime).should be_nil
|
parse("2000-02-01 25:13:14", :datetime).should be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return Time object when passed a Time object" do
|
it "should return Time object when passed a Time object" do
|
||||||
parse_method(Time.now, :datetime).should be_kind_of(Time)
|
parse(Time.now, :datetime).should be_kind_of(Time)
|
||||||
end
|
end
|
||||||
|
|
||||||
if RAILS_VER >= '2.1'
|
if RAILS_VER >= '2.1'
|
||||||
it "should convert time string into current timezone" do
|
it "should convert time string into current timezone" do
|
||||||
Time.zone = 'Melbourne'
|
Time.zone = 'Melbourne'
|
||||||
time = parse_method("2000-01-01 12:13:14", :datetime)
|
time = parse("2000-01-01 12:13:14", :datetime)
|
||||||
Time.zone.utc_offset.should == 10.hours
|
Time.zone.utc_offset.should == 10.hours
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nil for invalid date string" do
|
it "should return nil for invalid date string" do
|
||||||
parse_method("2000-02-30", :date).should be_nil
|
parse("2000-02-30", :date).should be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_method(*args)
|
def parse(*args)
|
||||||
ActiveRecord::Base.parse_date_time(*args)
|
ValidatesTimeliness::Parser.parse(*args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -43,14 +43,14 @@ describe ValidatesTimeliness::ValidationMethods do
|
|||||||
|
|
||||||
it "should create time using current timezone" do
|
it "should create time using current timezone" do
|
||||||
Time.zone = 'Melbourne'
|
Time.zone = 'Melbourne'
|
||||||
time = ActiveRecord::Base.send(:make_time, [2000,1,1,12,0,0])
|
time = ValidatesTimeliness::Parser.make_time([2000,1,1,12,0,0])
|
||||||
time.zone.should == "EST"
|
time.zone.should == "EST"
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
it "should create time using default timezone" do
|
it "should create time using default timezone" do
|
||||||
time = ActiveRecord::Base.send(:make_time, [2000,1,1,12,0,0])
|
time = ValidatesTimeliness::Parser.make_time([2000,1,1,12,0,0])
|
||||||
time.zone.should == "UTC"
|
time.zone.should == "UTC"
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -30,6 +30,7 @@ require 'active_record'
|
|||||||
require 'active_record/version'
|
require 'active_record/version'
|
||||||
require 'action_controller'
|
require 'action_controller'
|
||||||
require 'action_view'
|
require 'action_view'
|
||||||
|
require 'action_mailer'
|
||||||
|
|
||||||
require 'spec/rails'
|
require 'spec/rails'
|
||||||
require 'time_travel/time_travel'
|
require 'time_travel/time_travel'
|
||||||
@ -38,13 +39,15 @@ ActiveRecord::Base.default_timezone = :utc
|
|||||||
RAILS_VER = Rails::VERSION::STRING
|
RAILS_VER = Rails::VERSION::STRING
|
||||||
puts "Using #{vendored ? 'vendored' : 'gem'} Rails version #{RAILS_VER} (ActiveRecord version #{ActiveRecord::VERSION::STRING})"
|
puts "Using #{vendored ? 'vendored' : 'gem'} Rails version #{RAILS_VER} (ActiveRecord version #{ActiveRecord::VERSION::STRING})"
|
||||||
|
|
||||||
require 'validates_timeliness'
|
|
||||||
|
|
||||||
if RAILS_VER >= '2.1'
|
if RAILS_VER >= '2.1'
|
||||||
Time.zone_default = ActiveSupport::TimeZone['UTC']
|
Time.zone_default = ActiveSupport::TimeZone['UTC']
|
||||||
ActiveRecord::Base.time_zone_aware_attributes = true
|
ActiveRecord::Base.time_zone_aware_attributes = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
require 'validates_timeliness'
|
||||||
|
|
||||||
|
ValidatesTimeliness.enable_datetime_select_extension!
|
||||||
|
|
||||||
ActiveRecord::Migration.verbose = false
|
ActiveRecord::Migration.verbose = false
|
||||||
ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:'})
|
ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:'})
|
||||||
|
|
||||||
|
|||||||
@ -66,7 +66,7 @@ describe ValidatesTimeliness::Validator do
|
|||||||
|
|
||||||
it "should return array of Time objects when restriction is array of strings" do
|
it "should return array of Time objects when restriction is array of strings" do
|
||||||
time1, time2 = "2000-01-02", "2000-01-01"
|
time1, time2 = "2000-01-02", "2000-01-01"
|
||||||
evaluate_option_value([time1, time2], :datetime).should == [Person.parse_date_time(time2, :datetime), Person.parse_date_time(time1, :datetime)]
|
evaluate_option_value([time1, time2], :datetime).should == [parse(time2, :datetime), parse(time1, :datetime)]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return array of Time objects when restriction is Range of Time objects" do
|
it "should return array of Time objects when restriction is Range of Time objects" do
|
||||||
@ -76,7 +76,7 @@ describe ValidatesTimeliness::Validator do
|
|||||||
|
|
||||||
it "should return array of Time objects when restriction is Range of time strings" do
|
it "should return array of Time objects when restriction is Range of time strings" do
|
||||||
time1, time2 = "2000-01-02", "2000-01-01"
|
time1, time2 = "2000-01-02", "2000-01-01"
|
||||||
evaluate_option_value(time1..time2, :datetime).should == [Person.parse_date_time(time2, :datetime), Person.parse_date_time(time1, :datetime)]
|
evaluate_option_value(time1..time2, :datetime).should == [parse(time2, :datetime), parse(time1, :datetime)]
|
||||||
end
|
end
|
||||||
def evaluate_option_value(restriction, type)
|
def evaluate_option_value(restriction, type)
|
||||||
configure_validator(:type => type)
|
configure_validator(:type => type)
|
||||||
@ -554,12 +554,18 @@ describe ValidatesTimeliness::Validator do
|
|||||||
describe "custom formats" do
|
describe "custom formats" do
|
||||||
|
|
||||||
before :all do
|
before :all do
|
||||||
@@formats = ValidatesTimeliness::Validator.error_value_formats
|
custom = {
|
||||||
ValidatesTimeliness::Validator.error_value_formats = {
|
|
||||||
:time => '%H:%M %p',
|
:time => '%H:%M %p',
|
||||||
:date => '%d-%m-%Y',
|
:date => '%d-%m-%Y',
|
||||||
:datetime => '%d-%m-%Y %H:%M %p'
|
:datetime => '%d-%m-%Y %H:%M %p'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if defined?(I18n)
|
||||||
|
I18n.backend.store_translations 'en', :validates_timeliness => { :error_value_formats => custom }
|
||||||
|
else
|
||||||
|
@@formats = ValidatesTimeliness::Validator.error_value_formats
|
||||||
|
ValidatesTimeliness::Validator.error_value_formats = custom
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should format datetime value of restriction" do
|
it "should format datetime value of restriction" do
|
||||||
@ -581,12 +587,20 @@ describe ValidatesTimeliness::Validator do
|
|||||||
end
|
end
|
||||||
|
|
||||||
after :all do
|
after :all do
|
||||||
ValidatesTimeliness::Validator.error_value_formats = @@formats
|
if defined?(I18n)
|
||||||
|
I18n.reload!
|
||||||
|
else
|
||||||
|
ValidatesTimeliness::Validator.error_value_formats = @@formats
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse(*args)
|
||||||
|
ValidatesTimeliness::Parser.parse(*args)
|
||||||
|
end
|
||||||
|
|
||||||
def configure_validator(options={})
|
def configure_validator(options={})
|
||||||
@validator = ValidatesTimeliness::Validator.new(options)
|
@validator = ValidatesTimeliness::Validator.new(options)
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user