whyvalidationssuckin96 1.5.1 → 1.5.2
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/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.5.
|
1
|
+
1.5.2
|
@@ -10,6 +10,8 @@ module WhyValidationsSuckIn96
|
|
10
10
|
# validates_as_date :start_date
|
11
11
|
# end
|
12
12
|
class ValidatesDate < Validation
|
13
|
+
attr_reader :date
|
14
|
+
|
13
15
|
include WhyValidationsSuckIn96::SkippableValidation
|
14
16
|
include WhyValidationsSuckIn96::AttributeBasedValidation
|
15
17
|
DefaultDelimiters = %r{[-/]}
|
@@ -45,7 +47,7 @@ module WhyValidationsSuckIn96
|
|
45
47
|
|
46
48
|
def parse_date
|
47
49
|
parsed = options[:parser].call(attribute_value.to_s)
|
48
|
-
Date.civil(parsed[:year].to_i, parsed[:month].to_i, parsed[:day].to_i)
|
50
|
+
@date = Date.civil(parsed[:year].to_i, parsed[:month].to_i, parsed[:day].to_i)
|
49
51
|
end
|
50
52
|
end # Validation
|
51
53
|
|
@@ -3,35 +3,35 @@ require 'whyvalidationssuckin96/validation_collection'
|
|
3
3
|
|
4
4
|
module WhyValidationsSuckIn96
|
5
5
|
module ValidationSupport
|
6
|
-
|
6
|
+
|
7
7
|
def self.included(klass_or_mod)
|
8
8
|
klass_or_mod.module_eval do
|
9
9
|
extend WhyValidationsSuckIn96::ValidationSupport::ClassMethods
|
10
10
|
include WhyValidationsSuckIn96::ValidationSupport::InstanceMethods
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
# Instance methods added to any class or module that mixes in ValidationSupport
|
15
15
|
module InstanceMethods
|
16
|
-
|
16
|
+
|
17
17
|
def self.included(klass)
|
18
18
|
klass.module_eval do
|
19
19
|
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Is this object invalid?
|
24
24
|
# @return [true, false]
|
25
25
|
def invalid?
|
26
26
|
!valid?
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def valid?
|
30
30
|
self.class.run_with_generic_callbacks? ? valid_with_generic_callbacks? : valid_without_generic_callbacks?
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# Is this object valid?
|
34
|
-
# Also runs any callbacks if the class has callback support as defined by the
|
34
|
+
# Also runs any callbacks if the class has callback support as defined by the
|
35
35
|
# instance method run_callbacks being present.
|
36
36
|
# @return [true, false]
|
37
37
|
def valid_with_generic_callbacks?
|
@@ -40,7 +40,7 @@ module WhyValidationsSuckIn96
|
|
40
40
|
ensure
|
41
41
|
run_callbacks(:after_validation)
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
# Is this object valid?
|
45
45
|
# @return [true, false]
|
46
46
|
def valid_without_generic_callbacks?
|
@@ -49,19 +49,19 @@ module WhyValidationsSuckIn96
|
|
49
49
|
(validation.validates? == false) ? false : true
|
50
50
|
end.all?
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
# An array of instances of failed validations
|
54
54
|
# @return [Array]
|
55
55
|
def failed_validations
|
56
56
|
all_validations.select { |validation| validation.failed? }
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
# An array of instances of passed validations
|
60
60
|
# @return [Array]
|
61
61
|
def passed_validations
|
62
62
|
all_validations.select { |validation| validation.passed? }
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
# An array of instances of all validations for this object
|
66
66
|
# @return [Array]
|
67
67
|
def all_validations
|
@@ -70,12 +70,18 @@ module WhyValidationsSuckIn96
|
|
70
70
|
vc
|
71
71
|
end
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
|
+
def validations_for(attribute)
|
75
|
+
all_validations.select do |validation|
|
76
|
+
validation.respond_to?(:attribute) && validation.attribute == attribute.to_sym
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
74
80
|
end # InstanceMethods
|
75
|
-
|
81
|
+
|
76
82
|
module ClassMethods
|
77
|
-
|
78
|
-
# If the class or module has a public 'run_callbacks' instance method, we run validations and fire
|
83
|
+
|
84
|
+
# If the class or module has a public 'run_callbacks' instance method, we run validations and fire
|
79
85
|
# appropriate callbacks
|
80
86
|
# @return [true, false]
|
81
87
|
def run_with_generic_callbacks?
|
@@ -85,7 +91,7 @@ module WhyValidationsSuckIn96
|
|
85
91
|
@run_with_generic_callbacks = public_instance_methods.include?('run_callbacks')
|
86
92
|
end
|
87
93
|
end
|
88
|
-
|
94
|
+
|
89
95
|
# An array of arrays, the first element of each being the validation subclass that will be instantiated
|
90
96
|
# when validation is performed, the last element being the options the validation will be instantiated
|
91
97
|
# with.
|
@@ -96,14 +102,14 @@ module WhyValidationsSuckIn96
|
|
96
102
|
ancestor_with_validations ? ancestor_with_validations.validation_collection.dup : []
|
97
103
|
end
|
98
104
|
end
|
99
|
-
|
105
|
+
|
100
106
|
# Sets up validations for the class or module this module has been mixed into
|
101
107
|
def setup_validations(&definition_block)
|
102
108
|
self.validation_collection ||= ancestors.detect{|anc| !anc.validation_collection.nil?}.validation_collection.dup
|
103
109
|
builder = ValidationBuilder.new(self, definition_block)
|
104
110
|
builder.create_validations!
|
105
111
|
end
|
106
|
-
|
112
|
+
|
107
113
|
end # ClassMethods
|
108
114
|
end # ValidationSupport
|
109
115
|
end # WhyValidationsSuckIn96
|
@@ -32,5 +32,17 @@ context "validates date" do
|
|
32
32
|
validation = WhyValidationsSuckIn96::ValidatesDate.new(OpenStruct.new(:start_date => "4-20-1969"), :attribute => :start_date)
|
33
33
|
validation.validates?
|
34
34
|
end
|
35
|
+
|
36
|
+
should "have an accessor for the parsed date string" do
|
37
|
+
validation = WhyValidationsSuckIn96::ValidatesDate.new(OpenStruct.new(:start_date => "4-20-1969"), :attribute => :start_date)
|
38
|
+
validation.validates?
|
39
|
+
validation.date
|
40
|
+
end.equals(Date.civil(1969, 4, 20))
|
41
|
+
|
42
|
+
should "#date returns nil if validation does not pass" do
|
43
|
+
validation = WhyValidationsSuckIn96::ValidatesDate.new(OpenStruct.new(:start_date => "34-393"), :attribute => :start_date)
|
44
|
+
validation.validates?
|
45
|
+
validation.date
|
46
|
+
end.not!
|
35
47
|
end # validating an object
|
36
48
|
end # validates format
|
@@ -4,71 +4,71 @@ context "validation_support" do
|
|
4
4
|
|
5
5
|
context "when mixed into a class supporting callbacks" do
|
6
6
|
setup do
|
7
|
-
Class.new do
|
7
|
+
Class.new do
|
8
8
|
attr_reader :callbacks_run
|
9
|
-
|
9
|
+
|
10
10
|
def initialize
|
11
11
|
@callbacks_run = []
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def run_callbacks(callback_name)
|
15
15
|
@callbacks_run << callback_name
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
include WhyValidationsSuckIn96::ValidationSupport
|
19
19
|
setup_validations do
|
20
20
|
validate(:foo) { pass }
|
21
21
|
end
|
22
22
|
end.new
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
should "run the before_validation callback when calling valid?" do
|
26
26
|
topic.callbacks_run.clear
|
27
27
|
topic.valid?
|
28
28
|
topic.callbacks_run
|
29
29
|
end.includes(:before_validation)
|
30
|
-
|
30
|
+
|
31
31
|
should "run the after_validation callback when calling valid?" do
|
32
32
|
topic.callbacks_run.clear
|
33
33
|
topic.valid?
|
34
34
|
topic.callbacks_run
|
35
35
|
end.includes(:after_validation)
|
36
|
-
|
36
|
+
|
37
37
|
end # when mixed into a class supporting callbacks
|
38
|
-
|
38
|
+
|
39
39
|
context "when mixed into a class" do
|
40
40
|
setup do
|
41
41
|
Class.new { include WhyValidationsSuckIn96::ValidationSupport }
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
should "add a 'validation_collection' method" do
|
45
45
|
topic
|
46
46
|
end.respond_to(:validation_collection)
|
47
|
-
|
47
|
+
|
48
48
|
should "add a 'setup_validations' method" do
|
49
49
|
topic
|
50
50
|
end.respond_to(:setup_validations)
|
51
|
-
|
51
|
+
|
52
52
|
should "add a 'valid?' instance method" do
|
53
53
|
topic.new
|
54
54
|
end.respond_to(:valid?)
|
55
|
-
|
55
|
+
|
56
56
|
should "add a 'invalid?' instance method" do
|
57
57
|
topic.new
|
58
58
|
end.respond_to(:invalid?)
|
59
|
-
|
59
|
+
|
60
60
|
should "add a 'failed_validations' instance method" do
|
61
61
|
topic.new
|
62
62
|
end.respond_to(:failed_validations)
|
63
|
-
|
63
|
+
|
64
64
|
should "add a 'passed_validations' instance method" do
|
65
65
|
topic.new
|
66
66
|
end.respond_to(:passed_validations)
|
67
|
-
|
67
|
+
|
68
68
|
should "add a 'all_validations' instance method" do
|
69
69
|
topic.new
|
70
70
|
end.respond_to(:all_validations)
|
71
|
-
|
71
|
+
|
72
72
|
should "have a ValidationCollection for all_validations" do
|
73
73
|
topic.new.all_validations.instance_of?(WhyValidationsSuckIn96::ValidationCollection)
|
74
74
|
end
|
@@ -76,16 +76,16 @@ context "validation_support" do
|
|
76
76
|
should "have an empty validation collection" do
|
77
77
|
topic.validation_collection.size
|
78
78
|
end.equals(0)
|
79
|
-
|
79
|
+
|
80
80
|
should "be valid when no validations have been defined" do
|
81
81
|
topic.new.valid?
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
should "not be invalid when no validations have been defined" do
|
85
85
|
!topic.new.invalid?
|
86
86
|
end
|
87
87
|
end # mixed into a class
|
88
|
-
|
88
|
+
|
89
89
|
context "when mixed into a class and used to add a simple validation" do
|
90
90
|
setup do
|
91
91
|
Class.new do
|
@@ -99,46 +99,46 @@ context "validation_support" do
|
|
99
99
|
end # setup_validations
|
100
100
|
end # Class.new
|
101
101
|
end # setup
|
102
|
-
|
102
|
+
|
103
103
|
should "have one validation in the validation_collection" do
|
104
104
|
topic.validation_collection.size
|
105
105
|
end.equals(1)
|
106
|
-
|
106
|
+
|
107
107
|
should "be able to reflect on the validation and find its name" do
|
108
108
|
topic.validation_collection.first.first.name
|
109
109
|
end.equals(:title_is_present)
|
110
|
-
|
110
|
+
|
111
111
|
should "be able to reflect on the validation and find its options" do
|
112
112
|
topic.validation_collection.first.last
|
113
113
|
end.equals(:example => "the number song", :message => "title must be present")
|
114
|
-
|
114
|
+
|
115
115
|
context "given an instance of the class" do
|
116
116
|
setup { topic.new }
|
117
|
-
|
117
|
+
|
118
118
|
should "have one entry for all validations" do
|
119
119
|
topic.all_validations.size
|
120
120
|
end.equals(1)
|
121
|
-
|
121
|
+
|
122
122
|
should "have all the entries for all validations be validation instances" do
|
123
123
|
topic.all_validations.all? { |validation| validation.kind_of?(WhyValidationsSuckIn96::Validation) }
|
124
124
|
end
|
125
|
-
|
125
|
+
|
126
126
|
should "not be valid without a title" do
|
127
127
|
topic.title = nil
|
128
128
|
!topic.valid?
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
should "be valid with a title" do
|
132
132
|
topic.title = "building steam with a grain of salt"
|
133
133
|
topic.valid?
|
134
134
|
end
|
135
|
-
|
135
|
+
|
136
136
|
should "have one passed validation with a title" do
|
137
137
|
topic.title = "building steam with a grain of salt"
|
138
138
|
topic.valid?
|
139
139
|
topic.passed_validations.size
|
140
140
|
end.equals(1)
|
141
|
-
|
141
|
+
|
142
142
|
should "have one failed validation without a title" do
|
143
143
|
topic.title = nil
|
144
144
|
topic.valid?
|
@@ -146,10 +146,10 @@ context "validation_support" do
|
|
146
146
|
end.equals(1)
|
147
147
|
end # given an instance of the class
|
148
148
|
end # when mixed into a class and used to add a simple validation
|
149
|
-
|
149
|
+
|
150
150
|
context "when extending a class with existing validations and adding new validations" do
|
151
151
|
parent_class = child_class = nil
|
152
|
-
|
152
|
+
|
153
153
|
setup do
|
154
154
|
parent_class = Class.new do
|
155
155
|
attr_accessor :artist
|
@@ -161,7 +161,7 @@ context "validation_support" do
|
|
161
161
|
end
|
162
162
|
end # setup_validations
|
163
163
|
end # parent_class
|
164
|
-
|
164
|
+
|
165
165
|
child_class = Class.new(parent_class) do
|
166
166
|
attr_accessor :title
|
167
167
|
setup_validations do
|
@@ -172,32 +172,32 @@ context "validation_support" do
|
|
172
172
|
end # setup_validations
|
173
173
|
end # child_class
|
174
174
|
end # setup
|
175
|
-
|
175
|
+
|
176
176
|
should "have only one validation in the collection for the base class" do
|
177
177
|
parent_class.validation_collection.size
|
178
178
|
end.equals(1)
|
179
|
-
|
179
|
+
|
180
180
|
should "have a validation for the artist in the base class" do
|
181
181
|
parent_class.validation_collection.detect {|(validation, opts)| validation.name == :artist_is_present }
|
182
182
|
end
|
183
|
-
|
183
|
+
|
184
184
|
should "have two validations in the collection for the child class" do
|
185
185
|
child_class.validation_collection.size
|
186
186
|
end.equals(2)
|
187
|
-
|
187
|
+
|
188
188
|
should "have a validation for the artist in the child class" do
|
189
189
|
child_class.validation_collection.detect {|(validation, opts)| validation.name == :artist_is_present }
|
190
190
|
end
|
191
|
-
|
191
|
+
|
192
192
|
should "have a validation for the title in the child class" do
|
193
193
|
child_class.validation_collection.detect {|(validation, opts)| validation.name == :title_is_present }
|
194
194
|
end
|
195
|
-
|
195
|
+
|
196
196
|
end # when extending a class with existing validations
|
197
|
-
|
197
|
+
|
198
198
|
context "when extending a class with existing validations and not adding new validations" do
|
199
199
|
parent_class = child_class = nil
|
200
|
-
|
200
|
+
|
201
201
|
setup do
|
202
202
|
parent_class = Class.new do
|
203
203
|
attr_accessor :artist
|
@@ -209,16 +209,16 @@ context "validation_support" do
|
|
209
209
|
end
|
210
210
|
end # setup_validations
|
211
211
|
end # parent_class
|
212
|
-
|
212
|
+
|
213
213
|
child_class = Class.new(parent_class)
|
214
214
|
end # setup
|
215
|
-
|
215
|
+
|
216
216
|
should "have the parent class' validations by default" do
|
217
217
|
child_class.validation_collection.size
|
218
218
|
end.equals(1)
|
219
|
-
|
219
|
+
|
220
220
|
end # when extending a class with existing validations and not adding new validations
|
221
|
-
|
221
|
+
|
222
222
|
context "when calling setup_validations twice in a class" do
|
223
223
|
setup do
|
224
224
|
Class.new do
|
@@ -231,18 +231,38 @@ context "validation_support" do
|
|
231
231
|
end
|
232
232
|
end # Class.new
|
233
233
|
end # setup
|
234
|
-
|
234
|
+
|
235
235
|
should "add two validations to the class" do
|
236
236
|
topic.validation_collection.size
|
237
237
|
end.equals(2)
|
238
|
-
|
238
|
+
|
239
239
|
should "have the first validation" do
|
240
240
|
topic.validation_collection.detect { |(validation, opts)| validation.name == :first_validation }
|
241
241
|
end
|
242
|
-
|
242
|
+
|
243
243
|
should "have the second validation" do
|
244
244
|
topic.validation_collection.detect { |(validation, opts)| validation.name == :second_validation }
|
245
245
|
end
|
246
|
-
|
246
|
+
|
247
247
|
end # when calling setup_validations twice in a class
|
248
|
+
|
249
|
+
context "when asking for validations on a specific attribute" do
|
250
|
+
setup do
|
251
|
+
Class.new do
|
252
|
+
include WhyValidationsSuckIn96::ValidationSupport
|
253
|
+
setup_validations do
|
254
|
+
validates_presence_of :foo
|
255
|
+
end
|
256
|
+
end # Class.new
|
257
|
+
end
|
258
|
+
|
259
|
+
should "return validations on an instance" do
|
260
|
+
topic.new.validations_for(:foo).size
|
261
|
+
end
|
262
|
+
|
263
|
+
should "return validations an empty array if no validations on attribute" do
|
264
|
+
topic.new.validations_for(:bar).size
|
265
|
+
end.equals(0)
|
266
|
+
end
|
267
|
+
|
248
268
|
end # validation_support
|
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{whyvalidationssuckin96}
|
8
|
-
s.version = "1.5.
|
8
|
+
s.version = "1.5.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["gabrielg", "douglasmeyer"]
|