validates_timeliness 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +43 -0
- data/LICENSE +20 -0
- data/README.rdoc +320 -0
- data/Rakefile +58 -0
- data/TODO +8 -0
- data/lib/validates_timeliness.rb +66 -0
- data/lib/validates_timeliness/action_view/instance_tag.rb +45 -0
- data/lib/validates_timeliness/active_record/attribute_methods.rb +157 -0
- data/lib/validates_timeliness/active_record/multiparameter_attributes.rb +64 -0
- data/lib/validates_timeliness/core_ext/date.rb +13 -0
- data/lib/validates_timeliness/core_ext/date_time.rb +13 -0
- data/lib/validates_timeliness/core_ext/time.rb +13 -0
- data/lib/validates_timeliness/formats.rb +310 -0
- data/lib/validates_timeliness/locale/en.yml +11 -0
- data/lib/validates_timeliness/spec/rails/matchers/validate_timeliness.rb +121 -0
- data/lib/validates_timeliness/validation_methods.rb +82 -0
- data/lib/validates_timeliness/validator.rb +120 -0
- data/spec/action_view/instance_tag_spec.rb +38 -0
- data/spec/active_record/attribute_methods_spec.rb +204 -0
- data/spec/active_record/multiparameter_attributes_spec.rb +48 -0
- data/spec/core_ext/dummy_time_spec.rb +31 -0
- data/spec/formats_spec.rb +274 -0
- data/spec/ginger_scenarios.rb +19 -0
- data/spec/resources/application.rb +2 -0
- data/spec/resources/person.rb +3 -0
- data/spec/resources/schema.rb +10 -0
- data/spec/resources/sqlite_patch.rb +19 -0
- data/spec/spec/rails/matchers/validate_timeliness_spec.rb +178 -0
- data/spec/spec_helper.rb +54 -0
- data/spec/time_travel/MIT-LICENSE +20 -0
- data/spec/time_travel/time_extensions.rb +33 -0
- data/spec/time_travel/time_travel.rb +12 -0
- data/spec/validation_methods_spec.rb +61 -0
- data/spec/validator_spec.rb +438 -0
- metadata +105 -0
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
2
|
+
$:.unshift(File.dirname(__FILE__))
|
3
|
+
$:.unshift(File.dirname(__FILE__) + '/resources')
|
4
|
+
|
5
|
+
ENV['RAILS_ENV'] = 'test'
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
require 'spec'
|
9
|
+
|
10
|
+
vendored_rails = File.dirname(__FILE__) + '/../../../../vendor/rails'
|
11
|
+
|
12
|
+
if vendored = File.exists?(vendored_rails)
|
13
|
+
Dir.glob(vendored_rails + "/**/lib").each { |dir| $:.unshift dir }
|
14
|
+
else
|
15
|
+
begin
|
16
|
+
require 'ginger'
|
17
|
+
rescue LoadError
|
18
|
+
end
|
19
|
+
if ENV['VERSION']
|
20
|
+
gem 'rails', ENV['VERSION']
|
21
|
+
else
|
22
|
+
gem 'rails'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
RAILS_ROOT = File.dirname(__FILE__)
|
27
|
+
|
28
|
+
require 'rails/version'
|
29
|
+
require 'active_record'
|
30
|
+
require 'active_record/version'
|
31
|
+
require 'action_controller'
|
32
|
+
require 'action_view'
|
33
|
+
|
34
|
+
require 'spec/rails'
|
35
|
+
require 'time_travel/time_travel'
|
36
|
+
|
37
|
+
ActiveRecord::Base.default_timezone = :utc
|
38
|
+
RAILS_VER = Rails::VERSION::STRING
|
39
|
+
puts "Using #{vendored ? 'vendored' : 'gem'} Rails version #{RAILS_VER} (ActiveRecord version #{ActiveRecord::VERSION::STRING})"
|
40
|
+
|
41
|
+
require 'validates_timeliness'
|
42
|
+
|
43
|
+
if RAILS_VER >= '2.1'
|
44
|
+
Time.zone_default = ActiveSupport::TimeZone['UTC']
|
45
|
+
ActiveRecord::Base.time_zone_aware_attributes = true
|
46
|
+
end
|
47
|
+
|
48
|
+
ActiveRecord::Migration.verbose = false
|
49
|
+
ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:'})
|
50
|
+
|
51
|
+
require 'sqlite_patch' if RAILS_VER < '2.1'
|
52
|
+
|
53
|
+
require 'schema'
|
54
|
+
require 'person'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Peter Yandell
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module TimeTravel
|
4
|
+
module TimeExtensions
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
base.class_eval do
|
9
|
+
class << self
|
10
|
+
alias_method :immutable_now, :now
|
11
|
+
alias_method :now, :mutable_now
|
12
|
+
end
|
13
|
+
end
|
14
|
+
base.now = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
|
19
|
+
@@now = nil
|
20
|
+
|
21
|
+
def now=(time)
|
22
|
+
time = Time.parse(time) if time.instance_of?(String)
|
23
|
+
@@now = time
|
24
|
+
end
|
25
|
+
|
26
|
+
def mutable_now #:nodoc:
|
27
|
+
@@now || immutable_now
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe ValidatesTimeliness::ValidationMethods do
|
4
|
+
attr_accessor :person
|
5
|
+
|
6
|
+
describe "parse_date_time" do
|
7
|
+
it "should return time object for valid time string" do
|
8
|
+
parse_method("2000-01-01 12:13:14", :datetime).should be_kind_of(Time)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return nil for time string with invalid date part" do
|
12
|
+
parse_method("2000-02-30 12:13:14", :datetime).should be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return nil for time string with invalid time part" do
|
16
|
+
parse_method("2000-02-01 25:13:14", :datetime).should be_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should return Time object when passed a Time object" do
|
20
|
+
parse_method(Time.now, :datetime).should be_kind_of(Time)
|
21
|
+
end
|
22
|
+
|
23
|
+
if RAILS_VER >= '2.1'
|
24
|
+
it "should convert time string into current timezone" do
|
25
|
+
Time.zone = 'Melbourne'
|
26
|
+
time = parse_method("2000-01-01 12:13:14", :datetime)
|
27
|
+
Time.zone.utc_offset.should == 10.hours
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return nil for invalid date string" do
|
32
|
+
parse_method("2000-02-30", :date).should be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_method(*args)
|
36
|
+
ActiveRecord::Base.parse_date_time(*args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "make_time" do
|
41
|
+
|
42
|
+
if RAILS_VER >= '2.1'
|
43
|
+
|
44
|
+
it "should create time using current timezone" do
|
45
|
+
Time.zone = 'Melbourne'
|
46
|
+
time = ActiveRecord::Base.send(:make_time, [2000,1,1,12,0,0])
|
47
|
+
time.zone.should == "EST"
|
48
|
+
end
|
49
|
+
|
50
|
+
else
|
51
|
+
|
52
|
+
it "should create time using default timezone" do
|
53
|
+
time = ActiveRecord::Base.send(:make_time, [2000,1,1,12,0,0])
|
54
|
+
time.zone.should == "UTC"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,438 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe ValidatesTimeliness::Validator do
|
4
|
+
attr_accessor :person, :validator
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
# freezes time using time_travel plugin
|
8
|
+
Time.now = Time.utc(2000, 1, 1, 0, 0, 0)
|
9
|
+
end
|
10
|
+
|
11
|
+
after :all do
|
12
|
+
Time.now = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
@person = Person.new
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "restriction_value" do
|
20
|
+
it "should return Time object when restriction is Time object" do
|
21
|
+
restriction_value(Time.now, :datetime).should be_kind_of(Time)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return Time object when restriction is string" do
|
25
|
+
restriction_value("2007-01-01 12:00", :datetime).should be_kind_of(Time)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return Time object when restriction is method and method returns Time object" do
|
29
|
+
person.stub!(:datetime_attr).and_return(Time.now)
|
30
|
+
restriction_value(:datetime_attr, :datetime).should be_kind_of(Time)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return Time object when restriction is method and method returns string" do
|
34
|
+
person.stub!(:datetime_attr).and_return("2007-01-01 12:00")
|
35
|
+
restriction_value(:datetime_attr, :datetime).should be_kind_of(Time)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return Time object when restriction is proc which returns Time object" do
|
39
|
+
restriction_value(lambda { Time.now }, :datetime).should be_kind_of(Time)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return Time object when restriction is proc which returns string" do
|
43
|
+
restriction_value(lambda {"2007-01-01 12:00"}, :datetime).should be_kind_of(Time)
|
44
|
+
end
|
45
|
+
|
46
|
+
def restriction_value(restriction, type)
|
47
|
+
configure_validator(:type => type)
|
48
|
+
validator.send(:restriction_value, restriction, person)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "instance with defaults" do
|
53
|
+
|
54
|
+
describe "for datetime type" do
|
55
|
+
before do
|
56
|
+
configure_validator(:type => :datetime)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should have invalid error when date component is invalid" do
|
60
|
+
validate_with(:birth_date_and_time, "2000-01-32 01:02:03")
|
61
|
+
should_have_error(:birth_date_and_time, :invalid_datetime)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should have invalid error when time component is invalid" do
|
65
|
+
validate_with(:birth_date_and_time, "2000-01-01 25:02:03")
|
66
|
+
should_have_error(:birth_date_and_time, :invalid_datetime)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should have blank error when value is nil" do
|
70
|
+
validate_with(:birth_date_and_time, nil)
|
71
|
+
should_have_error(:birth_date_and_time, :blank)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should have no errors when value is valid" do
|
75
|
+
validate_with(:birth_date_and_time, "2000-01-01 12:00:00")
|
76
|
+
should_have_no_error(:birth_date_and_time, :invalid_datetime)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "for date type" do
|
81
|
+
before do
|
82
|
+
configure_validator(:type => :date)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should have invalid error when value is invalid" do
|
86
|
+
validate_with(:birth_date, "2000-01-32")
|
87
|
+
should_have_error(:birth_date, :invalid_date)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should have blank error when value is nil" do
|
91
|
+
validate_with(:birth_date, nil)
|
92
|
+
should_have_error(:birth_date, :blank)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should have no error when value is valid" do
|
96
|
+
validate_with(:birth_date, "2000-01-31")
|
97
|
+
should_have_no_error(:birth_date, :invalid_date)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "for time type" do
|
102
|
+
before do
|
103
|
+
configure_validator(:type => :time)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should have invalid error when value is invalid" do
|
107
|
+
validate_with(:birth_time, "25:00")
|
108
|
+
should_have_error(:birth_time, :invalid_time)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should have blank error when value is nil" do
|
112
|
+
validate_with(:birth_time, nil)
|
113
|
+
should_have_error(:birth_time, :blank)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should have no errors when value is valid" do
|
117
|
+
validate_with(:birth_date_and_time, "12:00")
|
118
|
+
should_have_no_error(:birth_time, :invalid_time)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "instance with before and after restrictions" do
|
125
|
+
|
126
|
+
describe "for datetime type" do
|
127
|
+
before :each do
|
128
|
+
configure_validator(:before => lambda { Time.now }, :after => lambda { 1.day.ago})
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should have before error when value is past :before restriction" do
|
132
|
+
validate_with(:birth_date_and_time, 1.minute.from_now)
|
133
|
+
should_have_error(:birth_date_and_time, :before)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should have before error when value is on boundary of :before restriction" do
|
137
|
+
validate_with(:birth_date_and_time, Time.now)
|
138
|
+
should_have_error(:birth_date_and_time, :before)
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should have after error when value is before :after restriction" do
|
142
|
+
validate_with(:birth_date_and_time, 2.days.ago)
|
143
|
+
should_have_error(:birth_date_and_time, :after)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should have after error when value is on boundary of :after restriction" do
|
147
|
+
validate_with(:birth_date_and_time, 1.day.ago)
|
148
|
+
should_have_error(:birth_date_and_time, :after)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "for date type" do
|
153
|
+
before :each do
|
154
|
+
configure_validator(:before => 1.day.from_now, :after => 1.day.ago, :type => :date)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should have error when value is past :before restriction" do
|
158
|
+
validate_with(:birth_date, 2.days.from_now)
|
159
|
+
should_have_error(:birth_date, :before)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should have error when value is before :after restriction" do
|
163
|
+
validate_with(:birth_date, 2.days.ago)
|
164
|
+
should_have_error(:birth_date, :after)
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should have no error when value is before :before restriction" do
|
168
|
+
validate_with(:birth_date, Time.now)
|
169
|
+
should_have_no_error(:birth_date, :before)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should have no error when value is after :after restriction" do
|
173
|
+
validate_with(:birth_date, Time.now)
|
174
|
+
should_have_no_error(:birth_date, :after)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "for time type" do
|
179
|
+
before :each do
|
180
|
+
configure_validator(:before => "23:00", :after => "06:00", :type => :time)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should have error when value is on boundary of :before restriction" do
|
184
|
+
validate_with(:birth_time, "23:00")
|
185
|
+
should_have_error(:birth_time, :before)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should have error when value is on boundary of :after restriction" do
|
189
|
+
validate_with(:birth_time, "06:00")
|
190
|
+
should_have_error(:birth_time, :after)
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should have error when value is past :before restriction" do
|
194
|
+
validate_with(:birth_time, "23:01")
|
195
|
+
should_have_error(:birth_time, :before)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should have error when value is before :after restriction" do
|
199
|
+
validate_with(:birth_time, "05:59")
|
200
|
+
should_have_error(:birth_time, :after)
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should not have error when value is before :before restriction" do
|
204
|
+
validate_with(:birth_time, "22:59")
|
205
|
+
should_have_no_error(:birth_time, :before)
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should have error when value is before :after restriction" do
|
209
|
+
validate_with(:birth_time, "06:01")
|
210
|
+
should_have_no_error(:birth_time, :before)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe "instance with on_or_before and on_or_after restrictions" do
|
216
|
+
|
217
|
+
describe "for datetime type" do
|
218
|
+
before do
|
219
|
+
configure_validator(:on_or_before => Time.now.at_midnight, :on_or_after => 1.day.ago)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should have error when value is past :on_or_before restriction" do
|
223
|
+
validate_with(:birth_date_and_time, Time.now.at_midnight + 1)
|
224
|
+
should_have_error(:birth_date_and_time, :on_of_before)
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should be valid when value is equal to :on_or_before restriction" do
|
228
|
+
validate_with(:birth_date_and_time, Time.now.at_midnight)
|
229
|
+
should_have_no_error(:birth_date_and_time, :on_of_before)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should have error when value is before :on_or_after restriction" do
|
233
|
+
validate_with(:birth_date_and_time, 1.days.ago - 1)
|
234
|
+
should_have_error(:birth_date_and_time, :on_of_after)
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should be valid when value is value equal to :on_or_after restriction" do
|
238
|
+
validate_with(:birth_date_and_time, 1.day.ago)
|
239
|
+
should_have_no_error(:birth_date_and_time, :on_of_after)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe "for date type" do
|
244
|
+
before :each do
|
245
|
+
configure_validator(:on_or_before => 1.day.from_now, :on_or_after => 1.day.ago, :type => :date)
|
246
|
+
end
|
247
|
+
|
248
|
+
it "should have error when value is past :on_or_before restriction" do
|
249
|
+
validate_with(:birth_date, 2.days.from_now)
|
250
|
+
should_have_error(:birth_date, :on_or_before)
|
251
|
+
end
|
252
|
+
|
253
|
+
it "should have error when value is before :on_or_after restriction" do
|
254
|
+
validate_with(:birth_date, 2.days.ago)
|
255
|
+
should_have_error(:birth_date, :on_or_after)
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should be valid when value is equal to :on_or_before restriction" do
|
259
|
+
validate_with(:birth_date, 1.day.from_now)
|
260
|
+
should_have_no_error(:birth_date, :on_or_before)
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should be valid when value value is equal to :on_or_after restriction" do
|
264
|
+
validate_with(:birth_date, 1.day.ago)
|
265
|
+
should_have_no_error(:birth_date, :on_or_before)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
describe "for time type" do
|
270
|
+
before :each do
|
271
|
+
configure_validator(:on_or_before => "23:00", :on_or_after => "06:00", :type => :time)
|
272
|
+
end
|
273
|
+
|
274
|
+
it "should have error when value is past :on_or_before restriction" do
|
275
|
+
validate_with(:birth_time, "23:01")
|
276
|
+
should_have_error(:birth_time, :on_or_before)
|
277
|
+
end
|
278
|
+
|
279
|
+
it "should have error when value is before :on_or_after restriction" do
|
280
|
+
validate_with(:birth_time, "05:59")
|
281
|
+
should_have_error(:birth_time, :on_or_after)
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should be valid when value is on boundary of :on_or_before restriction" do
|
285
|
+
validate_with(:birth_time, "23:00")
|
286
|
+
should_have_no_error(:birth_time, :on_or_before)
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should be valid when value is on boundary of :on_or_after restriction" do
|
290
|
+
validate_with(:birth_time, "06:00")
|
291
|
+
should_have_no_error(:birth_time, :on_or_after)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe "instance with mixed value and restriction types" do
|
297
|
+
|
298
|
+
it "should validate datetime attribute with Date restriction" do
|
299
|
+
configure_validator(:type => :datetime, :on_or_before => Date.new(2000,1,1))
|
300
|
+
validate_with(:birth_date_and_time, "2000-01-01 00:00:00")
|
301
|
+
should_have_no_error(:birth_date_and_time, :on_or_before)
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should validate date attribute with DateTime restriction value" do
|
305
|
+
configure_validator(:type => :date, :on_or_before => DateTime.new(2000, 1, 1, 0,0,0))
|
306
|
+
validate_with(:birth_date, "2000-01-01")
|
307
|
+
should_have_no_error(:birth_date, :on_or_before)
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should validate date attribute with Time restriction value" do
|
311
|
+
configure_validator(:type => :date, :on_or_before => Time.utc(2000, 1, 1, 0,0,0))
|
312
|
+
validate_with(:birth_date, "2000-01-01")
|
313
|
+
should_have_no_error(:birth_date, :on_or_before)
|
314
|
+
end
|
315
|
+
|
316
|
+
it "should validate time attribute with DateTime restriction value" do
|
317
|
+
configure_validator(:type => :time, :on_or_before => DateTime.new(2000, 1, 1, 12,0,0))
|
318
|
+
validate_with(:birth_time, "12:00")
|
319
|
+
should_have_no_error(:birth_time, :on_or_before)
|
320
|
+
end
|
321
|
+
|
322
|
+
it "should validate time attribute with Time restriction value" do
|
323
|
+
configure_validator(:type => :time, :on_or_before => Time.utc(2000, 1, 1, 12,0,0))
|
324
|
+
validate_with(:birth_time, "12:00")
|
325
|
+
should_have_no_error(:birth_time, :on_or_before)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
describe "restriction errors" do
|
330
|
+
before :each do
|
331
|
+
configure_validator(:type => :date, :before => lambda { raise })
|
332
|
+
end
|
333
|
+
|
334
|
+
it "should be added by default for invalid restriction" do
|
335
|
+
ValidatesTimeliness::Validator.ignore_restriction_errors = false
|
336
|
+
validate_with(:birth_date, Date.today)
|
337
|
+
person.errors.on(:birth_date).should match(/restriction 'before' value was invalid/)
|
338
|
+
end
|
339
|
+
|
340
|
+
it "should not be added when ignore switch is true and restriction is invalid" do
|
341
|
+
ValidatesTimeliness::Validator.ignore_restriction_errors = true
|
342
|
+
person.should be_valid
|
343
|
+
end
|
344
|
+
|
345
|
+
after :all do
|
346
|
+
ValidatesTimeliness::Validator.ignore_restriction_errors = false
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
describe "restriction value error message" do
|
351
|
+
|
352
|
+
describe "default formats" do
|
353
|
+
|
354
|
+
it "should format datetime value of restriction" do
|
355
|
+
configure_validator(:type => :datetime, :after => 1.day.from_now)
|
356
|
+
validate_with(:birth_date_and_time, Time.now)
|
357
|
+
person.errors.on(:birth_date_and_time).should match(/after \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\Z/)
|
358
|
+
end
|
359
|
+
|
360
|
+
it "should format date value of restriction" do
|
361
|
+
configure_validator(:type => :date, :after => 1.day.from_now)
|
362
|
+
validate_with(:birth_date, Time.now)
|
363
|
+
person.errors.on(:birth_date).should match(/after \d{4}-\d{2}-\d{2}\Z/)
|
364
|
+
end
|
365
|
+
|
366
|
+
it "should format time value of restriction" do
|
367
|
+
configure_validator(:type => :time, :after => '12:00')
|
368
|
+
validate_with(:birth_time, '11:59')
|
369
|
+
person.errors.on(:birth_time).should match(/after \d{2}:\d{2}:\d{2}\Z/)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
describe "custom formats" do
|
374
|
+
|
375
|
+
before :all do
|
376
|
+
@@formats = ValidatesTimeliness::Validator.error_value_formats
|
377
|
+
ValidatesTimeliness::Validator.error_value_formats = {
|
378
|
+
:time => '%H:%M %p',
|
379
|
+
:date => '%d-%m-%Y',
|
380
|
+
:datetime => '%d-%m-%Y %H:%M %p'
|
381
|
+
}
|
382
|
+
end
|
383
|
+
|
384
|
+
it "should format datetime value of restriction" do
|
385
|
+
configure_validator(:type => :datetime, :after => 1.day.from_now)
|
386
|
+
validate_with(:birth_date_and_time, Time.now)
|
387
|
+
person.errors.on(:birth_date_and_time).should match(/after \d{2}-\d{2}-\d{4} \d{2}:\d{2} (AM|PM)\Z/)
|
388
|
+
end
|
389
|
+
|
390
|
+
it "should format date value of restriction" do
|
391
|
+
configure_validator(:type => :date, :after => 1.day.from_now)
|
392
|
+
validate_with(:birth_date, Time.now)
|
393
|
+
person.errors.on(:birth_date).should match(/after \d{2}-\d{2}-\d{4}\Z/)
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should format time value of restriction" do
|
397
|
+
configure_validator(:type => :time, :after => '12:00')
|
398
|
+
validate_with(:birth_time, '11:59')
|
399
|
+
person.errors.on(:birth_time).should match(/after \d{2}:\d{2} (AM|PM)\Z/)
|
400
|
+
end
|
401
|
+
|
402
|
+
after :all do
|
403
|
+
ValidatesTimeliness::Validator.error_value_formats = @@formats
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
end
|
408
|
+
|
409
|
+
def configure_validator(options={})
|
410
|
+
@validator = ValidatesTimeliness::Validator.new(options)
|
411
|
+
end
|
412
|
+
|
413
|
+
def validate_with(attr_name, value)
|
414
|
+
person.send("#{attr_name}=", value)
|
415
|
+
validator.call(person, attr_name)
|
416
|
+
end
|
417
|
+
|
418
|
+
def should_have_error(attr_name, error)
|
419
|
+
message = error_messages[error]
|
420
|
+
person.errors.on(attr_name).should match(/#{message}/)
|
421
|
+
end
|
422
|
+
|
423
|
+
def should_have_no_error(attr_name, error)
|
424
|
+
message = error_messages[error]
|
425
|
+
errors = person.errors.on(attr_name)
|
426
|
+
if errors
|
427
|
+
errors.should_not match(/#{message}/)
|
428
|
+
else
|
429
|
+
errors.should be_nil
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
def error_messages
|
434
|
+
return @error_messages if defined?(@error_messages)
|
435
|
+
messages = validator.send(:error_messages)
|
436
|
+
@error_messages = messages.inject({}) {|h, (k, v)| h[k] = v.gsub(/ (\%s|\{\{\w*\}\})/, ''); h }
|
437
|
+
end
|
438
|
+
end
|