adzap-validates_timeliness 1.1.1
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 +49 -0
- data/LICENSE +20 -0
- data/README.rdoc +329 -0
- data/Rakefile +58 -0
- data/TODO +7 -0
- data/lib/validates_timeliness.rb +67 -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 +309 -0
- data/lib/validates_timeliness/locale/en.yml +12 -0
- data/lib/validates_timeliness/spec/rails/matchers/validate_timeliness.rb +157 -0
- data/lib/validates_timeliness/validation_methods.rb +82 -0
- data/lib/validates_timeliness/validator.rb +163 -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 +206 -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 +475 -0
- metadata +105 -0
@@ -0,0 +1,204 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe ValidatesTimeliness::ActiveRecord::AttributeMethods do
|
4
|
+
include ValidatesTimeliness::ActiveRecord::AttributeMethods
|
5
|
+
include ValidatesTimeliness::ValidationMethods
|
6
|
+
|
7
|
+
before do
|
8
|
+
@person = Person.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should call write_date_time_attribute when date attribute assigned value" do
|
12
|
+
@person.should_receive(:write_date_time_attribute)
|
13
|
+
@person.birth_date = "2000-01-01"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should call write_date_time_attribute when time attribute assigned value" do
|
17
|
+
@person.should_receive(:write_date_time_attribute)
|
18
|
+
@person.birth_time = "12:00"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should call write_date_time_attribute when datetime attribute assigned value" do
|
22
|
+
@person.should_receive(:write_date_time_attribute)
|
23
|
+
@person.birth_date_and_time = "2000-01-01 12:00"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should call parser on write for datetime attribute" do
|
27
|
+
@person.class.should_receive(:parse_date_time).once
|
28
|
+
@person.birth_date_and_time = "2000-01-01 02:03:04"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should call parser on write for date attribute" do
|
32
|
+
@person.class.should_receive(:parse_date_time).once
|
33
|
+
@person.birth_date = "2000-01-01"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should call parser on write for time attribute" do
|
37
|
+
@person.class.should_receive(:parse_date_time).once
|
38
|
+
@person.birth_time = "12:00"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should return raw string value for attribute_before_type_cast when written as string" do
|
42
|
+
time_string = "2000-01-01 02:03:04"
|
43
|
+
@person.birth_date_and_time = time_string
|
44
|
+
@person.birth_date_and_time_before_type_cast.should == time_string
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return Time object for attribute_before_type_cast when written as Time" do
|
48
|
+
@person.birth_date_and_time = Time.mktime(2000, 1, 1, 2, 3, 4)
|
49
|
+
@person.birth_date_and_time_before_type_cast.should be_kind_of(Time)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return Time object for datetime attribute read method when assigned Time object" do
|
53
|
+
@person.birth_date_and_time = Time.now
|
54
|
+
@person.birth_date_and_time.should be_kind_of(Time)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return Time object for datetime attribute read method when assigned string" do
|
58
|
+
@person.birth_date_and_time = "2000-01-01 02:03:04"
|
59
|
+
@person.birth_date_and_time.should be_kind_of(Time)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return Date object for date attribute read method when assigned Date object" do
|
63
|
+
@person.birth_date = Date.today
|
64
|
+
@person.birth_date.should be_kind_of(Date)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should return Date object for date attribute read method when assigned string" do
|
68
|
+
@person.birth_date = '2000-01-01'
|
69
|
+
@person.birth_date.should be_kind_of(Date)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should return nil when time is invalid" do
|
73
|
+
@person.birth_date_and_time = "2000-01-32 02:03:04"
|
74
|
+
@person.birth_date_and_time.should be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not save invalid date value to database" do
|
78
|
+
time_string = "2000-01-32 02:03:04"
|
79
|
+
@person = Person.new
|
80
|
+
@person.birth_date_and_time = time_string
|
81
|
+
@person.save
|
82
|
+
@person.reload
|
83
|
+
@person.birth_date_and_time_before_type_cast.should be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
unless RAILS_VER < '2.1'
|
87
|
+
it "should return stored time string as Time with correct timezone" do
|
88
|
+
Time.zone = 'Melbourne'
|
89
|
+
time_string = "2000-06-01 02:03:04"
|
90
|
+
@person.birth_date_and_time = time_string
|
91
|
+
@person.birth_date_and_time.strftime('%Y-%m-%d %H:%M:%S %Z %z').should == time_string + ' EST +1000'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should return time object from database in correct timezone" do
|
95
|
+
Time.zone = 'Melbourne'
|
96
|
+
time_string = "2000-06-01 09:00:00"
|
97
|
+
@person = Person.new
|
98
|
+
@person.birth_date_and_time = time_string
|
99
|
+
@person.save
|
100
|
+
@person.reload
|
101
|
+
@person.birth_date_and_time.strftime('%Y-%m-%d %H:%M:%S %Z %z').should == time_string + ' EST +1000'
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "dirty attributes" do
|
105
|
+
|
106
|
+
it "should return true for attribute changed? when value updated" do
|
107
|
+
time_string = "2000-01-01 02:03:04"
|
108
|
+
@person.birth_date_and_time = time_string
|
109
|
+
@person.birth_date_and_time_changed?.should be_true
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should show changes when time attribute changed from nil to Time object" do
|
113
|
+
time_string = "2000-01-01 02:03:04"
|
114
|
+
@person.birth_date_and_time = time_string
|
115
|
+
time = @person.birth_date_and_time
|
116
|
+
@person.changes.should == {"birth_date_and_time" => [nil, time]}
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should show changes when time attribute changed from Time object to nil" do
|
120
|
+
time_string = "2020-01-01 02:03:04"
|
121
|
+
@person.birth_date_and_time = time_string
|
122
|
+
@person.save false
|
123
|
+
@person.reload
|
124
|
+
time = @person.birth_date_and_time
|
125
|
+
@person.birth_date_and_time = nil
|
126
|
+
@person.changes.should == {"birth_date_and_time" => [time, nil]}
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should show no changes when assigned same value as Time object" do
|
130
|
+
time_string = "2020-01-01 02:03:04"
|
131
|
+
@person.birth_date_and_time = time_string
|
132
|
+
@person.save false
|
133
|
+
@person.reload
|
134
|
+
time = @person.birth_date_and_time
|
135
|
+
@person.birth_date_and_time = time
|
136
|
+
@person.changes.should == {}
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should show no changes when assigned same value as time string" do
|
140
|
+
time_string = "2020-01-01 02:03:04"
|
141
|
+
@person.birth_date_and_time = time_string
|
142
|
+
@person.save false
|
143
|
+
@person.reload
|
144
|
+
@person.birth_date_and_time = time_string
|
145
|
+
@person.changes.should == {}
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
else
|
150
|
+
|
151
|
+
it "should return time object from database in default timezone" do
|
152
|
+
ActiveRecord::Base.default_timezone = :utc
|
153
|
+
time_string = "2000-01-01 09:00:00"
|
154
|
+
@person = Person.new
|
155
|
+
@person.birth_date_and_time = time_string
|
156
|
+
@person.save
|
157
|
+
@person.reload
|
158
|
+
@person.birth_date_and_time.strftime('%Y-%m-%d %H:%M:%S %Z').should == time_string + ' GMT'
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should return same time object on repeat reads on existing object" do
|
164
|
+
Time.zone = 'Melbourne' unless RAILS_VER < '2.1'
|
165
|
+
time_string = "2000-01-01 09:00:00"
|
166
|
+
@person = Person.new
|
167
|
+
@person.birth_date_and_time = time_string
|
168
|
+
@person.save!
|
169
|
+
@person.reload
|
170
|
+
time = @person.birth_date_and_time
|
171
|
+
@person.birth_date_and_time.should == time
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should return same date object on repeat reads on existing object" do
|
175
|
+
date_string = Date.today
|
176
|
+
@person = Person.new
|
177
|
+
@person.birth_date = date_string
|
178
|
+
@person.save!
|
179
|
+
@person.reload
|
180
|
+
date = @person.birth_date
|
181
|
+
@person.birth_date.should == date
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should return correct date value after new value assigned" do
|
185
|
+
today = Date.today
|
186
|
+
tomorrow = Date.today + 1.day
|
187
|
+
@person = Person.new
|
188
|
+
@person.birth_date = today
|
189
|
+
@person.birth_date.should == today
|
190
|
+
@person.birth_date = tomorrow
|
191
|
+
@person.birth_date.should == tomorrow
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should update date attribute on existing object" do
|
195
|
+
today = Date.today
|
196
|
+
tomorrow = Date.today + 1.day
|
197
|
+
@person = Person.create(:birth_date => today)
|
198
|
+
@person.birth_date = tomorrow
|
199
|
+
@person.save!
|
200
|
+
@person.reload
|
201
|
+
@person.birth_date.should == tomorrow
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
@@ -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
|