Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial Rails 3 rewrite commit

completely rewritten for ActiveModel compatibility
uses ActiveModel EachValidator class as validator base class
simplifies :between by splitting into a :on_or_before and an :on_of_after
only :is_at option tested
  • Loading branch information...
commit fdc30869761301c21eacf04da34284c373fd7905 0 parents
@adzap authored
1  .gitignore
@@ -0,0 +1 @@
+pkg/
2  .rspec
@@ -0,0 +1,2 @@
+--format nested
+--color
11 Gemfile
@@ -0,0 +1,11 @@
+source 'http://rubygems.org'
+
+group :test do
+ gem 'ZenTest'
+ gem 'rails', '3.0.0.rc'
+ gem 'sqlite3-ruby', :require => 'sqlite3'
+ gem 'ruby-debug'
+ gem 'rspec', '>= 2.0.0.beta.17'
+ gem 'rspec-rails', '>= 2.0.0.beta.17'
+ gem 'timecop'
+end
104 Gemfile.lock
@@ -0,0 +1,104 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ ZenTest (4.3.3)
+ abstract (1.0.0)
+ actionmailer (3.0.0.rc)
+ actionpack (= 3.0.0.rc)
+ mail (~> 2.2.5)
+ actionpack (3.0.0.rc)
+ activemodel (= 3.0.0.rc)
+ activesupport (= 3.0.0.rc)
+ builder (~> 2.1.2)
+ erubis (~> 2.6.6)
+ i18n (~> 0.4.1)
+ rack (~> 1.2.1)
+ rack-mount (~> 0.6.9)
+ rack-test (~> 0.5.4)
+ tzinfo (~> 0.3.22)
+ activemodel (3.0.0.rc)
+ activesupport (= 3.0.0.rc)
+ builder (~> 2.1.2)
+ i18n (~> 0.4.1)
+ activerecord (3.0.0.rc)
+ activemodel (= 3.0.0.rc)
+ activesupport (= 3.0.0.rc)
+ arel (~> 0.4.0)
+ tzinfo (~> 0.3.22)
+ activeresource (3.0.0.rc)
+ activemodel (= 3.0.0.rc)
+ activesupport (= 3.0.0.rc)
+ activesupport (3.0.0.rc)
+ arel (0.4.0)
+ activesupport (>= 3.0.0.beta)
+ builder (2.1.2)
+ columnize (0.3.1)
+ diff-lcs (1.1.2)
+ erubis (2.6.6)
+ abstract (>= 1.0.0)
+ i18n (0.4.1)
+ linecache (0.43)
+ mail (2.2.5)
+ activesupport (>= 2.3.6)
+ mime-types
+ treetop (>= 1.4.5)
+ mime-types (1.16)
+ nokogiri (1.4.2)
+ polyglot (0.3.1)
+ rack (1.2.1)
+ rack-mount (0.6.9)
+ rack (>= 1.0.0)
+ rack-test (0.5.4)
+ rack (>= 1.0)
+ rails (3.0.0.rc)
+ actionmailer (= 3.0.0.rc)
+ actionpack (= 3.0.0.rc)
+ activerecord (= 3.0.0.rc)
+ activeresource (= 3.0.0.rc)
+ activesupport (= 3.0.0.rc)
+ bundler (>= 1.0.0.rc.1)
+ railties (= 3.0.0.rc)
+ railties (3.0.0.rc)
+ actionpack (= 3.0.0.rc)
+ activesupport (= 3.0.0.rc)
+ rake (>= 0.8.3)
+ thor (~> 0.14.0)
+ rake (0.8.7)
+ rspec (2.0.0.beta.19)
+ rspec-core (= 2.0.0.beta.19)
+ rspec-expectations (= 2.0.0.beta.19)
+ rspec-mocks (= 2.0.0.beta.19)
+ rspec-core (2.0.0.beta.19)
+ rspec-expectations (2.0.0.beta.19)
+ diff-lcs (>= 1.1.2)
+ rspec-mocks (2.0.0.beta.19)
+ rspec-rails (2.0.0.beta.19)
+ rspec (= 2.0.0.beta.19)
+ webrat (>= 0.7.2.beta.1)
+ ruby-debug (0.10.3)
+ columnize (>= 0.1)
+ ruby-debug-base (~> 0.10.3.0)
+ ruby-debug-base (0.10.3)
+ linecache (>= 0.3)
+ sqlite3-ruby (1.3.1)
+ thor (0.14.0)
+ timecop (0.3.5)
+ treetop (1.4.8)
+ polyglot (>= 0.3.1)
+ tzinfo (0.3.22)
+ webrat (0.7.2.beta.1)
+ nokogiri (>= 1.2.0)
+ rack (>= 1.0)
+ rack-test (>= 0.5.3)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ ZenTest
+ rails (= 3.0.0.rc)
+ rspec (>= 2.0.0.beta.17)
+ rspec-rails (>= 2.0.0.beta.17)
+ ruby-debug
+ sqlite3-ruby
+ timecop
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008-2010 Adam Meehan
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44 Rakefile
@@ -0,0 +1,44 @@
+require 'rubygems'
+require 'rake/rdoctask'
+require 'rake/gempackagetask'
+require 'rubygems/specification'
+require 'rspec/core/rake_task'
+require 'lib/validates_timeliness/version'
+
+GEM_NAME = "active_enum"
+GEM_VERSION = ValidatesTimeliness::VERSION
+
+desc 'Default: run specs.'
+task :default => :spec
+
+desc "Run specs"
+RSpec::Core::RakeTask.new do |t|
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
+end
+
+desc "Generate code coverage"
+RSpec::Core::RakeTask.new(:coverage) do |t|
+ t.rcov = true
+ t.rcov_opts = ['--exclude', 'spec']
+end
+
+desc 'Generate documentation for plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'ActiveEnum'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
+
+desc "install the gem locally"
+task :install => [:package] do
+ sh %{gem install pkg/#{GEM_NAME}-#{GEM_VERSION}}
+end
+
+desc "create a gemspec file"
+task :make_spec do
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
+ file.puts spec.to_ruby
+ end
+end
1  autotest/discover.rb
@@ -0,0 +1 @@
+Autotest.add_discovery { "rspec2" }
26 lib/validates_timeliness.rb
@@ -0,0 +1,26 @@
+require 'date'
+require 'active_support/time_with_zone'
+require 'active_support/core_ext/hash/except'
+require 'active_support/core_ext/string/conversions'
+require 'active_support/core_ext/date/acts_like'
+require 'active_support/core_ext/date/conversions'
+require 'active_support/core_ext/date/zones'
+require 'active_support/core_ext/time/acts_like'
+require 'active_support/core_ext/time/conversions'
+require 'active_support/core_ext/time/zones'
+require 'active_support/core_ext/date_time/acts_like'
+require 'active_support/core_ext/date_time/conversions'
+require 'active_support/core_ext/date_time/zones'
+
+module ValidatesTimeliness
+
+ # Set the dummy date part for a time type values.
+ mattr_accessor :dummy_date_for_time_type
+ @@dummy_date_for_time_type = [ 2000, 1, 1 ]
+
+end
+
+require 'validates_timeliness/conversion'
+require 'validates_timeliness/validator'
+require 'validates_timeliness/helper_methods'
+require 'validates_timeliness/version'
27 lib/validates_timeliness/conversion.rb
@@ -0,0 +1,27 @@
+module ValidatesTimeliness
+ module Conversion
+
+ def type_cast_value(value, type)
+ value = case type
+ when :time
+ dummy_time(value)
+ when :date
+ value.to_date
+ when :datetime
+ value.to_time.in_time_zone
+ end
+ end
+
+ def dummy_time(value)
+ time = if value.acts_like?(:time)
+ value = value.in_time_zone
+ [value.hour, value.min, value.sec]
+ else
+ [0,0,0]
+ end
+ dummy_date = ValidatesTimeliness.dummy_date_for_time_type
+ Time.local(*(dummy_date + time))
+ end
+
+ end
+end
19 lib/validates_timeliness/helper_methods.rb
@@ -0,0 +1,19 @@
+module ValidatesTimeliness
+ module HelperMethods
+ def validates_date(*attr_names)
+ validates_with Validator, _merge_attributes(attr_names).merge(:type => :date)
+ end
+
+ def validates_time(*attr_names)
+ validates_with Validator, _merge_attributes(attr_names).merge(:type => :time)
+ end
+
+ def validates_datetime(*attr_names)
+ validates_with Validator, _merge_attributes(attr_names).merge(:type => :datetime)
+ end
+ end
+end
+
+module ActiveModel::Validations::HelperMethods
+ include ValidatesTimeliness::HelperMethods
+end
16 lib/validates_timeliness/locale/en.yml
@@ -0,0 +1,16 @@
+en:
+ errors:
+ messages:
+ invalid_date: "is not a valid date"
+ 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}"
+ validates_timeliness:
+ error_value_formats:
+ date: '%Y-%m-%d'
+ time: '%H:%M:%S'
+ datetime: '%Y-%m-%d %H:%M:%S'
61 lib/validates_timeliness/validator.rb
@@ -0,0 +1,61 @@
+require 'active_model/validator'
+
+module ValidatesTimeliness
+ class Validator < ActiveModel::EachValidator
+ include Conversion
+
+ CHECKS = {
+ :is_at => :==,
+ :before => :<,
+ :after => :>,
+ :on_or_before => :<=,
+ :on_or_after => :>=,
+ }.freeze
+
+ def self.kind
+ :timeliness
+ end
+
+ def initialize(options)
+ @allow_nil, @allow_blank = options.delete(:allow_nil), options.delete(:allow_blank)
+ @type = options.delete(:type)
+
+ if range = options.delete(:between)
+ 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.begin, range.end
+ end
+ super
+ end
+
+ def check_validity!
+ end
+
+ def validate_each(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 record.errors.add(attr_name, :"invalid_#{@type}") if value.blank?
+
+ value = type_cast(value)
+
+ (CHECKS.keys & options.keys).each do |check|
+ check_value = type_cast(options[check])
+ unless value.send(CHECKS[check], check_value)
+ return record.errors.add(attr_name, check, :restriction => check_value)
+ end
+ end
+ end
+
+ def attribute_raw_value(record, attr_name)
+ before_type_cast = "#{attr_name}_before_type_cast"
+ record.send("#{attr_name}_before_type_cast") if record.respond_to?(before_type_cast)
+ end
+
+ def type_cast(value)
+ type_cast_value(value, @type)
+ end
+ end
+end
+
+# Compatibility with ActiveModel validates method which tries match option keys to their validator class
+TimelinessValidator = ValidatesTimeliness::Validator
3  lib/validates_timeliness/version.rb
@@ -0,0 +1,3 @@
+module ValidatesTimeliness
+ VERSION = '3.0.0'
+end
27 spec/model_helpers.rb
@@ -0,0 +1,27 @@
+module ModelHelpers
+
+ # Some test helpers from Rails source
+ def invalid!(attr_name, values, error = nil)
+ with_each_person_value(attr_name, values) do |record, value|
+ record.should be_invalid
+ record.errors[attr_name].size.should >= 1
+ record.errors[attr_name].first.should == error if error
+ end
+ end
+
+ def valid!(attr_name, values)
+ with_each_person_value(attr_name, values) do |record, value|
+ record.should be_valid
+ end
+ end
+
+ def with_each_person_value(attr_name, values)
+ record = Person.new
+ values = [values] unless values.is_a?(Array)
+ values.each do |value|
+ record.send("#{attr_name}=", value)
+ yield record, value
+ end
+ end
+
+end
44 spec/spec_helper.rb
@@ -0,0 +1,44 @@
+$:.unshift(File.dirname(__FILE__) + '/../lib')
+$:.unshift(File.dirname(__FILE__))
+
+require 'rspec'
+require 'rspec/autorun'
+
+require 'active_model'
+require 'active_model/validations'
+# require 'active_record'
+# require 'action_controller'
+# require 'action_view'
+# require 'action_mailer'
+# require 'rspec/rails'
+
+require 'timecop'
+require 'model_helpers'
+
+require 'validates_timeliness'
+
+Time.zone = 'Australia/Melbourne'
+
+LOCALE_PATH = File.expand_path(File.dirname(__FILE__) + '/../lib/validates_timeliness/locale/en.yml')
+I18n.load_path.unshift(LOCALE_PATH)
+
+class Person
+ include ActiveModel::Validations
+ extend ActiveModel::Translation
+
+ attr_accessor :birth_date, :birth_time, :birth_datetime
+
+ def initialize(attributes = {})
+ attributes.each do |key, value|
+ send "#{key}=", value
+ end
+ end
+end
+
+Rspec.configure do |c|
+ c.mock_with :rspec
+ c.before do
+ Person.reset_callbacks(:validate)
+ Person._validators.clear
+ end
+end
102 spec/validates_timeliness/conversion_spec.rb
@@ -0,0 +1,102 @@
+require 'spec_helper'
+
+describe ValidatesTimeliness::Conversion do
+ include ValidatesTimeliness::Conversion
+
+ before do
+ Timecop.freeze(Time.mktime(2010, 1, 1, 0, 0, 0))
+ end
+
+ describe "#type_cast_value" do
+ describe "for date type" do
+ it "should return same value for date value" do
+ type_cast_value(Date.new(2010, 1, 1), :date).should == Date.new(2010, 1, 1)
+ end
+
+ it "should return date part of time value" do
+ type_cast_value(Time.mktime(2010, 1, 1, 0, 0, 0), :date).should == Date.new(2010, 1, 1)
+ end
+
+ it "should return date part of datetime value" do
+ type_cast_value(DateTime.new(2010, 1, 1, 0, 0, 0), :date).should == Date.new(2010, 1, 1)
+ end
+ end
+
+ describe "for time type" do
+ it "should return same value for time value matching dummy date part" do
+ type_cast_value(Time.mktime(2000, 1, 1, 0, 0, 0), :time).should == Time.mktime(2000, 1, 1, 0, 0, 0)
+ end
+
+ it "should return dummy time value with same time part for time value with different date" do
+ type_cast_value(Time.mktime(2010, 1, 1, 0, 0, 0), :time).should == Time.mktime(2000, 1, 1, 0, 0, 0)
+ end
+
+ it "should return dummy time only for date value" do
+ type_cast_value(Date.new(2010, 1, 1), :time).should == Time.mktime(2000, 1, 1, 0, 0, 0)
+ end
+
+ it "should return dummy date with shifted local time for UTC datetime value" do
+ type_cast_value(DateTime.new(2010, 1, 1, 12, 34, 56), :time).should == Time.mktime(2000, 1, 1, 23, 34, 56)
+ end
+
+ it "should return dummy date with time part for local datetime value" do
+ type_cast_value(DateTime.civil_from_format(:local, 2010, 1, 1, 12, 34, 56), :time).should == Time.mktime(2000, 1, 1, 12, 34, 56)
+ end
+ end
+
+ describe "for datetime type" do
+ it "should return time in local offset for date value" do
+ type_cast_value(Date.new(2010, 1, 1), :datetime).should == Time.local_time(2010, 1, 1, 0, 0, 0)
+ end
+
+ it "should return same value for same time value in local offset" do
+ type_cast_value(Time.local_time(2010, 1, 1, 12, 34, 56), :datetime).should == Time.local_time(2010, 1, 1, 12, 34, 56)
+ end
+
+ it "should return shifted local time value for UTC time value" do
+ type_cast_value(Time.utc(2010, 1, 1, 12, 34, 56), :datetime).should == Time.local_time(2010, 1, 1, 23, 34, 56)
+ end
+
+ it "should return shifted local time value for UTC datetime value" do
+ type_cast_value(DateTime.new(2010, 1, 1, 12, 34, 56), :datetime).should == Time.local_time(2010, 1, 1, 23, 34, 56)
+ end
+
+ it "should return time value with same component values for local datetime value" do
+ type_cast_value(DateTime.civil_from_format(:local, 2010, 1, 1, 12, 34, 56), :datetime).should == Time.local_time(2010, 1, 1, 12, 34, 56)
+ end
+ end
+ end
+
+ describe "#dummy_time" do
+ it 'should return dummy date with shifted local time part for UTC time value' do
+ dummy_time(Time.utc(2010, 11, 22, 12, 34, 56)).should == Time.local_time(2000, 1, 1, 23, 34, 56)
+ end
+
+ it 'should return dummy date with same time part part for local time value with non-dummy date' do
+ dummy_time(Time.local_time(2010, 11, 22, 12, 34, 56)).should == Time.local_time(2000, 1, 1, 12, 34, 56)
+ end
+
+ it 'should return same value for local time with dummy date' do
+ dummy_time(Time.local_time(2000, 1, 1, 12, 34, 56)).should == Time.local_time(2000, 1, 1, 12, 34, 56)
+ end
+
+ it 'should return exact dummy time value for date value' do
+ dummy_time(Date.new(2010, 11, 22)).should == Time.mktime(2000, 1, 1, 0, 0, 0)
+ end
+
+ describe "with custom dummy date" do
+ before(:all) do
+ @@original_dummy_date = ValidatesTimeliness.dummy_date_for_time_type
+ ValidatesTimeliness.dummy_date_for_time_type = [2010, 1, 1]
+ end
+
+ it 'should return dummy time with custom dummy date' do
+ dummy_time(Time.local_time(1999, 11, 22, 12, 34, 56)).should == Time.local_time(2010, 1, 1, 12, 34, 56)
+ end
+
+ after(:all) do
+ ValidatesTimeliness.dummy_date_for_time_type = @@original_dummy_date
+ end
+ end
+ end
+end
85 spec/validates_timeliness/validator/is_at_spec.rb
@@ -0,0 +1,85 @@
+require 'spec_helper'
+
+describe ValidatesTimeliness::Validator, ":is_at option" do
+ include ModelHelpers
+
+ before do
+ Timecop.freeze(Time.local_time(2010, 1, 1, 0, 0, 0))
+ end
+
+ describe "for date type" do
+ it "should be equal to same date value" do
+ Person.validates_date :birth_date, :is_at => Date.new(2010, 1, 1)
+ valid!(:birth_date, Date.new(2010, 1, 1))
+ end
+
+ it "should be equal to Time with same date part" do
+ Person.validates_date :birth_date, :is_at => Time.local_time(2010, 1, 1, 0, 0, 0)
+ valid!(:birth_date, Date.new(2010, 1, 1))
+ end
+
+ it "should be equal to DateTime with same date part" do
+ Person.validates_date :birth_date, :is_at => DateTime.civil_from_format(:local, 2010, 1, 1, 0, 0, 0)
+ valid!(:birth_date, Date.new(2010, 1, 1))
+ end
+ end
+
+ describe "for time type" do
+ it "should be equal to Date if attribute value is midnight" do
+ Person.validates_time :birth_time, :is_at => Date.new(2010, 1, 1)
+ valid!(:birth_time, Time.local_time(2000, 1, 1, 0, 0, 0))
+ end
+
+ it "should not be be equal to Date if attribute value is other than midnight" do
+ Person.validates_time :birth_time, :is_at => Date.new(2010, 1, 1)
+ invalid!(:birth_time, Time.local_time(2000, 1, 1, 9, 30, 0))
+ end
+
+ it "should be equal to local Time with same time part" do
+ Person.validates_time :birth_time, :is_at => Time.local_time(2010, 1, 1, 0, 0, 0)
+ valid!(:birth_time, Time.local_time(2000, 1, 1, 0, 0, 0))
+ end
+
+ it "should not be equal to UTC Time with same time part" do
+ Person.validates_time :birth_time, :is_at => Time.utc(2010, 1, 1, 0, 0, 0)
+ invalid!(:birth_time, Time.local_time(2000, 1, 1, 0, 0, 0))
+ end
+
+ it "should be equal to local DateTime with same time part" do
+ Person.validates_time :birth_time, :is_at => DateTime.civil_from_format(:local, 2010, 1, 1, 0, 0, 0)
+ valid!(:birth_time, Time.local_time(2000, 1, 1, 0, 0, 0))
+ end
+
+ it "should not be equal to UTC DateTime with same time part" do
+ Person.validates_time :birth_time, :is_at => DateTime.new(2010, 1, 1, 0, 0, 0)
+ invalid!(:birth_time, Time.local_time(2000, 1, 1, 0, 0, 0))
+ end
+ end
+
+ describe "for datetime type" do
+ it "should be equal to Date with same" do
+ Person.validates_datetime :birth_datetime, :is_at => Date.new(2010, 1, 1)
+ valid!(:birth_datetime, DateTime.civil_from_format(:local, 2010, 1, 1, 0, 0, 0))
+ end
+
+ it "should be equal to local Time with same component values" do
+ Person.validates_datetime :birth_datetime, :is_at => Time.local_time(2010, 1, 1, 0, 0, 0)
+ valid!(:birth_datetime, DateTime.civil_from_format(:local, 2010, 1, 1, 0, 0, 0))
+ end
+
+ it "should not be equal to UTC Time with same component values" do
+ Person.validates_datetime :birth_datetime, :is_at => Time.utc(2010, 1, 1, 0, 0, 0)
+ invalid!(:birth_datetime, DateTime.civil_from_format(:local, 2010, 1, 1, 0, 0, 0))
+ end
+
+ it "should be equal to same local DateTime value" do
+ Person.validates_datetime :birth_datetime, :is_at => DateTime.civil_from_format(:local, 2010, 1, 1, 0, 0, 0)
+ valid!(:birth_datetime, DateTime.civil_from_format(:local, 2010, 1, 1, 0, 0, 0))
+ end
+
+ it "should not be equal to UTC DateTime with same component values" do
+ Person.validates_datetime :birth_datetime, :is_at => DateTime.new(2010, 1, 1, 0, 0, 0)
+ invalid!(:birth_datetime, DateTime.civil_from_format(:local, 2010, 1, 1, 0, 0, 0))
+ end
+ end
+end
49 spec/validates_timeliness/validator_spec.rb
@@ -0,0 +1,49 @@
+require 'spec_helper'
+
+describe ValidatesTimeliness::Validator do
+ include ModelHelpers
+ NIL = [nil]
+
+ before do
+ Timecop.freeze(Time.local_time(2010, 1, 1, 0, 0, 0))
+ end
+
+ it 'should return validator kind as :timeliness' do
+ ValidatesTimeliness::Validator.kind.should == :timeliness
+ end
+
+ describe "Model.validates :timeliness option" do
+ it 'should use plugin validator class' do
+ Person.validates :birth_date, :timeliness => {:is_at => Date.new(2010,1,1), :type => :date}
+ Person.validators.should have(1).kind_of(TimelinessValidator)
+ valid!(:birth_date, Date.new(2010,1,1))
+ invalid!(:birth_date, Date.new(2010,1,2))
+ end
+ end
+
+ describe ":allow_nil option" do
+ it 'should not allow nil by default' do
+ Person.validates_datetime :birth_date
+ invalid!(:birth_date, NIL)
+ valid!(:birth_date, Date.today)
+ end
+
+ it 'should allow nil when true' do
+ Person.validates_datetime :birth_date, :allow_nil => true
+ valid!(:birth_date, NIL)
+ end
+ end
+
+ describe ":allow_blank option" do
+ it 'should not allow blank by default' do
+ Person.validates_datetime :birth_date
+ invalid!(:birth_date, '')
+ valid!(:birth_date, Date.today)
+ end
+
+ it 'should allow blank when true' do
+ Person.validates_datetime :birth_date, :allow_blank => true
+ valid!(:birth_date, '')
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.