Compare commits

...

14 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
Adam Meehan
a1dfbf5d7d v3.0.14 2012-08-23 18:40:47 +10:00
Adam Meehan
02fbdc6028 Fix for validates :timeliness form to add attributes to plugin set 2012-08-23 18:38:33 +10:00
Adam Meehan
4fe22458d3 Add mongoid appraisals 2012-08-23 18:37:38 +10:00
20 changed files with 303 additions and 151 deletions

View File

@@ -9,3 +9,19 @@ end
appraise "rails_3_2" do appraise "rails_3_2" do
gem "rails", "~> 3.2.0" gem "rails", "~> 3.2.0"
end end
appraise "mongoid_2_1" do
gem "mongoid", "~> 2.1.0"
end
appraise "mongoid_2_2" do
gem "mongoid", "~> 2.2.0"
end
appraise "mongoid_2_3" do
gem "mongoid", "~> 2.3.0"
end
appraise "mongoid_2_4" do
gem "mongoid", "~> 2.4.0"
end

View File

@@ -1,3 +1,6 @@
= 3.0.14 [2012-08-23]
* Fix for using validates :timeliness => {} form to correctly add attributes to timeliness validated attributes.
= 3.0.13 [2012-08-21] = 3.0.13 [2012-08-21]
* Fix ActiveRecord issues with using plugin parser by using old way of caching values. * Fix ActiveRecord issues with using plugin parser by using old way of caching values.
* Allow any ActiveRecord non-column attribute to be validated * Allow any ActiveRecord non-column attribute to be validated

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

@@ -0,0 +1,16 @@
# This file was generated by Appraisal
source "http://rubygems.org"
gem "rails", "~> 3.2.6"
gem "rspec", "~> 2.8"
gem "rspec-rails", "~> 2.8"
gem "timecop"
gem "rspec_tag_matchers"
gem "ruby-debug", :platforms=>[:ruby_18, :jruby]
gem "debugger", :platforms=>[:ruby_19]
gem "appraisal"
gem "sqlite3"
gem "mongoid", "~> 2.1.0"
gemspec :path=>"../"

View File

@@ -0,0 +1,16 @@
# This file was generated by Appraisal
source "http://rubygems.org"
gem "rails", "~> 3.2.6"
gem "rspec", "~> 2.8"
gem "rspec-rails", "~> 2.8"
gem "timecop"
gem "rspec_tag_matchers"
gem "ruby-debug", :platforms=>[:ruby_18, :jruby]
gem "debugger", :platforms=>[:ruby_19]
gem "appraisal"
gem "sqlite3"
gem "mongoid", "~> 2.2.0"
gemspec :path=>"../"

View File

@@ -0,0 +1,16 @@
# This file was generated by Appraisal
source "http://rubygems.org"
gem "rails", "~> 3.2.6"
gem "rspec", "~> 2.8"
gem "rspec-rails", "~> 2.8"
gem "timecop"
gem "rspec_tag_matchers"
gem "ruby-debug", :platforms=>[:ruby_18, :jruby]
gem "debugger", :platforms=>[:ruby_19]
gem "appraisal"
gem "sqlite3"
gem "mongoid", "~> 2.3.0"
gemspec :path=>"../"

View File

@@ -0,0 +1,16 @@
# This file was generated by Appraisal
source "http://rubygems.org"
gem "rails", "~> 3.2.6"
gem "rspec", "~> 2.8"
gem "rspec-rails", "~> 2.8"
gem "timecop"
gem "rspec_tag_matchers"
gem "ruby-debug", :platforms=>[:ruby_18, :jruby]
gem "debugger", :platforms=>[:ruby_19]
gem "appraisal"
gem "sqlite3"
gem "mongoid", "~> 2.4.0"
gemspec :path=>"../"

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

@@ -15,12 +15,7 @@ module ActiveModel
end end
def timeliness_validation_for(attr_names, type) def timeliness_validation_for(attr_names, type)
options = _merge_attributes(attr_names).merge(:type => type) validates_with TimelinessValidator, _merge_attributes(attr_names).merge(:type => type)
if respond_to?(:timeliness_validated_attributes)
self.timeliness_validated_attributes ||= []
self.timeliness_validated_attributes += (attr_names - self.timeliness_validated_attributes)
end
validates_with TimelinessValidator, options
end end
end end

View File

@@ -21,7 +21,7 @@ module ValidatesTimeliness
def timeliness_attribute_type(attr_name) def timeliness_attribute_type(attr_name)
{ {
Date => :date, Date => :date,
Time => :datetime, Time => :time,
DateTime => :datetime DateTime => :datetime
}[fields[attr_name.to_s].type] || :datetime }[fields[attr_name.to_s].type] || :datetime
end end

View File

@@ -1,3 +1,4 @@
require 'active_model'
require 'active_model/validator' require 'active_model/validator'
module ValidatesTimeliness module ValidatesTimeliness
@@ -32,13 +33,25 @@ 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
super super
end end
def setup(model)
if model.respond_to?(:timeliness_validated_attributes)
model.timeliness_validated_attributes ||= []
model.timeliness_validated_attributes |= @attributes
end
end
def validate_each(record, attr_name, value) def validate_each(record, attr_name, value)
raw_value = attribute_raw_value(record, attr_name) || value raw_value = attribute_raw_value(record, attr_name) || value
return if (@allow_nil && raw_value.nil?) || (@allow_blank && raw_value.blank?) return if (@allow_nil && raw_value.nil?) || (@allow_blank && raw_value.blank?)

View File

@@ -1,3 +1,3 @@
module ValidatesTimeliness module ValidatesTimeliness
VERSION = '3.0.13' VERSION = '3.0.14'
end end

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

@@ -5,6 +5,7 @@ begin
require 'mongoid' require 'mongoid'
require 'validates_timeliness/orm/mongoid' require 'validates_timeliness/orm/mongoid'
Mongoid.configure do |config| Mongoid.configure do |config|
name = "validates_timeliness_test" name = "validates_timeliness_test"
host = "localhost" host = "localhost"
@@ -16,17 +17,17 @@ describe ValidatesTimeliness, 'Mongoid' do
class Article class Article
include Mongoid::Document include Mongoid::Document
ValidatesTimeliness.use_plugin_parser = true
field :publish_date, :type => Date field :publish_date, :type => Date
field :publish_time, :type => Time field :publish_time, :type => Time
field :publish_datetime, :type => DateTime field :publish_datetime, :type => DateTime
validates_date :publish_date, :allow_nil => true validates_date :publish_date, :allow_nil => true
validates_time :publish_time, :allow_nil => true validates_time :publish_time, :allow_nil => true
validates_datetime :publish_datetime, :allow_nil => true validates_datetime :publish_datetime, :allow_nil => true
ValidatesTimeliness.use_plugin_parser = false
end end
context "validation methods" do context "validation methods" do
let(:record) { Article.new }
it 'should be defined on the class' do it 'should be defined on the class' do
Article.should respond_to(:validates_date) Article.should respond_to(:validates_date)
Article.should respond_to(:validates_time) Article.should respond_to(:validates_time)
@@ -34,33 +35,33 @@ describe ValidatesTimeliness, 'Mongoid' do
end end
it 'should be defined on the instance' do it 'should be defined on the instance' do
Article.new.should respond_to(:validates_date) record.should respond_to(:validates_date)
Article.new.should respond_to(:validates_time) record.should respond_to(:validates_time)
Article.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 = Article.new record.publish_date = '2012-01-01'
r.publish_date = '2012-01-01'
r.valid? record.valid?
r.errors[:publish_date].should be_empty record.errors[:publish_date].should be_empty
end end
it "should validate a invalid value string" do it "should validate a invalid value string" do
r = Article.new begin
r.publish_date = 'not a date' record.publish_date = 'not a date'
rescue
end
r.valid? record.valid?
r.errors[:publish_date].should_not be_empty record.errors[:publish_date].should_not be_empty
end end
it "should validate a nil value" do it "should validate a nil value" do
r = Article.new record.publish_date = nil
r.publish_date = nil
r.valid? record.valid?
r.errors[:publish_date].should be_empty record.errors[:publish_date].should be_empty
end end
end end
@@ -69,46 +70,97 @@ describe ValidatesTimeliness, 'Mongoid' do
end end
context "attribute write method" do context "attribute write method" do
let(:record) { Article.new }
it 'should cache attribute raw value' do it 'should cache attribute raw value' do
r = Article.new record.publish_datetime = date_string = '2010-01-01'
r.publish_datetime = date_string = '2010-01-01'
r._timeliness_raw_value_for('publish_datetime').should == date_string record._timeliness_raw_value_for('publish_datetime').should == date_string
end end
context "with plugin parser" do context "with plugin parser" do
with_config(:use_plugin_parser, true) let(:record) { ArticleWithParser.new }
it 'should parse a string value' do class ArticleWithParser
Timeliness::Parser.should_receive(:parse) include Mongoid::Document
r = Article.new field :publish_date, :type => Date
r.publish_date = '2010-01-01' field :publish_time, :type => Time
end field :publish_datetime, :type => DateTime
it 'should parse an invalid value as nil' do ValidatesTimeliness.use_plugin_parser = true
Timeliness::Parser.should_receive(:parse) validates_date :publish_date, :allow_nil => true
r = Article.new validates_time :publish_time, :allow_nil => true
r.publish_date = 'bad value' validates_datetime :publish_datetime, :allow_nil => true
ValidatesTimeliness.use_plugin_parser = false
r.publish_date.should be_nil
end end
context "for a date column" do context "for a date column" do
it 'should store a Date value after parsing string' do it 'should parse a string value' do
r = Article.new Timeliness::Parser.should_receive(:parse)
r.publish_date = '2010-01-01'
r.publish_date.should be_kind_of(Date) record.publish_date = '2010-01-01'
r.publish_date.should == Date.new(2010, 1, 1) end
it 'should parse a invalid string value as nil' do
Timeliness::Parser.should_receive(:parse)
record.publish_date = 'not valid'
end
it 'should store a Date value after parsing string' do
record.publish_date = '2010-01-01'
record.publish_date.should be_kind_of(Date)
record.publish_date.should eq Date.new(2010, 1, 1)
end
end
context "for a time column" do
it 'should parse a string value' do
Timeliness::Parser.should_receive(:parse)
record.publish_time = '12:30'
end
it 'should parse a invalid string value as nil' do
Timeliness::Parser.should_receive(:parse)
record.publish_time = 'not valid'
end
it 'should store a Time value after parsing string' do
record.publish_time = '12:30'
record.publish_time.should be_kind_of(Time)
record.publish_time.should eq Time.utc(2000, 1, 1, 12, 30)
end end
end end
context "for a datetime column" do context "for a datetime column" do
it 'should parse string into DateTime value' do with_config(:default_timezone, 'Australia/Melbourne')
r = Article.new
r.publish_datetime = '2010-01-01 12:00'
r.publish_datetime.should be_kind_of(DateTime) it 'should parse a string value' do
r.publish_datetime.should == DateTime.new(2010,1,1,12,0) Timeliness::Parser.should_receive(:parse)
record.publish_datetime = '2010-01-01 12:00'
end
it 'should parse a invalid string value as nil' do
Timeliness::Parser.should_receive(:parse)
record.publish_datetime = 'not valid'
end
it 'should parse string into DateTime value' do
record.publish_datetime = '2010-01-01 12:00'
record.publish_datetime.should be_kind_of(DateTime)
end
pending 'should parse string as current timezone' do
record.publish_datetime = '2010-06-01 12:00'
record.publish_datetime.utc_offset.should eq Time.zone.utc_offset
end end
end end
end end
@@ -116,10 +168,10 @@ describe ValidatesTimeliness, 'Mongoid' do
context "cached value" do context "cached value" do
it 'should be cleared on reload' do it 'should be cleared on reload' do
r = Article.create! record = Article.create!
r.publish_date = '2010-01-01' record.publish_date = '2010-01-01'
r.reload record.reload
r._timeliness_raw_value_for('publish_date').should be_nil record._timeliness_raw_value_for('publish_date').should be_nil
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
@@ -19,6 +17,14 @@ describe ValidatesTimeliness::Validator do
Person.validates :birth_datetime, :timeliness => {:is_at => Time.mktime(2010,1,1)} Person.validates :birth_datetime, :timeliness => {:is_at => Time.mktime(2010,1,1)}
Person.validators.first.type.should == :datetime Person.validators.first.type.should == :datetime
end end
it 'should add attribute to timeliness attributes set' do
PersonWithShim.timeliness_validated_attributes.should_not include(:birth_time)
PersonWithShim.validates :birth_time, :timeliness => {:is_at => "12:30"}
PersonWithShim.timeliness_validated_attributes.should include(:birth_time)
end
end end
it 'should not be valid for value which not valid date or time value' do it 'should not be valid for value which not valid date or time value' do
@@ -38,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
@@ -109,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

@@ -12,9 +12,9 @@ Gem::Specification.new do |s|
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.files = `git ls-files`.split("\n") - %w{ .gitignore .rspec Gemfile Gemfile.lock autotest/discover.rb } s.files = `git ls-files`.split("\n") - %w{ .gitignore .rspec Gemfile Gemfile.lock autotest/discover.rb Appraisals Travis.yml } - Dir['gemsfiles/*']
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