hashrocket-validatable 1.7.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/README.rdoc +118 -0
- data/Rakefile +54 -0
- data/VERSION.yml +4 -0
- data/lib/child_validation.rb +15 -0
- data/lib/errors.rb +88 -0
- data/lib/included_validation.rb +9 -0
- data/lib/macros.rb +306 -0
- data/lib/object_extension.rb +21 -0
- data/lib/requireable.rb +26 -0
- data/lib/understandable.rb +31 -0
- data/lib/validatable.rb +25 -0
- data/lib/validatable_class_methods.rb +85 -0
- data/lib/validatable_instance_methods.rb +116 -0
- data/lib/validations/validates_acceptance_of.rb +14 -0
- data/lib/validations/validates_confirmation_of.rb +23 -0
- data/lib/validations/validates_each.rb +14 -0
- data/lib/validations/validates_format_of.rb +16 -0
- data/lib/validations/validates_length_of.rb +30 -0
- data/lib/validations/validates_numericality_of.rb +27 -0
- data/lib/validations/validates_presence_of.rb +17 -0
- data/lib/validations/validates_true_for.rb +13 -0
- data/lib/validations/validation_base.rb +91 -0
- data/test/all_tests.rb +1 -0
- data/test/functional/test_validatable.rb +589 -0
- data/test/functional/test_validates_acceptance_of.rb +16 -0
- data/test/functional/test_validates_confirmation_of.rb +56 -0
- data/test/functional/test_validates_each.rb +14 -0
- data/test/functional/test_validates_format_of.rb +34 -0
- data/test/functional/test_validates_length_of.rb +64 -0
- data/test/functional/test_validates_numericality_of.rb +57 -0
- data/test/functional/test_validates_presence_of.rb +16 -0
- data/test/functional/test_validates_true_for.rb +27 -0
- data/test/test_helper.rb +33 -0
- data/test/unit/test_errors.rb +64 -0
- data/test/unit/test_understandable.rb +19 -0
- data/test/unit/test_validatable.rb +38 -0
- data/test/unit/test_validates_acceptance_of.rb +45 -0
- data/test/unit/test_validates_confirmation_of.rb +76 -0
- data/test/unit/test_validates_format_of.rb +44 -0
- data/test/unit/test_validates_length_of.rb +80 -0
- data/test/unit/test_validates_numericality_of.rb +76 -0
- data/test/unit/test_validates_presence_of.rb +35 -0
- data/test/unit/test_validates_true_for.rb +29 -0
- data/test/unit/test_validation_base.rb +52 -0
- metadata +118 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
module Validatable
|
2
|
+
class ValidatesPresenceOf < ValidationBase #:nodoc:
|
3
|
+
def valid?(instance)
|
4
|
+
value = instance.send(self.attribute)
|
5
|
+
return true if allow_nil && value.nil?
|
6
|
+
return true if allow_blank && value.blank?
|
7
|
+
|
8
|
+
return false if instance.send(self.attribute).nil?
|
9
|
+
value.respond_to?(:strip) ? instance.send(self.attribute).strip.length != 0 : true
|
10
|
+
end
|
11
|
+
|
12
|
+
def message(instance)
|
13
|
+
super || "can't be empty"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Validatable
|
2
|
+
class ValidationBase #:nodoc:
|
3
|
+
def self.required_option(*args)
|
4
|
+
option(*args)
|
5
|
+
requires(*args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.option(*args)
|
9
|
+
attr_accessor(*args)
|
10
|
+
understands(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.default(hash)
|
14
|
+
defaults.merge! hash
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.defaults
|
18
|
+
@defaults ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.all_defaults
|
22
|
+
return defaults.merge(self.superclass.all_defaults) if self.superclass.respond_to? :all_defaults
|
23
|
+
defaults
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.after_validate(&block)
|
27
|
+
after_validations << block
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.after_validations
|
31
|
+
@after_validations ||= []
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.all_after_validations
|
35
|
+
return after_validations + self.superclass.all_after_validations if self.superclass.respond_to? :all_after_validations
|
36
|
+
after_validations
|
37
|
+
end
|
38
|
+
|
39
|
+
include Understandable
|
40
|
+
include Requireable
|
41
|
+
|
42
|
+
option :message, :if, :times, :level, :groups, :key, :after_validate, :allow_nil, :allow_blank
|
43
|
+
default :level => 1, :groups => []
|
44
|
+
attr_accessor :attribute
|
45
|
+
|
46
|
+
def initialize(klass, attribute, options={})
|
47
|
+
must_understand options
|
48
|
+
requires options
|
49
|
+
self.class.all_understandings.each do |understanding|
|
50
|
+
options[understanding] = self.class.all_defaults[understanding] unless options.has_key? understanding
|
51
|
+
self.instance_variable_set("@#{understanding}", options[understanding])
|
52
|
+
end
|
53
|
+
self.attribute = attribute
|
54
|
+
self.groups = [self.groups] unless self.groups.is_a?(Array)
|
55
|
+
self.key = "#{klass.name}/#{self.class.name}/#{self.key || self.attribute}"
|
56
|
+
raise_error_if_key_is_dup(klass)
|
57
|
+
end
|
58
|
+
|
59
|
+
def raise_error_if_key_is_dup(klass)
|
60
|
+
message = "key #{self.key} must be unique, provide the :key option to specify a unique key"
|
61
|
+
raise ArgumentError.new(message) if klass.validation_keys_include? self.key
|
62
|
+
end
|
63
|
+
|
64
|
+
def should_validate?(instance)
|
65
|
+
result = validate_this_time?(instance)
|
66
|
+
case self.if
|
67
|
+
when Proc
|
68
|
+
result &&= instance.instance_eval(&self.if)
|
69
|
+
when Symbol, String
|
70
|
+
result &&= instance.instance_eval(self.if.to_s)
|
71
|
+
end
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
75
|
+
def message(instance)
|
76
|
+
@message.respond_to?(:call) ? instance.instance_eval(&@message) : @message
|
77
|
+
end
|
78
|
+
|
79
|
+
def validate_this_time?(instance)
|
80
|
+
return true if @times.nil?
|
81
|
+
self.times > instance.times_validated(self.key)
|
82
|
+
end
|
83
|
+
|
84
|
+
def run_after_validate(result, instance, attribute)
|
85
|
+
self.class.all_after_validations.each do |block|
|
86
|
+
block.call result, instance, attribute
|
87
|
+
end
|
88
|
+
instance.instance_eval_with_params result, attribute, &self.after_validate unless self.after_validate.nil?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/test/all_tests.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Dir['test/**/test_*.rb'].each { |test_case| require test_case }
|
@@ -0,0 +1,589 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
functional_tests do
|
4
|
+
|
5
|
+
expect "can't be empty" do
|
6
|
+
child_class = Module.new do
|
7
|
+
include Validatable
|
8
|
+
validates_presence_of :name
|
9
|
+
end
|
10
|
+
klass = Class.new do
|
11
|
+
include Validatable
|
12
|
+
include_validations_from :child
|
13
|
+
define_method :child do
|
14
|
+
child_class
|
15
|
+
end
|
16
|
+
attr_accessor :name
|
17
|
+
end
|
18
|
+
instance = klass.new
|
19
|
+
instance.valid?
|
20
|
+
instance.errors.on(:name)
|
21
|
+
end
|
22
|
+
|
23
|
+
expect "can't be empty" do
|
24
|
+
child_class = Module.new do
|
25
|
+
include Validatable
|
26
|
+
validates_presence_of :name
|
27
|
+
end
|
28
|
+
klass = Class.new do
|
29
|
+
include Validatable
|
30
|
+
validates_presence_of :address
|
31
|
+
include_validations_from :child
|
32
|
+
define_method :child do
|
33
|
+
child_class
|
34
|
+
end
|
35
|
+
attr_accessor :name, :address
|
36
|
+
end
|
37
|
+
instance = klass.new
|
38
|
+
instance.valid?
|
39
|
+
instance.errors.on(:address)
|
40
|
+
end
|
41
|
+
|
42
|
+
expect :is_set do
|
43
|
+
klass = Class.new do
|
44
|
+
include Validatable
|
45
|
+
attr_accessor :result
|
46
|
+
before_validation do
|
47
|
+
self.result = :is_set
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
instance = klass.new
|
52
|
+
instance.valid?
|
53
|
+
instance.result
|
54
|
+
end
|
55
|
+
|
56
|
+
expect :is_set do
|
57
|
+
klass = Class.new do
|
58
|
+
include Validatable
|
59
|
+
attr_accessor :name, :result
|
60
|
+
validates_presence_of :name, :after_validate => lambda { |result, attribute| self.result = :is_set }
|
61
|
+
end
|
62
|
+
|
63
|
+
instance = klass.new
|
64
|
+
instance.valid?
|
65
|
+
instance.result
|
66
|
+
end
|
67
|
+
|
68
|
+
expect false do
|
69
|
+
klass = Class.new do
|
70
|
+
include Validatable
|
71
|
+
attr_accessor :name
|
72
|
+
validates_presence_of :name
|
73
|
+
end
|
74
|
+
subclass = Class.new klass do
|
75
|
+
end
|
76
|
+
subsubclass = Class.new subclass do
|
77
|
+
end
|
78
|
+
subsubclass.new.valid?
|
79
|
+
end
|
80
|
+
|
81
|
+
expect false do
|
82
|
+
klass = Class.new do
|
83
|
+
include Validatable
|
84
|
+
attr_accessor :name
|
85
|
+
validates_presence_of :name
|
86
|
+
end
|
87
|
+
subclass = Class.new klass do
|
88
|
+
end
|
89
|
+
subclass.new.valid?
|
90
|
+
end
|
91
|
+
|
92
|
+
expect true do
|
93
|
+
klass = Class.new do
|
94
|
+
include Validatable
|
95
|
+
attr_accessor :name
|
96
|
+
validates_presence_of :name
|
97
|
+
end
|
98
|
+
subclass = Class.new klass do
|
99
|
+
end
|
100
|
+
instance = subclass.new
|
101
|
+
instance.name = 'a name'
|
102
|
+
instance.valid?
|
103
|
+
end
|
104
|
+
|
105
|
+
expect ArgumentError do
|
106
|
+
Class.new do
|
107
|
+
include Validatable
|
108
|
+
attr_accessor :name
|
109
|
+
validates_presence_of :name, :times => 1
|
110
|
+
validates_presence_of :name, :times => 1
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
expect ArgumentError do
|
115
|
+
Class.new do
|
116
|
+
include Validatable
|
117
|
+
attr_accessor :name
|
118
|
+
validates_presence_of :name, :times => 1, :key => 'anything'
|
119
|
+
validates_presence_of :name, :times => 1, :key => 'anything'
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
expect "is invalid" do
|
124
|
+
child_class = Class.new do
|
125
|
+
include Validatable
|
126
|
+
attr_accessor :name, :address
|
127
|
+
validates_presence_of :name
|
128
|
+
validates_format_of :address, :with => /.+/
|
129
|
+
end
|
130
|
+
klass = Class.new do
|
131
|
+
include Validatable
|
132
|
+
include_errors_from :child
|
133
|
+
define_method :child do
|
134
|
+
child_class.new
|
135
|
+
end
|
136
|
+
end
|
137
|
+
instance = klass.new
|
138
|
+
instance.valid?
|
139
|
+
instance.errors.on(:address)
|
140
|
+
end
|
141
|
+
|
142
|
+
expect "can't be empty" do
|
143
|
+
child_class = Class.new do
|
144
|
+
include Validatable
|
145
|
+
attr_accessor :name, :address
|
146
|
+
validates_presence_of :name
|
147
|
+
validates_format_of :address, :with => /.+/
|
148
|
+
end
|
149
|
+
klass = Class.new do
|
150
|
+
include Validatable
|
151
|
+
include_errors_from :child
|
152
|
+
define_method :child do
|
153
|
+
child_class.new
|
154
|
+
end
|
155
|
+
end
|
156
|
+
instance = klass.new
|
157
|
+
instance.valid?
|
158
|
+
instance.errors.on(:name)
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
test "when child validations have errors, level 2 and higher parent validations are not performed" do
|
163
|
+
child_class = Class.new do
|
164
|
+
include Validatable
|
165
|
+
attr_accessor :name
|
166
|
+
validates_presence_of :name
|
167
|
+
end
|
168
|
+
|
169
|
+
klass = Class.new do
|
170
|
+
include Validatable
|
171
|
+
extend Forwardable
|
172
|
+
def_delegator :child, :name
|
173
|
+
validates_true_for :name, :logic => lambda { false }, :level => 2, :message => "invalid message"
|
174
|
+
include_errors_from :child
|
175
|
+
define_method :child do
|
176
|
+
@child ||= child_class.new
|
177
|
+
end
|
178
|
+
end
|
179
|
+
instance = klass.new
|
180
|
+
instance.valid?
|
181
|
+
assert_equal "can't be empty", instance.errors.on(:name)
|
182
|
+
end
|
183
|
+
|
184
|
+
test "when child validations have errors, level 1 parent validations are still performed" do
|
185
|
+
child_class = Class.new do
|
186
|
+
include Validatable
|
187
|
+
attr_accessor :name
|
188
|
+
validates_presence_of :name
|
189
|
+
end
|
190
|
+
|
191
|
+
klass = Class.new do
|
192
|
+
include Validatable
|
193
|
+
validates_true_for :address, :logic => lambda { false }, :level => 1, :message => "invalid message"
|
194
|
+
include_errors_from :child
|
195
|
+
define_method :child do
|
196
|
+
@child ||= child_class.new
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
instance = klass.new
|
201
|
+
instance.valid?
|
202
|
+
assert_equal "can't be empty", instance.errors.on(:name)
|
203
|
+
assert_equal "invalid message", instance.errors.on(:address)
|
204
|
+
end
|
205
|
+
|
206
|
+
expect "can't be empty" do
|
207
|
+
child_class = Class.new do
|
208
|
+
include Validatable
|
209
|
+
attr_accessor :name, :address
|
210
|
+
validates_presence_of :name
|
211
|
+
end
|
212
|
+
klass = Class.new do
|
213
|
+
include Validatable
|
214
|
+
include_errors_from :child, :map => {:name => :namen}
|
215
|
+
define_method :child do
|
216
|
+
child_class.new
|
217
|
+
end
|
218
|
+
end
|
219
|
+
instance = klass.new
|
220
|
+
instance.valid?
|
221
|
+
instance.errors.on(:namen)
|
222
|
+
end
|
223
|
+
|
224
|
+
expect "can't be empty" do
|
225
|
+
child_class = Class.new do
|
226
|
+
include Validatable
|
227
|
+
attr_accessor :name, :address
|
228
|
+
validates_presence_of :name
|
229
|
+
end
|
230
|
+
klass = Class.new do
|
231
|
+
include Validatable
|
232
|
+
include_errors_from :child, :if => lambda { true }
|
233
|
+
define_method :child do
|
234
|
+
child_class.new
|
235
|
+
end
|
236
|
+
end
|
237
|
+
instance = klass.new
|
238
|
+
instance.valid?
|
239
|
+
instance.errors.on(:name)
|
240
|
+
end
|
241
|
+
|
242
|
+
expect true do
|
243
|
+
child_class = Class.new do
|
244
|
+
include Validatable
|
245
|
+
attr_accessor :name, :address
|
246
|
+
validates_presence_of :name
|
247
|
+
end
|
248
|
+
klass = Class.new do
|
249
|
+
include Validatable
|
250
|
+
include_errors_from :child, :if => lambda { false }
|
251
|
+
define_method :child do
|
252
|
+
child_class.new
|
253
|
+
end
|
254
|
+
end
|
255
|
+
instance = klass.new
|
256
|
+
instance.valid?
|
257
|
+
end
|
258
|
+
|
259
|
+
test ':if with symbol should work' do
|
260
|
+
klass = Class.new do
|
261
|
+
include Validatable
|
262
|
+
attr_accessor :name, :name_required
|
263
|
+
validates_presence_of :name, :if => :name_required?
|
264
|
+
|
265
|
+
def name_required?
|
266
|
+
name_required
|
267
|
+
end
|
268
|
+
end
|
269
|
+
instance = klass.new
|
270
|
+
instance.name_required = false
|
271
|
+
assert instance.valid?
|
272
|
+
instance.name_required = true
|
273
|
+
assert !instance.valid?
|
274
|
+
assert_equal "can't be empty", instance.errors.on(:name)
|
275
|
+
end
|
276
|
+
|
277
|
+
test ':if with string should work' do
|
278
|
+
klass = Class.new do
|
279
|
+
include Validatable
|
280
|
+
attr_accessor :name, :name_required
|
281
|
+
validates_presence_of :name, :if => 'name_required?'
|
282
|
+
|
283
|
+
def name_required?
|
284
|
+
name_required
|
285
|
+
end
|
286
|
+
end
|
287
|
+
instance = klass.new
|
288
|
+
instance.name_required = false
|
289
|
+
assert instance.valid?
|
290
|
+
instance.name_required = true
|
291
|
+
assert !instance.valid?
|
292
|
+
assert_equal "can't be empty", instance.errors.on(:name)
|
293
|
+
end
|
294
|
+
|
295
|
+
test "classes only have valid_for_* methods for groups that appear in their validations" do
|
296
|
+
class_with_group_one = Class.new do
|
297
|
+
include Validatable
|
298
|
+
validates_presence_of :name, :groups => :group_one
|
299
|
+
attr_accessor :name
|
300
|
+
end
|
301
|
+
class_with_group_two = Class.new do
|
302
|
+
include Validatable
|
303
|
+
validates_presence_of :name, :groups => :group_two
|
304
|
+
attr_accessor :name
|
305
|
+
end
|
306
|
+
assert_equal false, class_with_group_one.public_instance_methods.include?(:valid_for_group_two?)
|
307
|
+
assert_equal false, class_with_group_two.public_instance_methods.include?(:valid_for_group_one?)
|
308
|
+
end
|
309
|
+
|
310
|
+
test "nonmatching groups are not used as validations" do
|
311
|
+
klass = Class.new do
|
312
|
+
include Validatable
|
313
|
+
validates_presence_of :name, :groups => :group_one
|
314
|
+
validates_presence_of :address, :groups => :group_two
|
315
|
+
attr_accessor :name, :address
|
316
|
+
end
|
317
|
+
instance = klass.new
|
318
|
+
assert_equal nil, instance.errors.on(:name)
|
319
|
+
end
|
320
|
+
|
321
|
+
expect "can't be empty twice changed message" do
|
322
|
+
klass = Class.new do
|
323
|
+
include Validatable
|
324
|
+
validates_presence_of :name
|
325
|
+
attr_accessor :name
|
326
|
+
end
|
327
|
+
|
328
|
+
Validatable::ValidationBase.class_eval do
|
329
|
+
after_validate do |result, instance, attribute|
|
330
|
+
instance.errors.add(attribute, " changed message")
|
331
|
+
end
|
332
|
+
end
|
333
|
+
Validatable::ValidatesPresenceOf.class_eval do
|
334
|
+
after_validate do |result, instance, attribute|
|
335
|
+
instance.errors.add(attribute, " twice")
|
336
|
+
end
|
337
|
+
end
|
338
|
+
instance = klass.new
|
339
|
+
instance.valid?
|
340
|
+
Validatable::ValidatesPresenceOf.after_validations.clear
|
341
|
+
Validatable::ValidationBase.after_validations.clear
|
342
|
+
instance.errors.on(:name).join
|
343
|
+
end
|
344
|
+
|
345
|
+
expect false do
|
346
|
+
klass = Class.new do
|
347
|
+
include Validatable
|
348
|
+
validates_presence_of :name, :groups => :group_one
|
349
|
+
attr_accessor :name
|
350
|
+
end
|
351
|
+
instance = klass.new
|
352
|
+
instance.valid_for_group_one?
|
353
|
+
end
|
354
|
+
|
355
|
+
expect false do
|
356
|
+
klass = Class.new do
|
357
|
+
include Validatable
|
358
|
+
validates_presence_of :name, :groups => [:group_one, :group_two]
|
359
|
+
attr_accessor :name
|
360
|
+
end
|
361
|
+
instance = klass.new
|
362
|
+
instance.valid_for_group_one?
|
363
|
+
end
|
364
|
+
|
365
|
+
expect true do
|
366
|
+
klass = Class.new do
|
367
|
+
include Validatable
|
368
|
+
validates_presence_of :name, :groups => :group_one
|
369
|
+
validates_presence_of :address
|
370
|
+
attr_accessor :name, :address
|
371
|
+
end
|
372
|
+
instance = klass.new
|
373
|
+
instance.address = 'anything'
|
374
|
+
instance.valid?
|
375
|
+
end
|
376
|
+
|
377
|
+
expect true do
|
378
|
+
klass = Class.new do
|
379
|
+
include Validatable
|
380
|
+
validates_presence_of :name, :groups => :group_one
|
381
|
+
attr_accessor :name
|
382
|
+
end
|
383
|
+
instance = klass.new
|
384
|
+
instance.valid?
|
385
|
+
end
|
386
|
+
|
387
|
+
expect true do
|
388
|
+
klass = Class.new do
|
389
|
+
include Validatable
|
390
|
+
validates_presence_of :name, :times => 1
|
391
|
+
attr_accessor :name
|
392
|
+
end
|
393
|
+
instance = klass.new
|
394
|
+
instance.valid?
|
395
|
+
instance.valid?
|
396
|
+
end
|
397
|
+
|
398
|
+
expect false do
|
399
|
+
klass = Class.new do
|
400
|
+
include Validatable
|
401
|
+
validates_presence_of :name, :times => 1
|
402
|
+
attr_accessor :name
|
403
|
+
end
|
404
|
+
instance1 = klass.new
|
405
|
+
instance1.valid?
|
406
|
+
instance2 = klass.new
|
407
|
+
instance2.valid?
|
408
|
+
end
|
409
|
+
|
410
|
+
expect "name message" do
|
411
|
+
klass = Class.new do
|
412
|
+
include Validatable
|
413
|
+
validates_presence_of :name, :level => 1, :message => "name message"
|
414
|
+
validates_presence_of :address, :level => 2
|
415
|
+
attr_accessor :name, :address
|
416
|
+
end
|
417
|
+
instance = klass.new
|
418
|
+
instance.valid?
|
419
|
+
instance.errors.on(:name)
|
420
|
+
end
|
421
|
+
|
422
|
+
expect nil do
|
423
|
+
klass = Class.new do
|
424
|
+
include Validatable
|
425
|
+
validates_presence_of :name, :level => 1, :message => "name message"
|
426
|
+
validates_presence_of :address, :level => 2
|
427
|
+
attr_accessor :name, :address
|
428
|
+
end
|
429
|
+
instance = klass.new
|
430
|
+
instance.valid?
|
431
|
+
instance.errors.on(:address)
|
432
|
+
end
|
433
|
+
|
434
|
+
expect "Mod::Klass/Validatable::ValidatesPresenceOf/name" do
|
435
|
+
module Mod
|
436
|
+
class Klass
|
437
|
+
include Validatable
|
438
|
+
validates_presence_of :name
|
439
|
+
end
|
440
|
+
end
|
441
|
+
Mod::Klass.validations.first.key
|
442
|
+
end
|
443
|
+
|
444
|
+
expect "/Validatable::ValidatesPresenceOf/custom key" do
|
445
|
+
klass = Class.new do
|
446
|
+
include Validatable
|
447
|
+
validates_presence_of :name, :key => "custom key"
|
448
|
+
end
|
449
|
+
klass.validations.first.key
|
450
|
+
end
|
451
|
+
|
452
|
+
expect "can't be empty" do
|
453
|
+
klass = Class.new do
|
454
|
+
include Validatable
|
455
|
+
validates_presence_of :name, :address
|
456
|
+
attr_accessor :name, :address
|
457
|
+
end
|
458
|
+
instance = klass.new
|
459
|
+
instance.validate_only("presence_of/name")
|
460
|
+
instance.errors.on(:name)
|
461
|
+
end
|
462
|
+
|
463
|
+
expect nil do
|
464
|
+
klass = Class.new do
|
465
|
+
include Validatable
|
466
|
+
validates_presence_of :name, :address
|
467
|
+
attr_accessor :name, :address
|
468
|
+
end
|
469
|
+
instance = klass.new
|
470
|
+
instance.validate_only("presence_of/name")
|
471
|
+
instance.errors.on(:address)
|
472
|
+
end
|
473
|
+
|
474
|
+
test 'validate callback' do
|
475
|
+
klass = Class.new do
|
476
|
+
include Validatable
|
477
|
+
attr_accessor :action
|
478
|
+
validate :action_presence
|
479
|
+
|
480
|
+
private
|
481
|
+
def action_presence
|
482
|
+
errors.add(:action, 'is invalid') if action.blank?
|
483
|
+
end
|
484
|
+
end
|
485
|
+
instance = klass.new
|
486
|
+
instance.valid?
|
487
|
+
assert_equal 'is invalid', instance.errors.on(:action)
|
488
|
+
|
489
|
+
instance.action = 'walk'
|
490
|
+
instance.valid?
|
491
|
+
assert_nil instance.errors.on(:action)
|
492
|
+
end
|
493
|
+
|
494
|
+
test 'validate on create callback for new record' do
|
495
|
+
klass = Class.new do
|
496
|
+
include Validatable
|
497
|
+
attr_accessor :action
|
498
|
+
validate_on_create :action_presence
|
499
|
+
|
500
|
+
def new?
|
501
|
+
true
|
502
|
+
end
|
503
|
+
|
504
|
+
private
|
505
|
+
def action_presence
|
506
|
+
errors.add(:action, 'is invalid') if action.blank?
|
507
|
+
end
|
508
|
+
end
|
509
|
+
instance = klass.new
|
510
|
+
instance.valid?
|
511
|
+
assert_equal 'is invalid', instance.errors.on(:action)
|
512
|
+
|
513
|
+
instance.action = 'walk'
|
514
|
+
instance.valid?
|
515
|
+
assert_nil instance.errors.on(:action)
|
516
|
+
end
|
517
|
+
|
518
|
+
test 'validate on create callback for not new record' do
|
519
|
+
klass = Class.new do
|
520
|
+
include Validatable
|
521
|
+
attr_accessor :action
|
522
|
+
validate_on_create :action_presence
|
523
|
+
|
524
|
+
def new?
|
525
|
+
false
|
526
|
+
end
|
527
|
+
|
528
|
+
private
|
529
|
+
def action_presence
|
530
|
+
errors.add(:action, 'is invalid') if action.blank?
|
531
|
+
end
|
532
|
+
end
|
533
|
+
instance = klass.new
|
534
|
+
instance.valid?
|
535
|
+
assert_nil instance.errors.on(:action)
|
536
|
+
|
537
|
+
instance.action = 'walk'
|
538
|
+
instance.valid?
|
539
|
+
assert_nil instance.errors.on(:action)
|
540
|
+
end
|
541
|
+
|
542
|
+
test 'validate on update callback for new record' do
|
543
|
+
klass = Class.new do
|
544
|
+
include Validatable
|
545
|
+
attr_accessor :action
|
546
|
+
validate_on_update :action_presence
|
547
|
+
|
548
|
+
def new?
|
549
|
+
true
|
550
|
+
end
|
551
|
+
|
552
|
+
private
|
553
|
+
def action_presence
|
554
|
+
errors.add(:action, 'is invalid') if action.blank?
|
555
|
+
end
|
556
|
+
end
|
557
|
+
instance = klass.new
|
558
|
+
instance.valid?
|
559
|
+
assert_nil instance.errors.on(:action)
|
560
|
+
|
561
|
+
instance.action = 'walk'
|
562
|
+
instance.valid?
|
563
|
+
assert_nil instance.errors.on(:action)
|
564
|
+
end
|
565
|
+
|
566
|
+
test 'validate on update callback for not new record' do
|
567
|
+
klass = Class.new do
|
568
|
+
include Validatable
|
569
|
+
attr_accessor :action
|
570
|
+
validate_on_update :action_presence
|
571
|
+
|
572
|
+
def new?
|
573
|
+
false
|
574
|
+
end
|
575
|
+
|
576
|
+
private
|
577
|
+
def action_presence
|
578
|
+
errors.add(:action, 'is invalid') if action.blank?
|
579
|
+
end
|
580
|
+
end
|
581
|
+
instance = klass.new
|
582
|
+
instance.valid?
|
583
|
+
assert_equal 'is invalid', instance.errors.on(:action)
|
584
|
+
|
585
|
+
instance.action = 'walk'
|
586
|
+
instance.valid?
|
587
|
+
assert_nil instance.errors.on(:action)
|
588
|
+
end
|
589
|
+
end
|