mirror of
https://github.com/ditkrg/validates_timeliness.git
synced 2026-01-22 22:06:45 +00:00
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
This commit is contained in:
commit
fdc3086976
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
pkg/
|
||||||
11
Gemfile
Normal file
11
Gemfile
Normal file
@ -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
Normal file
104
Gemfile.lock
Normal file
@ -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
Normal file
20
LICENSE
Normal file
@ -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
Normal file
44
Rakefile
Normal file
@ -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
Normal file
1
autotest/discover.rb
Normal file
@ -0,0 +1 @@
|
|||||||
|
Autotest.add_discovery { "rspec2" }
|
||||||
26
lib/validates_timeliness.rb
Normal file
26
lib/validates_timeliness.rb
Normal file
@ -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
Normal file
27
lib/validates_timeliness/conversion.rb
Normal file
@ -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
Normal file
19
lib/validates_timeliness/helper_methods.rb
Normal file
@ -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
Normal file
16
lib/validates_timeliness/locale/en.yml
Normal file
@ -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
Normal file
61
lib/validates_timeliness/validator.rb
Normal file
@ -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
Normal file
3
lib/validates_timeliness/version.rb
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module ValidatesTimeliness
|
||||||
|
VERSION = '3.0.0'
|
||||||
|
end
|
||||||
27
spec/model_helpers.rb
Normal file
27
spec/model_helpers.rb
Normal file
@ -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
Normal file
44
spec/spec_helper.rb
Normal file
@ -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
Normal file
102
spec/validates_timeliness/conversion_spec.rb
Normal file
@ -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
Normal file
85
spec/validates_timeliness/validator/is_at_spec.rb
Normal file
@ -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
Normal file
49
spec/validates_timeliness/validator_spec.rb
Normal file
@ -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
|
||||||
Loading…
Reference in New Issue
Block a user