diff --git a/lib/validates_timeliness/helper_methods.rb b/lib/validates_timeliness/helper_methods.rb index dc9535d..122dfe3 100644 --- a/lib/validates_timeliness/helper_methods.rb +++ b/lib/validates_timeliness/helper_methods.rb @@ -15,12 +15,7 @@ module ActiveModel end def timeliness_validation_for(attr_names, type) - options = _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 + validates_with TimelinessValidator, _merge_attributes(attr_names).merge(:type => type) end end diff --git a/lib/validates_timeliness/orm/mongoid.rb b/lib/validates_timeliness/orm/mongoid.rb index ffaaf7c..b1cf43e 100644 --- a/lib/validates_timeliness/orm/mongoid.rb +++ b/lib/validates_timeliness/orm/mongoid.rb @@ -21,7 +21,7 @@ module ValidatesTimeliness def timeliness_attribute_type(attr_name) { Date => :date, - Time => :datetime, + Time => :time, DateTime => :datetime }[fields[attr_name.to_s].type] || :datetime end diff --git a/lib/validates_timeliness/validator.rb b/lib/validates_timeliness/validator.rb index cc0baef..b52e979 100644 --- a/lib/validates_timeliness/validator.rb +++ b/lib/validates_timeliness/validator.rb @@ -39,6 +39,13 @@ module ValidatesTimeliness super 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) raw_value = attribute_raw_value(record, attr_name) || value return if (@allow_nil && raw_value.nil?) || (@allow_blank && raw_value.blank?) diff --git a/spec/validates_timeliness/orm/mongoid_spec.rb b/spec/validates_timeliness/orm/mongoid_spec.rb index 63a36fc..59bb491 100644 --- a/spec/validates_timeliness/orm/mongoid_spec.rb +++ b/spec/validates_timeliness/orm/mongoid_spec.rb @@ -5,6 +5,7 @@ begin require 'mongoid' require 'validates_timeliness/orm/mongoid' + Mongoid.configure do |config| name = "validates_timeliness_test" host = "localhost" @@ -16,17 +17,17 @@ describe ValidatesTimeliness, 'Mongoid' do class Article include Mongoid::Document - ValidatesTimeliness.use_plugin_parser = true field :publish_date, :type => Date field :publish_time, :type => Time field :publish_datetime, :type => DateTime validates_date :publish_date, :allow_nil => true validates_time :publish_time, :allow_nil => true validates_datetime :publish_datetime, :allow_nil => true - ValidatesTimeliness.use_plugin_parser = false end context "validation methods" do + let(:record) { Article.new } + it 'should be defined on the class' do Article.should respond_to(:validates_date) Article.should respond_to(:validates_time) @@ -34,33 +35,33 @@ describe ValidatesTimeliness, 'Mongoid' do end it 'should be defined on the instance' do - Article.new.should respond_to(:validates_date) - Article.new.should respond_to(:validates_time) - Article.new.should respond_to(:validates_datetime) + record.should respond_to(:validates_date) + record.should respond_to(:validates_time) + record.should respond_to(:validates_datetime) end it "should validate a valid value string" do - r = Article.new - r.publish_date = '2012-01-01' + record.publish_date = '2012-01-01' - r.valid? - r.errors[:publish_date].should be_empty + record.valid? + record.errors[:publish_date].should be_empty end it "should validate a invalid value string" do - r = Article.new - r.publish_date = 'not a date' + begin + record.publish_date = 'not a date' + rescue + end - r.valid? - r.errors[:publish_date].should_not be_empty + record.valid? + record.errors[:publish_date].should_not be_empty end it "should validate a nil value" do - r = Article.new - r.publish_date = nil + record.publish_date = nil - r.valid? - r.errors[:publish_date].should be_empty + record.valid? + record.errors[:publish_date].should be_empty end end @@ -69,46 +70,97 @@ describe ValidatesTimeliness, 'Mongoid' do end context "attribute write method" do + let(:record) { Article.new } + it 'should cache attribute raw value' do - r = Article.new - r.publish_datetime = date_string = '2010-01-01' - r._timeliness_raw_value_for('publish_datetime').should == date_string + record.publish_datetime = date_string = '2010-01-01' + + record._timeliness_raw_value_for('publish_datetime').should == date_string end context "with plugin parser" do - with_config(:use_plugin_parser, true) + let(:record) { ArticleWithParser.new } - it 'should parse a string value' do - Timeliness::Parser.should_receive(:parse) - r = Article.new - r.publish_date = '2010-01-01' - end + class ArticleWithParser + include Mongoid::Document + field :publish_date, :type => Date + field :publish_time, :type => Time + field :publish_datetime, :type => DateTime - it 'should parse an invalid value as nil' do - Timeliness::Parser.should_receive(:parse) - r = Article.new - r.publish_date = 'bad value' - - r.publish_date.should be_nil + ValidatesTimeliness.use_plugin_parser = true + validates_date :publish_date, :allow_nil => true + validates_time :publish_time, :allow_nil => true + validates_datetime :publish_datetime, :allow_nil => true + ValidatesTimeliness.use_plugin_parser = false end context "for a date column" do - it 'should store a Date value after parsing string' do - r = Article.new - r.publish_date = '2010-01-01' + it 'should parse a string value' do + Timeliness::Parser.should_receive(:parse) - r.publish_date.should be_kind_of(Date) - r.publish_date.should == Date.new(2010, 1, 1) + record.publish_date = '2010-01-01' + 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 context "for a datetime column" do - it 'should parse string into DateTime value' do - r = Article.new - r.publish_datetime = '2010-01-01 12:00' + with_config(:default_timezone, 'Australia/Melbourne') - r.publish_datetime.should be_kind_of(DateTime) - r.publish_datetime.should == DateTime.new(2010,1,1,12,0) + it 'should parse a string value' do + 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 @@ -116,10 +168,10 @@ describe ValidatesTimeliness, 'Mongoid' do context "cached value" do it 'should be cleared on reload' do - r = Article.create! - r.publish_date = '2010-01-01' - r.reload - r._timeliness_raw_value_for('publish_date').should be_nil + record = Article.create! + record.publish_date = '2010-01-01' + record.reload + record._timeliness_raw_value_for('publish_date').should be_nil end end diff --git a/spec/validates_timeliness/validator_spec.rb b/spec/validates_timeliness/validator_spec.rb index 0a0f0c1..2b8970a 100644 --- a/spec/validates_timeliness/validator_spec.rb +++ b/spec/validates_timeliness/validator_spec.rb @@ -19,6 +19,14 @@ describe ValidatesTimeliness::Validator do Person.validates :birth_datetime, :timeliness => {:is_at => Time.mktime(2010,1,1)} Person.validators.first.type.should == :datetime 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 it 'should not be valid for value which not valid date or time value' do