validates_timeliness 3.0.6 → 3.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,10 @@
1
+ = 3.0.7 [2011-09-21]
2
+ * Fix ActiveRecord before_type_cast extension for non-dirty attributes.
3
+ * Don't override AR before_type_cast for >= 3.1.0 which now has it's own implementation for date/time attributes.
4
+ * Fix DateTimeSelect extension to convert params to integers (#45)
5
+ * Add #change method to DateTimeSelect extension (@trusche, #45)
6
+ * Cleanup Mongoid shim.
7
+
1
8
  = 3.0.6 [2011-05-09]
2
9
  * Fix for AR type conversion for date columns when using plugin parser.
3
10
  * Add timeliness_type_cast_code for ORM specific type casting after parsing.
@@ -46,7 +46,7 @@ module ValidatesTimeliness
46
46
  def define_timeliness_before_type_cast_method(attr_name)
47
47
  method_body, line = <<-EOV, __LINE__ + 1
48
48
  def #{attr_name}_before_type_cast
49
- _timeliness_raw_value_for('#{attr_name}')
49
+ _timeliness_raw_value_for('#{attr_name}') || @attributes['#{attr_name}']
50
50
  end
51
51
  EOV
52
52
  generated_timeliness_methods.module_eval(method_body, __FILE__, line)
@@ -10,29 +10,49 @@ module ValidatesTimeliness
10
10
 
11
11
  included do
12
12
  alias_method_chain :datetime_selector, :timeliness
13
+ alias_method_chain :value, :timeliness
13
14
  end
14
15
 
15
- module InstanceMethods
16
-
17
- TimelinessDateTime = Struct.new(:year, :month, :day, :hour, :min, :sec)
16
+ class TimelinessDateTime
17
+ attr_accessor :year, :month, :day, :hour, :min, :sec
18
+
19
+ def initialize(year, month, day, hour, min, sec)
20
+ @year, @month, @day, @hour, @min, @sec = year, month, day, hour, min, sec
21
+ end
22
+
23
+ # adapted from activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 36 (3.0.7)
24
+ def change(options)
25
+ TimelinessDateTime.new(
26
+ options[:year] || year,
27
+ options[:month] || month,
28
+ options[:day] || day,
29
+ options[:hour] || hour,
30
+ options[:min] || (options[:hour] ? 0 : min),
31
+ options[:sec] || ((options[:hour] || options[:min]) ? 0 : sec)
32
+ )
33
+ end
34
+ end
18
35
 
36
+ module InstanceMethods
19
37
  def datetime_selector_with_timeliness(*args)
20
38
  @timeliness_date_or_time_tag = true
21
39
  datetime_selector_without_timeliness(*args)
22
40
  end
23
41
 
24
- def value(object)
42
+ def value_with_timeliness(object)
25
43
  unless @timeliness_date_or_time_tag && @template_object.params[@object_name]
26
- return super
44
+ return value_without_timeliness(object)
27
45
  end
46
+
47
+ @template_object.params[@object_name]
28
48
 
29
49
  pairs = @template_object.params[@object_name].select {|k,v| k =~ /^#{@method_name}\(/ }
30
- return super if pairs.empty?
50
+ return value_without_timeliness(object) if pairs.empty?
31
51
 
32
52
  values = [nil] * 6
33
53
  pairs.map do |(param, value)|
34
- position = param.scan(/\(([0-9]*).*\)/).first.first
35
- values[position.to_i-1] = value
54
+ position = param.scan(/\((\d+)\w+\)/).first.first
55
+ values[position.to_i-1] = value.to_i
36
56
  end
37
57
 
38
58
  TimelinessDateTime.new(*values)
@@ -7,7 +7,8 @@ module ValidatesTimeliness
7
7
  def define_attribute_methods
8
8
  super
9
9
  # Define write method and before_type_cast method
10
- define_timeliness_methods(true)
10
+ use_before_type_cast = ::ActiveRecord::VERSION::STRING < '3.1.0'
11
+ define_timeliness_methods(use_before_type_cast)
11
12
  end
12
13
 
13
14
  def timeliness_attribute_timezone_aware?(attr_name)
@@ -36,18 +36,8 @@ module ValidatesTimeliness
36
36
  end
37
37
 
38
38
  module Mongoid::Document
39
- # Due to how Mongoid misuses ActiveSupport::Concern,
40
- # the only way to override a core component method is
41
- # using an append_features hook.
42
- #
43
- module TimelinessConcern
44
- def append_features(base)
45
- super
46
- base.send :include, ValidatesTimeliness::AttributeMethods
47
- base.send :include, ValidatesTimeliness::ORM::Mongoid
48
- end
49
- end
50
- extend TimelinessConcern
39
+ include ValidatesTimeliness::AttributeMethods
40
+ include ValidatesTimeliness::ORM::Mongoid
51
41
 
52
42
  def reload_with_timeliness
53
43
  _clear_timeliness_cache
@@ -1,3 +1,3 @@
1
1
  module ValidatesTimeliness
2
- VERSION = '3.0.6'
2
+ VERSION = '3.0.7'
3
3
  end
@@ -49,9 +49,7 @@ class Person
49
49
  attribute :birth_date, :date
50
50
  attribute :birth_time, :time
51
51
  attribute :birth_datetime, :datetime
52
- validates_date :birth_date
53
- validates_time :birth_time
54
- validates_datetime :birth_datetime
52
+
55
53
  define_attribute_methods model_attributes.keys
56
54
  end
57
55
 
@@ -73,12 +71,10 @@ ActiveRecord::Schema.define(:version => 1) do
73
71
  end
74
72
 
75
73
  class Employee < ActiveRecord::Base
76
- validates_date :birth_date
77
- validates_time :birth_time
78
- validates_datetime :birth_datetime
79
- define_attribute_methods
80
-
81
74
  attr_accessor :redefined_birth_date_called
75
+ validates_date :birth_date, :allow_nil => true
76
+ validates_date :birth_time, :allow_nil => true
77
+ validates_date :birth_datetime, :allow_nil => true
82
78
 
83
79
  def birth_date=(value)
84
80
  self.redefined_birth_date_called = true
@@ -86,7 +82,7 @@ class Employee < ActiveRecord::Base
86
82
  end
87
83
  end
88
84
 
89
- Rspec.configure do |c|
85
+ RSpec.configure do |c|
90
86
  c.mock_with :rspec
91
87
  c.include(RspecTagMatchers)
92
88
  c.include(ModelHelpers)
@@ -95,8 +91,5 @@ Rspec.configure do |c|
95
91
  Person.reset_callbacks(:validate)
96
92
  PersonWithShim.timeliness_validated_attributes = []
97
93
  Person._validators.clear
98
- Employee.reset_callbacks(:validate)
99
- Employee.timeliness_validated_attributes = []
100
- Employee._validators.clear
101
94
  end
102
95
  end
@@ -31,7 +31,7 @@ module TestModel
31
31
  end
32
32
 
33
33
  def initialize(attributes = nil)
34
- @attributes = self.class.model_attributes.inject({}) do |hash, column|
34
+ @attributes = self.class.model_attributes.keys.inject({}) do |hash, column|
35
35
  hash[column.to_s] = nil
36
36
  hash
37
37
  end
@@ -39,7 +39,7 @@ module TestModel
39
39
  end
40
40
 
41
41
  def attributes
42
- @attributes.keys
42
+ @attributes
43
43
  end
44
44
 
45
45
  def attributes=(new_attributes={})
@@ -49,14 +49,12 @@ module TestModel
49
49
  end
50
50
 
51
51
  def method_missing(method_id, *args, &block)
52
- if !self.class.attribute_methods_generated?
53
- self.class.define_attribute_methods self.class.model_attributes.keys.map(&:to_s)
54
- method_name = method_id.to_s
52
+ if match_attribute_method?(method_id.to_s)
53
+ self.class.define_attribute_methods self.class.model_attributes.keys
55
54
  send(method_id, *args, &block)
56
55
  else
57
56
  super
58
57
  end
59
58
  end
60
-
61
59
  end
62
60
 
@@ -14,12 +14,12 @@ describe ValidatesTimeliness::Extensions::DateTimeSelect do
14
14
  describe "datetime_select" do
15
15
  it "should use param values when attribute is nil" do
16
16
  @params["person"] = {
17
- "birth_datetime(1i)" => 2009,
18
- "birth_datetime(2i)" => 2,
19
- "birth_datetime(3i)" => 29,
20
- "birth_datetime(4i)" => 12,
21
- "birth_datetime(5i)" => 13,
22
- "birth_datetime(6i)" => 14,
17
+ "birth_datetime(1i)" => '2009',
18
+ "birth_datetime(2i)" => '2',
19
+ "birth_datetime(3i)" => '29',
20
+ "birth_datetime(4i)" => '12',
21
+ "birth_datetime(5i)" => '13',
22
+ "birth_datetime(6i)" => '14',
23
23
  }
24
24
  person.birth_datetime = nil
25
25
  @output = datetime_select(:person, :birth_datetime, :include_blank => true, :include_seconds => true)
@@ -28,12 +28,12 @@ describe ValidatesTimeliness::Extensions::DateTimeSelect do
28
28
 
29
29
  it "should override object values and use params if present" do
30
30
  @params["person"] = {
31
- "birth_datetime(1i)" => 2009,
32
- "birth_datetime(2i)" => 2,
33
- "birth_datetime(3i)" => 29,
34
- "birth_datetime(4i)" => 12,
35
- "birth_datetime(5i)" => 13,
36
- "birth_datetime(6i)" => 14,
31
+ "birth_datetime(1i)" => '2009',
32
+ "birth_datetime(2i)" => '2',
33
+ "birth_datetime(3i)" => '29',
34
+ "birth_datetime(4i)" => '12',
35
+ "birth_datetime(5i)" => '13',
36
+ "birth_datetime(6i)" => '14',
37
37
  }
38
38
  person.birth_datetime = "2010-01-01 15:16:17"
39
39
  @output = datetime_select(:person, :birth_datetime, :include_blank => true, :include_seconds => true)
@@ -63,44 +63,56 @@ describe ValidatesTimeliness::Extensions::DateTimeSelect do
63
63
  describe "date_select" do
64
64
  it "should use param values when attribute is nil" do
65
65
  @params["person"] = {
66
- "birth_date(1i)" => 2009,
67
- "birth_date(2i)" => 2,
68
- "birth_date(3i)" => 29,
66
+ "birth_date(1i)" => '2009',
67
+ "birth_date(2i)" => '2',
68
+ "birth_date(3i)" => '29',
69
69
  }
70
70
  person.birth_date = nil
71
- @output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
71
+ @output = date_select(:person, :birth_date, :include_blank => true)
72
72
  should_have_datetime_selected(:birth_date, :year => 2009, :month => 'February', :day => 29)
73
73
  end
74
74
 
75
75
  it "should override object values and use params if present" do
76
76
  @params["person"] = {
77
- "birth_date(1i)" => 2009,
78
- "birth_date(2i)" => 2,
79
- "birth_date(3i)" => 29,
77
+ "birth_date(1i)" => '2009',
78
+ "birth_date(2i)" => '2',
79
+ "birth_date(3i)" => '29',
80
80
  }
81
81
  person.birth_date = "2009-03-01"
82
- @output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
82
+ @output = date_select(:person, :birth_date, :include_blank => true)
83
83
  should_have_datetime_selected(:birth_date, :year => 2009, :month => 'February', :day => 29)
84
84
  end
85
85
 
86
86
  it "should select attribute values from object if no params" do
87
87
  person.birth_date = "2009-01-02"
88
- @output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
88
+ @output = date_select(:person, :birth_date, :include_blank => true)
89
89
  should_have_datetime_selected(:birth_date, :year => 2009, :month => 'January', :day => 2)
90
90
  end
91
91
 
92
92
  it "should select attribute values if params does not contain attribute params" do
93
93
  person.birth_date = "2009-01-02"
94
94
  @params["person"] = { }
95
- @output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
95
+ @output = date_select(:person, :birth_date, :include_blank => true)
96
96
  should_have_datetime_selected(:birth_date, :year => 2009, :month => 'January', :day => 2)
97
97
  end
98
98
 
99
99
  it "should not select values when attribute value is nil and has no param values" do
100
100
  person.birth_date = nil
101
- @output = date_select(:person, :birth_date, :include_blank => true, :include_seconds => true)
101
+ @output = date_select(:person, :birth_date, :include_blank => true)
102
102
  should_not_have_datetime_selected(:birth_time, :year, :month, :day)
103
103
  end
104
+
105
+ it "should allow the day part to be discarded" do
106
+ @params["person"] = {
107
+ "birth_date(1i)" => '2009',
108
+ "birth_date(2i)" => '2',
109
+ }
110
+
111
+ @output = date_select(:person, :birth_date, :include_blank => true, :discard_day => true)
112
+ should_have_datetime_selected(:birth_date, :year => 2009, :month => 'February')
113
+ should_not_have_datetime_selected(:birth_time, :day)
114
+ @output.should have_tag("input[id=person_birth_date_3i][type=hidden][value='1']")
115
+ end
104
116
  end
105
117
 
106
118
  describe "time_select" do
@@ -110,12 +122,12 @@ describe ValidatesTimeliness::Extensions::DateTimeSelect do
110
122
 
111
123
  it "should use param values when attribute is nil" do
112
124
  @params["person"] = {
113
- "birth_time(1i)" => 2000,
114
- "birth_time(2i)" => 1,
115
- "birth_time(3i)" => 1,
116
- "birth_time(4i)" => 12,
117
- "birth_time(5i)" => 13,
118
- "birth_time(6i)" => 14,
125
+ "birth_time(1i)" => '2000',
126
+ "birth_time(2i)" => '1',
127
+ "birth_time(3i)" => '1',
128
+ "birth_time(4i)" => '12',
129
+ "birth_time(5i)" => '13',
130
+ "birth_time(6i)" => '14',
119
131
  }
120
132
  person.birth_time = nil
121
133
  @output = time_select(:person, :birth_time, :include_blank => true, :include_seconds => true)
@@ -13,9 +13,18 @@ describe ValidatesTimeliness, 'HelperMethods' do
13
13
  Person.new.should respond_to(:validates_datetime)
14
14
  end
15
15
 
16
- it 'should validate instance when validation method called' do
16
+ it 'should validate instance using class validation defined' do
17
+ Person.validates_date :birth_date
18
+ r = Person.new
19
+ r.valid?
20
+
21
+ r.errors[:birth_date].should_not be_empty
22
+ end
23
+
24
+ it 'should validate instance using instance valiation method' do
17
25
  r = Person.new
18
26
  r.validates_date :birth_date
27
+
19
28
  r.errors[:birth_date].should_not be_empty
20
29
  end
21
30
  end
@@ -82,6 +82,7 @@ describe ValidatesTimeliness, 'ActiveRecord' do
82
82
  r = Employee.create!
83
83
  r.birth_date = '2010-01-01'
84
84
  r.reload
85
+
85
86
  r._timeliness_raw_value_for(:birth_date).should be_nil
86
87
  end
87
88
  end
@@ -94,7 +95,16 @@ describe ValidatesTimeliness, 'ActiveRecord' do
94
95
  it 'should return original value' do
95
96
  r = Employee.new
96
97
  r.birth_datetime = date_string = '2010-01-01'
98
+
97
99
  r.birth_datetime_before_type_cast.should == date_string
98
100
  end
101
+
102
+ it 'should return attribute if no attribute assignment has been made' do
103
+ datetime = Time.zone.local(2010,01,01)
104
+ Employee.create(:birth_datetime => datetime)
105
+
106
+ r = Employee.last
107
+ r.birth_datetime_before_type_cast.should match(/2010-01-01 00:00:00/)
108
+ end
99
109
  end
100
110
  end
@@ -15,15 +15,15 @@ end
15
15
  describe ValidatesTimeliness, 'Mongoid' do
16
16
 
17
17
  class Article
18
- ::ValidatesTimeliness.use_plugin_parser = true
19
18
  include Mongoid::Document
19
+ ValidatesTimeliness.use_plugin_parser = true
20
20
  field :publish_date, :type => Date
21
21
  field :publish_time, :type => Time
22
22
  field :publish_datetime, :type => DateTime
23
23
  validates_date :publish_date, :allow_nil => true
24
24
  validates_time :publish_time, :allow_nil => true
25
25
  validates_datetime :publish_datetime, :allow_nil => true
26
- ::ValidatesTimeliness.use_plugin_parser = false
26
+ ValidatesTimeliness.use_plugin_parser = false
27
27
  end
28
28
 
29
29
  context "validation methods" do
@@ -52,7 +52,7 @@ describe ValidatesTimeliness, 'Mongoid' do
52
52
  end
53
53
 
54
54
  context "with plugin parser" do
55
- with_config(:use_plugin_parser, false)
55
+ with_config(:use_plugin_parser, true)
56
56
 
57
57
  it 'should parse a string value' do
58
58
  Timeliness::Parser.should_receive(:parse)
@@ -60,12 +60,20 @@ describe ValidatesTimeliness, 'Mongoid' do
60
60
  r.publish_date = '2010-01-01'
61
61
  end
62
62
 
63
+ it 'should parse an invalid value as nil' do
64
+ Timeliness::Parser.should_receive(:parse)
65
+ r = Article.new
66
+ r.publish_date = 'bad value'
67
+
68
+ r.publish_date.should be_nil
69
+ end
70
+
63
71
  context "for a date column" do
64
- it 'should store a date value after parsing string' do
72
+ it 'should store a Time value after parsing string' do
65
73
  r = Article.new
66
74
  r.publish_date = '2010-01-01'
67
75
 
68
- r.publish_date.should be_kind_of(Date)
76
+ r.publish_date.should be_kind_of(Time)
69
77
  r.publish_date.should == Date.new(2010, 1, 1)
70
78
  end
71
79
  end
@@ -138,7 +138,7 @@ describe ValidatesTimeliness::Validator do
138
138
  it "should be added when ignore_restriction_errors is false" do
139
139
  with_config(:ignore_restriction_errors, false) do
140
140
  person.valid?
141
- person.errors[:birth_date].first.should match("Error occurred validating birth_date for :is_at restriction")
141
+ person.errors[:birth_date].first.should match("Error occurred validating birth_date")
142
142
  end
143
143
  end
144
144
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validates_timeliness
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 9
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 6
10
- version: 3.0.6
9
+ - 7
10
+ version: 3.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Adam Meehan
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-09 00:00:00 +10:00
18
+ date: 2011-09-21 00:00:00 +10:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency