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.
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