Compare commits

..

11 Commits

Author SHA1 Message Date
Adam Meehan
00ce472d3e Merge pull request #99 from softace/fixing_build
Fix for running tests in non-Australian timezones
2013-06-16 15:22:33 -07:00
Jarl Friis
0d2c7ce554 Fix for running tests in non-Australian timezones 2013-04-30 19:56:19 +02:00
Adam Meehan
3d798697e1 Merge pull request #98 from 907th/master
Range with excluded end passed to :between option should be split into :on_or_after and :before options
2013-04-30 04:45:54 -07:00
Alexey Chernenkov
dc0fdc0340 Range with excluded end passed to :between option should be split into :on_or_after and :before options 2013-04-30 15:37:44 +06:00
Adam Meehan
dd3b6b5514 Merge pull request #95 from will-ob/fix/require-active-model
Require 'active_model'
2013-04-25 22:01:51 -07:00
Will O'Brien
609fafe7bb Require 'active_model'
Apparently classes are lazily required when using autoload. Prompted by
'uninitialized constant ActiveModel::Validations'
2013-04-25 22:42:28 -04:00
Adam Meehan
df9677f5bf timeliness minimum dep 0.3.7 2012-10-15 20:37:05 +11:00
Adam Meehan
b463b4356a Update rdoc require 2012-10-15 08:46:11 +11:00
Adam Meehan
7dd579b0e0 Get rid of this silly constant for nil array value 2012-10-15 08:45:57 +11:00
Adam Meehan
5becd7886b Removing silly class variables from config module 2012-09-14 18:44:35 +10:00
Adam Meehan
2225c747e1 DRYing up some specs 2012-08-26 16:38:00 +10:00
10 changed files with 103 additions and 96 deletions

View File

@@ -55,7 +55,10 @@ NOTE: You may wish to enable the plugin parser and the extensions to start. Plea
validates_datetime :finish_time, :after => :start_time # Method symbol validates_datetime :finish_time, :after => :start_time # Method symbol
validates_date :booked_at, :on => :create, :on_or_after => :today # See Restriction Shorthand. validates_date :booked_at, :on => :create, :on_or_after => :today # See Restriction Shorthand.
validates_time :booked_at, :between => ['9.00am', '5:00pm']
validates_time :booked_at, :between => ['9:00am', '5:00pm'] # On or after 9:00AM and on or before 5:00PM
validates_time :booked_at, :between => '9:00am'..'5:00pm' # The same as previous example
validates_time :booked_at, :between => '9:00am'...'5:00pm' # On or after 9:00AM and strictly before 5:00PM
validates_time :breakfast_time, :on_or_after => '6:00am', validates_time :breakfast_time, :on_or_after => '6:00am',
:on_or_after_message => 'must be after opening time', :on_or_after_message => 'must be after opening time',
@@ -173,8 +176,8 @@ You can also use validation options for custom error messages. The following opt
:after_message :after_message
:on_or_after_message :on_or_after_message
Note: There is no :between_message option. The between error message should be defined using the Note: There is no :between_message option. The between error message should be defined using the :on_or_after and :on_or_before
:on_or_before and :on_or_after messages. (:before in case when :between argument is a Range with excluded high value, see Examples) messages.
It is highly recommended you use the I18n system for error messages. It is highly recommended you use the I18n system for error messages.

View File

@@ -5,7 +5,7 @@ require 'appraisal'
Bundler::GemHelper.install_tasks Bundler::GemHelper.install_tasks
require 'rake/rdoctask' require 'rdoc/task'
require 'rspec/core/rake_task' require 'rspec/core/rake_task'
desc "Run specs" desc "Run specs"

View File

@@ -24,26 +24,24 @@ module ValidatesTimeliness
class << self class << self
delegate :default_timezone, :default_timezone=, :dummy_date_for_time_type, :dummy_date_for_time_type=, :to => Timeliness delegate :default_timezone, :default_timezone=, :dummy_date_for_time_type, :dummy_date_for_time_type=, :to => Timeliness
attr_accessor :extend_orms, :ignore_restriction_errors, :restriction_shorthand_symbols, :use_plugin_parser
end end
# Extend ORM/ODMs for full support (:active_record, :mongoid). # Extend ORM/ODMs for full support (:active_record, :mongoid).
mattr_accessor :extend_orms self.extend_orms = []
@@extend_orms = []
# Ignore errors when restriction options are evaluated # Ignore errors when restriction options are evaluated
mattr_accessor :ignore_restriction_errors self.ignore_restriction_errors = false
@@ignore_restriction_errors = false
# Shorthand time and date symbols for restrictions # Shorthand time and date symbols for restrictions
mattr_accessor :restriction_shorthand_symbols self.restriction_shorthand_symbols = {
@@restriction_shorthand_symbols = {
:now => lambda { Time.current }, :now => lambda { Time.current },
:today => lambda { Date.current } :today => lambda { Date.current }
} }
# Use the plugin date/time parser which is stricter and extensible # Use the plugin date/time parser which is stricter and extensible
mattr_accessor :use_plugin_parser self.use_plugin_parser = false
@@use_plugin_parser = false
# Default timezone # Default timezone
self.default_timezone = :utc self.default_timezone = :utc
@@ -51,10 +49,6 @@ module ValidatesTimeliness
# Set the dummy date part for a time type values. # Set the dummy date part for a time type values.
self.dummy_date_for_time_type = [ 2000, 1, 1 ] self.dummy_date_for_time_type = [ 2000, 1, 1 ]
def self.parser
Timeliness
end
# Setup method for plugin configuration # Setup method for plugin configuration
def self.setup def self.setup
yield self yield self
@@ -64,6 +58,8 @@ module ValidatesTimeliness
def self.load_orms def self.load_orms
extend_orms.each {|orm| require "validates_timeliness/orm/#{orm}" } extend_orms.each {|orm| require "validates_timeliness/orm/#{orm}" }
end end
def self.parser; Timeliness end
end end
require 'validates_timeliness/conversion' require 'validates_timeliness/conversion'

View File

@@ -1,3 +1,4 @@
require 'active_model'
require 'active_model/validator' require 'active_model/validator'
module ValidatesTimeliness module ValidatesTimeliness
@@ -32,7 +33,12 @@ module ValidatesTimeliness
if range = options.delete(:between) if range = options.delete(:between)
raise ArgumentError, ":between must be a Range or an Array" unless range.is_a?(Range) || range.is_a?(Array) raise ArgumentError, ":between must be a Range or an Array" unless range.is_a?(Range) || range.is_a?(Array)
options[:on_or_after], options[:on_or_before] = range.first, range.last options[:on_or_after] = range.first
if range.is_a?(Range) && range.exclude_end?
options[:before] = range.last
else
options[:on_or_before] = range.last
end
end end
@restrictions_to_check = RESTRICTIONS.keys & options.keys @restrictions_to_check = RESTRICTIONS.keys & options.keys

View File

@@ -57,6 +57,7 @@ class PersonWithShim < Person
include TestModelShim include TestModelShim
end end
ActiveRecord::Base.default_timezone = :utc
ActiveRecord::Base.time_zone_aware_attributes = true ActiveRecord::Base.time_zone_aware_attributes = true
ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:'}) ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:'})
ActiveRecord::Migration.verbose = false ActiveRecord::Migration.verbose = false

View File

@@ -10,7 +10,7 @@ describe ValidatesTimeliness::Extensions::MultiparameterHandler do
it 'should assign a Time value for valid datetimes' do it 'should assign a Time value for valid datetimes' do
employee = record_with_multiparameter_attribute(:birth_datetime, [2000, 2, 28, 12, 0, 0]) employee = record_with_multiparameter_attribute(:birth_datetime, [2000, 2, 28, 12, 0, 0])
employee.birth_datetime_before_type_cast.should eq Time.local(2000, 2, 28, 12, 0, 0) employee.birth_datetime_before_type_cast.should eq Time.zone.local(2000, 2, 28, 12, 0, 0)
end end
it 'should assign a string value for incomplete time' do it 'should assign a string value for incomplete time' do

View File

@@ -1,6 +1,8 @@
require 'spec_helper' require 'spec_helper'
describe ValidatesTimeliness, 'HelperMethods' do describe ValidatesTimeliness, 'HelperMethods' do
let(:record) { Person.new }
it 'should define class validation methods' do it 'should define class validation methods' do
Person.should respond_to(:validates_date) Person.should respond_to(:validates_date)
Person.should respond_to(:validates_time) Person.should respond_to(:validates_time)
@@ -8,23 +10,21 @@ describe ValidatesTimeliness, 'HelperMethods' do
end end
it 'should define instance validation methods' do it 'should define instance validation methods' do
Person.new.should respond_to(:validates_date) record.should respond_to(:validates_date)
Person.new.should respond_to(:validates_time) record.should respond_to(:validates_time)
Person.new.should respond_to(:validates_datetime) record.should respond_to(:validates_datetime)
end end
it 'should validate instance using class validation defined' do it 'should validate instance using class validation defined' do
Person.validates_date :birth_date Person.validates_date :birth_date
r = Person.new record.valid?
r.valid?
r.errors[:birth_date].should_not be_empty record.errors[:birth_date].should_not be_empty
end end
it 'should validate instance using instance valiation method' do it 'should validate instance using instance valiation method' do
r = Person.new record.validates_date :birth_date
r.validates_date :birth_date
r.errors[:birth_date].should_not be_empty record.errors[:birth_date].should_not be_empty
end end
end end

View File

@@ -3,6 +3,8 @@ require 'spec_helper'
describe ValidatesTimeliness, 'ActiveRecord' do describe ValidatesTimeliness, 'ActiveRecord' do
context "validation methods" do context "validation methods" do
let(:record) { Employee.new }
it 'should be defined for the class' do it 'should be defined for the class' do
ActiveRecord::Base.should respond_to(:validates_date) ActiveRecord::Base.should respond_to(:validates_date)
ActiveRecord::Base.should respond_to(:validates_time) ActiveRecord::Base.should respond_to(:validates_time)
@@ -10,33 +12,30 @@ describe ValidatesTimeliness, 'ActiveRecord' do
end end
it 'should defines for the instance' do it 'should defines for the instance' do
Employee.new.should respond_to(:validates_date) record.should respond_to(:validates_date)
Employee.new.should respond_to(:validates_time) record.should respond_to(:validates_time)
Employee.new.should respond_to(:validates_datetime) record.should respond_to(:validates_datetime)
end end
it "should validate a valid value string" do it "should validate a valid value string" do
r = Employee.new record.birth_date = '2012-01-01'
r.birth_date = '2012-01-01'
r.valid? record.valid?
r.errors[:birth_date].should be_empty record.errors[:birth_date].should be_empty
end end
it "should validate a invalid value string" do it "should validate a invalid value string" do
r = Employee.new record.birth_date = 'not a date'
r.birth_date = 'not a date'
r.valid? record.valid?
r.errors[:birth_date].should_not be_empty record.errors[:birth_date].should_not be_empty
end end
it "should validate a nil value" do it "should validate a nil value" do
r = Employee.new record.birth_date = nil
r.birth_date = nil
r.valid? record.valid?
r.errors[:birth_date].should be_empty record.errors[:birth_date].should be_empty
end end
end end
@@ -83,36 +82,36 @@ describe ValidatesTimeliness, 'ActiveRecord' do
end end
context 'value cache' do context 'value cache' do
let(:record) { EmployeeWithCache.new }
context 'for datetime column' do context 'for datetime column' do
it 'should store raw value' do it 'should store raw value' do
r = EmployeeWithCache.new record.birth_datetime = datetime_string = '2010-01-01 12:30'
r.birth_datetime = datetime_string = '2010-01-01 12:30'
r._timeliness_raw_value_for('birth_datetime').should eq datetime_string record._timeliness_raw_value_for('birth_datetime').should eq datetime_string
end end
end end
context 'for date column' do context 'for date column' do
it 'should store raw value' do it 'should store raw value' do
r = EmployeeWithCache.new record.birth_date = date_string = '2010-01-01'
r.birth_date = date_string = '2010-01-01'
r._timeliness_raw_value_for('birth_date').should eq date_string record._timeliness_raw_value_for('birth_date').should eq date_string
end end
end end
context 'for time column' do context 'for time column' do
it 'should store raw value' do it 'should store raw value' do
r = EmployeeWithCache.new record.birth_time = time_string = '12:12'
r.birth_time = time_string = '12:12'
r._timeliness_raw_value_for('birth_time').should eq time_string record._timeliness_raw_value_for('birth_time').should eq time_string
end end
end end
end end
context "with plugin parser" do context "with plugin parser" do
with_config(:use_plugin_parser, true) with_config(:use_plugin_parser, true)
let(:record) { EmployeeWithParser.new }
class EmployeeWithParser < ActiveRecord::Base class EmployeeWithParser < ActiveRecord::Base
self.table_name = 'employees' self.table_name = 'employees'
@@ -125,22 +124,20 @@ describe ValidatesTimeliness, 'ActiveRecord' do
it 'should parse a string value' do it 'should parse a string value' do
Timeliness::Parser.should_receive(:parse) Timeliness::Parser.should_receive(:parse)
r = EmployeeWithParser.new record.birth_date = '2010-01-01'
r.birth_date = '2010-01-01'
end end
it 'should parse a invalid string value as nil' do it 'should parse a invalid string value as nil' do
Timeliness::Parser.should_receive(:parse) Timeliness::Parser.should_receive(:parse)
r = EmployeeWithParser.new
r.birth_date = 'not valid' record.birth_date = 'not valid'
end end
it 'should store a Date value after parsing string' do it 'should store a Date value after parsing string' do
r = EmployeeWithParser.new record.birth_date = '2010-01-01'
r.birth_date = '2010-01-01'
r.birth_date.should be_kind_of(Date) record.birth_date.should be_kind_of(Date)
r.birth_date.should eq Date.new(2010, 1, 1) record.birth_date.should eq Date.new(2010, 1, 1)
end end
end end
@@ -148,23 +145,20 @@ describe ValidatesTimeliness, 'ActiveRecord' do
it 'should parse a string value' do it 'should parse a string value' do
Timeliness::Parser.should_receive(:parse) Timeliness::Parser.should_receive(:parse)
r = EmployeeWithParser.new record.birth_time = '12:30'
r.birth_time = '12:30'
end end
it 'should parse a invalid string value as nil' do it 'should parse a invalid string value as nil' do
Timeliness::Parser.should_receive(:parse) Timeliness::Parser.should_receive(:parse)
r = EmployeeWithParser.new record.birth_time = 'not valid'
r.birth_time = 'not valid'
end end
it 'should store a Time value after parsing string' do it 'should store a Time value after parsing string' do
r = EmployeeWithParser.new record.birth_time = '12:30'
r.birth_time = '12:30'
r.birth_time.should be_kind_of(Time) record.birth_time.should be_kind_of(Time)
r.birth_time.should eq Time.utc(2000, 1, 1, 12, 30) record.birth_time.should eq Time.utc(2000, 1, 1, 12, 30)
end end
end end
@@ -174,29 +168,25 @@ describe ValidatesTimeliness, 'ActiveRecord' do
it 'should parse a string value' do it 'should parse a string value' do
Timeliness::Parser.should_receive(:parse) Timeliness::Parser.should_receive(:parse)
r = EmployeeWithParser.new record.birth_datetime = '2010-01-01 12:00'
r.birth_datetime = '2010-01-01 12:00'
end end
it 'should parse a invalid string value as nil' do it 'should parse a invalid string value as nil' do
Timeliness::Parser.should_receive(:parse) Timeliness::Parser.should_receive(:parse)
r = EmployeeWithParser.new record.birth_datetime = 'not valid'
r.birth_datetime = 'not valid'
end end
it 'should parse string into Time value' do it 'should parse string into Time value' do
r = EmployeeWithParser.new record.birth_datetime = '2010-01-01 12:00'
r.birth_datetime = '2010-01-01 12:00'
r.birth_datetime.should be_kind_of(Time) record.birth_datetime.should be_kind_of(Time)
end end
it 'should parse string as current timezone' do it 'should parse string as current timezone' do
r = EmployeeWithParser.new record.birth_datetime = '2010-06-01 12:00'
r.birth_datetime = '2010-06-01 12:00'
r.birth_datetime.utc_offset.should eq Time.zone.utc_offset record.birth_datetime.utc_offset.should eq Time.zone.utc_offset
end end
end end
end end
@@ -204,43 +194,43 @@ describe ValidatesTimeliness, 'ActiveRecord' do
context "reload" do context "reload" do
it 'should clear cache value' do it 'should clear cache value' do
r = Employee.create! record = Employee.create!
r.birth_date = '2010-01-01' record.birth_date = '2010-01-01'
r.reload record.reload
r._timeliness_raw_value_for('birth_date').should be_nil record._timeliness_raw_value_for('birth_date').should be_nil
end end
end end
context "before_type_cast method" do context "before_type_cast method" do
let(:record) { Employee.new }
it 'should be defined on class if ORM supports it' do it 'should be defined on class if ORM supports it' do
Employee.new.should respond_to(:birth_datetime_before_type_cast) record.should respond_to(:birth_datetime_before_type_cast)
end end
it 'should return original value' do it 'should return original value' do
r = Employee.new record.birth_datetime = date_string = '2010-01-01'
r.birth_datetime = date_string = '2010-01-01'
r.birth_datetime_before_type_cast.should eq date_string record.birth_datetime_before_type_cast.should eq date_string
end end
it 'should return attribute if no attribute assignment has been made' do it 'should return attribute if no attribute assignment has been made' do
datetime = Time.zone.local(2010,01,01) datetime = Time.zone.local(2010,01,01)
Employee.create(:birth_datetime => datetime) Employee.create(:birth_datetime => datetime)
r = Employee.last record = Employee.last
r.birth_datetime_before_type_cast.should match(/2010-01-01 00:00:00/) record.birth_datetime_before_type_cast.should match(/#{datetime.utc.to_s[0...-4]}/)
end end
context "with plugin parser" do context "with plugin parser" do
with_config(:use_plugin_parser, true) with_config(:use_plugin_parser, true)
it 'should return original value' do it 'should return original value' do
r = Employee.new record.birth_datetime = date_string = '2010-01-31'
r.birth_datetime = date_string = '2010-01-31'
r.birth_datetime_before_type_cast.should eq date_string record.birth_datetime_before_type_cast.should eq date_string
end end
end end

View File

@@ -1,8 +1,6 @@
require 'spec_helper' require 'spec_helper'
describe ValidatesTimeliness::Validator do describe ValidatesTimeliness::Validator do
NIL = [nil]
before do before do
Timecop.freeze(Time.local_time(2010, 1, 1, 0, 0, 0)) Timecop.freeze(Time.local_time(2010, 1, 1, 0, 0, 0))
end end
@@ -46,13 +44,13 @@ describe ValidatesTimeliness::Validator do
describe ":allow_nil option" do describe ":allow_nil option" do
it 'should not allow nil by default' do it 'should not allow nil by default' do
Person.validates_date :birth_date Person.validates_date :birth_date
invalid!(:birth_date, NIL, 'is not a valid date') invalid!(:birth_date, [nil], 'is not a valid date')
valid!(:birth_date, Date.today) valid!(:birth_date, Date.today)
end end
it 'should allow nil when true' do it 'should allow nil when true' do
Person.validates_date :birth_date, :allow_nil => true Person.validates_date :birth_date, :allow_nil => true
valid!(:birth_date, NIL) valid!(:birth_date, [nil])
end end
context "with raw value cache" do context "with raw value cache" do
@@ -117,6 +115,19 @@ describe ValidatesTimeliness::Validator do
valid!(:birth_date, on_or_before) valid!(:birth_date, on_or_before)
end end
end end
describe "range with excluded end value" do
it 'should be split option into :on_or_after and :before values' do
on_or_after, before = Date.new(2010,1,1), Date.new(2010,1,3)
Person.validates_date :birth_date, :between => on_or_after...before
Person.validators.first.options[:on_or_after].should == on_or_after
Person.validators.first.options[:before].should == before
invalid!(:birth_date, on_or_after - 1, "must be on or after 2010-01-01")
invalid!(:birth_date, before, "must be before 2010-01-03")
valid!(:birth_date, on_or_after)
valid!(:birth_date, before - 1)
end
end
end end
describe ":ignore_usec option" do describe ":ignore_usec option" do

View File

@@ -16,5 +16,5 @@ Gem::Specification.new do |s|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "LICENSE"] s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc", "LICENSE"]
s.add_runtime_dependency(%q<timeliness>, ["~> 0.3.6"]) s.add_runtime_dependency(%q<timeliness>, ["~> 0.3.7"])
end end