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
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe ValidatesTimeliness::ActiveRecord::MultiparameterAttributes do
|
4
|
+
def obj
|
5
|
+
@obj ||= Person.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should convert array for datetime type into datetime string" do
|
9
|
+
time_string = obj.time_array_to_string([2000,2,1,9,10,11], :datetime)
|
10
|
+
time_string.should == "2000-02-01 09:10:11"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should convert array for date type into date string" do
|
14
|
+
time_string = obj.time_array_to_string([2000,2,1], :date)
|
15
|
+
time_string.should == "2000-02-01"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should convert array for time type into time string" do
|
19
|
+
time_string = obj.time_array_to_string([2000,1,1,9,10,11], :time)
|
20
|
+
time_string.should == "09:10:11"
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "execute_callstack_for_multiparameter_attributes" do
|
24
|
+
before do
|
25
|
+
@callstack = {
|
26
|
+
'birth_date_and_time' => [2000,2,1,9,10,11],
|
27
|
+
'birth_date' => [2000,2,1,9,10,11],
|
28
|
+
'birth_time' => [2000,2,1,9,10,11]
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should store datetime string for datetime column" do
|
33
|
+
obj.should_receive(:birth_date_and_time=).once.with("2000-02-01 09:10:11")
|
34
|
+
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should store date string for a date column" do
|
38
|
+
obj.should_receive(:birth_date=).once.with("2000-02-01")
|
39
|
+
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should store time string for a time column" do
|
43
|
+
obj.should_receive(:birth_time=).once.with("09:10:11")
|
44
|
+
obj.send(:execute_callstack_for_multiparameter_attributes, @callstack)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe ValidatesTimeliness::CoreExtensions::Date do
|
4
|
+
before do
|
5
|
+
@a_date = Date.new(2008, 7, 1)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should make a date value into a dummy time value" do
|
9
|
+
@a_date.to_dummy_time.should == Time.utc(2000,1,1,0,0,0)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ValidatesTimeliness::CoreExtensions::Time do
|
14
|
+
before do
|
15
|
+
@a_time = Time.mktime(2008, 7, 1, 2, 3, 4)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should make a time value into a dummy time value" do
|
19
|
+
@a_time.to_dummy_time.should == Time.utc(2000,1,1,2,3,4)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe ValidatesTimeliness::CoreExtensions::DateTime do
|
24
|
+
before do
|
25
|
+
@a_datetime = DateTime.new(2008, 7, 1, 2, 3, 4)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should make a datetime value into a dummy time value" do
|
29
|
+
@a_datetime.to_dummy_time.should == Time.utc(2000,1,1,2,3,4)
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,274 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe ValidatesTimeliness::Formats do
|
4
|
+
attr_reader :formats
|
5
|
+
|
6
|
+
before do
|
7
|
+
@formats = ValidatesTimeliness::Formats
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "expression generator" do
|
11
|
+
it "should generate regexp for time" do
|
12
|
+
generate_regexp_str('hh:nn:ss').should == '/(\d{2}):(\d{2}):(\d{2})/'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should generate regexp for time with meridian" do
|
16
|
+
generate_regexp_str('hh:nn:ss ampm').should == '/(\d{2}):(\d{2}):(\d{2}) ((?:[aApP])\.?[mM]\.?)/'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should generate regexp for time with meridian and optional space between" do
|
20
|
+
generate_regexp_str('hh:nn:ss_ampm').should == '/(\d{2}):(\d{2}):(\d{2})\s?((?:[aApP])\.?[mM]\.?)/'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should generate regexp for time with single or double digits" do
|
24
|
+
generate_regexp_str('h:n:s').should == '/(\d{1,2}):(\d{1,2}):(\d{1,2})/'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should generate regexp for date" do
|
28
|
+
generate_regexp_str('yyyy-mm-dd').should == '/(\d{4})-(\d{2})-(\d{2})/'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should generate regexp for date with slashes" do
|
32
|
+
generate_regexp_str('dd/mm/yyyy').should == '/(\d{2})\/(\d{2})\/(\d{4})/'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should generate regexp for date with dots" do
|
36
|
+
generate_regexp_str('dd.mm.yyyy').should == '/(\d{2})\.(\d{2})\.(\d{4})/'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should generate regexp for Ruby time string" do
|
40
|
+
expected = '/(\w{3,9}) (\w{3,9}) (\d{2}):(\d{2}):(\d{2}) (?:[+-]\d{2}:?\d{2}) (\d{4})/'
|
41
|
+
generate_regexp_str('ddd mmm hh:nn:ss zo yyyy').should == expected
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should generate regexp for iso8601 datetime" do
|
45
|
+
expected = '/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:Z|(?:[+-]\d{2}:?\d{2}))/'
|
46
|
+
generate_regexp_str('yyyy-mm-ddThh:nn:ss(?:Z|zo)').should == expected
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "format proc generator" do
|
51
|
+
it "should generate proc which outputs date array with values in correct order" do
|
52
|
+
generate_proc('yyyy-mm-dd').call('2000', '1', '2').should == [2000,1,2,0,0,0,0]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should generate proc which outputs date array from format with different order" do
|
56
|
+
generate_proc('dd/mm/yyyy').call('2', '1', '2000').should == [2000,1,2,0,0,0,0]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should generate proc which outputs time array" do
|
60
|
+
generate_proc('hh:nn:ss').call('01', '02', '03').should == [0,0,0,1,2,3,0]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should generate proc which outputs time array with meridian 'pm' adjusted hour" do
|
64
|
+
generate_proc('hh:nn:ss ampm').call('01', '02', '03', 'pm').should == [0,0,0,13,2,3,0]
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should generate proc which outputs time array with meridian 'am' unadjusted hour" do
|
68
|
+
generate_proc('hh:nn:ss ampm').call('01', '02', '03', 'am').should == [0,0,0,1,2,3,0]
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should generate proc which outputs time array with microseconds" do
|
72
|
+
generate_proc('hh:nn:ss.u').call('01', '02', '03', '99').should == [0,0,0,1,2,3,990000]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "validation regexps" do
|
77
|
+
|
78
|
+
describe "for time formats" do
|
79
|
+
format_tests = {
|
80
|
+
'hh:nn:ss' => {:pass => ['12:12:12', '01:01:01'], :fail => ['1:12:12', '12:1:12', '12:12:1', '12-12-12']},
|
81
|
+
'hh-nn-ss' => {:pass => ['12-12-12', '01-01-01'], :fail => ['1-12-12', '12-1-12', '12-12-1', '12:12:12']},
|
82
|
+
'h:nn' => {:pass => ['12:12', '1:01'], :fail => ['12:2', '12-12']},
|
83
|
+
'h.nn' => {:pass => ['2.12', '12.12'], :fail => ['2.1', '12:12']},
|
84
|
+
'h nn' => {:pass => ['2 12', '12 12'], :fail => ['2 1', '2.12', '12:12']},
|
85
|
+
'h-nn' => {:pass => ['2-12', '12-12'], :fail => ['2-1', '2.12', '12:12']},
|
86
|
+
'h:nn_ampm' => {:pass => ['2:12am', '2:12 pm', '2:12 AM', '2:12PM'], :fail => ['1:2am', '1:12 pm', '2.12am']},
|
87
|
+
'h.nn_ampm' => {:pass => ['2.12am', '2.12 pm'], :fail => ['1:2am', '1:12 pm', '2:12am']},
|
88
|
+
'h nn_ampm' => {:pass => ['2 12am', '2 12 pm'], :fail => ['1 2am', '1 12 pm', '2:12am']},
|
89
|
+
'h-nn_ampm' => {:pass => ['2-12am', '2-12 pm'], :fail => ['1-2am', '1-12 pm', '2:12am']},
|
90
|
+
'h_ampm' => {:pass => ['2am', '2 am', '12 pm'], :fail => ['1.am', '12 pm', '2:12am']},
|
91
|
+
}
|
92
|
+
format_tests.each do |format, values|
|
93
|
+
it "should correctly validate times in format '#{format}'" do
|
94
|
+
regexp = generate_regexp(format)
|
95
|
+
values[:pass].each {|value| value.should match(regexp)}
|
96
|
+
values[:fail].each {|value| value.should_not match(regexp)}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "for date formats" do
|
102
|
+
format_tests = {
|
103
|
+
'yyyy/mm/dd' => {:pass => ['2000/02/01'], :fail => ['2000\02\01', '2000/2/1', '00/02/01']},
|
104
|
+
'yyyy-mm-dd' => {:pass => ['2000-02-01'], :fail => ['2000\02\01', '2000-2-1', '00-02-01']},
|
105
|
+
'yyyy.mm.dd' => {:pass => ['2000.02.01'], :fail => ['2000\02\01', '2000.2.1', '00.02.01']},
|
106
|
+
'm/d/yy' => {:pass => ['2/1/01', '02/01/00', '02/01/2000'], :fail => ['2/1/0', '2.1.01']},
|
107
|
+
'd/m/yy' => {:pass => ['1/2/01', '01/02/00', '01/02/2000'], :fail => ['1/2/0', '1.2.01']},
|
108
|
+
'm\d\yy' => {:pass => ['2\1\01', '2\01\00', '02\01\2000'], :fail => ['2\1\0', '2/1/01']},
|
109
|
+
'd\m\yy' => {:pass => ['1\2\01', '1\02\00', '01\02\2000'], :fail => ['1\2\0', '1/2/01']},
|
110
|
+
'd-m-yy' => {:pass => ['1-2-01', '1-02-00', '01-02-2000'], :fail => ['1-2-0', '1/2/01']},
|
111
|
+
'd.m.yy' => {:pass => ['1.2.01', '1.02.00', '01.02.2000'], :fail => ['1.2.0', '1/2/01']},
|
112
|
+
'd mmm yy' => {:pass => ['1 Feb 00', '1 Feb 2000', '1 February 00', '01 February 2000'],
|
113
|
+
:fail => ['1 Fe 00', 'Feb 1 2000', '1 Feb 0']}
|
114
|
+
}
|
115
|
+
format_tests.each do |format, values|
|
116
|
+
it "should correctly validate dates in format '#{format}'" do
|
117
|
+
regexp = generate_regexp(format)
|
118
|
+
values[:pass].each {|value| value.should match(regexp)}
|
119
|
+
values[:fail].each {|value| value.should_not match(regexp)}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "for datetime formats" do
|
125
|
+
format_tests = {
|
126
|
+
'ddd mmm d hh:nn:ss zo yyyy' => {:pass => ['Sat Jul 19 12:00:00 +1000 2008'], :fail => []},
|
127
|
+
'yyyy-mm-ddThh:nn:ss(?:Z|zo)' => {:pass => ['2008-07-19T12:00:00+10:00', '2008-07-19T12:00:00Z'], :fail => ['2008-07-19T12:00:00Z+10:00']},
|
128
|
+
}
|
129
|
+
format_tests.each do |format, values|
|
130
|
+
it "should correctly validate datetimes in format '#{format}'" do
|
131
|
+
regexp = generate_regexp(format)
|
132
|
+
values[:pass].each {|value| value.should match(regexp)}
|
133
|
+
values[:fail].each {|value| value.should_not match(regexp)}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "extracting values" do
|
140
|
+
|
141
|
+
it "should return time array from date string" do
|
142
|
+
time_array = formats.parse('12:13:14', :time, true)
|
143
|
+
time_array.should == [0,0,0,12,13,14,0]
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should return date array from time string" do
|
147
|
+
time_array = formats.parse('2000-02-01', :date, true)
|
148
|
+
time_array.should == [2000,2,1,0,0,0,0]
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should return datetime array from string value" do
|
152
|
+
time_array = formats.parse('2000-02-01 12:13:14', :datetime, true)
|
153
|
+
time_array.should == [2000,2,1,12,13,14,0]
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should parse date string when type is datetime" do
|
157
|
+
time_array = formats.parse('2000-02-01', :datetime, false)
|
158
|
+
time_array.should == [2000,2,1,0,0,0,0]
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should ignore time when extracting date and strict is false" do
|
162
|
+
time_array = formats.parse('2000-02-01 12:12', :date, false)
|
163
|
+
time_array.should == [2000,2,1,0,0,0,0]
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should ignore date when extracting time and strict is false" do
|
167
|
+
time_array = formats.parse('2000-02-01 12:12', :time, false)
|
168
|
+
time_array.should == [0,0,0,12,12,0,0]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "removing formats" do
|
173
|
+
before do
|
174
|
+
formats.compile_format_expressions
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should remove format from format array" do
|
178
|
+
formats.remove_formats(:time, 'h.nn_ampm')
|
179
|
+
formats.time_formats.should_not include("h o'clock")
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should not match time after its format is removed" do
|
183
|
+
validate('2.12am', :time).should be_true
|
184
|
+
formats.remove_formats(:time, 'h.nn_ampm')
|
185
|
+
validate('2.12am', :time).should be_false
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should raise error if format does not exist" do
|
189
|
+
lambda { formats.remove_formats(:time, "ss:hh:nn") }.should raise_error()
|
190
|
+
end
|
191
|
+
|
192
|
+
after do
|
193
|
+
formats.time_formats << 'h.nn_ampm'
|
194
|
+
# reload class instead
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "adding formats" do
|
199
|
+
before do
|
200
|
+
formats.compile_format_expressions
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should add format to format array" do
|
204
|
+
formats.add_formats(:time, "h o'clock")
|
205
|
+
formats.time_formats.should include("h o'clock")
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should match new format after its added" do
|
209
|
+
validate("12 o'clock", :time).should be_false
|
210
|
+
formats.add_formats(:time, "h o'clock")
|
211
|
+
validate("12 o'clock", :time).should be_true
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should add format before specified format and be higher precedence" do
|
215
|
+
formats.add_formats(:time, "ss:hh:nn", :before => 'hh:nn:ss')
|
216
|
+
validate("59:23:58", :time).should be_true
|
217
|
+
time_array = formats.parse('59:23:58', :time)
|
218
|
+
time_array.should == [0,0,0,23,58,59,0]
|
219
|
+
end
|
220
|
+
|
221
|
+
it "should raise error if format exists" do
|
222
|
+
lambda { formats.add_formats(:time, "hh:nn:ss") }.should raise_error()
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should raise error if format exists" do
|
226
|
+
lambda { formats.add_formats(:time, "ss:hh:nn", :before => 'nn:hh:ss') }.should raise_error()
|
227
|
+
end
|
228
|
+
|
229
|
+
after do
|
230
|
+
formats.time_formats.delete("h o'clock")
|
231
|
+
formats.time_formats.delete("ss:hh:nn")
|
232
|
+
# reload class instead
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
describe "removing US formats" do
|
237
|
+
it "should validate a date as European format when US formats removed" do
|
238
|
+
time_array = formats.parse('01/02/2000', :date)
|
239
|
+
time_array.should == [2000, 1, 2,0,0,0,0]
|
240
|
+
formats.remove_us_formats
|
241
|
+
time_array = formats.parse('01/02/2000', :date)
|
242
|
+
time_array.should == [2000, 2, 1,0,0,0,0]
|
243
|
+
end
|
244
|
+
|
245
|
+
after do
|
246
|
+
# reload class
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def validate(time_string, type)
|
251
|
+
valid = false
|
252
|
+
formats.send("#{type}_expressions").each do |(regexp, processor)|
|
253
|
+
valid = true and break if /\A#{regexp}\Z/ =~ time_string
|
254
|
+
end
|
255
|
+
valid
|
256
|
+
end
|
257
|
+
|
258
|
+
def generate_regexp(format)
|
259
|
+
# wrap in line start and end anchors to emulate extract values method
|
260
|
+
/\A#{formats.send(:format_expression_generator, format)[0]}\Z/
|
261
|
+
end
|
262
|
+
|
263
|
+
def generate_regexp_str(format)
|
264
|
+
formats.send(:format_expression_generator, format)[0].inspect
|
265
|
+
end
|
266
|
+
|
267
|
+
def generate_proc(format)
|
268
|
+
formats.send(:format_expression_generator, format)[1]
|
269
|
+
end
|
270
|
+
|
271
|
+
def delete_format(type, format)
|
272
|
+
formats.send("#{type}_formats").delete(format)
|
273
|
+
end
|
274
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# For use with the ginger gem to test plugin against multiple versions of Rails.
|
2
|
+
#
|
3
|
+
# To use ginger:
|
4
|
+
#
|
5
|
+
# sudo gem install freelancing-god-ginger --source=http://gems.github.com
|
6
|
+
#
|
7
|
+
# Then run
|
8
|
+
#
|
9
|
+
# ginger spec
|
10
|
+
#
|
11
|
+
Ginger.configure do |config|
|
12
|
+
rails_versions = ['2.0.2', '2.1.2', '2.2.2']
|
13
|
+
|
14
|
+
rails_versions.each do |v|
|
15
|
+
g = Ginger::Scenario.new
|
16
|
+
g['rails'] = v
|
17
|
+
config.scenarios << g.dup
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# patches adapter in rails 2.0 which mistakenly made time attributes map to datetime column type
|
2
|
+
ActiveRecord::ConnectionAdapters::SQLiteAdapter.class_eval do
|
3
|
+
def native_database_types #:nodoc:
|
4
|
+
{
|
5
|
+
:primary_key => default_primary_key_type,
|
6
|
+
:string => { :name => "varchar", :limit => 255 },
|
7
|
+
:text => { :name => "text" },
|
8
|
+
:integer => { :name => "integer" },
|
9
|
+
:float => { :name => "float" },
|
10
|
+
:decimal => { :name => "decimal" },
|
11
|
+
:datetime => { :name => "datetime" },
|
12
|
+
:timestamp => { :name => "datetime" },
|
13
|
+
:time => { :name => "time" },
|
14
|
+
:date => { :name => "date" },
|
15
|
+
:binary => { :name => "blob" },
|
16
|
+
:boolean => { :name => "boolean" }
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
class NoValidation < Person
|
4
|
+
end
|
5
|
+
|
6
|
+
class WithValidation < Person
|
7
|
+
validates_date :birth_date,
|
8
|
+
:before => '2000-01-10', :after => '2000-01-01',
|
9
|
+
:on_or_before => '2000-01-09', :on_or_after => '2000-01-02'
|
10
|
+
validates_time :birth_time,
|
11
|
+
:before => '23:00', :after => '09:00',
|
12
|
+
:on_or_before => '22:00', :on_or_after => '10:00'
|
13
|
+
validates_datetime :birth_date_and_time,
|
14
|
+
:before => '2000-01-10 23:00', :after => '2000-01-01 09:00',
|
15
|
+
:on_or_before => '2000-01-09 23:00', :on_or_after => '2000-01-02 09:00'
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
class CustomMessages < Person
|
20
|
+
validates_date :birth_date, :invalid_date_message => 'is not really a date',
|
21
|
+
:before => '2000-01-10', :before_message => 'is too late',
|
22
|
+
:after => '2000-01-01', :after_message => 'is too early',
|
23
|
+
:on_or_before=> '2000-01-09', :on_or_before_message => 'is just too late',
|
24
|
+
:on_or_after => '2000-01-02', :on_or_after_message => 'is just too early'
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "ValidateTimeliness matcher" do
|
28
|
+
attr_accessor :no_validation, :with_validation
|
29
|
+
|
30
|
+
before do
|
31
|
+
@no_validation = NoValidation.new
|
32
|
+
@with_validation = WithValidation.new
|
33
|
+
end
|
34
|
+
|
35
|
+
[:date, :time, :datetime].each do |type|
|
36
|
+
attribute = type == :datetime ? :date_and_time : type
|
37
|
+
|
38
|
+
it "should report that #{type} is validated" do
|
39
|
+
with_validation.should self.send("validate_#{type}", "birth_#{attribute}".to_sym)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should report that #{type} is not validated" do
|
43
|
+
no_validation.should_not self.send("validate_#{type}", "birth_#{attribute}".to_sym)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "with before option" do
|
48
|
+
test_values = {
|
49
|
+
:date => ['2000-01-10', '2000-01-11'],
|
50
|
+
:time => ['23:00', '22:59'],
|
51
|
+
:datetime => ['2000-01-10 23:00', '2000-01-10 22:59']
|
52
|
+
}
|
53
|
+
|
54
|
+
[:date, :time, :datetime].each do |type|
|
55
|
+
attribute = type == :datetime ? :date_and_time : type
|
56
|
+
|
57
|
+
it "should report that #{type} is validated" do
|
58
|
+
with_validation.should self.send("validate_#{type}", "birth_#{attribute}", :before => test_values[type][0])
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should report that #{type} is not validated when option value is incorrect" do
|
62
|
+
with_validation.should_not self.send("validate_#{type}", "birth_#{attribute}", :before => test_values[type][1])
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should report that #{type} is not validated with option" do
|
66
|
+
no_validation.should_not self.send("validate_#{type}", "birth_#{attribute}", :before => test_values[type][0])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "with after option" do
|
72
|
+
test_values = {
|
73
|
+
:date => ['2000-01-01', '2000-01-02'],
|
74
|
+
:time => ['09:00', '09:01'],
|
75
|
+
:datetime => ['2000-01-01 09:00', '2000-01-01 09:01']
|
76
|
+
}
|
77
|
+
|
78
|
+
[:date, :time, :datetime].each do |type|
|
79
|
+
attribute = type == :datetime ? :date_and_time : type
|
80
|
+
|
81
|
+
it "should report that #{type} is validated" do
|
82
|
+
with_validation.should self.send("validate_#{type}", "birth_#{attribute}", :after => test_values[type][0])
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should report that #{type} is not validated when option value is incorrect" do
|
86
|
+
with_validation.should_not self.send("validate_#{type}", "birth_#{attribute}", :after => test_values[type][1])
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should report that #{type} is not validated with option" do
|
90
|
+
no_validation.should_not self.send("validate_#{type}", "birth_#{attribute}", :after => test_values[type][0])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "with on_or_before option" do
|
96
|
+
test_values = {
|
97
|
+
:date => ['2000-01-09', '2000-01-08'],
|
98
|
+
:time => ['22:00', '21:59'],
|
99
|
+
:datetime => ['2000-01-09 23:00', '2000-01-09 22:59']
|
100
|
+
}
|
101
|
+
|
102
|
+
[:date, :time, :datetime].each do |type|
|
103
|
+
attribute = type == :datetime ? :date_and_time : type
|
104
|
+
|
105
|
+
it "should report that #{type} is validated" do
|
106
|
+
with_validation.should self.send("validate_#{type}", "birth_#{attribute}", :on_or_before => test_values[type][0])
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should report that #{type} is not validated when option value is incorrect" do
|
110
|
+
with_validation.should_not self.send("validate_#{type}", "birth_#{attribute}", :on_or_before => test_values[type][1])
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should report that #{type} is not validated with option" do
|
114
|
+
no_validation.should_not self.send("validate_#{type}", "birth_#{attribute}", :on_or_before => test_values[type][0])
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "with on_or_after option" do
|
120
|
+
test_values = {
|
121
|
+
:date => ['2000-01-02', '2000-01-03'],
|
122
|
+
:time => ['10:00', '10:01'],
|
123
|
+
:datetime => ['2000-01-02 09:00', '2000-01-02 09:01']
|
124
|
+
}
|
125
|
+
|
126
|
+
[:date, :time, :datetime].each do |type|
|
127
|
+
attribute = type == :datetime ? :date_and_time : type
|
128
|
+
|
129
|
+
it "should report that #{type} is validated" do
|
130
|
+
with_validation.should self.send("validate_#{type}", "birth_#{attribute}", :on_or_after => test_values[type][0])
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should report that #{type} is not validated when option value is incorrect" do
|
134
|
+
with_validation.should_not self.send("validate_#{type}", "birth_#{attribute}", :on_or_after => test_values[type][1])
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should report that #{type} is not validated with option" do
|
138
|
+
no_validation.should_not self.send("validate_#{type}", "birth_#{attribute}", :on_or_after => test_values[type][0])
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "custom messages" do
|
144
|
+
|
145
|
+
before do
|
146
|
+
@person = CustomMessages.new
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should match error message for invalid" do
|
150
|
+
@person.should validate_date(:birth_date, :invalid_date_message => 'is not really a date')
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should match error message for before option" do
|
154
|
+
@person.should validate_date(:birth_date, :before => '2000-01-10',
|
155
|
+
:invalid_date_message => 'is not really a date',
|
156
|
+
:before_message => 'is too late')
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should match error message for after option" do
|
160
|
+
@person.should validate_date(:birth_date, :after => '2000-01-01',
|
161
|
+
:invalid_date_message => 'is not really a date',
|
162
|
+
:after_message => 'is too early')
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should match error message for on_or_before option" do
|
166
|
+
@person.should validate_date(:birth_date, :on_or_before => '2000-01-09',
|
167
|
+
:invalid_date_message => 'is not really a date',
|
168
|
+
:on_or_before_message => 'is just too late')
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should match error message for on_or_after option" do
|
172
|
+
@person.should validate_date(:birth_date, :on_or_after => '2000-01-02',
|
173
|
+
:invalid_date_message => 'is not really a date',
|
174
|
+
:on_or_after_message => 'is just too early')
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|