mirror of
https://github.com/ditkrg/validates_timeliness.git
synced 2026-01-26 07:43:00 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b874e786b6 | ||
|
|
b356363791 | ||
|
|
e9eb812c9e | ||
|
|
353f154330 | ||
|
|
ccfad007d1 | ||
|
|
f3c0dd6144 | ||
|
|
6349990243 | ||
|
|
220b58ab14 | ||
|
|
f98e503e25 | ||
|
|
3e1a9fc107 | ||
|
|
99d742e3d0 | ||
|
|
77f338d97c | ||
|
|
d255bbfccf | ||
|
|
4df1974524 | ||
|
|
82c0e1bcd3 | ||
|
|
f1a0016bf7 | ||
|
|
59d9957ab6 | ||
|
|
694c3b0ce3 | ||
|
|
a859827af4 | ||
|
|
f8b9f72693 | ||
|
|
7f1ed79a89 | ||
|
|
f3c119e191 | ||
|
|
3bfc7b748f | ||
|
|
40369efdff | ||
|
|
f41016af93 | ||
|
|
5258256d5e | ||
|
|
9cfbb2a458 | ||
|
|
78baa7a3cc | ||
|
|
7d6967da90 | ||
|
|
0c38b6abd1 | ||
|
|
a6712de5ff | ||
|
|
c580c3e682 | ||
|
|
9c5db44500 | ||
|
|
f109443fb7 | ||
|
|
96bf4bf184 | ||
|
|
90be6a6db5 |
15
CHANGELOG
15
CHANGELOG
@@ -1,3 +1,18 @@
|
|||||||
|
= 2.3.1 [2010-03-19]
|
||||||
|
- Fixed bug where custom attribute writer method for date/times were being overriden
|
||||||
|
|
||||||
|
= 2.3.0 [2010-02-04]
|
||||||
|
- Backwards incompatible change to :equal_to option. Fixed error message clash with :equal_to option which exists in Rails already. Option is now :is_at.
|
||||||
|
- Fixed I18n support so it returns missing translation message instead of error
|
||||||
|
- Fixed attribute method bug. Write method was bypassed when method was first generated and used Rails default parser.
|
||||||
|
- Fixed date/time selects when using enable_datetime_select_extension! when some values empty
|
||||||
|
- Fixed ISO8601 datetime format which is now split into two formats
|
||||||
|
- Changed I18n error value format to fallback to global default if missing in locale
|
||||||
|
- Refactored date/time select invalid value extension to use param values. Functionality will be extracted from plugin for v3.
|
||||||
|
|
||||||
|
= 2.2.2 [2009-09-19]
|
||||||
|
- Fixed dummy_time using make_time to respect timezone. Fixes 1.9.1 bug.
|
||||||
|
|
||||||
= 2.2.1 [2009-09-12]
|
= 2.2.1 [2009-09-12]
|
||||||
- Fixed dummy date part for time types in Validator.type_cast_value
|
- Fixed dummy date part for time types in Validator.type_cast_value
|
||||||
- No more core extensions! Removed dummy_time methods.
|
- No more core extensions! Removed dummy_time methods.
|
||||||
|
|||||||
31
README.rdoc
31
README.rdoc
@@ -1,14 +1,14 @@
|
|||||||
= validates_timeliness
|
= validates_timeliness
|
||||||
|
|
||||||
* Source: http://github.com/adzap/validates_timeliness
|
* Source: http://github.com/adzap/validates_timeliness
|
||||||
* Bugs: http://adzap.lighthouseapp.com/projects/14111-validates_timeliness
|
* Bugs: http://github.com/adzap/validates_timeliness/issues
|
||||||
|
|
||||||
== DESCRIPTION:
|
== DESCRIPTION:
|
||||||
|
|
||||||
Validate dates, times and datetimes for Rails 2.x. Plays nicely with new Rails 2.1
|
Validate dates, times and datetimes for Rails 2.x. Plays nicely with Rails
|
||||||
features such as automatic timezone handling and dirty attributes. Allows you to
|
automatic timezone handling. Allows you to add custom formats or remove defaults
|
||||||
add custom formats or remove defaults easily. This allows you to control what you
|
easily. This allows you to control what you think should be a valid date or
|
||||||
think should be a valid date or time string.
|
time string.
|
||||||
|
|
||||||
|
|
||||||
== FEATURES:
|
== FEATURES:
|
||||||
@@ -63,7 +63,7 @@ The validation methods take the usual options plus some specific ones to restric
|
|||||||
the valid range of dates or times allowed
|
the valid range of dates or times allowed
|
||||||
|
|
||||||
Temporal options (or restrictions):
|
Temporal options (or restrictions):
|
||||||
:equal_to - Attribute must be equal to value to be valid
|
:is_at - Attribute must be equal to value to be valid
|
||||||
:before - Attribute must be before this 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
|
: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
|
:after - Attribute must be after this value to be valid
|
||||||
@@ -86,7 +86,7 @@ Message options: - Use these to override the default error messages
|
|||||||
:invalid_date_message
|
:invalid_date_message
|
||||||
:invalid_time_message
|
:invalid_time_message
|
||||||
:invalid_datetime_message
|
:invalid_datetime_message
|
||||||
:equal_to_message
|
:is_at_message
|
||||||
:before_message
|
:before_message
|
||||||
:on_or_before_message
|
:on_or_before_message
|
||||||
:after_message
|
:after_message
|
||||||
@@ -165,7 +165,8 @@ NOTE: To use non-US date formats see US/EURO FORMATS section
|
|||||||
yyyy-mm-dd hh:nn:ss
|
yyyy-mm-dd hh:nn:ss
|
||||||
yyyy-mm-dd h:nn
|
yyyy-mm-dd h:nn
|
||||||
ddd mmm d hh:nn:ss zo yyyy # Ruby time string
|
ddd mmm d hh:nn:ss zo yyyy # Ruby time string
|
||||||
yyyy-mm-ddThh:nn:ss(?:Z|zo) # ISO 8601
|
yyyy-mm-ddThh:nn:ssZ # ISO 8601 without zone offset
|
||||||
|
yyyy-mm-ddThh:nn:sszo # ISO 8601 with zone offset
|
||||||
|
|
||||||
NOTE: To use non-US date formats see US/EURO FORMATS section
|
NOTE: To use non-US date formats see US/EURO FORMATS section
|
||||||
|
|
||||||
@@ -305,6 +306,7 @@ To activate it, put this in an initializer:
|
|||||||
|
|
||||||
ValidatesTimeliness.enable_datetime_select_extension!
|
ValidatesTimeliness.enable_datetime_select_extension!
|
||||||
|
|
||||||
|
This will be removed from v3 as it adds too little to maintain.
|
||||||
|
|
||||||
=== OTHER CUSTOMISATION:
|
=== OTHER CUSTOMISATION:
|
||||||
|
|
||||||
@@ -317,6 +319,7 @@ For Rails 2.0/2.1:
|
|||||||
:invalid_date => "is not a valid date",
|
:invalid_date => "is not a valid date",
|
||||||
:invalid_time => "is not a valid time",
|
:invalid_time => "is not a valid time",
|
||||||
:invalid_datetime => "is not a valid datetime",
|
:invalid_datetime => "is not a valid datetime",
|
||||||
|
:is_at => "must be at %s",
|
||||||
:before => "must be before %s",
|
:before => "must be before %s",
|
||||||
:on_or_before => "must be on or before %s",
|
:on_or_before => "must be on or before %s",
|
||||||
:after => "must be after %s",
|
:after => "must be after %s",
|
||||||
@@ -332,8 +335,14 @@ Rails 2.2+ using the I18n system to define new defaults:
|
|||||||
activerecord:
|
activerecord:
|
||||||
errors:
|
errors:
|
||||||
messages:
|
messages:
|
||||||
on_or_before: "must be equal to or before {{restriction}}"
|
invalid_date: "is not a valid date"
|
||||||
on_or_after: "must be equal to or after {{restriction}}"
|
invalid_time: "is not a valid time"
|
||||||
|
invalid_datetime: "is not a valid datetime"
|
||||||
|
is_at: "must be at {{restriction}}"
|
||||||
|
before: "must be before {{restriction}}"
|
||||||
|
on_or_before: "must be on or before {{restriction}}"
|
||||||
|
after: "must be 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}}"
|
||||||
|
|
||||||
The {{restriction}} signifies where the interpolation value for the restriction
|
The {{restriction}} signifies where the interpolation value for the restriction
|
||||||
@@ -391,4 +400,4 @@ The matcher names are just the singular of the validation methods.
|
|||||||
|
|
||||||
== LICENSE:
|
== LICENSE:
|
||||||
|
|
||||||
Copyright (c) 2008 Adam Meehan, released under the MIT license
|
Copyright (c) 2008-2010 Adam Meehan, released under the MIT license
|
||||||
|
|||||||
12
Rakefile
12
Rakefile
@@ -7,10 +7,6 @@ require 'lib/validates_timeliness/version'
|
|||||||
|
|
||||||
GEM = "validates_timeliness"
|
GEM = "validates_timeliness"
|
||||||
GEM_VERSION = ValidatesTimeliness::VERSION
|
GEM_VERSION = ValidatesTimeliness::VERSION
|
||||||
AUTHOR = "Adam Meehan"
|
|
||||||
EMAIL = "adam.meehan@gmail.com"
|
|
||||||
HOMEPAGE = "http://github.com/adzap/validates_timeliness"
|
|
||||||
SUMMARY = "Date and time validation plugin for Rails 2.x which allows custom formats"
|
|
||||||
|
|
||||||
spec = Gem::Specification.new do |s|
|
spec = Gem::Specification.new do |s|
|
||||||
s.name = GEM
|
s.name = GEM
|
||||||
@@ -19,11 +15,11 @@ spec = Gem::Specification.new do |s|
|
|||||||
s.rubyforge_project = "validatestime"
|
s.rubyforge_project = "validatestime"
|
||||||
s.has_rdoc = true
|
s.has_rdoc = true
|
||||||
s.extra_rdoc_files = ["README.rdoc", "LICENSE", "TODO", "CHANGELOG"]
|
s.extra_rdoc_files = ["README.rdoc", "LICENSE", "TODO", "CHANGELOG"]
|
||||||
s.summary = SUMMARY
|
s.summary = "Date and time validation plugin for Rails 2.x which allows custom formats"
|
||||||
s.description = s.summary
|
s.description = s.summary
|
||||||
s.author = AUTHOR
|
s.author = "Adam Meehan"
|
||||||
s.email = EMAIL
|
s.email = "adam.meehan@gmail.com"
|
||||||
s.homepage = HOMEPAGE
|
s.homepage = "http://github.com/adzap/validates_timeliness"
|
||||||
|
|
||||||
s.require_path = 'lib'
|
s.require_path = 'lib'
|
||||||
s.autorequire = GEM
|
s.autorequire = GEM
|
||||||
|
|||||||
3
TODO
3
TODO
@@ -3,3 +3,6 @@
|
|||||||
- array of values for all temporal options
|
- array of values for all temporal options
|
||||||
- use tz and zo value from time string?
|
- use tz and zo value from time string?
|
||||||
- filter valid formats rather than remove for hot swapping without recompilation
|
- filter valid formats rather than remove for hot swapping without recompilation
|
||||||
|
- config generator
|
||||||
|
- move all config into top namespace
|
||||||
|
- remove action_view stuff
|
||||||
|
|||||||
@@ -25,15 +25,15 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
def load_error_messages
|
def load_error_messages
|
||||||
|
defaults = YAML::load(IO.read(LOCALE_PATH))['en']
|
||||||
|
ValidatesTimeliness::Validator.error_value_formats = defaults['validates_timeliness']['error_value_formats'].symbolize_keys
|
||||||
|
|
||||||
if defined?(I18n)
|
if defined?(I18n)
|
||||||
I18n.load_path.unshift(LOCALE_PATH)
|
I18n.load_path.unshift(LOCALE_PATH)
|
||||||
I18n.reload!
|
I18n.reload!
|
||||||
else
|
else
|
||||||
defaults = YAML::load(IO.read(LOCALE_PATH))['en']
|
|
||||||
errors = defaults['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
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# TODO remove this from the plugin for v3.
|
||||||
module ValidatesTimeliness
|
module ValidatesTimeliness
|
||||||
|
|
||||||
def self.enable_datetime_select_invalid_value_extension!
|
def self.enable_datetime_select_invalid_value_extension!
|
||||||
@@ -6,14 +7,15 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
module ActionView
|
module ActionView
|
||||||
|
|
||||||
# Intercepts the date and time select helpers to allow the
|
# Intercepts the date and time select helpers to reuse the values from the
|
||||||
# attribute value before type cast to be used as in the select helpers.
|
# the params rather than the parsed value. This allows invalid date/time
|
||||||
# This means that an invalid date or time will be redisplayed rather than the
|
# values to be redisplayed instead of blanks to aid correction by the user.
|
||||||
# type cast value which would be nil if invalid.
|
# Its a minor usability improvement which is rarely an issue for the user.
|
||||||
|
#
|
||||||
module InstanceTag
|
module InstanceTag
|
||||||
|
|
||||||
def self.included(base)
|
def self.included(base)
|
||||||
selector_method = Rails::VERSION::STRING < '2.2' ? :date_or_time_select : :datetime_selector
|
selector_method = Rails::VERSION::STRING.to_f < 2.2 ? :date_or_time_select : :datetime_selector
|
||||||
base.class_eval do
|
base.class_eval do
|
||||||
alias_method :datetime_selector_without_timeliness, selector_method
|
alias_method :datetime_selector_without_timeliness, selector_method
|
||||||
alias_method selector_method, :datetime_selector_with_timeliness
|
alias_method selector_method, :datetime_selector_with_timeliness
|
||||||
@@ -29,17 +31,19 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
def value_with_timeliness(object)
|
def value_with_timeliness(object)
|
||||||
return value_without_timeliness(object) unless @timeliness_date_or_time_tag
|
unless @timeliness_date_or_time_tag && @template_object.params[@object_name]
|
||||||
|
|
||||||
raw_value = value_before_type_cast(object)
|
|
||||||
|
|
||||||
if raw_value.nil? || raw_value.acts_like?(:time) || raw_value.is_a?(Date)
|
|
||||||
return value_without_timeliness(object)
|
return value_without_timeliness(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
time_array = ValidatesTimeliness::Formats.parse(raw_value, :datetime)
|
pairs = @template_object.params[@object_name].select {|k,v| k =~ /^#{@method_name}\(/ }
|
||||||
|
return value_without_timeliness(object) if pairs.empty?
|
||||||
|
|
||||||
TimelinessDateTime.new(*time_array[0..5])
|
values = pairs.map do |(param, value)|
|
||||||
|
position = param.scan(/\(([0-9]*).*\)/).first.first
|
||||||
|
[position, value]
|
||||||
|
end.sort {|a,b| a[0] <=> b[0] }.map {|v| v[1] }
|
||||||
|
|
||||||
|
TimelinessDateTime.new(*values)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
def write_date_time_attribute(attr_name, value, type, time_zone_aware)
|
def write_date_time_attribute(attr_name, value, type, time_zone_aware)
|
||||||
@attributes_cache["_#{attr_name}_before_type_cast"] = value
|
@attributes_cache["_#{attr_name}_before_type_cast"] = value
|
||||||
|
|
||||||
value = ValidatesTimeliness::Parser.parse(value, type)
|
value = ValidatesTimeliness::Parser.parse(value, type)
|
||||||
|
|
||||||
if value && type != :date
|
if value && type != :date
|
||||||
@@ -49,17 +48,25 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
columns_hash.each do |name, column|
|
columns_hash.each do |name, column|
|
||||||
if [:date, :time, :datetime].include?(column.type)
|
if [:date, :time, :datetime].include?(column.type)
|
||||||
time_zone_aware = create_time_zone_conversion_attribute?(name, column) rescue false
|
method_name = "#{name}="
|
||||||
|
next if instance_method_already_implemented?(method_name)
|
||||||
|
|
||||||
define_method("#{name}=") do |value|
|
time_zone_aware = create_time_zone_conversion_attribute?(name, column) rescue false
|
||||||
write_date_time_attribute(name, value, column.type, time_zone_aware)
|
define_method(method_name) do |value|
|
||||||
|
write_date_time_attribute(name, value, column.type, time_zone_aware)
|
||||||
end
|
end
|
||||||
timeliness_methods << name
|
timeliness_methods << method_name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Hack to get around instance_method_already_implemented? caching the
|
||||||
|
# methods in the ivar. It then appears to subsequent calls that the
|
||||||
|
# methods defined here, have not been and get defined again.
|
||||||
|
@_defined_class_methods = nil
|
||||||
|
|
||||||
define_attribute_methods_without_timeliness
|
define_attribute_methods_without_timeliness
|
||||||
@generated_methods += timeliness_methods
|
# add generated methods which is a Set object hence no += method
|
||||||
|
timeliness_methods.each {|attr| generated_methods << attr }
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
def extract_date_from_multiparameter_attributes(values)
|
def extract_date_from_multiparameter_attributes(values)
|
||||||
year = ValidatesTimeliness::Formats.unambiguous_year(values[0].rjust(2, "0"))
|
year = values[0].blank? ? nil : ValidatesTimeliness::Formats.unambiguous_year(values[0].rjust(2, "0"))
|
||||||
[year, *values.slice(1, 2).map { |s| s.rjust(2, "0") }].join("-")
|
[year, *values.slice(1, 2).map { |s| s.blank? ? nil : s.rjust(2, "0") }].join("-")
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_time_from_multiparameter_attributes(values)
|
def extract_time_from_multiparameter_attributes(values)
|
||||||
values[3..5].map { |s| s.rjust(2, "0") }.join(":")
|
values[3..5].map { |s| s.blank? ? nil : s.rjust(2, "0") }.join(":")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -39,7 +39,6 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Assign dates and times as formatted strings to force the use of the plugin parser
|
# Assign dates and times as formatted strings to force the use of the plugin parser
|
||||||
# and store a before_type_cast value for attribute
|
|
||||||
def execute_callstack_for_multiparameter_attributes_with_timeliness(callstack)
|
def execute_callstack_for_multiparameter_attributes_with_timeliness(callstack)
|
||||||
errors = []
|
errors = []
|
||||||
callstack.each do |name, values|
|
callstack.each do |name, values|
|
||||||
@@ -47,7 +46,7 @@ module ValidatesTimeliness
|
|||||||
if column && [:date, :time, :datetime].include?(column.type)
|
if column && [:date, :time, :datetime].include?(column.type)
|
||||||
begin
|
begin
|
||||||
callstack.delete(name)
|
callstack.delete(name)
|
||||||
if values.empty?
|
if values.empty? || values.all?(&:nil?)
|
||||||
send("#{name}=", nil)
|
send("#{name}=", nil)
|
||||||
else
|
else
|
||||||
value = ValidatesTimeliness::ActiveRecord.time_array_to_string(values, column.type)
|
value = ValidatesTimeliness::ActiveRecord.time_array_to_string(values, column.type)
|
||||||
|
|||||||
@@ -2,11 +2,9 @@ require 'date'
|
|||||||
|
|
||||||
module ValidatesTimeliness
|
module ValidatesTimeliness
|
||||||
|
|
||||||
# A date and time format regular expression generator. Allows you to
|
# A date and time parsing library which allows you to add custom formats using
|
||||||
# construct a date, time or datetime format using predefined tokens in
|
# simple predefined tokens. This makes it much easier to catalogue and customize
|
||||||
# a string. This makes it much easier to catalogue and customize the formats
|
# the formats rather than dealing directly with regular expressions.
|
||||||
# rather than dealing directly with regular expressions. The formats are then
|
|
||||||
# compiled into regular expressions for use validating date or time strings.
|
|
||||||
#
|
#
|
||||||
# Formats can be added or removed to customize the set of valid date or time
|
# Formats can be added or removed to customize the set of valid date or time
|
||||||
# string values.
|
# string values.
|
||||||
@@ -115,7 +113,8 @@ module ValidatesTimeliness
|
|||||||
'd/m/yy h:nn',
|
'd/m/yy h:nn',
|
||||||
'ddd, dd mmm yyyy hh:nn:ss (zo|tz)', # RFC 822
|
'ddd, dd mmm yyyy hh:nn:ss (zo|tz)', # RFC 822
|
||||||
'ddd mmm d hh:nn:ss zo yyyy', # Ruby time string
|
'ddd mmm d hh:nn:ss zo yyyy', # Ruby time string
|
||||||
'yyyy-mm-ddThh:nn:ss(?:Z|zo)' # iso 8601
|
'yyyy-mm-ddThh:nn:ssZ', # iso 8601 without zone offset
|
||||||
|
'yyyy-mm-ddThh:nn:sszo' # iso 8601 with zone offset
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -297,8 +296,8 @@ module ValidatesTimeliness
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Compile formats into validation regexps and format procs
|
# Generate regular expression and processor from format string
|
||||||
def format_expression_generator(string_format)
|
def generate_format_expression(string_format)
|
||||||
regexp = string_format.dup
|
regexp = string_format.dup
|
||||||
order = {}
|
order = {}
|
||||||
regexp.gsub!(/([\.\\])/, '\\\\\1') # escapes dots and backslashes
|
regexp.gsub!(/([\.\\])/, '\\\\\1') # escapes dots and backslashes
|
||||||
@@ -338,7 +337,7 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
def compile_formats(formats)
|
def compile_formats(formats)
|
||||||
formats.map { |format| [ format, *format_expression_generator(format) ] }
|
formats.map { |format| [ format, *generate_format_expression(format) ] }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Pick expression set and combine date and datetimes for
|
# Pick expression set and combine date and datetimes for
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ en:
|
|||||||
invalid_date: "is not a valid date"
|
invalid_date: "is not a valid date"
|
||||||
invalid_time: "is not a valid time"
|
invalid_time: "is not a valid time"
|
||||||
invalid_datetime: "is not a valid datetime"
|
invalid_datetime: "is not a valid datetime"
|
||||||
equal_to: "must be equal to {{restriction}}"
|
is_at: "must be at {{restriction}}"
|
||||||
before: "must be before {{restriction}}"
|
before: "must be before {{restriction}}"
|
||||||
on_or_before: "must be on or before {{restriction}}"
|
on_or_before: "must be on or before {{restriction}}"
|
||||||
after: "must be after {{restriction}}"
|
after: "must be after {{restriction}}"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ module Spec
|
|||||||
}
|
}
|
||||||
|
|
||||||
OPTION_TEST_SETTINGS = {
|
OPTION_TEST_SETTINGS = {
|
||||||
:equal_to => { :method => :+, :modify_on => :invalid },
|
:is_at => { :method => :+, :modify_on => :invalid },
|
||||||
:before => { :method => :-, :modify_on => :valid },
|
:before => { :method => :-, :modify_on => :valid },
|
||||||
:after => { :method => :+, :modify_on => :valid },
|
:after => { :method => :+, :modify_on => :valid },
|
||||||
:on_or_before => { :method => :+, :modify_on => :invalid },
|
:on_or_before => { :method => :+, :modify_on => :invalid },
|
||||||
@@ -28,7 +28,7 @@ module Spec
|
|||||||
|
|
||||||
valid = test_validity
|
valid = test_validity
|
||||||
|
|
||||||
valid = test_option(:equal_to) if valid && @options[:equal_to]
|
valid = test_option(:is_at) if valid && @options[:is_at]
|
||||||
valid = test_option(:before) if valid && @options[:before]
|
valid = test_option(:before) if valid && @options[:before]
|
||||||
valid = test_option(:after) if valid && @options[:after]
|
valid = test_option(:after) if valid && @options[:after]
|
||||||
valid = test_option(:on_or_before) if valid && @options[:on_or_before]
|
valid = test_option(:on_or_before) if valid && @options[:on_or_before]
|
||||||
@@ -115,27 +115,26 @@ module Spec
|
|||||||
pass
|
pass
|
||||||
end
|
end
|
||||||
|
|
||||||
def error_message_for(option)
|
def error_message_for(message)
|
||||||
msg = @validator.error_messages[option]
|
restriction = @validator.class.send(:evaluate_option_value, @validator.configuration[message], @type, @record)
|
||||||
restriction = @validator.class.send(:evaluate_option_value, @validator.configuration[option], @type, @record)
|
|
||||||
|
|
||||||
if restriction
|
if restriction
|
||||||
restriction = [restriction] unless restriction.is_a?(Array)
|
restriction = @validator.class.send(:type_cast_value, restriction, @type)
|
||||||
restriction.map! {|r| @validator.class.send(:type_cast_value, r, @type) }
|
interpolate = @validator.send(:interpolation_values, message, restriction)
|
||||||
interpolate = @validator.send(:interpolation_values, option, restriction )
|
end
|
||||||
|
|
||||||
# get I18n message if defined and has interpolation keys in msg
|
if defined?(I18n)
|
||||||
if defined?(I18n) && !@validator.send(:custom_error_messages).include?(option)
|
interpolate ||= {}
|
||||||
msg = if defined?(ActiveRecord::Error)
|
options = interpolate.merge(:default => @validator.send(:custom_error_messages)[message])
|
||||||
ActiveRecord::Error.new(@record, @expected, option, interpolate).message
|
if defined?(ActiveRecord::Error)
|
||||||
else
|
ActiveRecord::Error.new(@record, @expected, message, options).message
|
||||||
@record.errors.generate_message(@expected, option, interpolate)
|
else
|
||||||
end
|
@record.errors.generate_message(@expected, message, options)
|
||||||
else
|
end
|
||||||
msg = msg % interpolate
|
else
|
||||||
end
|
interpolate ||= nil
|
||||||
|
@validator.error_messages[message] % interpolate
|
||||||
end
|
end
|
||||||
msg
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_value(value)
|
def format_value(value)
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
|
#TODO remove deprecated option :equal_to
|
||||||
module ValidatesTimeliness
|
module ValidatesTimeliness
|
||||||
|
|
||||||
class Validator
|
class Validator
|
||||||
|
cattr_accessor :error_value_formats
|
||||||
cattr_accessor :ignore_restriction_errors
|
cattr_accessor :ignore_restriction_errors
|
||||||
self.ignore_restriction_errors = false
|
self.ignore_restriction_errors = false
|
||||||
|
|
||||||
RESTRICTION_METHODS = {
|
RESTRICTION_METHODS = {
|
||||||
|
:is_at => :==,
|
||||||
:equal_to => :==,
|
:equal_to => :==,
|
||||||
:before => :<,
|
:before => :<,
|
||||||
:after => :>,
|
:after => :>,
|
||||||
@@ -13,17 +16,18 @@ module ValidatesTimeliness
|
|||||||
:between => lambda {|v, r| (r.first..r.last).include?(v) }
|
:between => lambda {|v, r| (r.first..r.last).include?(v) }
|
||||||
}
|
}
|
||||||
|
|
||||||
VALID_OPTIONS = [
|
VALID_OPTION_KEYS = [
|
||||||
:on, :if, :unless, :allow_nil, :empty, :allow_blank,
|
:on, :if, :unless, :allow_nil, :empty, :allow_blank,
|
||||||
:with_time, :with_date, :ignore_usec, :format,
|
:with_time, :with_date, :ignore_usec, :format,
|
||||||
:invalid_time_message, :invalid_date_message, :invalid_datetime_message
|
:invalid_time_message, :invalid_date_message, :invalid_datetime_message
|
||||||
] + RESTRICTION_METHODS.keys.map {|option| [option, "#{option}_message".to_sym] }.flatten
|
] + RESTRICTION_METHODS.keys.map {|option| [option, "#{option}_message".to_sym] }.flatten
|
||||||
|
|
||||||
|
DEFAULT_OPTIONS = { :on => :save, :type => :datetime, :allow_nil => false, :allow_blank => false, :ignore_usec => false }
|
||||||
|
|
||||||
attr_reader :configuration, :type
|
attr_reader :configuration, :type
|
||||||
|
|
||||||
def initialize(configuration)
|
def initialize(configuration)
|
||||||
defaults = { :on => :save, :type => :datetime, :allow_nil => false, :allow_blank => false, :ignore_usec => false }
|
@configuration = DEFAULT_OPTIONS.merge(configuration)
|
||||||
@configuration = defaults.merge(configuration)
|
|
||||||
@type = @configuration.delete(:type)
|
@type = @configuration.delete(:type)
|
||||||
validate_options(@configuration)
|
validate_options(@configuration)
|
||||||
end
|
end
|
||||||
@@ -44,7 +48,7 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
def error_messages
|
def error_messages
|
||||||
@error_messages ||= self.class.default_error_messages.merge(custom_error_messages)
|
@error_messages ||= ::ActiveRecord::Errors.default_error_messages.merge(custom_error_messages)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -81,14 +85,13 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
def interpolation_values(option, restriction)
|
def interpolation_values(option, restriction)
|
||||||
format = self.class.error_value_formats[type]
|
format = self.class.error_value_format_for(type)
|
||||||
restriction = [restriction] unless restriction.is_a?(Array)
|
restriction = [restriction] unless restriction.is_a?(Array)
|
||||||
|
|
||||||
if defined?(I18n)
|
if defined?(I18n)
|
||||||
message = I18n.t('activerecord.errors.messages')[option]
|
|
||||||
subs = message.scan(/\{\{([^\}]*)\}\}/)
|
|
||||||
interpolations = {}
|
interpolations = {}
|
||||||
subs.each_with_index {|s, i| interpolations[s[0].to_sym] = restriction[i].strftime(format) }
|
keys = restriction.size == 1 ? [:restriction] : [:earliest, :latest]
|
||||||
|
keys.each_with_index {|key, i| interpolations[key] = restriction[i].strftime(format) }
|
||||||
interpolations
|
interpolations
|
||||||
else
|
else
|
||||||
restriction.map {|r| r.strftime(format) }
|
restriction.map {|r| r.strftime(format) }
|
||||||
@@ -112,8 +115,7 @@ module ValidatesTimeliness
|
|||||||
record.errors.add(attr_name, message, { :default => custom }.merge(interpolate || {}))
|
record.errors.add(attr_name, message, { :default => custom }.merge(interpolate || {}))
|
||||||
else
|
else
|
||||||
message = error_messages[message] if message.is_a?(Symbol)
|
message = error_messages[message] if message.is_a?(Symbol)
|
||||||
message = message % interpolate
|
record.errors.add(attr_name, message % interpolate)
|
||||||
record.errors.add(attr_name, message)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -140,10 +142,16 @@ module ValidatesTimeliness
|
|||||||
end
|
end
|
||||||
|
|
||||||
def validate_options(options)
|
def validate_options(options)
|
||||||
|
if options.key?(:equal_to)
|
||||||
|
::ActiveSupport::Deprecation.warn("ValidatesTimeliness :equal_to option is deprecated due to clash with a default Rails option. Use :is_at instead. You will need to fix any I18n error message references to this option date/time attributes now.")
|
||||||
|
options[:is_at] = options.delete(:equal_to)
|
||||||
|
options[:is_at_message] = options.delete(:equal_to_message)
|
||||||
|
end
|
||||||
|
|
||||||
invalid_for_type = ([:time, :date, :datetime] - [type]).map {|k| "invalid_#{k}_message".to_sym }
|
invalid_for_type = ([:time, :date, :datetime] - [type]).map {|k| "invalid_#{k}_message".to_sym }
|
||||||
invalid_for_type << :with_date unless type == :time
|
invalid_for_type << :with_date unless type == :time
|
||||||
invalid_for_type << :with_time unless type == :date
|
invalid_for_type << :with_time unless type == :date
|
||||||
options.assert_valid_keys(VALID_OPTIONS - invalid_for_type)
|
options.assert_valid_keys(VALID_OPTION_KEYS - invalid_for_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
def implied_type
|
def implied_type
|
||||||
@@ -153,26 +161,15 @@ module ValidatesTimeliness
|
|||||||
# class methods
|
# class methods
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
def default_error_messages
|
def error_value_format_for(type)
|
||||||
if defined?(I18n)
|
if defined?(I18n)
|
||||||
I18n.t('activerecord.errors.messages')
|
# work around for syntax check in vendored I18n for Rails <= 2.3.3
|
||||||
|
I18n.t('validates_timeliness.error_value_formats')[type] || error_value_formats[type]
|
||||||
else
|
else
|
||||||
::ActiveRecord::Errors.default_error_messages
|
error_value_formats[type]
|
||||||
end
|
end
|
||||||
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
|
when Time, Date
|
||||||
@@ -224,7 +221,7 @@ module ValidatesTimeliness
|
|||||||
time = [0,0,0]
|
time = [0,0,0]
|
||||||
end
|
end
|
||||||
dummy_date = ValidatesTimeliness::Formats.dummy_date_for_time_type
|
dummy_date = ValidatesTimeliness::Formats.dummy_date_for_time_type
|
||||||
Time.send(ValidatesTimeliness.default_timezone, *(dummy_date + time))
|
ValidatesTimeliness::Parser.make_time(dummy_date + time)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module ValidatesTimeliness
|
module ValidatesTimeliness
|
||||||
VERSION = "2.2.1"
|
VERSION = "2.3.1"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
||||||
|
|
||||||
ValidatesTimeliness.enable_datetime_select_extension!
|
|
||||||
|
|
||||||
describe 'ValidatesTimeliness::ActionView::InstanceTag' do
|
describe 'ValidatesTimeliness::ActionView::InstanceTag' do
|
||||||
include ActionView::Helpers::DateHelper
|
include ActionView::Helpers::DateHelper
|
||||||
include ActionController::Assertions::SelectorAssertions
|
include ActionController::Assertions::SelectorAssertions
|
||||||
@@ -10,33 +8,187 @@ describe 'ValidatesTimeliness::ActionView::InstanceTag' do
|
|||||||
@person = Person.new
|
@person = Person.new
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should display invalid datetime as datetime_select values" do
|
def params
|
||||||
@person.birth_date_and_time = "2008-02-30 12:00:22"
|
@params ||= {}
|
||||||
output = datetime_select(:person, :birth_date_and_time, :include_blank => true, :include_seconds => true)
|
end
|
||||||
|
|
||||||
output.should have_tag('select[id=person_birth_date_and_time_1i]') do
|
describe "datetime_select" do
|
||||||
with_tag('option[selected=selected]', '2008')
|
it "should use param values when attribute is nil" do
|
||||||
|
params["person"] = {
|
||||||
|
"birth_date_and_time(1i)" => 2009,
|
||||||
|
"birth_date_and_time(2i)" => 2,
|
||||||
|
"birth_date_and_time(3i)" => 29,
|
||||||
|
"birth_date_and_time(4i)" => 12,
|
||||||
|
"birth_date_and_time(5i)" => 13,
|
||||||
|
"birth_date_and_time(6i)" => 14,
|
||||||
|
}
|
||||||
|
@person.birth_date_and_time = nil
|
||||||
|
output = datetime_select(:person, :birth_date_and_time, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_1i] option[selected=selected]', '2009')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_2i] option[selected=selected]', 'February')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_3i] option[selected=selected]', '29')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_4i] option[selected=selected]', '12')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_5i] option[selected=selected]', '13')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_6i] option[selected=selected]', '14')
|
||||||
end
|
end
|
||||||
output.should have_tag('select[id=person_birth_date_and_time_2i]') do
|
|
||||||
with_tag('option[selected=selected]', 'February')
|
it "should override object values and use params if present" do
|
||||||
|
params["person"] = {
|
||||||
|
"birth_date_and_time(1i)" => 2009,
|
||||||
|
"birth_date_and_time(2i)" => 2,
|
||||||
|
"birth_date_and_time(3i)" => 29,
|
||||||
|
"birth_date_and_time(4i)" => 13,
|
||||||
|
"birth_date_and_time(5i)" => 14,
|
||||||
|
"birth_date_and_time(6i)" => 15,
|
||||||
|
}
|
||||||
|
@person.birth_date_and_time = "2009-03-01 13:14:15"
|
||||||
|
output = datetime_select(:person, :birth_date_and_time, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_1i] option[selected=selected]', '2009')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_2i] option[selected=selected]', 'February')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_3i] option[selected=selected]', '29')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_4i] option[selected=selected]', '13')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_5i] option[selected=selected]', '14')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_6i] option[selected=selected]', '15')
|
||||||
end
|
end
|
||||||
output.should have_tag('select[id=person_birth_date_and_time_3i]') do
|
|
||||||
with_tag('option[selected=selected]', '30')
|
it "should select attribute values from object if no params" do
|
||||||
|
@person.birth_date_and_time = "2009-01-02 13:14:15"
|
||||||
|
output = datetime_select(:person, :birth_date_and_time, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_1i] option[selected=selected]', '2009')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_2i] option[selected=selected]', 'January')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_3i] option[selected=selected]', '2')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_4i] option[selected=selected]', '13')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_5i] option[selected=selected]', '14')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_6i] option[selected=selected]', '15')
|
||||||
end
|
end
|
||||||
output.should have_tag('select[id=person_birth_date_and_time_4i]') do
|
|
||||||
with_tag('option[selected=selected]', '12')
|
it "should select attribute values if params does not contain attribute params" do
|
||||||
|
@person.birth_date_and_time = "2009-01-02 13:14:15"
|
||||||
|
params["person"] = { }
|
||||||
|
output = datetime_select(:person, :birth_date_and_time, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_1i] option[selected=selected]', '2009')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_2i] option[selected=selected]', 'January')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_3i] option[selected=selected]', '2')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_4i] option[selected=selected]', '13')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_5i] option[selected=selected]', '14')
|
||||||
|
output.should have_tag('select[id=person_birth_date_and_time_6i] option[selected=selected]', '15')
|
||||||
end
|
end
|
||||||
output.should have_tag('select[id=person_birth_date_and_time_5i]') do
|
|
||||||
with_tag('option[selected=selected]', '00')
|
it "should not select values when attribute value is nil and has no param values" do
|
||||||
end
|
@person.birth_date_and_time = nil
|
||||||
output.should have_tag('select[id=person_birth_date_and_time_6i]') do
|
output = datetime_select(:person, :birth_date_and_time, :include_blank => true, :include_seconds => true)
|
||||||
with_tag('option[selected=selected]', '22')
|
output.should_not have_tag('select[id=person_birth_date_and_time_1i] option[selected=selected]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_date_and_time_2i] option[selected=selected]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_date_and_time_3i] option[selected=selected]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_date_and_time_4i] option[selected=selected]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_date_and_time_5i] option[selected=selected]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_date_and_time_6i] option[selected=selected]')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should display datetime_select when datetime value is nil" do
|
describe "date_select" do
|
||||||
@person.birth_date_and_time = nil
|
it "should use param values when attribute is nil" do
|
||||||
output = datetime_select(:person, :birth_date_and_time, :include_blank => true, :include_seconds => true)
|
params["person"] = {
|
||||||
output.should have_tag('select', 6)
|
"birth_date(1i)" => 2009,
|
||||||
|
"birth_date(2i)" => 2,
|
||||||
|
"birth_date(3i)" => 29,
|
||||||
|
}
|
||||||
|
@person.birth_date = nil
|
||||||
|
output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('select[id=person_birth_date_1i] option[selected=selected]', '2009')
|
||||||
|
output.should have_tag('select[id=person_birth_date_2i] option[selected=selected]', 'February')
|
||||||
|
output.should have_tag('select[id=person_birth_date_3i] option[selected=selected]', '29')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should override object values and use params if present" do
|
||||||
|
params["person"] = {
|
||||||
|
"birth_date(1i)" => 2009,
|
||||||
|
"birth_date(2i)" => 2,
|
||||||
|
"birth_date(3i)" => 29,
|
||||||
|
}
|
||||||
|
@person.birth_date = "2009-03-01"
|
||||||
|
output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('select[id=person_birth_date_1i] option[selected=selected]', '2009')
|
||||||
|
output.should have_tag('select[id=person_birth_date_2i] option[selected=selected]', 'February')
|
||||||
|
output.should have_tag('select[id=person_birth_date_3i] option[selected=selected]', '29')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should select attribute values from object if no params" do
|
||||||
|
@person.birth_date = "2009-01-02"
|
||||||
|
output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('select[id=person_birth_date_1i] option[selected=selected]', '2009')
|
||||||
|
output.should have_tag('select[id=person_birth_date_2i] option[selected=selected]', 'January')
|
||||||
|
output.should have_tag('select[id=person_birth_date_3i] option[selected=selected]', '2')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should select attribute values if params does not contain attribute params" do
|
||||||
|
@person.birth_date = "2009-01-02"
|
||||||
|
params["person"] = { }
|
||||||
|
output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('select[id=person_birth_date_1i] option[selected=selected]', '2009')
|
||||||
|
output.should have_tag('select[id=person_birth_date_2i] option[selected=selected]', 'January')
|
||||||
|
output.should have_tag('select[id=person_birth_date_3i] option[selected=selected]', '2')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not select values when attribute value is nil and has no param values" do
|
||||||
|
@person.birth_date = nil
|
||||||
|
output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should_not have_tag('select[id=person_birth_date_1i] option[selected=selected]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_date_2i] option[selected=selected]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_date_3i] option[selected=selected]')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "time_select" do
|
||||||
|
before :all do
|
||||||
|
Time.now = Time.mktime(2009,1,1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should use param values when attribute is nil" do
|
||||||
|
params["person"] = {
|
||||||
|
"birth_time(1i)" => 2000,
|
||||||
|
"birth_time(2i)" => 1,
|
||||||
|
"birth_time(3i)" => 1,
|
||||||
|
"birth_time(4i)" => 12,
|
||||||
|
"birth_time(5i)" => 13,
|
||||||
|
"birth_time(6i)" => 14,
|
||||||
|
}
|
||||||
|
@person.birth_time = nil
|
||||||
|
output = time_select(:person, :birth_time, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('input[id=person_birth_time_1i][value=2000]')
|
||||||
|
output.should have_tag('input[id=person_birth_time_2i][value=1]')
|
||||||
|
output.should have_tag('input[id=person_birth_time_3i][value=1]')
|
||||||
|
output.should have_tag('select[id=person_birth_time_4i] option[selected=selected]', '12')
|
||||||
|
output.should have_tag('select[id=person_birth_time_5i] option[selected=selected]', '13')
|
||||||
|
output.should have_tag('select[id=person_birth_time_6i] option[selected=selected]', '14')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should select attribute values from object if no params" do
|
||||||
|
@person.birth_time = "13:14:15"
|
||||||
|
output = time_select(:person, :birth_time, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('input[id=person_birth_time_1i][value=2000]')
|
||||||
|
output.should have_tag('input[id=person_birth_time_2i][value=1]')
|
||||||
|
output.should have_tag('input[id=person_birth_time_3i][value=1]')
|
||||||
|
output.should have_tag('select[id=person_birth_time_4i] option[selected=selected]', '13')
|
||||||
|
output.should have_tag('select[id=person_birth_time_5i] option[selected=selected]', '14')
|
||||||
|
output.should have_tag('select[id=person_birth_time_6i] option[selected=selected]', '15')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not select values when attribute value is nil and has no param values" do
|
||||||
|
@person.birth_time = nil
|
||||||
|
output = time_select(:person, :birth_time, :include_blank => true, :include_seconds => true)
|
||||||
|
output.should have_tag('input[id=person_birth_time_1i][value=""]')
|
||||||
|
# Annoyingly these may or not have value attribute depending on rails version.
|
||||||
|
# output.should have_tag('input[id=person_birth_time_2i][value=""]')
|
||||||
|
# output.should have_tag('input[id=person_birth_time_3i][value=""]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_time_4i] option[selected=selected]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_time_5i] option[selected=selected]')
|
||||||
|
output.should_not have_tag('select[id=person_birth_time_6i] option[selected=selected]')
|
||||||
|
end
|
||||||
|
|
||||||
|
after :all do
|
||||||
|
Time.now = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,9 +5,12 @@ describe ValidatesTimeliness::ActiveRecord::AttributeMethods do
|
|||||||
@person = Person.new
|
@person = Person.new
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should call write_date_time_attribute when date attribute assigned value" do
|
it "should define and call write method on first assign" do
|
||||||
@person.should_receive(:write_date_time_attribute)
|
Person.class_eval { @generated_methods = Set.new; @_defined_class_methods = nil }
|
||||||
@person.birth_date = "2000-01-01"
|
Person.send(:undef_method, :birth_date=) if Person.instance_methods.include?('birth_date=')
|
||||||
|
person = Person.new
|
||||||
|
person.should_receive(:write_date_time_attribute)
|
||||||
|
person.birth_date = "2000-01-01"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should call write_date_time_attribute when time attribute assigned value" do
|
it "should call write_date_time_attribute when time attribute assigned value" do
|
||||||
@@ -78,7 +81,6 @@ describe ValidatesTimeliness::ActiveRecord::AttributeMethods do
|
|||||||
|
|
||||||
it "should not save invalid date value to database" do
|
it "should not save invalid date value to database" do
|
||||||
time_string = "2000-01-32 02:03:04"
|
time_string = "2000-01-32 02:03:04"
|
||||||
@person = Person.new
|
|
||||||
@person.birth_date_and_time = time_string
|
@person.birth_date_and_time = time_string
|
||||||
@person.save
|
@person.save
|
||||||
@person.reload
|
@person.reload
|
||||||
@@ -90,11 +92,10 @@ describe ValidatesTimeliness::ActiveRecord::AttributeMethods do
|
|||||||
it "should return time object from database in default timezone" do
|
it "should return time object from database in default timezone" do
|
||||||
ActiveRecord::Base.default_timezone = :utc
|
ActiveRecord::Base.default_timezone = :utc
|
||||||
time_string = "2000-01-01 09:00:00"
|
time_string = "2000-01-01 09:00:00"
|
||||||
@person = Person.new
|
|
||||||
@person.birth_date_and_time = time_string
|
@person.birth_date_and_time = time_string
|
||||||
@person.save
|
@person.save
|
||||||
@person.reload
|
@person.reload
|
||||||
@person.birth_date_and_time.strftime('%Y-%m-%d %H:%M:%S %Z').should == time_string + ' GMT'
|
@person.birth_date_and_time.strftime('%Y-%m-%d %H:%M:%S %Z').should == time_string + ' UTC'
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -109,7 +110,6 @@ describe ValidatesTimeliness::ActiveRecord::AttributeMethods do
|
|||||||
it "should return time object from database in correct timezone" do
|
it "should return time object from database in correct timezone" do
|
||||||
Time.zone = 'Melbourne'
|
Time.zone = 'Melbourne'
|
||||||
time_string = "2000-06-01 09:00:00"
|
time_string = "2000-06-01 09:00:00"
|
||||||
@person = Person.new
|
|
||||||
@person.birth_date_and_time = time_string
|
@person.birth_date_and_time = time_string
|
||||||
@person.save
|
@person.save
|
||||||
@person.reload
|
@person.reload
|
||||||
@@ -121,7 +121,6 @@ describe ValidatesTimeliness::ActiveRecord::AttributeMethods do
|
|||||||
it "should return correct date value after new value assigned" do
|
it "should return correct date value after new value assigned" do
|
||||||
today = Date.today
|
today = Date.today
|
||||||
tomorrow = Date.today + 1.day
|
tomorrow = Date.today + 1.day
|
||||||
@person = Person.new
|
|
||||||
@person.birth_date = today
|
@person.birth_date = today
|
||||||
@person.birth_date.should == today
|
@person.birth_date.should == today
|
||||||
@person.birth_date = tomorrow
|
@person.birth_date = tomorrow
|
||||||
@@ -131,11 +130,28 @@ describe ValidatesTimeliness::ActiveRecord::AttributeMethods do
|
|||||||
it "should update date attribute on existing object" do
|
it "should update date attribute on existing object" do
|
||||||
today = Date.today
|
today = Date.today
|
||||||
tomorrow = Date.today + 1.day
|
tomorrow = Date.today + 1.day
|
||||||
@person = Person.create(:birth_date => today)
|
person = Person.create(:birth_date => today)
|
||||||
@person.birth_date = tomorrow
|
person.birth_date = tomorrow
|
||||||
@person.save!
|
person.save!
|
||||||
@person.reload
|
person.reload
|
||||||
@person.birth_date.should == tomorrow
|
person.birth_date.should == tomorrow
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "attribute writer" do
|
||||||
|
|
||||||
|
it "should be able to be overridden in class" do
|
||||||
|
Person.class_eval { attr_accessor :birth_date }
|
||||||
|
person = Person.new
|
||||||
|
person.birth_date = 'overriden'
|
||||||
|
person.birth_date.should == 'overriden'
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Person.class_eval do
|
||||||
|
undef_method(:birth_date)
|
||||||
|
undef_method(:birth_date=)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -21,27 +21,93 @@ describe ValidatesTimeliness::ActiveRecord::MultiparameterAttributes do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "execute_callstack_for_multiparameter_attributes" do
|
describe "execute_callstack_for_multiparameter_attributes" do
|
||||||
before do
|
|
||||||
@callstack = {
|
describe "for valid values" do
|
||||||
'birth_date_and_time' => [2000,2,1,9,10,11],
|
before do
|
||||||
'birth_date' => [2000,2,1,9,10,11],
|
@callstack = {
|
||||||
'birth_time' => [2000,2,1,9,10,11]
|
'birth_date_and_time' => [2000,2,1,9,10,11],
|
||||||
}
|
'birth_date' => [2000,2,1,9,10,11],
|
||||||
|
'birth_time' => [2000,2,1,9,10,11]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store datetime string for datetime column" do
|
||||||
|
obj.should_receive(:birth_date_and_time=).once.with("2000-02-01 09:10:11")
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store date string for a date column" do
|
||||||
|
obj.should_receive(:birth_date=).once.with("2000-02-01")
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store time string for a time column" do
|
||||||
|
obj.should_receive(:birth_time=).once.with("09:10:11")
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should store datetime string for datetime column" do
|
describe "for invalid values" do
|
||||||
obj.should_receive(:birth_date_and_time=).once.with("2000-02-01 09:10:11")
|
before do
|
||||||
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
@callstack = {
|
||||||
|
'birth_date_and_time' => [2000,13,1,9,10,11],
|
||||||
|
'birth_date' => [2000,2,41,9,10,11],
|
||||||
|
'birth_time' => [2000,2,1,25,10,11]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store invalid datetime string for datetime column" do
|
||||||
|
obj.should_receive(:birth_date_and_time=).once.with("2000-13-01 09:10:11")
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store invalid date string for a date column" do
|
||||||
|
obj.should_receive(:birth_date=).once.with("2000-02-41")
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store invalid time string for a time column" do
|
||||||
|
obj.should_receive(:birth_time=).once.with("25:10:11")
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should store date string for a date column" do
|
describe "for missing values" do
|
||||||
obj.should_receive(:birth_date=).once.with("2000-02-01")
|
it "should store nil if all datetime values nil" do
|
||||||
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
obj.should_receive(:birth_date_and_time=).once.with(nil)
|
||||||
end
|
callstack = { 'birth_date_and_time' => [nil,nil,nil,nil,nil,nil] }
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, callstack)
|
||||||
|
end
|
||||||
|
|
||||||
it "should store time string for a time column" do
|
it "should store nil year as empty value in string" do
|
||||||
obj.should_receive(:birth_time=).once.with("09:10:11")
|
obj.should_receive(:birth_date_and_time=).once.with("-02-01 09:10:11")
|
||||||
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
callstack = { 'birth_date_and_time' => [nil,2,1,9,10,11] }
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, callstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store nil month as empty value in string" do
|
||||||
|
obj.should_receive(:birth_date_and_time=).once.with("2000--01 09:10:11")
|
||||||
|
callstack = { 'birth_date_and_time' => [2000,nil,1,9,10,11] }
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, callstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store nil day as empty value in string" do
|
||||||
|
obj.should_receive(:birth_date_and_time=).once.with("2000-02- 09:10:11")
|
||||||
|
callstack = { 'birth_date_and_time' => [2000,2,nil,9,10,11] }
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, callstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store nil hour as empty value in string" do
|
||||||
|
obj.should_receive(:birth_date_and_time=).once.with("2000-02-01 :10:11")
|
||||||
|
callstack = { 'birth_date_and_time' => [2000,2,1,nil,10,11] }
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, callstack)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should store nil minute as empty value in string" do
|
||||||
|
obj.should_receive(:birth_date_and_time=).once.with("2000-02-01 09:10:")
|
||||||
|
callstack = { 'birth_date_and_time' => [2000,2,1,9,10,nil] }
|
||||||
|
obj.send(:execute_callstack_for_multiparameter_attributes, callstack)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ describe ValidatesTimeliness::Formats do
|
|||||||
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
|
||||||
generate_proc('yyyy-mm-dd').call('2000', '1', '2').should == [2000,1,2,0,0,0,0]
|
generate_proc('yyyy-mm-dd').call('2000', '1', '2').should == [2000,1,2,0,0,0,0]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should generate proc which outputs date array from format with different order" do
|
it "should generate proc which outputs date array from format with different order" do
|
||||||
generate_proc('dd/mm/yyyy').call('2', '1', '2000').should == [2000,1,2,0,0,0,0]
|
generate_proc('dd/mm/yyyy').call('2', '1', '2000').should == [2000,1,2,0,0,0,0]
|
||||||
@@ -32,7 +32,7 @@ describe ValidatesTimeliness::Formats do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "validation regexps" do
|
describe "validate regexps" do
|
||||||
|
|
||||||
describe "for time formats" do
|
describe "for time formats" do
|
||||||
format_tests = {
|
format_tests = {
|
||||||
@@ -132,7 +132,7 @@ describe ValidatesTimeliness::Formats do
|
|||||||
time_array.should == [2000,1,1,12,13,0,0]
|
time_array.should == [2000,1,1,12,13,0,0]
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return zone offset when :include_offset options is true" do
|
it "should return zone offset when :include_offset option is true" do
|
||||||
time_array = formats.parse('2000-02-01T12:13:14-10:30', :datetime, :include_offset => true)
|
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]
|
time_array.should == [2000,2,1,12,13,14,0,-37800]
|
||||||
end
|
end
|
||||||
@@ -188,6 +188,18 @@ describe ValidatesTimeliness::Formats do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "parse ISO8601 datetime" do
|
||||||
|
it "should return array without zone offset when no offset in string" do
|
||||||
|
time_array = formats.parse('2000-02-01T12:13:14Z', :datetime, :strict => true)
|
||||||
|
time_array.should == [2000,2,1,12,13,14,0]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return array with zone offset when offset in string" do
|
||||||
|
time_array = formats.parse('2000-02-01T12:13:14+10:00', :datetime, :strict => true)
|
||||||
|
time_array.should == [2000,2,1,12,13,14,0,36000]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "removing formats" do
|
describe "removing formats" do
|
||||||
it "should remove format from format array" do
|
it "should remove format from format array" do
|
||||||
formats.remove_formats(:time, 'h.nn_ampm')
|
formats.remove_formats(:time, 'h.nn_ampm')
|
||||||
@@ -277,15 +289,15 @@ describe ValidatesTimeliness::Formats do
|
|||||||
|
|
||||||
def generate_regexp(format)
|
def generate_regexp(format)
|
||||||
# wrap in line start and end anchors to emulate extract values method
|
# wrap in line start and end anchors to emulate extract values method
|
||||||
/\A#{formats.send(:format_expression_generator, format)[0]}\Z/
|
/\A#{formats.send(:generate_format_expression, format)[0]}\Z/
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_regexp_str(format)
|
def generate_regexp_str(format)
|
||||||
formats.send(:format_expression_generator, format)[0].inspect
|
formats.send(:generate_format_expression, format)[0].inspect
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_proc(format)
|
def generate_proc(format)
|
||||||
formats.send(:format_expression_generator, format)[1]
|
formats.send(:generate_format_expression, format)[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_format(type, format)
|
def delete_format(type, format)
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
#
|
#
|
||||||
# To use ginger:
|
# To use ginger:
|
||||||
#
|
#
|
||||||
# sudo gem install freelancing-god-ginger --source=http://gems.github.com
|
# gem install ginger
|
||||||
#
|
#
|
||||||
# Then run
|
# Then run
|
||||||
#
|
#
|
||||||
# ginger spec
|
# ginger spec
|
||||||
#
|
#
|
||||||
Ginger.configure do |config|
|
Ginger.configure do |config|
|
||||||
rails_versions = ['2.0.2', '2.1.2', '2.2.2', '2.3.3', '2.3.4']
|
rails_versions = ['2.0.2', '2.1.2', '2.2.2', '2.3.3', '2.3.4', '2.3.5']
|
||||||
|
|
||||||
rails_versions.each do |v|
|
rails_versions.each do |v|
|
||||||
g = Ginger::Scenario.new("Rails #{v}")
|
g = Ginger::Scenario.new("Rails #{v}")
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ end
|
|||||||
|
|
||||||
class WithValidation < Person
|
class WithValidation < Person
|
||||||
validates_date :birth_date,
|
validates_date :birth_date,
|
||||||
:equal_to => '2000-01-01',
|
:is_at => '2000-01-01',
|
||||||
:before => '2000-01-10',
|
:before => '2000-01-10',
|
||||||
:after => '2000-01-01',
|
:after => '2000-01-01',
|
||||||
:on_or_before => '2000-01-09',
|
:on_or_before => '2000-01-09',
|
||||||
@@ -14,7 +14,7 @@ class WithValidation < Person
|
|||||||
:between => ['2000-01-01', '2000-01-03']
|
:between => ['2000-01-01', '2000-01-03']
|
||||||
|
|
||||||
validates_time :birth_time,
|
validates_time :birth_time,
|
||||||
:equal_to => '09:00',
|
:is_at => '09:00',
|
||||||
:before => '23:00',
|
:before => '23:00',
|
||||||
:after => '09:00',
|
:after => '09:00',
|
||||||
:on_or_before => '22:00',
|
:on_or_before => '22:00',
|
||||||
@@ -22,7 +22,7 @@ class WithValidation < Person
|
|||||||
:between => ['09:00', '17:00']
|
:between => ['09:00', '17:00']
|
||||||
|
|
||||||
validates_datetime :birth_date_and_time,
|
validates_datetime :birth_date_and_time,
|
||||||
:equal_to => '2000-01-01 09:00',
|
:is_at => '2000-01-01 09:00',
|
||||||
:before => '2000-01-10 23:00',
|
:before => '2000-01-10 23:00',
|
||||||
:after => '2000-01-01 09:00',
|
:after => '2000-01-01 09:00',
|
||||||
:on_or_before => '2000-01-09 23:00',
|
:on_or_before => '2000-01-09 23:00',
|
||||||
@@ -65,7 +65,7 @@ describe "ValidateTimeliness matcher" do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "with equal_to option" do
|
describe "with is_at option" do
|
||||||
test_values = {
|
test_values = {
|
||||||
:date => ['2000-01-01', '2000-01-02'],
|
:date => ['2000-01-01', '2000-01-02'],
|
||||||
:time => ['09:00', '09:01'],
|
:time => ['09:00', '09:01'],
|
||||||
@@ -75,15 +75,15 @@ describe "ValidateTimeliness matcher" do
|
|||||||
[:date, :time, :datetime].each do |type|
|
[:date, :time, :datetime].each do |type|
|
||||||
|
|
||||||
it "should report that #{type} is validated" do
|
it "should report that #{type} is validated" do
|
||||||
with_validation.should self.send("validate_#{type}", attribute_for_type(type), :equal_to => test_values[type][0])
|
with_validation.should self.send("validate_#{type}", attribute_for_type(type), :is_at => test_values[type][0])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should report that #{type} is not validated when option value is incorrect" do
|
it "should report that #{type} is not validated when option value is incorrect" do
|
||||||
with_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :equal_to => test_values[type][1])
|
with_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :is_at => test_values[type][1])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should report that #{type} is not validated with option" do
|
it "should report that #{type} is not validated with option" do
|
||||||
no_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :equal_to => test_values[type][0])
|
no_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :is_at => test_values[type][0])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ end
|
|||||||
require 'validates_timeliness'
|
require 'validates_timeliness'
|
||||||
require 'validates_timeliness/matcher'
|
require 'validates_timeliness/matcher'
|
||||||
|
|
||||||
|
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:'})
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,17 @@ describe ValidatesTimeliness::Validator do
|
|||||||
Time.now = nil
|
Time.now = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
before :each do
|
def person
|
||||||
@person = Person.new
|
@person ||= Person.new
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "option keys validation" do
|
describe "option keys validation" do
|
||||||
|
before(:all) do
|
||||||
|
ActiveSupport::Deprecation.silenced = true
|
||||||
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
keys = ValidatesTimeliness::Validator::VALID_OPTIONS - [:invalid_date_message, :invalid_time_message, :with_date, :with_time]
|
keys = ValidatesTimeliness::Validator::VALID_OPTION_KEYS - [:invalid_date_message, :invalid_time_message, :with_date, :with_time]
|
||||||
@valid_options = keys.inject({}) {|hash, opt| hash[opt] = nil; hash }
|
@valid_options = keys.inject({}) {|hash, opt| hash[opt] = nil; hash }
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -30,6 +34,15 @@ describe ValidatesTimeliness::Validator do
|
|||||||
it "should not raise error if option keys are valid" do
|
it "should not raise error if option keys are valid" do
|
||||||
lambda { Person.validates_datetime(@valid_options) }.should_not raise_error(ArgumentError)
|
lambda { Person.validates_datetime(@valid_options) }.should_not raise_error(ArgumentError)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should display deprecation notice for :equal_to" do
|
||||||
|
::ActiveSupport::Deprecation.should_receive(:warn)
|
||||||
|
Person.validates_datetime :equal_to => Time.now
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:all) do
|
||||||
|
ActiveSupport::Deprecation.silenced = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "evaluate_option_value" do
|
describe "evaluate_option_value" do
|
||||||
@@ -346,53 +359,53 @@ describe ValidatesTimeliness::Validator do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "instance with :equal_to restriction" do
|
describe "instance with :is_at restriction" do
|
||||||
|
|
||||||
describe "for datetime type" do
|
describe "for datetime type" do
|
||||||
before do
|
before do
|
||||||
configure_validator(:equal_to => Time.now)
|
configure_validator(:is_at => Time.now)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should have error when value not equal to :equal_to restriction" do
|
it "should have error when value not equal to :is_at restriction" do
|
||||||
validate_with(:birth_date_and_time, Time.now + 1)
|
validate_with(:birth_date_and_time, Time.now + 1)
|
||||||
should_have_error(:birth_date_and_time, :equal_to)
|
should_have_error(:birth_date_and_time, :is_at)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should be valid when value is equal to :equal_to restriction" do
|
it "should be valid when value is equal to :is_at restriction" do
|
||||||
validate_with(:birth_date_and_time, Time.now)
|
validate_with(:birth_date_and_time, Time.now)
|
||||||
should_have_no_error(:birth_date_and_time, :equal_to)
|
should_have_no_error(:birth_date_and_time, :is_at)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for date type" do
|
describe "for date type" do
|
||||||
before do
|
before do
|
||||||
configure_validator(:type => :date, :equal_to => Date.today)
|
configure_validator(:type => :date, :is_at => Date.today)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should have error when value is not equal to :equal_to restriction" do
|
it "should have error when value is not equal to :is_at restriction" do
|
||||||
validate_with(:birth_date, Date.today + 1)
|
validate_with(:birth_date, Date.today + 1)
|
||||||
should_have_error(:birth_date, :equal_to)
|
should_have_error(:birth_date, :is_at)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should be valid when value is equal to :equal_to restriction" do
|
it "should be valid when value is equal to :is_at restriction" do
|
||||||
validate_with(:birth_date, Date.today)
|
validate_with(:birth_date, Date.today)
|
||||||
should_have_no_error(:birth_date, :equal_to)
|
should_have_no_error(:birth_date, :is_at)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for time type" do
|
describe "for time type" do
|
||||||
before do
|
before do
|
||||||
configure_validator(:type => :time, :equal_to => "09:00:00")
|
configure_validator(:type => :time, :is_at => "09:00:00")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should have error when value is not equal to :equal_to restriction" do
|
it "should have error when value is not equal to :is_at restriction" do
|
||||||
validate_with(:birth_time, "09:00:01")
|
validate_with(:birth_time, "09:00:01")
|
||||||
should_have_error(:birth_time, :equal_to)
|
should_have_error(:birth_time, :is_at)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should be valid when value is equal to :equal_to restriction" do
|
it "should be valid when value is equal to :is_at restriction" do
|
||||||
validate_with(:birth_time, "09:00:00")
|
validate_with(:birth_time, "09:00:00")
|
||||||
should_have_no_error(:birth_time, :equal_to)
|
should_have_no_error(:birth_time, :is_at)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -400,9 +413,9 @@ describe ValidatesTimeliness::Validator do
|
|||||||
describe "instance with :ignore_usec option" do
|
describe "instance with :ignore_usec option" do
|
||||||
|
|
||||||
it "should ignore usec on time values when evaluated" do
|
it "should ignore usec on time values when evaluated" do
|
||||||
configure_validator(:equal_to => Time.utc(2000, 1, 1, 0, 0, 0, 0), :ignore_usec => true)
|
configure_validator(:is_at => 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))
|
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)
|
should_have_no_error(:birth_date_and_time, :is_at)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -422,9 +435,9 @@ describe ValidatesTimeliness::Validator do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "should should ignore usec value on combined value if :ignore_usec option is true" do
|
it "should should ignore usec value on combined value if :ignore_usec option is true" do
|
||||||
configure_validator(:type => :date, :with_time => Time.mktime(2000,1,1,12,30,0,500), :equal_to => Time.mktime(2000,1,1,12,30), :ignore_usec => true)
|
configure_validator(:type => :date, :with_time => Time.mktime(2000,1,1,12,30,0,500), :is_at => Time.mktime(2000,1,1,12,30), :ignore_usec => true)
|
||||||
validate_with(:birth_date, "2000-01-01")
|
validate_with(:birth_date, "2000-01-01")
|
||||||
should_have_no_error(:birth_date, :equal_to)
|
should_have_no_error(:birth_date, :is_at)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -496,6 +509,38 @@ describe ValidatesTimeliness::Validator do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if defined?(I18n)
|
||||||
|
|
||||||
|
describe "localized error messages" do
|
||||||
|
before(:all) do
|
||||||
|
translations = {
|
||||||
|
:activerecord => {:errors => {:messages => { :after => 'retfa {{restriction}}' }}},
|
||||||
|
:validates_timeliness => {:error_value_formats => {}}
|
||||||
|
}
|
||||||
|
I18n.backend.store_translations 'zz', translations
|
||||||
|
I18n.locale = :zz
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be used if defined" do
|
||||||
|
configure_validator(:type => :date, :after => Date.today)
|
||||||
|
validate_with(:birth_date, 1.day.ago)
|
||||||
|
person.errors.on(:birth_date).should match(/retfa/)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should use I18n translation missing message when not defined" do
|
||||||
|
configure_validator(:type => :date, :on_or_after => Date.today)
|
||||||
|
validate_with(:birth_date, 1.day.ago)
|
||||||
|
person.errors.on(:birth_date).should match(/translation missing/)
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:all) do
|
||||||
|
I18n.locale = :en
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
describe "custom_error_messages" do
|
describe "custom_error_messages" do
|
||||||
it "should return hash of custom error messages from configuration with _message truncated from keys" do
|
it "should return hash of custom error messages from configuration with _message truncated from keys" do
|
||||||
configure_validator(:type => :date, :invalid_date_message => 'thats no date')
|
configure_validator(:type => :date, :invalid_date_message => 'thats no date')
|
||||||
@@ -566,6 +611,24 @@ describe ValidatesTimeliness::Validator do
|
|||||||
validate_with(:birth_time, '11:59')
|
validate_with(:birth_time, '11:59')
|
||||||
person.errors.on(:birth_time).should match(/after \d{2}:\d{2}:\d{2}\Z/)
|
person.errors.on(:birth_time).should match(/after \d{2}:\d{2}:\d{2}\Z/)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if defined?(I18n)
|
||||||
|
|
||||||
|
describe "I18n" do
|
||||||
|
it "should use global default if locale format missing" do
|
||||||
|
I18n.backend.store_translations 'zz', :activerecord => {:errors => {:messages => { :after => 'after {{restriction}}' }}}
|
||||||
|
I18n.locale = :zz
|
||||||
|
configure_validator(:type => :datetime, :after => 1.day.from_now)
|
||||||
|
validate_with(:birth_date_and_time, Time.now)
|
||||||
|
person.errors.on(:birth_date_and_time).should match(/after \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\Z/)
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
I18n.locale = :en
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "custom formats" do
|
describe "custom formats" do
|
||||||
@@ -644,7 +707,7 @@ describe ValidatesTimeliness::Validator do
|
|||||||
|
|
||||||
def error_messages
|
def error_messages
|
||||||
return @error_messages if defined?(@error_messages)
|
return @error_messages if defined?(@error_messages)
|
||||||
messages = validator.send(:error_messages)
|
messages = defined?(I18n) ? I18n.t('activerecord.errors.messages') : validator.send(:error_messages)
|
||||||
@error_messages = messages.inject({}) {|h, (k, v)| h[k] = v.sub(/ (\%s|\{\{\w*\}\}).*/, ''); h }
|
@error_messages = messages.inject({}) {|h, (k, v)| h[k] = v.sub(/ (\%s|\{\{\w*\}\}).*/, ''); h }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,20 +2,20 @@
|
|||||||
|
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = %q{validates_timeliness}
|
s.name = %q{validates_timeliness}
|
||||||
s.version = "2.2.1"
|
s.version = "2.3.1"
|
||||||
|
|
||||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||||
s.authors = ["Adam Meehan"]
|
s.authors = ["Adam Meehan"]
|
||||||
s.autorequire = %q{validates_timeliness}
|
s.autorequire = %q{validates_timeliness}
|
||||||
s.date = %q{2009-09-12}
|
s.date = %q{2010-03-19}
|
||||||
s.description = %q{Date and time validation plugin for Rails 2.x which allows custom formats}
|
s.description = %q{Date and time validation plugin for Rails 2.x which allows custom formats}
|
||||||
s.email = %q{adam.meehan@gmail.com}
|
s.email = %q{adam.meehan@gmail.com}
|
||||||
s.extra_rdoc_files = ["README.rdoc", "LICENSE", "TODO", "CHANGELOG"]
|
s.extra_rdoc_files = ["README.rdoc", "LICENSE", "TODO", "CHANGELOG"]
|
||||||
s.files = ["LICENSE", "README.rdoc", "Rakefile", "TODO", "CHANGELOG", "lib/validates_timeliness", "lib/validates_timeliness/active_record", "lib/validates_timeliness/active_record/multiparameter_attributes.rb", "lib/validates_timeliness/active_record/attribute_methods.rb", "lib/validates_timeliness/parser.rb", "lib/validates_timeliness/version.rb", "lib/validates_timeliness/validator.rb", "lib/validates_timeliness/validation_methods.rb", "lib/validates_timeliness/locale", "lib/validates_timeliness/locale/en.yml", "lib/validates_timeliness/spec", "lib/validates_timeliness/spec/rails", "lib/validates_timeliness/spec/rails/matchers", "lib/validates_timeliness/spec/rails/matchers/validate_timeliness.rb", "lib/validates_timeliness/matcher.rb", "lib/validates_timeliness/action_view", "lib/validates_timeliness/action_view/instance_tag.rb", "lib/validates_timeliness/formats.rb", "lib/validates_timeliness.rb", "spec/active_record", "spec/active_record/multiparameter_attributes_spec.rb", "spec/active_record/attribute_methods_spec.rb", "spec/formats_spec.rb", "spec/parser_spec.rb", "spec/spec_helper.rb", "spec/ginger_scenarios.rb", "spec/time_travel", "spec/time_travel/time_extensions.rb", "spec/time_travel/time_travel.rb", "spec/time_travel/MIT-LICENSE", "spec/spec", "spec/spec/rails", "spec/spec/rails/matchers", "spec/spec/rails/matchers/validate_timeliness_spec.rb", "spec/validator_spec.rb", "spec/action_view", "spec/action_view/instance_tag_spec.rb", "spec/resources", "spec/resources/schema.rb", "spec/resources/application.rb", "spec/resources/person.rb", "spec/resources/sqlite_patch.rb"]
|
s.files = ["LICENSE", "README.rdoc", "Rakefile", "TODO", "CHANGELOG", "lib/validates_timeliness", "lib/validates_timeliness/action_view", "lib/validates_timeliness/action_view/instance_tag.rb", "lib/validates_timeliness/active_record", "lib/validates_timeliness/active_record/attribute_methods.rb", "lib/validates_timeliness/active_record/multiparameter_attributes.rb", "lib/validates_timeliness/formats.rb", "lib/validates_timeliness/locale", "lib/validates_timeliness/locale/en.yml", "lib/validates_timeliness/matcher.rb", "lib/validates_timeliness/parser.rb", "lib/validates_timeliness/spec", "lib/validates_timeliness/spec/rails", "lib/validates_timeliness/spec/rails/matchers", "lib/validates_timeliness/spec/rails/matchers/validate_timeliness.rb", "lib/validates_timeliness/validation_methods.rb", "lib/validates_timeliness/validator.rb", "lib/validates_timeliness/version.rb", "lib/validates_timeliness.rb", "spec/action_view", "spec/action_view/instance_tag_spec.rb", "spec/active_record", "spec/active_record/attribute_methods_spec.rb", "spec/active_record/multiparameter_attributes_spec.rb", "spec/formats_spec.rb", "spec/ginger_scenarios.rb", "spec/parser_spec.rb", "spec/resources", "spec/resources/application.rb", "spec/resources/person.rb", "spec/resources/schema.rb", "spec/resources/sqlite_patch.rb", "spec/spec", "spec/spec/rails", "spec/spec/rails/matchers", "spec/spec/rails/matchers/validate_timeliness_spec.rb", "spec/spec_helper.rb", "spec/time_travel", "spec/time_travel/MIT-LICENSE", "spec/time_travel/time_extensions.rb", "spec/time_travel/time_travel.rb", "spec/validator_spec.rb"]
|
||||||
s.homepage = %q{http://github.com/adzap/validates_timeliness}
|
s.homepage = %q{http://github.com/adzap/validates_timeliness}
|
||||||
s.require_paths = ["lib"]
|
s.require_paths = ["lib"]
|
||||||
s.rubyforge_project = %q{validatestime}
|
s.rubyforge_project = %q{validatestime}
|
||||||
s.rubygems_version = %q{1.3.3}
|
s.rubygems_version = %q{1.3.5}
|
||||||
s.summary = %q{Date and time validation plugin for Rails 2.x which allows custom formats}
|
s.summary = %q{Date and time validation plugin for Rails 2.x which allows custom formats}
|
||||||
|
|
||||||
if s.respond_to? :specification_version then
|
if s.respond_to? :specification_version then
|
||||||
|
|||||||
Reference in New Issue
Block a user