Compare commits

..

21 Commits
2.1.0 ... 2.2.0

Author SHA1 Message Date
Adam Meehan
76e159b350 version 2.2.0 2009-09-12 13:43:50 +10:00
Adam Meehan
c762b6d4f8 added version file with VERSION constant 2009-09-12 13:42:07 +10:00
Adam Meehan
91f9f65bc0 tiny doc change 2009-09-12 13:36:57 +10:00
Adam Meehan
6db8b7d908 push dummy date value assignment into Formats.parse and allow custom values to be used 2009-09-12 13:07:01 +10:00
Adam Meehan
d3c5101f92 use implied_type in restriction evaluations 2009-09-12 13:05:12 +10:00
Adam Meehan
899e96b880 tiny clean up 2009-09-12 13:05:12 +10:00
Adam Meehan
162faf632a push strict override for format option into Formats.parse 2009-09-12 13:05:12 +10:00
Adam Meehan
1b865cc834 split ignore_sec into own describe 2009-09-12 13:05:11 +10:00
Adam Meehan
c29478df45 fix deprecation for ActiveRecord::Errors#generate_message in Rails 2.3.4
ginger scenario added 2.3.4
2009-09-12 13:05:11 +10:00
Adam Meehan
df3283e5a1 fix ignore_usec for with_date and with_time options 2009-09-12 13:05:04 +10:00
Adam Meehan
0e382e15f2 moved action view extension enable call to relevant spec 2009-09-11 13:13:02 +10:00
Adam Meehan
9a697b9cab finally fixed spec for latest rspec 2009-09-11 13:11:09 +10:00
Adam Meehan
7bf7ed0569 catch both possible exception types 2009-09-09 16:25:04 +10:00
Adam Meehan
a969a49ae8 little tweaks 2009-09-09 16:16:11 +10:00
Adam Meehan
687e61a3f2 Merge branch 'master' of github.com:adzap/validates_timeliness 2009-09-05 19:50:43 +10:00
Adam Meehan
4cc20ae620 fixed some bad rescue behaviour in parse method 2009-09-05 19:47:49 +10:00
adzap
2d510504e6 change to lambda in examples 2009-08-26 21:07:29 -07:00
Adam Meehan
2028d68b17 checking proc arity in option value for ruby 1.9 compat 2009-08-22 14:59:46 +10:00
Adam Meehan
e399c6b510 moved mutliparam helper methods our of AR to reduce method pollution 2009-07-28 12:52:25 +10:00
Adam Meehan
7aa1a87731 require matcher in spec helper 2009-07-28 12:51:32 +10:00
Adam Meehan
1a31e7463d have to manually require matcher now because the presence of the Spec
namespace caused issues for shoulda when not using rspec:wq
2009-07-07 15:32:15 +10:00
20 changed files with 193 additions and 115 deletions

View File

@@ -1,3 +1,10 @@
= 2.2.0 [2009-09-12]
- Ruby 1.9 support!
- Customise dummy date values for time types. See DUMMY DATE FOR TIME TYPES.
- Fixed matcher conflict with Shoulda. Load plugin matcher manually now see matcher section in README
- Fixed :ignore_usec when used with :with_time or :with_date
- Some clean up and refactoring
= 2.1.0 [2009-06-20] = 2.1.0 [2009-06-20]
- Added ambiguous year threshold setting in Formats class to customize the threshold for 2 digit years (See README) - Added ambiguous year threshold setting in Formats class to customize the threshold for 2 digit years (See README)
- Fixed interpolation values in custom error message for Rails 2.2+ - Fixed interpolation values in custom error message for Rails 2.2+

View File

@@ -22,9 +22,9 @@ think should be a valid date or time string.
* Restores ability to see raw value entered for date/time attributes with * Restores ability to see raw value entered for date/time attributes with
_before_type_cast modifier, which was lost in Rails 2.1. _before_type_cast modifier, which was lost in Rails 2.1.
* Respects new timezone features of Rails 2.1. * Supports Rails timezone handling
* Supports Rails 2.2 I18n for the error messages * Supports Rails I18n for the error messages
* Rspec matcher for testing model validation of dates and times * Rspec matcher for testing model validation of dates and times
@@ -107,7 +107,7 @@ temporal options.
== EXAMPLES: == EXAMPLES:
validates_date :date_of_birth :before => Proc.new { 18.years.ago }, validates_date :date_of_birth :before => lambda { 18.years.ago },
:before_message => "must be at least 18 years old" :before_message => "must be at least 18 years old"
validates_time :breakfast_time, :on_or_after => '6:00am', validates_time :breakfast_time, :on_or_after => '6:00am',
@@ -115,7 +115,7 @@ temporal options.
:before => :second_breakfast_time, :before => :second_breakfast_time,
:allow_nil => true :allow_nil => true
validates_datetime :appointment_date, :before => Proc.new { 1.week.from_now } validates_datetime :appointment_date, :before => lambda { 1.week.from_now }
validates_date :entry_date, :with_time => '17:00', :on_or_before => :competition_closing validates_date :entry_date, :with_time => '17:00', :on_or_before => :competition_closing
@@ -263,6 +263,18 @@ Now you get:
year of 20 is considered 1920 year of 20 is considered 1920
=== DUMMY DATE FOR TIME TYPES
Given that Ruby has no support for a time-only type, all time type columns are evaluated
as a regular Time class objects with a dummy date value set. Rails defines the dummy date as
2000-01-01. So a time of '12:30' is evaluated as a Time value of '2000-01-01 12:30'. If you
need to customize this for some reason you can do so as follows
ValidatesTimeliness::Formats.dummy_date_for_time_type = [2009, 1, 1]
The value should be an array of 3 values being year, month and day in that order.
=== TEMPORAL RESTRICTION ERRORS: === TEMPORAL RESTRICTION ERRORS:
When using the validation temporal restrictions there are times when the restriction When using the validation temporal restrictions there are times when the restriction
@@ -355,9 +367,15 @@ To sweeten the deal that little bit more, you have an Rspec matcher available fo
you model specs. Now you can easily test the validations you have just written you model specs. Now you can easily test the validations you have just written
with the plugin or better yet *before* you write them! You just use the with the plugin or better yet *before* you write them! You just use the
validation options you want as you would with the validation method. Those validation options you want as you would with the validation method. Those
options are then verified and reported if they fail. Use it like so: options are then verified and reported if they fail.
@person.should validate_date(:birth_date, :before => Time.now, :before_message => 'should be before today') First require it in your spec_helper.rb
require 'validates_timeliness/matcher'
Use it like so:
@person.should validate_date(:birth_date, :before => Time.now, :before_message => 'should be before today')
The matcher names are just the singular of the validation methods. The matcher names are just the singular of the validation methods.

View File

@@ -3,9 +3,10 @@ require 'rake/gempackagetask'
require 'rubygems/specification' require 'rubygems/specification'
require 'date' require 'date'
require 'spec/rake/spectask' require 'spec/rake/spectask'
require 'lib/validates_timeliness/version'
GEM = "validates_timeliness" GEM = "validates_timeliness"
GEM_VERSION = "2.1.0" GEM_VERSION = ValidatesTimeliness::VERSION
AUTHOR = "Adam Meehan" AUTHOR = "Adam Meehan"
EMAIL = "adam.meehan@gmail.com" EMAIL = "adam.meehan@gmail.com"
HOMEPAGE = "http://github.com/adzap/validates_timeliness" HOMEPAGE = "http://github.com/adzap/validates_timeliness"

View File

@@ -2,7 +2,6 @@ require 'validates_timeliness/formats'
require 'validates_timeliness/parser' 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/active_record/attribute_methods' require 'validates_timeliness/active_record/attribute_methods'
require 'validates_timeliness/active_record/multiparameter_attributes' require 'validates_timeliness/active_record/multiparameter_attributes'

View File

@@ -36,7 +36,8 @@ module ValidatesTimeliness
end end
def read_attribute_before_type_cast_with_timeliness(attr_name) def read_attribute_before_type_cast_with_timeliness(attr_name)
return @attributes_cache["_#{attr_name}_before_type_cast"] if @attributes_cache.has_key?("_#{attr_name}_before_type_cast") cached_attr = "_#{attr_name}_before_type_cast"
return @attributes_cache[cached_attr] if @attributes_cache.has_key?(cached_attr)
read_attribute_before_type_cast_without_timeliness(attr_name) read_attribute_before_type_cast_without_timeliness(attr_name)
end end
@@ -50,11 +51,9 @@ module ValidatesTimeliness
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 time_zone_aware = create_time_zone_conversion_attribute?(name, column) rescue false
class_eval <<-EOV define_method("#{name}=") do |value|
def #{name}=(value) write_date_time_attribute(name, value, column.type, time_zone_aware)
write_date_time_attribute('#{name}', value, #{column.type.inspect}, #{time_zone_aware}) end
end
EOV
timeliness_methods << name timeliness_methods << name
end end
end end

View File

@@ -5,6 +5,33 @@ module ValidatesTimeliness
end end
module ActiveRecord module ActiveRecord
class << self
def time_array_to_string(values, type)
values.collect! {|v| v.to_s }
case type
when :date
extract_date_from_multiparameter_attributes(values)
when :time
extract_time_from_multiparameter_attributes(values)
when :datetime
extract_date_from_multiparameter_attributes(values) + " " + extract_time_from_multiparameter_attributes(values)
end
end
def extract_date_from_multiparameter_attributes(values)
year = ValidatesTimeliness::Formats.unambiguous_year(values[0].rjust(2, "0"))
[year, *values.slice(1, 2).map { |s| s.rjust(2, "0") }].join("-")
end
def extract_time_from_multiparameter_attributes(values)
values[3..5].map { |s| s.rjust(2, "0") }.join(":")
end
end
module MultiparameterAttributes module MultiparameterAttributes
def self.included(base) def self.included(base)
@@ -23,7 +50,7 @@ module ValidatesTimeliness
if values.empty? if values.empty?
send("#{name}=", nil) send("#{name}=", nil)
else else
value = time_array_to_string(values, column.type) value = ValidatesTimeliness::ActiveRecord.time_array_to_string(values, column.type)
send("#{name}=", value) send("#{name}=", value)
end end
rescue => ex rescue => ex
@@ -37,28 +64,6 @@ module ValidatesTimeliness
execute_callstack_for_multiparameter_attributes_without_timeliness(callstack) execute_callstack_for_multiparameter_attributes_without_timeliness(callstack)
end end
def time_array_to_string(values, type)
values.collect! {|v| v.to_s }
case type
when :date
extract_date_from_multiparameter_attributes(values)
when :time
extract_time_from_multiparameter_attributes(values)
when :datetime
extract_date_from_multiparameter_attributes(values) + " " + extract_time_from_multiparameter_attributes(values)
end
end
def extract_date_from_multiparameter_attributes(values)
year = ValidatesTimeliness::Formats.unambiguous_year(values[0].rjust(2, "0"))
[year, *values.slice(1, 2).map { |s| s.rjust(2, "0") }].join("-")
end
def extract_time_from_multiparameter_attributes(values)
values[3..5].map { |s| s.rjust(2, "0") }.join(":")
end
end end
end end

View File

@@ -23,6 +23,7 @@ module ValidatesTimeliness
# Set the threshold value for a two digit year to be considered last century # Set the threshold value for a two digit year to be considered last century
#
# Default: 30 # Default: 30
# #
# Example: # Example:
@@ -32,6 +33,14 @@ module ValidatesTimeliness
cattr_accessor :ambiguous_year_threshold cattr_accessor :ambiguous_year_threshold
self.ambiguous_year_threshold = 30 self.ambiguous_year_threshold = 30
# Set the dummy date part for a time type value. Should be an array of 3 values
# being year, month and day in that order.
#
# Default: [ 2000, 1, 1 ] same as ActiveRecord
#
cattr_accessor :dummy_date_for_time_type
self.dummy_date_for_time_type = [ 2000, 1, 1 ]
# Format tokens: # Format tokens:
# y = year # y = year
# m = month # m = month
@@ -179,6 +188,7 @@ module ValidatesTimeliness
options.reverse_merge!(:strict => true) options.reverse_merge!(:strict => true)
sets = if options[:format] sets = if options[:format]
options[:strict] = true
[ send("#{type}_expressions").assoc(options[:format]) ] [ send("#{type}_expressions").assoc(options[:format]) ]
else else
expression_set(type, string) expression_set(type, string)
@@ -195,7 +205,11 @@ module ValidatesTimeliness
break(proc) if matches = full.match(string.strip) break(proc) if matches = full.match(string.strip)
end end
last = options[:include_offset] ? 8 : 7 last = options[:include_offset] ? 8 : 7
processor.call(*matches[1..last]) if matches if matches
values = processor.call(*matches[1..last])
values[0..2] = dummy_date_for_time_type if type == :time
return values
end
end end
# Delete formats of specified type. Error raised if format not found. # Delete formats of specified type. Error raised if format not found.

View File

@@ -0,0 +1 @@
require 'validates_timeliness/spec/rails/matchers/validate_timeliness'

View File

@@ -7,28 +7,24 @@ module ValidatesTimeliness
return nil if raw_value.blank? return nil if raw_value.blank?
return raw_value if raw_value.acts_like?(:time) || raw_value.is_a?(Date) 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.reverse_merge(:strict => true))
return nil if time_array.nil?
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 if type == :date
time_array[0..2] = 2000, 1, 1 if type == :time Date.new(*time_array[0..2]) rescue nil
else
# Date.new enforces days per month, unlike Time make_time(time_array[0..7])
date = Date.new(*time_array[0..2]) unless type == :time end
return date if type == :date
make_time(time_array[0..7])
rescue
nil
end end
def make_time(time_array) def make_time(time_array)
# Enforce date part validity which Time class does not
return nil unless Date.valid_civil?(*time_array[0..2])
if Time.respond_to?(:zone) && ValidatesTimeliness.use_time_zones if Time.respond_to?(:zone) && ValidatesTimeliness.use_time_zones
Time.zone.local(*time_array) Time.zone.local(*time_array)
else else
# Older AR way of handling times with datetime fallback
begin begin
time_zone = ValidatesTimeliness.default_timezone time_zone = ValidatesTimeliness.default_timezone
Time.send(time_zone, *time_array) Time.send(time_zone, *time_array)
@@ -38,6 +34,8 @@ module ValidatesTimeliness
DateTime.civil(*(time_array << zone_offset)) DateTime.civil(*(time_array << zone_offset))
end end
end end
rescue ArgumentError, TypeError
nil
end end
end end

View File

@@ -28,13 +28,12 @@ module Spec
valid = test_validity valid = test_validity
valid = test_option(:equal_to) if @options[:equal_to] && valid valid = test_option(:equal_to) if valid && @options[:equal_to]
valid = test_option(:before) if @options[:before] && valid valid = test_option(:before) if valid && @options[:before]
valid = test_option(:after) if @options[:after] && valid valid = test_option(:after) if valid && @options[:after]
valid = test_option(:on_or_before) if @options[:on_or_before] && valid valid = test_option(:on_or_before) if valid && @options[:on_or_before]
valid = test_option(:on_or_after) if @options[:on_or_after] && valid valid = test_option(:on_or_after) if valid && @options[:on_or_after]
valid = test_between if valid && @options[:between]
valid = test_between if @options[:between] && valid
return valid return valid
end end
@@ -124,9 +123,14 @@ module Spec
restriction = [restriction] unless restriction.is_a?(Array) restriction = [restriction] unless restriction.is_a?(Array)
restriction.map! {|r| @validator.class.send(:type_cast_value, r, @type) } restriction.map! {|r| @validator.class.send(:type_cast_value, r, @type) }
interpolate = @validator.send(:interpolation_values, option, restriction ) interpolate = @validator.send(:interpolation_values, option, restriction )
# get I18n message if defined and has interpolation keys in msg # get I18n message if defined and has interpolation keys in msg
if defined?(I18n) && !@validator.send(:custom_error_messages).include?(option) if defined?(I18n) && !@validator.send(:custom_error_messages).include?(option)
msg = @record.errors.generate_message(@expected, option, interpolate) msg = if defined?(ActiveRecord::Error)
ActiveRecord::Error.new(@record, @expected, option, interpolate).message
else
@record.errors.generate_message(@expected, option, interpolate)
end
else else
msg = msg % interpolate msg = msg % interpolate
end end

View File

@@ -32,21 +32,13 @@ module ValidatesTimeliness
raw_value = raw_value(record, attr_name) || value raw_value = raw_value(record, attr_name) || value
if value.is_a?(String) || configuration[:format] if value.is_a?(String) || configuration[:format]
strict = !configuration[:format].nil? value = ValidatesTimeliness::Parser.parse(raw_value, type, :strict => false, :format => configuration[:format])
value = ValidatesTimeliness::Parser.parse(raw_value, type, :strict => strict, :format => configuration[:format])
end end
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])
if raw_value.blank? return add_error(record, attr_name, :blank) if raw_value.blank?
add_error(record, attr_name, :blank) return add_error(record, attr_name, "invalid_#{type}".to_sym) if value.nil?
return
end
if value.nil?
add_error(record, attr_name, "invalid_#{type}".to_sym)
return
end
validate_restrictions(record, attr_name, value) validate_restrictions(record, attr_name, value)
end end
@@ -62,21 +54,20 @@ module ValidatesTimeliness
end end
def validate_restrictions(record, attr_name, value) def validate_restrictions(record, attr_name, value)
value = if configuration[:with_time] || configuration[:with_date] if configuration[:with_time] || configuration[:with_date]
restriction_type = :datetime value = combine_date_and_time(value, record)
combine_date_and_time(value, record)
else
restriction_type = type
self.class.type_cast_value(value, type, configuration[:ignore_usec])
end end
value = self.class.type_cast_value(value, implied_type, configuration[:ignore_usec])
return if value.nil? return if value.nil?
RESTRICTION_METHODS.each do |option, method| RESTRICTION_METHODS.each do |option, method|
next unless restriction = configuration[option] next unless restriction = configuration[option]
begin begin
restriction = self.class.evaluate_option_value(restriction, restriction_type, record) restriction = self.class.evaluate_option_value(restriction, implied_type, record)
next if restriction.nil? next if restriction.nil?
restriction = self.class.type_cast_value(restriction, restriction_type, configuration[:ignore_usec]) restriction = self.class.type_cast_value(restriction, implied_type, configuration[:ignore_usec])
unless evaluate_restriction(restriction, value, method) unless evaluate_restriction(restriction, value, method)
add_error(record, attr_name, option, interpolation_values(option, restriction)) add_error(record, attr_name, option, interpolation_values(option, restriction))
@@ -155,6 +146,10 @@ module ValidatesTimeliness
options.assert_valid_keys(VALID_OPTIONS - invalid_for_type) options.assert_valid_keys(VALID_OPTIONS - invalid_for_type)
end end
def implied_type
@implied_type ||= configuration[:with_date] || configuration[:with_time] ? :datetime : type
end
# class methods # class methods
class << self class << self
@@ -185,7 +180,8 @@ module ValidatesTimeliness
when Symbol when Symbol
evaluate_option_value(record.send(value), type, record) evaluate_option_value(record.send(value), type, record)
when Proc when Proc
evaluate_option_value(value.call(record), type, record) result = value.arity > 0 ? value.call(record) : value.call
evaluate_option_value(result, type, record)
when Array when Array
value.map {|r| evaluate_option_value(r, type, record) }.sort value.map {|r| evaluate_option_value(r, type, record) }.sort
when Range when Range

View File

@@ -0,0 +1,3 @@
module ValidatesTimeliness
VERSION = "2.2.0"
end

View File

@@ -1,6 +1,10 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe ValidatesTimeliness::ActionView::InstanceTag, :type => :helper do ValidatesTimeliness.enable_datetime_select_extension!
describe 'ValidatesTimeliness::ActionView::InstanceTag' do
include ActionView::Helpers::DateHelper
include ActionController::Assertions::SelectorAssertions
before do before do
@person = Person.new @person = Person.new

View File

@@ -6,17 +6,17 @@ describe ValidatesTimeliness::ActiveRecord::MultiparameterAttributes do
end end
it "should convert array for datetime type into datetime string" do it "should convert array for datetime type into datetime string" do
time_string = obj.time_array_to_string([2000,2,1,9,10,11], :datetime) time_string = time_array_to_string([2000,2,1,9,10,11], :datetime)
time_string.should == "2000-02-01 09:10:11" time_string.should == "2000-02-01 09:10:11"
end end
it "should convert array for date type into date string" do it "should convert array for date type into date string" do
time_string = obj.time_array_to_string([2000,2,1], :date) time_string = time_array_to_string([2000,2,1], :date)
time_string.should == "2000-02-01" time_string.should == "2000-02-01"
end end
it "should convert array for time type into time string" do it "should convert array for time type into time string" do
time_string = obj.time_array_to_string([2000,1,1,9,10,11], :time) time_string = time_array_to_string([2000,1,1,9,10,11], :time)
time_string.should == "09:10:11" time_string.should == "09:10:11"
end end
@@ -44,5 +44,9 @@ describe ValidatesTimeliness::ActiveRecord::MultiparameterAttributes do
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack) obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
end end
end end
def time_array_to_string(*args)
ValidatesTimeliness::ActiveRecord.time_array_to_string(*args)
end
end end

View File

@@ -1,11 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/spec_helper') require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
describe ValidatesTimeliness::Formats do describe ValidatesTimeliness::Formats do
attr_reader :formats
before do
@formats = ValidatesTimeliness::Formats
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
@@ -104,7 +99,7 @@ describe ValidatesTimeliness::Formats 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, :strict => true) time_array = formats.parse('12:13:14', :time, :strict => true)
time_array.should == [0,0,0,12,13,14,0] time_array.should == [2000,1,1,12,13,14,0]
end end
it "should return date array from time string" do it "should return date array from time string" do
@@ -134,7 +129,7 @@ describe ValidatesTimeliness::Formats do
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:13', :time, :strict => false) time_array = formats.parse('2000-02-01 12:13', :time, :strict => false)
time_array.should == [0,0,0,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 options is true" do
@@ -177,6 +172,22 @@ describe ValidatesTimeliness::Formats do
end end
end end
describe "parse with custom dummy date values" do
before(:all) do
@old_dummy_date = formats.dummy_date_for_time_type
formats.dummy_date_for_time_type = [2009,1,1]
end
it "should return time array with custom dummy date" do
time_array = formats.parse('12:13:14', :time, :strict => true)
time_array.should == [2009,1,1,12,13,14,0]
end
after(:all) do
formats.dummy_date_for_time_type = @old_dummy_date
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')
@@ -219,7 +230,7 @@ describe ValidatesTimeliness::Formats do
formats.add_formats(:time, "ss:hh:nn", :before => 'hh:nn:ss') formats.add_formats(:time, "ss:hh:nn", :before => 'hh:nn:ss')
validate("59:23:58", :time).should be_true validate("59:23:58", :time).should be_true
time_array = formats.parse('59:23:58', :time) time_array = formats.parse('59:23:58', :time)
time_array.should == [0,0,0,23,58,59,0] time_array.should == [2000,1,1,23,58,59,0]
end end
it "should raise error if format exists" do it "should raise error if format exists" do
@@ -251,6 +262,11 @@ describe ValidatesTimeliness::Formats do
end end
end end
def formats
ValidatesTimeliness::Formats
end
def validate(time_string, type) def validate(time_string, type)
valid = false valid = false
formats.send("#{type}_expressions").each do |format, regexp, processor| formats.send("#{type}_expressions").each do |format, regexp, processor|

View File

@@ -9,7 +9,7 @@
# 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.2'] rails_versions = ['2.0.2', '2.1.2', '2.2.2', '2.3.3', '2.3.4']
rails_versions.each do |v| rails_versions.each do |v|
g = Ginger::Scenario.new("Rails #{v}") g = Ginger::Scenario.new("Rails #{v}")

View File

@@ -1,4 +1,5 @@
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
require 'validates_timeliness/matcher'
class NoValidation < Person class NoValidation < Person
end end

View File

@@ -45,8 +45,7 @@ if RAILS_VER >= '2.1'
end end
require 'validates_timeliness' require 'validates_timeliness'
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:'})

View File

@@ -358,18 +358,6 @@ describe ValidatesTimeliness::Validator do
should_have_error(:birth_date_and_time, :equal_to) should_have_error(:birth_date_and_time, :equal_to)
end end
it "should have error when value is equal to :equal_to restriction for all values except microscond, and microsecond is not ignored" do
configure_validator(:equal_to => Time.utc(2000, 1, 1, 0, 0, 0, 0), :ignore_usec => false)
validate_with(:birth_date_and_time, Time.utc(2000, 1, 1, 0, 0, 0, 500))
should_have_error(:birth_date_and_time, :equal_to)
end
it "should be valid when value is equal to :equal_to restriction for all values except microscond, and microsecond is ignored" do
configure_validator(:equal_to => Time.utc(2000, 1, 1, 0, 0, 0, 0), :ignore_usec => true)
validate_with(:birth_date_and_time, Time.utc(2000, 1, 1, 0, 0, 0, 500))
should_have_no_error(:birth_date_and_time, :equal_to)
end
it "should be valid when value is equal to :equal_to restriction" do it "should be valid when value is equal to :equal_to 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, :equal_to)
@@ -409,6 +397,16 @@ describe ValidatesTimeliness::Validator do
end end
end end
describe "instance with :ignore_usec option" 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)
validate_with(:birth_date_and_time, Time.utc(2000, 1, 1, 0, 0, 0, 500))
should_have_no_error(:birth_date_and_time, :equal_to)
end
end
describe "instance with :with_time option" do describe "instance with :with_time option" do
it "should validate date attribute as datetime combining value of :with_time against restrictions " do it "should validate date attribute as datetime combining value of :with_time against restrictions " do
@@ -423,20 +421,31 @@ describe ValidatesTimeliness::Validator do
should_have_no_error(:birth_date, :on_or_before) should_have_no_error(:birth_date, :on_or_before)
end end
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)
validate_with(:birth_date, "2000-01-01")
should_have_no_error(:birth_date, :equal_to)
end
end end
describe "instance with :with_date option" do describe "instance with :with_date option" do
it "should validate time attribute as datetime combining value of :with_date against restrictions " do it "should validate time attribute as datetime combining value of :with_date against restrictions " do
configure_validator(:type => :time, :with_date => '2009-01-01', :on_or_before => Time.mktime(2000,1,1,12,30)) configure_validator(:type => :time, :with_date => '2009-01-01', :on_or_before => Time.mktime(2000,1,1,12,30))
validate_with(:birth_date, "12:30") validate_with(:birth_time, "12:30")
should_have_error(:birth_date, :on_or_before) should_have_error(:birth_time, :on_or_before)
end end
it "should skip restriction validation if :with_date value is nil" do it "should skip restriction validation if :with_date value is nil" do
configure_validator(:type => :time, :with_date => nil, :on_or_before => Time.mktime(2000,1,1,12,30)) configure_validator(:type => :time, :with_date => nil, :on_or_before => Time.mktime(2000,1,1,12,30))
validate_with(:birth_date, "12:30") validate_with(:birth_time, "12:30")
should_have_no_error(:birth_date, :on_or_before) should_have_no_error(:birth_time, :on_or_before)
end
it "should should ignore usec value on combined value if :ignore_usec option is true" do
configure_validator(:type => :time, :with_date => Date.new(2000,1,1), :on_or_before => Time.mktime(2000,1,1,12,30), :ignore_usec => true)
validate_with(:birth_time, Time.mktime(2000,1,1,12,30,0,50))
should_have_no_error(:birth_time, :on_or_before)
end end
end end

View File

@@ -2,16 +2,16 @@
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = %q{validates_timeliness} s.name = %q{validates_timeliness}
s.version = "2.1.0" s.version = "2.2.0"
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-06-20} s.date = %q{2009-09-12}
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/core_ext", "lib/validates_timeliness/core_ext/date.rb", "lib/validates_timeliness/core_ext/time.rb", "lib/validates_timeliness/core_ext/date_time.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/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/core_ext", "spec/core_ext/dummy_time_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/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/core_ext", "lib/validates_timeliness/core_ext/date.rb", "lib/validates_timeliness/core_ext/time.rb", "lib/validates_timeliness/core_ext/date_time.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/core_ext", "spec/core_ext/dummy_time_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.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}