adzap-validates_timeliness 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/CHANGELOG +49 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +329 -0
  4. data/Rakefile +58 -0
  5. data/TODO +7 -0
  6. data/lib/validates_timeliness.rb +67 -0
  7. data/lib/validates_timeliness/action_view/instance_tag.rb +45 -0
  8. data/lib/validates_timeliness/active_record/attribute_methods.rb +157 -0
  9. data/lib/validates_timeliness/active_record/multiparameter_attributes.rb +64 -0
  10. data/lib/validates_timeliness/core_ext/date.rb +13 -0
  11. data/lib/validates_timeliness/core_ext/date_time.rb +13 -0
  12. data/lib/validates_timeliness/core_ext/time.rb +13 -0
  13. data/lib/validates_timeliness/formats.rb +309 -0
  14. data/lib/validates_timeliness/locale/en.yml +12 -0
  15. data/lib/validates_timeliness/spec/rails/matchers/validate_timeliness.rb +157 -0
  16. data/lib/validates_timeliness/validation_methods.rb +82 -0
  17. data/lib/validates_timeliness/validator.rb +163 -0
  18. data/spec/action_view/instance_tag_spec.rb +38 -0
  19. data/spec/active_record/attribute_methods_spec.rb +204 -0
  20. data/spec/active_record/multiparameter_attributes_spec.rb +48 -0
  21. data/spec/core_ext/dummy_time_spec.rb +31 -0
  22. data/spec/formats_spec.rb +274 -0
  23. data/spec/ginger_scenarios.rb +19 -0
  24. data/spec/resources/application.rb +2 -0
  25. data/spec/resources/person.rb +3 -0
  26. data/spec/resources/schema.rb +10 -0
  27. data/spec/resources/sqlite_patch.rb +19 -0
  28. data/spec/spec/rails/matchers/validate_timeliness_spec.rb +206 -0
  29. data/spec/spec_helper.rb +54 -0
  30. data/spec/time_travel/MIT-LICENSE +20 -0
  31. data/spec/time_travel/time_extensions.rb +33 -0
  32. data/spec/time_travel/time_travel.rb +12 -0
  33. data/spec/validation_methods_spec.rb +61 -0
  34. data/spec/validator_spec.rb +475 -0
  35. 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