validatable 1.1.2 → 1.2.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/README +30 -1
- data/lib/base.rb +96 -20
- data/lib/child_validation.rb +15 -0
- data/lib/errors.rb +6 -1
- data/lib/validatable.rb +4 -1
- data/lib/validations/validates_confirmation_of.rb +4 -1
- data/lib/validations/validates_numericality_of.rb +13 -0
- data/lib/validations/validates_true_for.rb +13 -0
- data/lib/validations/validation_base.rb +26 -4
- data/rakefile.rb +1 -1
- data/test/functional/validatable_test.rb +129 -0
- data/test/functional/validates_confirmation_of_test.rb +38 -0
- data/test/functional/validates_numericality_of_test.rb +45 -0
- data/test/functional/validates_true_for_test.rb +27 -0
- data/test/unit/validatable_test.rb +1 -9
- data/test/unit/validates_confirmation_of_test.rb +50 -0
- data/test/unit/validates_numericality_of_test.rb +36 -0
- data/test/unit/validates_true_for_test.rb +16 -0
- metadata +11 -3
data/README
CHANGED
@@ -72,8 +72,37 @@ Similar to Rails, Validatable also supports conditional validation.
|
|
72
72
|
validates_format_of :name, :with => /.+/, :if => Proc.new { !name.nil? }
|
73
73
|
end
|
74
74
|
Person.new.valid? #=> true
|
75
|
+
|
76
|
+
Validatable also exposes an after_validate hook method.
|
77
|
+
|
78
|
+
class Person
|
79
|
+
include Validatable
|
80
|
+
validates_presence_of :name
|
81
|
+
attr_accessor :name
|
82
|
+
end
|
83
|
+
|
84
|
+
class ValidatesPresenceOf
|
85
|
+
after_validate do |result, instance, attribute|
|
86
|
+
instance.errors.add("#{attribute} can't be blank") unless result
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
person = Person.new
|
91
|
+
person.valid? #=> false
|
92
|
+
person.errors.on(:name) #=> "name can't be blank"
|
93
|
+
|
94
|
+
The after_validate hook yields the result of the validation being run,
|
95
|
+
the instance the validation was run on, and the attribute that was validate
|
96
|
+
|
97
|
+
In the above example the attribute "name" is appended to the message.
|
75
98
|
|
76
99
|
See the tests for more examples
|
77
100
|
|
78
101
|
== Contributors
|
79
|
-
Rick Bradley (Revision 25)
|
102
|
+
Rick Bradley (Revision 25)
|
103
|
+
|
104
|
+
Zak Tamsen (Revision 29)
|
105
|
+
|
106
|
+
Jason Miller (Revision 31)
|
107
|
+
|
108
|
+
Ali Aghareza (Revision 45)
|
data/lib/base.rb
CHANGED
@@ -18,6 +18,7 @@ module Validatable
|
|
18
18
|
# * level - The level at which the validation should occur
|
19
19
|
# * if - A block that when executed must return true of the validation will not occur
|
20
20
|
# * with - The regular expression used to validate the format
|
21
|
+
# * group - The group that this validation belongs to. A validation can belong to multiple groups
|
21
22
|
def validates_format_of(*args)
|
22
23
|
add_validations(args, ValidatesFormatOf) do |validation, options|
|
23
24
|
validation.with = options[:with]
|
@@ -42,6 +43,7 @@ module Validatable
|
|
42
43
|
# * if - A block that when executed must return true of the validation will not occur
|
43
44
|
# * minimum - The minimum size of the attribute
|
44
45
|
# * maximum - The maximum size of the attribute
|
46
|
+
# * group - The group that this validation belongs to. A validation can belong to multiple groups
|
45
47
|
def validates_length_of(*args)
|
46
48
|
add_validations(args, ValidatesLengthOf) do |validation, options|
|
47
49
|
validation.minimum = options[:minimum]
|
@@ -49,6 +51,26 @@ module Validatable
|
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
54
|
+
# call-seq: validates_numericality_of(*args)
|
55
|
+
#
|
56
|
+
# Validates that the specified attribute is numeric.
|
57
|
+
#
|
58
|
+
# class Person
|
59
|
+
# include Validatable
|
60
|
+
# validates_numericality_of :age
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# Configuration options:
|
64
|
+
#
|
65
|
+
# * message - The message to add to the errors collection when the validation fails
|
66
|
+
# * times - The number of times the validation applies
|
67
|
+
# * level - The level at which the validation should occur
|
68
|
+
# * if - A block that when executed must return true of the validation will not occur
|
69
|
+
# * group - The group that this validation belongs to. A validation can belong to multiple groups
|
70
|
+
def validates_numericality_of(*args)
|
71
|
+
add_validations(args, ValidatesNumericalityOf)
|
72
|
+
end
|
73
|
+
|
52
74
|
# call-seq: validates_acceptance_of(*args)
|
53
75
|
#
|
54
76
|
# Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example:
|
@@ -65,6 +87,7 @@ module Validatable
|
|
65
87
|
# * times - The number of times the validation applies
|
66
88
|
# * level - The level at which the validation should occur
|
67
89
|
# * if - A block that when executed must return true of the validation will not occur
|
90
|
+
# * group - The group that this validation belongs to. A validation can belong to multiple groups
|
68
91
|
def validates_acceptance_of(*args)
|
69
92
|
add_validations(args, ValidatesAcceptanceOf)
|
70
93
|
end
|
@@ -86,12 +109,20 @@ module Validatable
|
|
86
109
|
#
|
87
110
|
# Configuration options:
|
88
111
|
#
|
112
|
+
# * case_sensitive - Whether or not to apply case-sensitivity on the comparison. Defaults to true.
|
89
113
|
# * message - The message to add to the errors collection when the validation fails
|
90
114
|
# * times - The number of times the validation applies
|
91
115
|
# * level - The level at which the validation should occur
|
92
116
|
# * if - A block that when executed must return true of the validation will not occur
|
117
|
+
# * group - The group that this validation belongs to. A validation can belong to multiple groups
|
93
118
|
def validates_confirmation_of(*args)
|
94
|
-
add_validations(args, ValidatesConfirmationOf)
|
119
|
+
add_validations(args, ValidatesConfirmationOf) do |validation, options|
|
120
|
+
validation.case_sensitive = if options.has_key? :case_sensitive
|
121
|
+
options[:case_sensitive]
|
122
|
+
else
|
123
|
+
true
|
124
|
+
end
|
125
|
+
end
|
95
126
|
end
|
96
127
|
|
97
128
|
# call-seq: validates_presence_of(*args)
|
@@ -111,11 +142,37 @@ module Validatable
|
|
111
142
|
# * times - The number of times the validation applies
|
112
143
|
# * level - The level at which the validation should occur
|
113
144
|
# * if - A block that when executed must return true of the validation will not occur
|
145
|
+
# * group - The group that this validation belongs to. A validation can belong to multiple groups
|
114
146
|
def validates_presence_of(*args)
|
115
147
|
add_validations(args, ValidatesPresenceOf)
|
116
148
|
end
|
117
149
|
|
118
|
-
# call-seq:
|
150
|
+
# call-seq: validates_true_for(*args)
|
151
|
+
#
|
152
|
+
# Validates that the logic evaluates to true
|
153
|
+
#
|
154
|
+
# class Person
|
155
|
+
# include Validatable
|
156
|
+
# validates_true_for :first_name, :logic => lambda { first_name == 'Jamie' }
|
157
|
+
# end
|
158
|
+
#
|
159
|
+
# The logic option is required.
|
160
|
+
#
|
161
|
+
# Configuration options:
|
162
|
+
#
|
163
|
+
# * message - The message to add to the errors collection when the validation fails
|
164
|
+
# * times - The number of times the validation applies
|
165
|
+
# * level - The level at which the validation should occur
|
166
|
+
# * if - A block that when executed must return true of the validation will not occur
|
167
|
+
# * group - The group that this validation belongs to. A validation can belong to multiple groups
|
168
|
+
# * logic - A block that executes to perform the validation
|
169
|
+
def validates_true_for(*args)
|
170
|
+
add_validations(args, ValidatesTrueFor) do |validation, options|
|
171
|
+
validation.logic = options[:logic]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# call-seq: include_validations_for(attribute_to_validate, options = {})
|
119
176
|
#
|
120
177
|
# Validates the specified attributes.
|
121
178
|
# class Person
|
@@ -126,7 +183,7 @@ module Validatable
|
|
126
183
|
#
|
127
184
|
# class PersonPresenter
|
128
185
|
# include Validatable
|
129
|
-
# include_validations_for :person
|
186
|
+
# include_validations_for :person, :map => { :name => :namen }, :if => lambda { not person.nil? }
|
130
187
|
# attr_accessor :person
|
131
188
|
#
|
132
189
|
# def initialize(person)
|
@@ -136,11 +193,16 @@ module Validatable
|
|
136
193
|
#
|
137
194
|
# presenter = PersonPresenter.new(Person.new)
|
138
195
|
# presenter.valid? #=> false
|
139
|
-
# presenter.errors.on(:
|
196
|
+
# presenter.errors.on(:namen) #=> "can't be blank"
|
140
197
|
#
|
141
198
|
# The person attribute will be validated. If person is invalid the errors will be added to the PersonPresenter errors collection.
|
142
|
-
|
143
|
-
|
199
|
+
#
|
200
|
+
# Configuration options:
|
201
|
+
#
|
202
|
+
# * map - A hash that maps attributes of the child to attributes of the parent.
|
203
|
+
# * if - A block that when executed must return true of the validation will not occur.
|
204
|
+
def include_validations_for(attribute_to_validate, options = {})
|
205
|
+
children_to_validate << ChildValidation.new(attribute_to_validate, options[:map] || {}, options[:if] || lambda { true })
|
144
206
|
end
|
145
207
|
|
146
208
|
def validate(instance) #:nodoc:
|
@@ -155,12 +217,13 @@ module Validatable
|
|
155
217
|
end
|
156
218
|
end
|
157
219
|
|
158
|
-
def validate_children(instance) #:nodoc:
|
159
|
-
self.children_to_validate.each do |
|
160
|
-
|
161
|
-
child.
|
220
|
+
def validate_children(instance, groups) #:nodoc:
|
221
|
+
self.children_to_validate.each do |child_validation|
|
222
|
+
next unless child_validation.should_validate?(instance)
|
223
|
+
child = instance.send child_validation.attribute
|
224
|
+
child.valid?(*groups)
|
162
225
|
child.errors.each do |attribute, message|
|
163
|
-
instance.errors.add(attribute, message)
|
226
|
+
instance.errors.add(child_validation.map[attribute.to_sym] || attribute, message)
|
164
227
|
end
|
165
228
|
end
|
166
229
|
end
|
@@ -191,10 +254,10 @@ module Validatable
|
|
191
254
|
# call-seq: valid?
|
192
255
|
#
|
193
256
|
# Returns true if no errors were added otherwise false.
|
194
|
-
def valid?
|
257
|
+
def valid?(*groups)
|
195
258
|
errors.clear
|
196
|
-
self.class.validate_children(self)
|
197
|
-
self.validate
|
259
|
+
self.class.validate_children(self, groups)
|
260
|
+
self.validate(groups)
|
198
261
|
errors.empty?
|
199
262
|
end
|
200
263
|
|
@@ -206,17 +269,25 @@ module Validatable
|
|
206
269
|
end
|
207
270
|
|
208
271
|
protected
|
209
|
-
def validate #:nodoc:
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
272
|
+
def validate(groups) #:nodoc:
|
273
|
+
validations_for_groups(groups).each do |validation|
|
274
|
+
validation_levels.sort.each do |level|
|
275
|
+
validations_for_level(level).each do |validation|
|
276
|
+
if validation.should_validate?(self)
|
277
|
+
run_validation(validation)
|
278
|
+
end
|
214
279
|
end
|
280
|
+
return unless self.errors.empty?
|
215
281
|
end
|
216
|
-
return unless self.errors.empty?
|
217
282
|
end
|
218
283
|
end
|
219
284
|
|
285
|
+
def run_validation(validation) #:nodoc:
|
286
|
+
validation_result = validation.valid?(self)
|
287
|
+
self.errors.add(validation.attribute, validation.message) unless validation_result
|
288
|
+
validation.run_after_validate(validation_result, self, validation.attribute)
|
289
|
+
end
|
290
|
+
|
220
291
|
def validation_levels #:nodoc:
|
221
292
|
self.validations.collect { |validation| validation.level }.uniq
|
222
293
|
end
|
@@ -225,6 +296,11 @@ module Validatable
|
|
225
296
|
self.validations.select { |validation| validation.level == level }
|
226
297
|
end
|
227
298
|
|
299
|
+
def validations_for_groups(groups) #:nodoc:
|
300
|
+
return self.validations if groups.empty?
|
301
|
+
self.validations.select { |validation| (groups & validation.groups).any? }
|
302
|
+
end
|
303
|
+
|
228
304
|
def validations #:nodoc:
|
229
305
|
@validations ||= self.class.validations.collect { |validation| validation.dup }
|
230
306
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Validatable
|
2
|
+
class ChildValidation #:nodoc:
|
3
|
+
attr_accessor :attribute, :map, :should_validate_proc
|
4
|
+
|
5
|
+
def initialize(attribute, map, should_validate_proc)
|
6
|
+
@attribute = attribute
|
7
|
+
@map = map
|
8
|
+
@should_validate_proc = should_validate_proc
|
9
|
+
end
|
10
|
+
|
11
|
+
def should_validate?(instance)
|
12
|
+
instance.instance_eval &should_validate_proc
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/errors.rb
CHANGED
@@ -2,7 +2,7 @@ module Validatable
|
|
2
2
|
class Errors
|
3
3
|
extend Forwardable
|
4
4
|
|
5
|
-
def_delegators :errors, :
|
5
|
+
def_delegators :errors, :any?, :clear, :each, :each_pair, :empty?, :length, :size
|
6
6
|
|
7
7
|
# call-seq: on(attribute)
|
8
8
|
#
|
@@ -15,6 +15,11 @@ module Validatable
|
|
15
15
|
def add(attribute, message) #:nodoc:
|
16
16
|
errors[attribute.to_sym] = message
|
17
17
|
end
|
18
|
+
|
19
|
+
def merge!(errors) #:nodoc:
|
20
|
+
errors.each_pair{|k, v| add(k,v)}
|
21
|
+
self
|
22
|
+
end
|
18
23
|
|
19
24
|
def errors #:nodoc:
|
20
25
|
@errors ||= {}
|
data/lib/validatable.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/errors')
|
3
3
|
require File.expand_path(File.dirname(__FILE__) + '/base')
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/child_validation')
|
4
5
|
require File.expand_path(File.dirname(__FILE__) + '/validations/validation_base')
|
5
6
|
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_format_of')
|
6
7
|
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_presence_of')
|
7
8
|
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_acceptance_of')
|
8
9
|
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_confirmation_of')
|
9
|
-
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_length_of')
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_length_of')
|
11
|
+
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_true_for')
|
12
|
+
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_numericality_of')
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module Validatable
|
2
2
|
class ValidatesConfirmationOf < ValidationBase #:nodoc:
|
3
|
+
attr_accessor :case_sensitive
|
4
|
+
|
3
5
|
def valid?(instance)
|
4
|
-
instance.send(self.attribute) == instance.send("#{self.attribute}_confirmation".to_sym)
|
6
|
+
return instance.send(self.attribute) == instance.send("#{self.attribute}_confirmation".to_sym) if case_sensitive
|
7
|
+
instance.send(self.attribute).to_s.casecmp(instance.send("#{self.attribute}_confirmation".to_sym).to_s) == 0
|
5
8
|
end
|
6
9
|
|
7
10
|
def message
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Validatable
|
2
2
|
class ValidationBase #:nodoc:
|
3
|
-
attr_accessor :attribute, :message
|
4
|
-
attr_reader :level
|
3
|
+
attr_accessor :attribute, :message, :times
|
4
|
+
attr_reader :level, :groups
|
5
5
|
|
6
6
|
def initialize(attribute, options={})
|
7
7
|
@attribute = attribute
|
@@ -9,6 +9,7 @@ module Validatable
|
|
9
9
|
@conditional = options[:if] || Proc.new { true }
|
10
10
|
@times = options[:times]
|
11
11
|
@level = options[:level] || 1
|
12
|
+
@groups = options[:groups].is_a?(Array) ? options[:groups] : [options[:groups]]
|
12
13
|
end
|
13
14
|
|
14
15
|
def should_validate?(instance)
|
@@ -17,8 +18,29 @@ module Validatable
|
|
17
18
|
|
18
19
|
def validate_this_time?
|
19
20
|
return true if @times.nil?
|
20
|
-
|
21
|
-
|
21
|
+
self.times -= 1
|
22
|
+
self.times >= 0
|
23
|
+
end
|
24
|
+
|
25
|
+
def run_after_validate(result, instance, attribute)
|
26
|
+
self.class.all_after_validations.each do |block|
|
27
|
+
block.call result, instance, attribute
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class << self
|
32
|
+
def after_validate(&block)
|
33
|
+
after_validations << block
|
34
|
+
end
|
35
|
+
|
36
|
+
def after_validations
|
37
|
+
@after_validations ||= []
|
38
|
+
end
|
39
|
+
|
40
|
+
def all_after_validations
|
41
|
+
return after_validations + self.superclass.after_validations if self.superclass.respond_to? :after_validations
|
42
|
+
after_validations
|
43
|
+
end
|
22
44
|
end
|
23
45
|
end
|
24
46
|
end
|
data/rakefile.rb
CHANGED
@@ -29,7 +29,7 @@ Gem::manage_gems
|
|
29
29
|
specification = Gem::Specification.new do |s|
|
30
30
|
s.name = "validatable"
|
31
31
|
s.summary = "Validatable is a library for adding validations."
|
32
|
-
s.version = "1.1
|
32
|
+
s.version = "1.2.1"
|
33
33
|
s.author = 'Jay Fields'
|
34
34
|
s.description = "Validatable is a library for adding validations."
|
35
35
|
s.email = 'validatable-developer@rubyforge.org'
|
@@ -22,6 +22,135 @@ module Functional
|
|
22
22
|
assert_equal "can't be empty", instance.errors.on(:name)
|
23
23
|
end
|
24
24
|
|
25
|
+
test "given a child class with validations, the error is in the parent objects error collection as the mapped attribute" do
|
26
|
+
child_class = Class.new do
|
27
|
+
include Validatable
|
28
|
+
attr_accessor :name, :address
|
29
|
+
validates_presence_of :name
|
30
|
+
end
|
31
|
+
klass = Class.new do
|
32
|
+
include Validatable
|
33
|
+
include_validations_for :child, :map => {:name => :namen}
|
34
|
+
define_method :child do
|
35
|
+
child_class.new
|
36
|
+
end
|
37
|
+
end
|
38
|
+
instance = klass.new
|
39
|
+
instance.valid?
|
40
|
+
assert_equal "can't be empty", instance.errors.on(:namen)
|
41
|
+
end
|
42
|
+
|
43
|
+
test "given a child class with validations, the error is in the parent objects error collection when the 'if' evals to true" do
|
44
|
+
child_class = Class.new do
|
45
|
+
include Validatable
|
46
|
+
attr_accessor :name, :address
|
47
|
+
validates_presence_of :name
|
48
|
+
end
|
49
|
+
klass = Class.new do
|
50
|
+
include Validatable
|
51
|
+
include_validations_for :child, :if => lambda { true }
|
52
|
+
define_method :child do
|
53
|
+
child_class.new
|
54
|
+
end
|
55
|
+
end
|
56
|
+
instance = klass.new
|
57
|
+
instance.valid?
|
58
|
+
assert_equal "can't be empty", instance.errors.on(:name)
|
59
|
+
end
|
60
|
+
|
61
|
+
test "given a child class with validations, the error is not in the parent objects error collection when the if evals to false" do
|
62
|
+
child_class = Class.new do
|
63
|
+
include Validatable
|
64
|
+
attr_accessor :name, :address
|
65
|
+
validates_presence_of :name
|
66
|
+
end
|
67
|
+
klass = Class.new do
|
68
|
+
include Validatable
|
69
|
+
include_validations_for :child, :if => lambda { false }
|
70
|
+
define_method :child do
|
71
|
+
child_class.new
|
72
|
+
end
|
73
|
+
end
|
74
|
+
instance = klass.new
|
75
|
+
assert_equal true, instance.valid?
|
76
|
+
end
|
77
|
+
|
78
|
+
test "nonmatching groups are not used as validations" do
|
79
|
+
klass = Class.new do
|
80
|
+
include Validatable
|
81
|
+
validates_presence_of :name, :groups => :group_one
|
82
|
+
attr_accessor :name
|
83
|
+
end
|
84
|
+
instance = klass.new
|
85
|
+
assert_equal true, instance.valid?(:group_two)
|
86
|
+
end
|
87
|
+
|
88
|
+
test "after validate is called following a validation" do
|
89
|
+
klass = Class.new do
|
90
|
+
include Validatable
|
91
|
+
validates_presence_of :name
|
92
|
+
attr_accessor :name
|
93
|
+
end
|
94
|
+
|
95
|
+
Validatable::ValidationBase.class_eval do
|
96
|
+
after_validate do |result, instance, attribute|
|
97
|
+
instance.errors.add(attribute, instance.errors.on(attribute) + " changed message")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
Validatable::ValidatesPresenceOf.class_eval do
|
101
|
+
after_validate do |result, instance, attribute|
|
102
|
+
instance.errors.add(attribute, instance.errors.on(attribute) + " twice")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
instance = klass.new
|
106
|
+
instance.valid?
|
107
|
+
assert_equal "can't be empty twice changed message", instance.errors.on(:name)
|
108
|
+
Validatable::ValidatesPresenceOf.after_validations.clear
|
109
|
+
Validatable::ValidationBase.after_validations.clear
|
110
|
+
end
|
111
|
+
|
112
|
+
test "matching groups are used as validations when multiple groups are given to valid" do
|
113
|
+
klass = Class.new do
|
114
|
+
include Validatable
|
115
|
+
validates_presence_of :name, :groups => :group_one
|
116
|
+
attr_accessor :name
|
117
|
+
end
|
118
|
+
instance = klass.new
|
119
|
+
assert_equal false, instance.valid?(:group_one)
|
120
|
+
end
|
121
|
+
|
122
|
+
test "matching groups are used as validations when validations are part of multiple groups" do
|
123
|
+
klass = Class.new do
|
124
|
+
include Validatable
|
125
|
+
validates_presence_of :name, :groups => [:group_one, :group_two]
|
126
|
+
attr_accessor :name
|
127
|
+
end
|
128
|
+
instance = klass.new
|
129
|
+
assert_equal false, instance.valid?(:group_one)
|
130
|
+
end
|
131
|
+
|
132
|
+
test "no group given then all validations are used" do
|
133
|
+
klass = Class.new do
|
134
|
+
include Validatable
|
135
|
+
validates_presence_of :name, :groups => :group_one
|
136
|
+
attr_accessor :name
|
137
|
+
end
|
138
|
+
instance = klass.new
|
139
|
+
assert_equal false, instance.valid?
|
140
|
+
end
|
141
|
+
|
142
|
+
test "matching multiple groups for validations" do
|
143
|
+
klass = Class.new do
|
144
|
+
include Validatable
|
145
|
+
validates_presence_of :name, :groups => :group_one
|
146
|
+
validates_presence_of :address, :groups => :group_two
|
147
|
+
attr_accessor :name, :address
|
148
|
+
end
|
149
|
+
instance = klass.new
|
150
|
+
instance.valid?(:group_one, :group_two)
|
151
|
+
assert_equal 2, instance.errors.size
|
152
|
+
end
|
153
|
+
|
25
154
|
expect true do
|
26
155
|
klass = Class.new do
|
27
156
|
include Validatable
|
@@ -14,5 +14,43 @@ module Functional
|
|
14
14
|
instance.valid?
|
15
15
|
assert_equal "doesn't match confirmation", instance.errors.on(:name)
|
16
16
|
end
|
17
|
+
|
18
|
+
test "given matching attributes, when validated, then no error is in the objects error collection" do
|
19
|
+
klass = Class.new do
|
20
|
+
include Validatable
|
21
|
+
attr_accessor :name, :name_confirmation
|
22
|
+
validates_confirmation_of :name
|
23
|
+
end
|
24
|
+
instance = klass.new
|
25
|
+
instance.name = "foo"
|
26
|
+
instance.name_confirmation = "foo"
|
27
|
+
assert_equal true, instance.valid?
|
28
|
+
end
|
29
|
+
|
30
|
+
test "given matching attributes of different case, when validated with case sensitive false, then no error is in the objects error collection" do
|
31
|
+
klass = Class.new do
|
32
|
+
include Validatable
|
33
|
+
attr_accessor :name, :name_confirmation
|
34
|
+
validates_confirmation_of :name, :case_sensitive => false
|
35
|
+
end
|
36
|
+
instance = klass.new
|
37
|
+
instance.name = "foo"
|
38
|
+
instance.name_confirmation = "FOO"
|
39
|
+
assert_equal true, instance.valid?
|
40
|
+
end
|
41
|
+
|
42
|
+
test "given matching attributes of different case, when validated with case sensitive true, then error is in the objects error collection" do
|
43
|
+
klass = Class.new do
|
44
|
+
include Validatable
|
45
|
+
attr_accessor :name, :name_confirmation
|
46
|
+
validates_confirmation_of :name
|
47
|
+
end
|
48
|
+
instance = klass.new
|
49
|
+
instance.name = "foo"
|
50
|
+
instance.name_confirmation = "FOO"
|
51
|
+
assert_equal false, instance.valid?
|
52
|
+
assert_equal "doesn't match confirmation", instance.errors.on(:name)
|
53
|
+
|
54
|
+
end
|
17
55
|
end
|
18
56
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
class ValidatesNumericalityOfTest < Test::Unit::TestCase
|
5
|
+
test "when validating numericality and the value is nil an error should exist on the instance" do
|
6
|
+
klass = Class.new do
|
7
|
+
include Validatable
|
8
|
+
attr_accessor :nothing
|
9
|
+
validates_numericality_of :nothing
|
10
|
+
end
|
11
|
+
instance = klass.new
|
12
|
+
instance.valid?
|
13
|
+
assert_equal "must be a number", instance.errors.on(:nothing)
|
14
|
+
end
|
15
|
+
|
16
|
+
test "when validating numericality and the value has a non numeric character an error should exist on the instance" do
|
17
|
+
klass = Class.new do
|
18
|
+
include Validatable
|
19
|
+
validates_numericality_of :some_string
|
20
|
+
|
21
|
+
def some_string
|
22
|
+
"some_string"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
instance = klass.new
|
26
|
+
instance.valid?
|
27
|
+
assert_equal "must be a number", instance.errors.on(:some_string)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "when validating a number no error will be in the instance" do
|
31
|
+
klass = Class.new do
|
32
|
+
include Validatable
|
33
|
+
validates_numericality_of :valid_number
|
34
|
+
|
35
|
+
def valid_number
|
36
|
+
1.23
|
37
|
+
end
|
38
|
+
end
|
39
|
+
instance = klass.new
|
40
|
+
instance.valid?
|
41
|
+
assert_equal nil, instance.errors.on(:valid_number)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
class ValidatesFormatOfTest < Test::Unit::TestCase
|
5
|
+
test "given invalid name, when validated, then error is in the objects error collection" do
|
6
|
+
klass = Class.new do
|
7
|
+
include Validatable
|
8
|
+
attr_accessor :name
|
9
|
+
validates_true_for :name, :logic => lambda { name == "nombre" }
|
10
|
+
end
|
11
|
+
instance = klass.new
|
12
|
+
instance.valid?
|
13
|
+
assert_equal "is invalid", instance.errors.on(:name)
|
14
|
+
end
|
15
|
+
|
16
|
+
test "given valid name, when validated, then no error is in the objects error collection" do
|
17
|
+
klass = Class.new do
|
18
|
+
include Validatable
|
19
|
+
attr_accessor :name
|
20
|
+
validates_true_for :name, :logic => lambda { name == "nombre" }
|
21
|
+
end
|
22
|
+
instance = klass.new
|
23
|
+
instance.name = "nombre"
|
24
|
+
assert_equal true, instance.valid?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
|
3
3
|
module Unit
|
4
4
|
class ValidatableTest < Test::Unit::TestCase
|
5
5
|
expect false do
|
6
|
-
validation = stub(:valid? => false, :should_validate? => true, :attribute => "attribute", :message => "message", :level => 1)
|
6
|
+
validation = stub(:valid? => false, :should_validate? => true, :attribute => "attribute", :message => "message", :level => 1, :run_after_validate => nil)
|
7
7
|
klass = Class.new do
|
8
8
|
include Validatable
|
9
9
|
validations << validation
|
@@ -11,14 +11,6 @@ module Unit
|
|
11
11
|
klass.new.valid?
|
12
12
|
end
|
13
13
|
|
14
|
-
expect [:anything, :else] do
|
15
|
-
klass = Class.new do
|
16
|
-
include Validatable
|
17
|
-
include_validations_for :anything, :else
|
18
|
-
end
|
19
|
-
klass.send(:children_to_validate)
|
20
|
-
end
|
21
|
-
|
22
14
|
test "when validate is executed, then messages are added for each validation that fails" do
|
23
15
|
klass = Class.new do
|
24
16
|
include Validatable
|
@@ -12,4 +12,54 @@ class ValidatesConfirmationOfTest < Test::Unit::TestCase
|
|
12
12
|
instance = stub(:username=>"username", :username_confirmation=>"usessrname")
|
13
13
|
assert_equal false, validation.valid?(instance)
|
14
14
|
end
|
15
|
+
|
16
|
+
test "valid confirmation with case insensitive" do
|
17
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
18
|
+
validation.case_sensitive = false
|
19
|
+
instance = stub(:username=>"username", :username_confirmation=>"USERNAME")
|
20
|
+
assert_equal true, validation.valid?(instance)
|
21
|
+
end
|
22
|
+
|
23
|
+
test "invalid confirmation with case sensitive" do
|
24
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
25
|
+
validation.case_sensitive = true
|
26
|
+
instance = stub(:username=>"username", :username_confirmation=>"USERNAME")
|
27
|
+
assert_equal false, validation.valid?(instance)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "invalid confirmation if value is nil and confirmation is not with case sensitive true" do
|
31
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
32
|
+
validation.case_sensitive = true
|
33
|
+
assert_equal false, validation.valid?(stub(:username => nil, :username_confirmation => 'something'))
|
34
|
+
end
|
35
|
+
|
36
|
+
test "invalid confirmation if confirmation is nil and value is not with case sensitive true" do
|
37
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
38
|
+
validation.case_sensitive = true
|
39
|
+
assert_equal false, validation.valid?(stub(:username => 'something', :username_confirmation => nil))
|
40
|
+
end
|
41
|
+
|
42
|
+
test "valid confirmation if value and confirmation are nil with case sensitive true" do
|
43
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
44
|
+
validation.case_sensitive = true
|
45
|
+
assert_equal true, validation.valid?(stub(:username => nil, :username_confirmation => nil))
|
46
|
+
end
|
47
|
+
|
48
|
+
test "invalid confirmation if value is nil and confirmation is not with case sensitive false" do
|
49
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
50
|
+
validation.case_sensitive = false
|
51
|
+
assert_equal false, validation.valid?(stub(:username => nil, :username_confirmation => 'something'))
|
52
|
+
end
|
53
|
+
|
54
|
+
test "invalid confirmation if confirmation is nil and value is not with case sensitive false" do
|
55
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
56
|
+
validation.case_sensitive = false
|
57
|
+
assert_equal false, validation.valid?(stub(:username => 'something', :username_confirmation => nil))
|
58
|
+
end
|
59
|
+
|
60
|
+
test "valid confirmation if value and confirmation are nil with case sensitive false" do
|
61
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
62
|
+
validation.case_sensitive = false
|
63
|
+
assert_equal true, validation.valid?(stub(:username => nil, :username_confirmation => nil))
|
64
|
+
end
|
15
65
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Unit
|
4
|
+
class ValidatesNumericalityOfTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
test "when the value is nil then valid is false" do
|
7
|
+
validation = Validatable::ValidatesNumericalityOf.new :nothing
|
8
|
+
instance = stub(:nothing => nil)
|
9
|
+
assert_equal false, validation.valid?(instance)
|
10
|
+
end
|
11
|
+
|
12
|
+
test "when value is an integer then valid is true" do
|
13
|
+
validation = Validatable::ValidatesNumericalityOf.new :some_int
|
14
|
+
instance = stub(:some_int => 50)
|
15
|
+
assert_equal true, validation.valid?(instance)
|
16
|
+
end
|
17
|
+
|
18
|
+
test "when value is an decimal then valid is true" do
|
19
|
+
validation = Validatable::ValidatesNumericalityOf.new :some_decimal
|
20
|
+
instance = stub(:some_decimal => 1.23)
|
21
|
+
assert_equal true, validation.valid?(instance)
|
22
|
+
end
|
23
|
+
|
24
|
+
test "when value has non numeric characters then valid is false" do
|
25
|
+
validation = Validatable::ValidatesNumericalityOf.new :some_non_numeric
|
26
|
+
instance = stub(:some_non_numeric => "50F")
|
27
|
+
assert_equal false, validation.valid?(instance)
|
28
|
+
end
|
29
|
+
|
30
|
+
test "when value is a string with multiple dots then valid is false" do
|
31
|
+
validation = Validatable::ValidatesNumericalityOf.new :multiple_dots
|
32
|
+
instance = stub(:multiple_dots => "50.0.0")
|
33
|
+
assert_equal false, validation.valid?(instance)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class ValidatesTrueForTest < Test::Unit::TestCase
|
4
|
+
test "when block returns false for attribute value, then valid is false" do
|
5
|
+
validation = Validatable::ValidatesTrueFor.new :name
|
6
|
+
validation.logic = lambda { false }
|
7
|
+
assert_equal false, validation.valid?(stub_everything)
|
8
|
+
end
|
9
|
+
|
10
|
+
test "when block returns true for attribute value, then valid is false" do
|
11
|
+
validation = Validatable::ValidatesTrueFor.new :name
|
12
|
+
validation.logic = lambda { true }
|
13
|
+
assert_equal true, validation.valid?(stub_everything)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.2
|
3
3
|
specification_version: 1
|
4
4
|
name: validatable
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.1
|
7
|
-
date: 2007-
|
6
|
+
version: 1.2.1
|
7
|
+
date: 2007-04-26 00:00:00 -04:00
|
8
8
|
summary: Validatable is a library for adding validations.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -25,17 +25,21 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
|
+
post_install_message:
|
28
29
|
authors:
|
29
30
|
- Jay Fields
|
30
31
|
files:
|
31
32
|
- lib/base.rb
|
33
|
+
- lib/child_validation.rb
|
32
34
|
- lib/errors.rb
|
33
35
|
- lib/validatable.rb
|
34
36
|
- lib/validations/validates_acceptance_of.rb
|
35
37
|
- lib/validations/validates_confirmation_of.rb
|
36
38
|
- lib/validations/validates_format_of.rb
|
37
39
|
- lib/validations/validates_length_of.rb
|
40
|
+
- lib/validations/validates_numericality_of.rb
|
38
41
|
- lib/validations/validates_presence_of.rb
|
42
|
+
- lib/validations/validates_true_for.rb
|
39
43
|
- lib/validations/validation_base.rb
|
40
44
|
- test/all_tests.rb
|
41
45
|
- test/test_helper.rb
|
@@ -44,14 +48,18 @@ files:
|
|
44
48
|
- test/functional/validates_confirmation_of_test.rb
|
45
49
|
- test/functional/validates_format_of_test.rb
|
46
50
|
- test/functional/validates_length_of_test.rb
|
51
|
+
- test/functional/validates_numericality_of_test.rb
|
47
52
|
- test/functional/validates_presence_of_test.rb
|
53
|
+
- test/functional/validates_true_for_test.rb
|
48
54
|
- test/unit/errors_test.rb
|
49
55
|
- test/unit/validatable_test.rb
|
50
56
|
- test/unit/validates_acceptance_of_test.rb
|
51
57
|
- test/unit/validates_confirmation_of_test.rb
|
52
58
|
- test/unit/validates_format_of_test.rb
|
53
59
|
- test/unit/validates_length_of_test.rb
|
60
|
+
- test/unit/validates_numericality_of_test.rb
|
54
61
|
- test/unit/validates_presence_of_test.rb
|
62
|
+
- test/unit/validates_true_for_test.rb
|
55
63
|
- test/unit/validation_base_test.rb
|
56
64
|
- rakefile.rb
|
57
65
|
- README
|