validates_timeliness 3.0.0.beta.4 → 3.0.0.beta.5
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 +3 -1
- data/README.rdoc +16 -13
- data/Rakefile +1 -0
- data/lib/generators/validates_timeliness/templates/validates_timeliness.rb +7 -4
- data/lib/validates_timeliness.rb +23 -19
- data/lib/validates_timeliness/attribute_methods.rb +1 -1
- data/lib/validates_timeliness/conversion.rb +4 -4
- data/lib/validates_timeliness/orm/mongoid.rb +1 -1
- data/lib/validates_timeliness/railtie.rb +14 -0
- data/lib/validates_timeliness/validator.rb +9 -4
- data/lib/validates_timeliness/version.rb +1 -1
- data/spec/validates_timeliness/attribute_methods_spec.rb +3 -3
- data/spec/validates_timeliness/conversion_spec.rb +4 -4
- data/spec/validates_timeliness/helper_methods_spec.rb +3 -3
- data/spec/validates_timeliness/orm/active_record_spec.rb +5 -5
- data/spec/validates_timeliness/orm/mongoid_spec.rb +14 -6
- data/spec/validates_timeliness/validator_spec.rb +5 -2
- data/validates_timeliness.gemspec +6 -3
- metadata +22 -8
- data/lib/validates_timeliness/parser.rb +0 -404
- data/spec/validates_timeliness/parser_spec.rb +0 -331
@@ -1,331 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ValidatesTimeliness::Parser do
|
4
|
-
|
5
|
-
describe "format proc generator" do
|
6
|
-
it "should generate proc which outputs date array with values in correct order" do
|
7
|
-
generate_method('yyyy-mm-dd').call('2000', '1', '2').should == [2000,1,2,0,0,0,0]
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should generate proc which outputs date array from format with different order" do
|
11
|
-
generate_method('dd/mm/yyyy').call('2', '1', '2000').should == [2000,1,2,0,0,0,0]
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should generate proc which outputs time array" do
|
15
|
-
generate_method('hh:nn:ss').call('01', '02', '03').should == [0,0,0,1,2,3,0]
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should generate proc which outputs time array with meridian 'pm' adjusted hour" do
|
19
|
-
generate_method('hh:nn:ss ampm').call('01', '02', '03', 'pm').should == [0,0,0,13,2,3,0]
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should generate proc which outputs time array with meridian 'am' unadjusted hour" do
|
23
|
-
generate_method('hh:nn:ss ampm').call('01', '02', '03', 'am').should == [0,0,0,1,2,3,0]
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should generate proc which outputs time array with microseconds" do
|
27
|
-
generate_method('hh:nn:ss.u').call('01', '02', '03', '99').should == [0,0,0,1,2,3,990000]
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should generate proc which outputs datetime array with zone offset" do
|
31
|
-
generate_method('yyyy-mm-dd hh:nn:ss.u zo').call('2001', '02', '03', '04', '05', '06', '99', '+10:00').should == [2001,2,3,4,5,6,990000,36000]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "validate regexps" do
|
36
|
-
|
37
|
-
describe "for time formats" do
|
38
|
-
format_tests = {
|
39
|
-
'hh:nn:ss' => {:pass => ['12:12:12', '01:01:01'], :fail => ['1:12:12', '12:1:12', '12:12:1', '12-12-12']},
|
40
|
-
'hh-nn-ss' => {:pass => ['12-12-12', '01-01-01'], :fail => ['1-12-12', '12-1-12', '12-12-1', '12:12:12']},
|
41
|
-
'h:nn' => {:pass => ['12:12', '1:01'], :fail => ['12:2', '12-12']},
|
42
|
-
'h.nn' => {:pass => ['2.12', '12.12'], :fail => ['2.1', '12:12']},
|
43
|
-
'h nn' => {:pass => ['2 12', '12 12'], :fail => ['2 1', '2.12', '12:12']},
|
44
|
-
'h-nn' => {:pass => ['2-12', '12-12'], :fail => ['2-1', '2.12', '12:12']},
|
45
|
-
'h:nn_ampm' => {:pass => ['2:12am', '2:12 pm', '2:12 AM', '2:12PM'], :fail => ['1:2am', '1:12 pm', '2.12am']},
|
46
|
-
'h.nn_ampm' => {:pass => ['2.12am', '2.12 pm'], :fail => ['1:2am', '1:12 pm', '2:12am']},
|
47
|
-
'h nn_ampm' => {:pass => ['2 12am', '2 12 pm'], :fail => ['1 2am', '1 12 pm', '2:12am']},
|
48
|
-
'h-nn_ampm' => {:pass => ['2-12am', '2-12 pm'], :fail => ['1-2am', '1-12 pm', '2:12am']},
|
49
|
-
'h_ampm' => {:pass => ['2am', '2 am', '12 pm'], :fail => ['1.am', '12 pm', '2:12am']},
|
50
|
-
}
|
51
|
-
format_tests.each do |format, values|
|
52
|
-
it "should correctly validate times in format '#{format}'" do
|
53
|
-
regexp = generate_regexp(format)
|
54
|
-
values[:pass].each {|value| value.should match(regexp)}
|
55
|
-
values[:fail].each {|value| value.should_not match(regexp)}
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe "for date formats" do
|
61
|
-
format_tests = {
|
62
|
-
'yyyy/mm/dd' => {:pass => ['2000/02/01'], :fail => ['2000\02\01', '2000/2/1', '00/02/01']},
|
63
|
-
'yyyy-mm-dd' => {:pass => ['2000-02-01'], :fail => ['2000\02\01', '2000-2-1', '00-02-01']},
|
64
|
-
'yyyy.mm.dd' => {:pass => ['2000.02.01'], :fail => ['2000\02\01', '2000.2.1', '00.02.01']},
|
65
|
-
'm/d/yy' => {:pass => ['2/1/01', '02/01/00', '02/01/2000'], :fail => ['2/1/0', '2.1.01']},
|
66
|
-
'd/m/yy' => {:pass => ['1/2/01', '01/02/00', '01/02/2000'], :fail => ['1/2/0', '1.2.01']},
|
67
|
-
'm\d\yy' => {:pass => ['2\1\01', '2\01\00', '02\01\2000'], :fail => ['2\1\0', '2/1/01']},
|
68
|
-
'd\m\yy' => {:pass => ['1\2\01', '1\02\00', '01\02\2000'], :fail => ['1\2\0', '1/2/01']},
|
69
|
-
'd-m-yy' => {:pass => ['1-2-01', '1-02-00', '01-02-2000'], :fail => ['1-2-0', '1/2/01']},
|
70
|
-
'd.m.yy' => {:pass => ['1.2.01', '1.02.00', '01.02.2000'], :fail => ['1.2.0', '1/2/01']},
|
71
|
-
'd mmm yy' => {:pass => ['1 Feb 00', '1 Feb 2000', '1 February 00', '01 February 2000'],
|
72
|
-
:fail => ['1 Fe 00', 'Feb 1 2000', '1 Feb 0']}
|
73
|
-
}
|
74
|
-
format_tests.each do |format, values|
|
75
|
-
it "should correctly validate dates in format '#{format}'" do
|
76
|
-
regexp = generate_regexp(format)
|
77
|
-
values[:pass].each {|value| value.should match(regexp)}
|
78
|
-
values[:fail].each {|value| value.should_not match(regexp)}
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe "for datetime formats" do
|
84
|
-
format_tests = {
|
85
|
-
'ddd mmm d hh:nn:ss zo yyyy' => {:pass => ['Sat Jul 19 12:00:00 +1000 2008'], :fail => []},
|
86
|
-
'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']},
|
87
|
-
}
|
88
|
-
format_tests.each do |format, values|
|
89
|
-
it "should correctly validate datetimes in format '#{format}'" do
|
90
|
-
regexp = generate_regexp(format)
|
91
|
-
values[:pass].each {|value| value.should match(regexp)}
|
92
|
-
values[:fail].each {|value| value.should_not match(regexp)}
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
describe "_parse" do
|
99
|
-
|
100
|
-
it "should return time array from date string" do
|
101
|
-
time_array = formats._parse('12:13:14', :time, :strict => true)
|
102
|
-
time_array.should == [2000,1,1,12,13,14,0]
|
103
|
-
end
|
104
|
-
|
105
|
-
it "should return nil if time hour is out of range for AM meridian" do
|
106
|
-
time_array = formats._parse('13:14 am', :time, :strict => true)
|
107
|
-
time_array.should == nil
|
108
|
-
time_array = formats._parse('00:14 am', :time, :strict => true)
|
109
|
-
time_array.should == nil
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should return date array from time string" do
|
113
|
-
time_array = formats._parse('2000-02-01', :date, :strict => true)
|
114
|
-
time_array.should == [2000,2,1,0,0,0,0]
|
115
|
-
end
|
116
|
-
|
117
|
-
it "should return datetime array from string value" do
|
118
|
-
time_array = formats._parse('2000-02-01 12:13:14', :datetime, :strict => true)
|
119
|
-
time_array.should == [2000,2,1,12,13,14,0]
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should parse date string when type is datetime" do
|
123
|
-
time_array = formats._parse('2000-02-01', :datetime, :strict => false)
|
124
|
-
time_array.should == [2000,2,1,0,0,0,0]
|
125
|
-
end
|
126
|
-
|
127
|
-
it "should ignore time when extracting date and strict is false" do
|
128
|
-
time_array = formats._parse('2000-02-01 12:13', :date, :strict => false)
|
129
|
-
time_array.should == [2000,2,1,0,0,0,0]
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should ignore time when extracting date from format with trailing year and strict is false" do
|
133
|
-
time_array = formats._parse('01-02-2000 12:13', :date, :strict => false)
|
134
|
-
time_array.should == [2000,2,1,0,0,0,0]
|
135
|
-
end
|
136
|
-
|
137
|
-
it "should ignore date when extracting time and strict is false" do
|
138
|
-
time_array = formats._parse('2000-02-01 12:13', :time, :strict => false)
|
139
|
-
time_array.should == [2000,1,1,12,13,0,0]
|
140
|
-
end
|
141
|
-
|
142
|
-
it "should return zone offset when :include_offset option is true" do
|
143
|
-
time_array = formats._parse('2000-02-01T12:13:14-10:30', :datetime, :include_offset => true)
|
144
|
-
time_array.should == [2000,2,1,12,13,14,0,-37800]
|
145
|
-
end
|
146
|
-
|
147
|
-
context "with format option" do
|
148
|
-
it "should return values if string matches specified format" do
|
149
|
-
time_array = formats._parse('2000-02-01 12:13:14', :datetime, :format => 'yyyy-mm-dd hh:nn:ss')
|
150
|
-
time_array.should == [2000,2,1,12,13,14,0]
|
151
|
-
end
|
152
|
-
|
153
|
-
it "should return nil if string does not match specified format" do
|
154
|
-
time_array = formats._parse('2000-02-01 12:13', :datetime, :format => 'yyyy-mm-dd hh:nn:ss')
|
155
|
-
time_array.should be_nil
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
context "date with ambiguous year" do
|
160
|
-
it "should return year in current century if year below threshold" do
|
161
|
-
time_array = formats._parse('01-02-29', :date)
|
162
|
-
time_array.should == [2029,2,1,0,0,0,0]
|
163
|
-
end
|
164
|
-
|
165
|
-
it "should return year in last century if year at or above threshold" do
|
166
|
-
time_array = formats._parse('01-02-30', :date)
|
167
|
-
time_array.should == [1930,2,1,0,0,0,0]
|
168
|
-
end
|
169
|
-
|
170
|
-
it "should allow custom threshold" do
|
171
|
-
default = ValidatesTimeliness::Parser.ambiguous_year_threshold
|
172
|
-
ValidatesTimeliness::Parser.ambiguous_year_threshold = 40
|
173
|
-
time_array = formats._parse('01-02-39', :date)
|
174
|
-
time_array.should == [2039,2,1,0,0,0,0]
|
175
|
-
time_array = formats._parse('01-02-40', :date)
|
176
|
-
time_array.should == [1940,2,1,0,0,0,0]
|
177
|
-
ValidatesTimeliness::Parser.ambiguous_year_threshold = default
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
describe "parse" do
|
183
|
-
it "should return time object for valid time string" do
|
184
|
-
parse("2000-01-01 12:13:14", :datetime).should be_kind_of(Time)
|
185
|
-
end
|
186
|
-
|
187
|
-
it "should return nil for time string with invalid date part" do
|
188
|
-
parse("2000-02-30 12:13:14", :datetime).should be_nil
|
189
|
-
end
|
190
|
-
|
191
|
-
it "should return nil for time string with invalid time part" do
|
192
|
-
parse("2000-02-01 25:13:14", :datetime).should be_nil
|
193
|
-
end
|
194
|
-
|
195
|
-
it "should return Time object when passed a Time object" do
|
196
|
-
parse(Time.now, :datetime).should be_kind_of(Time)
|
197
|
-
end
|
198
|
-
|
199
|
-
it "should convert time string into current timezone" do
|
200
|
-
Time.zone = 'Melbourne'
|
201
|
-
time = parse("2000-01-01 12:13:14", :datetime, :timezone_aware => true)
|
202
|
-
Time.zone.utc_offset.should == 10.hours
|
203
|
-
end
|
204
|
-
|
205
|
-
it "should return nil for invalid date string" do
|
206
|
-
parse("2000-02-30", :date).should be_nil
|
207
|
-
end
|
208
|
-
|
209
|
-
def parse(*args)
|
210
|
-
ValidatesTimeliness::Parser.parse(*args)
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
describe "make_time" do
|
215
|
-
it "should create time using current timezone" do
|
216
|
-
time = ValidatesTimeliness::Parser.make_time([2000,1,1,12,0,0])
|
217
|
-
time.zone.should == "UTC"
|
218
|
-
end
|
219
|
-
|
220
|
-
it "should create time using current timezone" do
|
221
|
-
Time.zone = 'Melbourne'
|
222
|
-
time = ValidatesTimeliness::Parser.make_time([2000,1,1,12,0,0], true)
|
223
|
-
time.zone.should == "EST"
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
describe "removing formats" do
|
228
|
-
it "should remove format from format array" do
|
229
|
-
formats.remove_formats(:time, 'h.nn_ampm')
|
230
|
-
formats.time_formats.should_not include("h o'clock")
|
231
|
-
end
|
232
|
-
|
233
|
-
it "should not match time after its format is removed" do
|
234
|
-
validate('2.12am', :time).should be_true
|
235
|
-
formats.remove_formats(:time, 'h.nn_ampm')
|
236
|
-
validate('2.12am', :time).should be_false
|
237
|
-
end
|
238
|
-
|
239
|
-
it "should raise error if format does not exist" do
|
240
|
-
lambda { formats.remove_formats(:time, "ss:hh:nn") }.should raise_error()
|
241
|
-
end
|
242
|
-
|
243
|
-
after do
|
244
|
-
formats.time_formats << 'h.nn_ampm'
|
245
|
-
formats.compile_format_expressions
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
describe "adding formats" do
|
250
|
-
before do
|
251
|
-
formats.compile_format_expressions
|
252
|
-
end
|
253
|
-
|
254
|
-
it "should add format to format array" do
|
255
|
-
formats.add_formats(:time, "h o'clock")
|
256
|
-
formats.time_formats.should include("h o'clock")
|
257
|
-
end
|
258
|
-
|
259
|
-
it "should match new format after its added" do
|
260
|
-
validate("12 o'clock", :time).should be_false
|
261
|
-
formats.add_formats(:time, "h o'clock")
|
262
|
-
validate("12 o'clock", :time).should be_true
|
263
|
-
end
|
264
|
-
|
265
|
-
it "should add format before specified format and be higher precedence" do
|
266
|
-
formats.add_formats(:time, "ss:hh:nn", :before => 'hh:nn:ss')
|
267
|
-
validate("59:23:58", :time).should be_true
|
268
|
-
time_array = formats._parse('59:23:58', :time)
|
269
|
-
time_array.should == [2000,1,1,23,58,59,0]
|
270
|
-
end
|
271
|
-
|
272
|
-
it "should raise error if format exists" do
|
273
|
-
lambda { formats.add_formats(:time, "hh:nn:ss") }.should raise_error()
|
274
|
-
end
|
275
|
-
|
276
|
-
it "should raise error if format exists" do
|
277
|
-
lambda { formats.add_formats(:time, "ss:hh:nn", :before => 'nn:hh:ss') }.should raise_error()
|
278
|
-
end
|
279
|
-
|
280
|
-
after do
|
281
|
-
formats.time_formats.delete("h o'clock")
|
282
|
-
formats.time_formats.delete("ss:hh:nn")
|
283
|
-
# reload class instead
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
describe "removing US formats" do
|
288
|
-
it "should validate a date as European format when US formats removed" do
|
289
|
-
time_array = formats._parse('01/02/2000', :date)
|
290
|
-
time_array.should == [2000, 1, 2,0,0,0,0]
|
291
|
-
formats.remove_us_formats
|
292
|
-
time_array = formats._parse('01/02/2000', :date)
|
293
|
-
time_array.should == [2000, 2, 1,0,0,0,0]
|
294
|
-
end
|
295
|
-
|
296
|
-
after do
|
297
|
-
# reload class
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
|
302
|
-
def formats
|
303
|
-
ValidatesTimeliness::Parser
|
304
|
-
end
|
305
|
-
|
306
|
-
def validate(time_string, type)
|
307
|
-
valid = false
|
308
|
-
formats.send("#{type}_expressions").each do |format, regexp, processor|
|
309
|
-
valid = true and break if /\A#{regexp}\Z/ =~ time_string
|
310
|
-
end
|
311
|
-
valid
|
312
|
-
end
|
313
|
-
|
314
|
-
def generate_regexp(format)
|
315
|
-
# wrap in line start and end anchors to emulate extract values method
|
316
|
-
/\A#{formats.send(:generate_format_expression, format)}\Z/
|
317
|
-
end
|
318
|
-
|
319
|
-
def generate_regexp_str(format)
|
320
|
-
formats.send(:generate_format_expression, format).inspect
|
321
|
-
end
|
322
|
-
|
323
|
-
def generate_method(format)
|
324
|
-
formats.send(:generate_format_expression, format)
|
325
|
-
ValidatesTimeliness::Parser.method(:"format_#{format}")
|
326
|
-
end
|
327
|
-
|
328
|
-
def delete_format(type, format)
|
329
|
-
formats.send("#{type}_formats").delete(format)
|
330
|
-
end
|
331
|
-
end
|