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,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,2 @@
1
+ class ApplicationController; end
2
+
@@ -0,0 +1,3 @@
1
+ class Person < ActiveRecord::Base
2
+ set_table_name 'people'
3
+ end
@@ -0,0 +1,10 @@
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+
3
+ create_table "people", :force => true do |t|
4
+ t.column "name", :string
5
+ t.column "birth_date_and_time", :datetime
6
+ t.column "birth_date", :date
7
+ t.column "birth_time", :time
8
+ end
9
+
10
+ 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,206 @@
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
+ :between => ['2000-01-01', '2000-01-03']
11
+
12
+ validates_time :birth_time,
13
+ :before => '23:00', :after => '09:00',
14
+ :on_or_before => '22:00', :on_or_after => '10:00',
15
+ :between => ['09:00', '17:00']
16
+ validates_datetime :birth_date_and_time,
17
+ :before => '2000-01-10 23:00', :after => '2000-01-01 09:00',
18
+ :on_or_before => '2000-01-09 23:00', :on_or_after => '2000-01-02 09:00',
19
+ :between => ['2000-01-01 09:00', '2000-01-01 17:00']
20
+
21
+ end
22
+
23
+ class CustomMessages < Person
24
+ validates_date :birth_date, :invalid_date_message => 'is not really a date',
25
+ :before => '2000-01-10', :before_message => 'is too late',
26
+ :after => '2000-01-01', :after_message => 'is too early',
27
+ :on_or_before=> '2000-01-09', :on_or_before_message => 'is just too late',
28
+ :on_or_after => '2000-01-02', :on_or_after_message => 'is just too early'
29
+ end
30
+
31
+ describe "ValidateTimeliness matcher" do
32
+ attr_accessor :no_validation, :with_validation
33
+
34
+ @@attribute_for_type = { :date => :birth_date, :time => :birth_time, :datetime => :birth_date_and_time }
35
+
36
+ before do
37
+ @no_validation = NoValidation.new
38
+ @with_validation = WithValidation.new
39
+ end
40
+
41
+ [:date, :time, :datetime].each do |type|
42
+
43
+ it "should report that #{type} is validated" do
44
+ with_validation.should self.send("validate_#{type}", attribute_for_type(type))
45
+ end
46
+
47
+ it "should report that #{type} is not validated" do
48
+ no_validation.should_not self.send("validate_#{type}", attribute_for_type(type))
49
+ end
50
+ end
51
+
52
+ describe "with before option" do
53
+ test_values = {
54
+ :date => ['2000-01-10', '2000-01-11'],
55
+ :time => ['23:00', '22:59'],
56
+ :datetime => ['2000-01-10 23:00', '2000-01-10 22:59']
57
+ }
58
+
59
+ [:date, :time, :datetime].each do |type|
60
+
61
+ it "should report that #{type} is validated" do
62
+ with_validation.should self.send("validate_#{type}", attribute_for_type(type), :before => test_values[type][0])
63
+ end
64
+
65
+ it "should report that #{type} is not validated when option value is incorrect" do
66
+ with_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :before => test_values[type][1])
67
+ end
68
+
69
+ it "should report that #{type} is not validated with option" do
70
+ no_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :before => test_values[type][0])
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "with after option" do
76
+ test_values = {
77
+ :date => ['2000-01-01', '2000-01-02'],
78
+ :time => ['09:00', '09:01'],
79
+ :datetime => ['2000-01-01 09:00', '2000-01-01 09:01']
80
+ }
81
+
82
+ [:date, :time, :datetime].each do |type|
83
+
84
+ it "should report that #{type} is validated" do
85
+ with_validation.should self.send("validate_#{type}", attribute_for_type(type), :after => test_values[type][0])
86
+ end
87
+
88
+ it "should report that #{type} is not validated when option value is incorrect" do
89
+ with_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :after => test_values[type][1])
90
+ end
91
+
92
+ it "should report that #{type} is not validated with option" do
93
+ no_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :after => test_values[type][0])
94
+ end
95
+ end
96
+ end
97
+
98
+ describe "with on_or_before option" do
99
+ test_values = {
100
+ :date => ['2000-01-09', '2000-01-08'],
101
+ :time => ['22:00', '21:59'],
102
+ :datetime => ['2000-01-09 23:00', '2000-01-09 22:59']
103
+ }
104
+
105
+ [:date, :time, :datetime].each do |type|
106
+
107
+ it "should report that #{type} is validated" do
108
+ with_validation.should self.send("validate_#{type}", attribute_for_type(type), :on_or_before => test_values[type][0])
109
+ end
110
+
111
+ it "should report that #{type} is not validated when option value is incorrect" do
112
+ with_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :on_or_before => test_values[type][1])
113
+ end
114
+
115
+ it "should report that #{type} is not validated with option" do
116
+ no_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :on_or_before => test_values[type][0])
117
+ end
118
+ end
119
+ end
120
+
121
+ describe "with on_or_after option" do
122
+ test_values = {
123
+ :date => ['2000-01-02', '2000-01-03'],
124
+ :time => ['10:00', '10:01'],
125
+ :datetime => ['2000-01-02 09:00', '2000-01-02 09:01']
126
+ }
127
+
128
+ [:date, :time, :datetime].each do |type|
129
+
130
+ it "should report that #{type} is validated" do
131
+ with_validation.should self.send("validate_#{type}", attribute_for_type(type), :on_or_after => test_values[type][0])
132
+ end
133
+
134
+ it "should report that #{type} is not validated when option value is incorrect" do
135
+ with_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :on_or_after => test_values[type][1])
136
+ end
137
+
138
+ it "should report that #{type} is not validated with option" do
139
+ no_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :on_or_after => test_values[type][0])
140
+ end
141
+ end
142
+ end
143
+
144
+ describe "between option" do
145
+ test_values = {
146
+ :date => [ ['2000-01-01', '2000-01-03'], ['2000-01-01', '2000-01-04'] ],
147
+ :time => [ ['09:00', '17:00'], ['09:00', '17:01'] ],
148
+ :datetime => [ ['2000-01-01 09:00', '2000-01-01 17:00'], ['2000-01-01 09:00', '2000-01-01 17:01'] ]
149
+ }
150
+
151
+ [:date, :time, :datetime].each do |type|
152
+
153
+ it "should report that #{type} is validated" do
154
+ with_validation.should self.send("validate_#{type}", attribute_for_type(type), :between => test_values[type][0])
155
+ end
156
+
157
+ it "should report that #{type} is not validated when option value is incorrect" do
158
+ with_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :between => test_values[type][1])
159
+ end
160
+
161
+ it "should report that #{type} is not validated with option" do
162
+ no_validation.should_not self.send("validate_#{type}", attribute_for_type(type), :between => test_values[type][0])
163
+ end
164
+ end
165
+ end
166
+
167
+ describe "custom messages" do
168
+
169
+ before do
170
+ @person = CustomMessages.new
171
+ end
172
+
173
+ it "should match error message for invalid" do
174
+ @person.should validate_date(:birth_date, :invalid_date_message => 'is not really a date')
175
+ end
176
+
177
+ it "should match error message for before option" do
178
+ @person.should validate_date(:birth_date, :before => '2000-01-10',
179
+ :invalid_date_message => 'is not really a date',
180
+ :before_message => 'is too late')
181
+ end
182
+
183
+ it "should match error message for after option" do
184
+ @person.should validate_date(:birth_date, :after => '2000-01-01',
185
+ :invalid_date_message => 'is not really a date',
186
+ :after_message => 'is too early')
187
+ end
188
+
189
+ it "should match error message for on_or_before option" do
190
+ @person.should validate_date(:birth_date, :on_or_before => '2000-01-09',
191
+ :invalid_date_message => 'is not really a date',
192
+ :on_or_before_message => 'is just too late')
193
+ end
194
+
195
+ it "should match error message for on_or_after option" do
196
+ @person.should validate_date(:birth_date, :on_or_after => '2000-01-02',
197
+ :invalid_date_message => 'is not really a date',
198
+ :on_or_after_message => 'is just too early')
199
+ end
200
+
201
+ end
202
+
203
+ def attribute_for_type(type)
204
+ @@attribute_for_type[type.to_sym]
205
+ end
206
+ end
@@ -0,0 +1,54 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ $:.unshift(File.dirname(__FILE__))
3
+ $:.unshift(File.dirname(__FILE__) + '/resources')
4
+
5
+ ENV['RAILS_ENV'] = 'test'
6
+
7
+ require 'rubygems'
8
+ require 'spec'
9
+
10
+ vendored_rails = File.dirname(__FILE__) + '/../../../../vendor/rails'
11
+
12
+ if vendored = File.exists?(vendored_rails)
13
+ Dir.glob(vendored_rails + "/**/lib").each { |dir| $:.unshift dir }
14
+ else
15
+ begin
16
+ require 'ginger'
17
+ rescue LoadError
18
+ end
19
+ if ENV['VERSION']
20
+ gem 'rails', ENV['VERSION']
21
+ else
22
+ gem 'rails'
23
+ end
24
+ end
25
+
26
+ RAILS_ROOT = File.dirname(__FILE__)
27
+
28
+ require 'rails/version'
29
+ require 'active_record'
30
+ require 'active_record/version'
31
+ require 'action_controller'
32
+ require 'action_view'
33
+
34
+ require 'spec/rails'
35
+ require 'time_travel/time_travel'
36
+
37
+ ActiveRecord::Base.default_timezone = :utc
38
+ RAILS_VER = Rails::VERSION::STRING
39
+ puts "Using #{vendored ? 'vendored' : 'gem'} Rails version #{RAILS_VER} (ActiveRecord version #{ActiveRecord::VERSION::STRING})"
40
+
41
+ require 'validates_timeliness'
42
+
43
+ if RAILS_VER >= '2.1'
44
+ Time.zone_default = ActiveSupport::TimeZone['UTC']
45
+ ActiveRecord::Base.time_zone_aware_attributes = true
46
+ end
47
+
48
+ ActiveRecord::Migration.verbose = false
49
+ ActiveRecord::Base.establish_connection({:adapter => 'sqlite3', :database => ':memory:'})
50
+
51
+ require 'sqlite_patch' if RAILS_VER < '2.1'
52
+
53
+ require 'schema'
54
+ require 'person'
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Peter Yandell
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,33 @@
1
+ require 'time'
2
+
3
+ module TimeTravel
4
+ module TimeExtensions
5
+
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ base.class_eval do
9
+ class << self
10
+ alias_method :immutable_now, :now
11
+ alias_method :now, :mutable_now
12
+ end
13
+ end
14
+ base.now = nil
15
+ end
16
+
17
+ module ClassMethods
18
+
19
+ @@now = nil
20
+
21
+ def now=(time)
22
+ time = Time.parse(time) if time.instance_of?(String)
23
+ @@now = time
24
+ end
25
+
26
+ def mutable_now #:nodoc:
27
+ @@now || immutable_now
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ require 'time_travel/time_extensions'
2
+
3
+ Time.send(:include, TimeTravel::TimeExtensions)
4
+
5
+ def at_time(time)
6
+ Time.now = time
7
+ begin
8
+ yield
9
+ ensure
10
+ Time.now = nil
11
+ end
12
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe ValidatesTimeliness::ValidationMethods do
4
+ attr_accessor :person
5
+
6
+ describe "parse_date_time" do
7
+ it "should return time object for valid time string" do
8
+ parse_method("2000-01-01 12:13:14", :datetime).should be_kind_of(Time)
9
+ end
10
+
11
+ it "should return nil for time string with invalid date part" do
12
+ parse_method("2000-02-30 12:13:14", :datetime).should be_nil
13
+ end
14
+
15
+ it "should return nil for time string with invalid time part" do
16
+ parse_method("2000-02-01 25:13:14", :datetime).should be_nil
17
+ end
18
+
19
+ it "should return Time object when passed a Time object" do
20
+ parse_method(Time.now, :datetime).should be_kind_of(Time)
21
+ end
22
+
23
+ if RAILS_VER >= '2.1'
24
+ it "should convert time string into current timezone" do
25
+ Time.zone = 'Melbourne'
26
+ time = parse_method("2000-01-01 12:13:14", :datetime)
27
+ Time.zone.utc_offset.should == 10.hours
28
+ end
29
+ end
30
+
31
+ it "should return nil for invalid date string" do
32
+ parse_method("2000-02-30", :date).should be_nil
33
+ end
34
+
35
+ def parse_method(*args)
36
+ ActiveRecord::Base.parse_date_time(*args)
37
+ end
38
+ end
39
+
40
+ describe "make_time" do
41
+
42
+ if RAILS_VER >= '2.1'
43
+
44
+ it "should create time using current timezone" do
45
+ Time.zone = 'Melbourne'
46
+ time = ActiveRecord::Base.send(:make_time, [2000,1,1,12,0,0])
47
+ time.zone.should == "EST"
48
+ end
49
+
50
+ else
51
+
52
+ it "should create time using default timezone" do
53
+ time = ActiveRecord::Base.send(:make_time, [2000,1,1,12,0,0])
54
+ time.zone.should == "UTC"
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+
61
+ end