veto 0.0.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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +561 -0
- data/Rakefile +1 -0
- data/lib/veto/attribute_validator_factory.rb +32 -0
- data/lib/veto/builder.rb +65 -0
- data/lib/veto/conditions.rb +23 -0
- data/lib/veto/conditions_evaluator.rb +30 -0
- data/lib/veto/configuration.rb +42 -0
- data/lib/veto/errors.rb +35 -0
- data/lib/veto/exceptions.rb +5 -0
- data/lib/veto/model.rb +37 -0
- data/lib/veto/validator.rb +150 -0
- data/lib/veto/validators/abstract_validator.rb +15 -0
- data/lib/veto/validators/attribute_validator.rb +22 -0
- data/lib/veto/validators/custom_method_validator.rb +19 -0
- data/lib/veto/validators/exact_length_validator.rb +15 -0
- data/lib/veto/validators/format_validator.rb +15 -0
- data/lib/veto/validators/inclusion_validator.rb +16 -0
- data/lib/veto/validators/integer_validator.rb +17 -0
- data/lib/veto/validators/length_range_validator.rb +16 -0
- data/lib/veto/validators/max_length_validator.rb +15 -0
- data/lib/veto/validators/min_length_validator.rb +15 -0
- data/lib/veto/validators/not_null_validator.rb +14 -0
- data/lib/veto/validators/numeric_validator.rb +17 -0
- data/lib/veto/validators/presence_validator.rb +15 -0
- data/lib/veto/version.rb +3 -0
- data/lib/veto.rb +53 -0
- data/spec/attribute_validator_factory_spec.rb +72 -0
- data/spec/builder_spec.rb +38 -0
- data/spec/conditions_evaluator_spec.rb +90 -0
- data/spec/conditions_spec.rb +16 -0
- data/spec/configuration/message_spec.rb +30 -0
- data/spec/configuration_spec.rb +6 -0
- data/spec/errors_spec.rb +22 -0
- data/spec/model_spec.rb +67 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/system/validator_spec.rb +380 -0
- data/spec/validator_spec.rb +119 -0
- data/spec/validators/exact_length_validator_spec.rb +37 -0
- data/spec/validators/format_validator_spec.rb +32 -0
- data/spec/validators/inclusion_validator_spec.rb +45 -0
- data/spec/validators/integer_validator_spec.rb +42 -0
- data/spec/validators/length_range_validator_spec.rb +55 -0
- data/spec/validators/max_length_validator_spec.rb +32 -0
- data/spec/validators/min_length_validator_spec.rb +32 -0
- data/spec/validators/not_null_validator_spec.rb +27 -0
- data/spec/validators/numeric_validator_spec.rb +42 -0
- data/spec/validators/presence_validator_spec.rb +47 -0
- data/spec/veto_spec.rb +24 -0
- data/veto.gemspec +24 -0
- metadata +161 -0
@@ -0,0 +1,380 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto'
|
3
|
+
|
4
|
+
describe Veto do
|
5
|
+
let(:entity){ stub }
|
6
|
+
let(:validator_class) { Class.new{ include Veto.validator }}
|
7
|
+
let(:validator) { validator_class.new(entity) }
|
8
|
+
|
9
|
+
describe 'built-in validations' do
|
10
|
+
let(:value) { 'abc123' }
|
11
|
+
let(:entity) {stub(:name => value)}
|
12
|
+
let(:errors) { validator.valid?; validator.errors.on(:name) }
|
13
|
+
let(:validator_type){ :presence }
|
14
|
+
let(:options) { true }
|
15
|
+
let(:validator_class) do
|
16
|
+
klass = Class.new{ include Veto.validator }
|
17
|
+
klass.validates :name, options
|
18
|
+
klass
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'exact_length' do
|
22
|
+
let(:options) {{:exact_length => 10}}
|
23
|
+
|
24
|
+
context 'when value exact length' do
|
25
|
+
let(:value) { 'abcdefghij' }
|
26
|
+
it { errors.must_be_nil }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when value is too short' do
|
30
|
+
let(:value) { 'short' }
|
31
|
+
it { errors.must_equal ["is not 10 characters"] }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when value is too long' do
|
35
|
+
let(:value) { 'this title is wayyyy to long' }
|
36
|
+
it { errors.must_equal ["is not 10 characters"] }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when value is nil' do
|
40
|
+
let(:value) { nil }
|
41
|
+
it { errors.must_equal ["is not 10 characters"] }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe 'format' do
|
46
|
+
let(:options) {{:format => /^\d+$/}}
|
47
|
+
|
48
|
+
context 'when value matches pattern' do
|
49
|
+
let(:value) { 123 }
|
50
|
+
it { errors.must_be_nil }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when value does not match' do
|
54
|
+
let(:value) { 'abc' }
|
55
|
+
it { errors.must_equal ["is not valid"] }
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when value is nil' do
|
59
|
+
let(:value) { nil }
|
60
|
+
it { errors.must_equal ["is not valid"] }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'inclusion' do
|
65
|
+
context 'when set is array' do
|
66
|
+
let(:options) {{:inclusion => %w(cat dog bird rabbit)}}
|
67
|
+
|
68
|
+
context 'when value is in set' do
|
69
|
+
let(:value) { 'cat' }
|
70
|
+
it { errors.must_be_nil }
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when value is not in set' do
|
74
|
+
let(:value) { 'goat' }
|
75
|
+
it { errors.must_equal ["is not in set: [\"cat\", \"dog\", \"bird\", \"rabbit\"]"]}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'when set is range' do
|
80
|
+
let(:options) {{:inclusion => 10..20}}
|
81
|
+
|
82
|
+
context 'when value is in set' do
|
83
|
+
let(:value) { 11 }
|
84
|
+
it { errors.must_be_nil }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when value is not in set' do
|
88
|
+
let(:value) { 5 }
|
89
|
+
it { errors.must_equal ["is not in set: 10..20"] }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'integer' do
|
95
|
+
let(:options) {{:integer => true}}
|
96
|
+
|
97
|
+
context 'when value is integer' do
|
98
|
+
let(:value) { 123 }
|
99
|
+
it { errors.must_be_nil }
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when value is float' do
|
103
|
+
let(:value) { 123.4 }
|
104
|
+
it { errors.must_equal ["is not a number"]}
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'when value is string' do
|
108
|
+
let(:value) { 'abc' }
|
109
|
+
it { errors.must_equal ["is not a number"]}
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'when value is nil' do
|
113
|
+
let(:value) { nil }
|
114
|
+
it { errors.must_equal ["is not a number"]}
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'when value is everything else' do
|
118
|
+
let(:value) { ['array'] }
|
119
|
+
it { errors.must_equal ["is not a number"]}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe 'length_range' do
|
124
|
+
context 'when range is array' do
|
125
|
+
let(:options) {{:length_range => [5, 8, 15]}}
|
126
|
+
|
127
|
+
context 'when value length is in array' do
|
128
|
+
let(:value) { 'abcde' }
|
129
|
+
it { errors.must_be_nil }
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'when value length is not in array' do
|
133
|
+
let(:value) { 'abc' }
|
134
|
+
it { errors.must_equal ["is too short or too long"] }
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'when value length is nil' do
|
138
|
+
let(:value) { nil }
|
139
|
+
it { errors.must_equal ["is too short or too long"] }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'when range is range' do
|
144
|
+
let(:options) {{:length_range => 5..10}}
|
145
|
+
|
146
|
+
context 'when value length is in range' do
|
147
|
+
let(:value) { 'abcdef' }
|
148
|
+
it { errors.must_be_nil }
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'when value length is not in range' do
|
152
|
+
let(:value) { 'abc' }
|
153
|
+
it { errors.must_equal ["is too short or too long"] }
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'when value length is nil' do
|
157
|
+
let(:value) { nil }
|
158
|
+
it { errors.must_equal ["is too short or too long"] }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe 'max_length' do
|
164
|
+
let(:options) {{:max_length => 10}}
|
165
|
+
|
166
|
+
context 'when value length is less than max' do
|
167
|
+
let(:value) { 'abc' }
|
168
|
+
it { errors.must_be_nil }
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'when value is too long' do
|
172
|
+
let(:value) { 'abcdefghijklmnop' }
|
173
|
+
it { errors.must_equal ["is longer than 10 characters"] }
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'when value is nil' do
|
177
|
+
let(:value) { nil }
|
178
|
+
it { errors.must_equal ["is longer than 10 characters"] }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe 'min_length' do
|
183
|
+
let(:options) {{:min_length => 5}}
|
184
|
+
|
185
|
+
context 'when value length is greater than min' do
|
186
|
+
let(:value) { 'abcdefg' }
|
187
|
+
it { errors.must_be_nil }
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'when value is too short' do
|
191
|
+
let(:value) { 'abcd' }
|
192
|
+
it { errors.must_equal ["is shorter than 5 characters"] }
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'when value is nil' do
|
196
|
+
let(:value) { nil }
|
197
|
+
it { errors.must_equal ["is shorter than 5 characters"] }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe 'not_null' do
|
202
|
+
let(:options) {{:not_null => 5}}
|
203
|
+
|
204
|
+
context 'when value is not null' do
|
205
|
+
let(:value) { 123 }
|
206
|
+
it { errors.must_be_nil }
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'when value is nil' do
|
210
|
+
let(:value) { nil }
|
211
|
+
it { errors.must_equal ["is not present"]}
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe 'numeric' do
|
216
|
+
let(:options) {{:numeric => true}}
|
217
|
+
|
218
|
+
context 'when value is integer' do
|
219
|
+
let(:value) { 123 }
|
220
|
+
it { errors.must_be_nil }
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'when value is float' do
|
224
|
+
let(:value) { 123.4 }
|
225
|
+
it { errors.must_be_nil }
|
226
|
+
end
|
227
|
+
|
228
|
+
context 'when value is string' do
|
229
|
+
let(:value) { 'abc' }
|
230
|
+
it { errors.must_equal ["is not a number"]}
|
231
|
+
end
|
232
|
+
|
233
|
+
context 'when value is nil' do
|
234
|
+
let(:value) { nil }
|
235
|
+
it { errors.must_equal ["is not a number"]}
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'when value is everything else' do
|
239
|
+
let(:value) { ['array'] }
|
240
|
+
it { errors.must_equal ["is not a number"]}
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
describe 'presence' do
|
245
|
+
let(:options) {{:presence => true}}
|
246
|
+
|
247
|
+
context 'when value is not null' do
|
248
|
+
let(:value) { 123 }
|
249
|
+
it { errors.must_be_nil }
|
250
|
+
end
|
251
|
+
|
252
|
+
context 'when value is nil' do
|
253
|
+
let(:value) { nil }
|
254
|
+
it { errors.must_equal ["is not present"]}
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'when value is empty string' do
|
258
|
+
let(:value) { '' }
|
259
|
+
it { errors.must_equal ["is not present"]}
|
260
|
+
end
|
261
|
+
|
262
|
+
context 'when value is string of whitespace' do
|
263
|
+
let(:value) { ' ' }
|
264
|
+
it { errors.must_equal ["is not present"]}
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'when value is empty array' do
|
268
|
+
let(:value) { [] }
|
269
|
+
it { errors.must_equal ["is not present"]}
|
270
|
+
end
|
271
|
+
|
272
|
+
context 'when value is empty hash' do
|
273
|
+
let(:value) {{}}
|
274
|
+
it { errors.must_equal ["is not present"]}
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
describe 'conditions' do
|
280
|
+
describe 'with_options' do
|
281
|
+
let(:conditions) {{:if => true}}
|
282
|
+
let(:validator_class) do
|
283
|
+
klass = Class.new{
|
284
|
+
include Veto.validator
|
285
|
+
|
286
|
+
def create_errors
|
287
|
+
errors.add(:base, "error")
|
288
|
+
end
|
289
|
+
}
|
290
|
+
klass.with_options conditions do
|
291
|
+
validate :create_errors
|
292
|
+
end
|
293
|
+
klass
|
294
|
+
end
|
295
|
+
|
296
|
+
context 'when conditions pass' do
|
297
|
+
let(:conditions) {{:if => true}}
|
298
|
+
|
299
|
+
it 'performs validations within block' do
|
300
|
+
validator.valid?.must_equal false
|
301
|
+
validator.errors.full_messages.must_equal ['base error']
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
context 'when conditions fail' do
|
306
|
+
let(:conditions) {{:if => false}}
|
307
|
+
|
308
|
+
it 'does not perform validations within block' do
|
309
|
+
validator.valid?
|
310
|
+
validator.errors.must_be_empty
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
describe 'validates' do
|
316
|
+
let(:entity){ stub(:title => nil, :name => 'John') }
|
317
|
+
let(:options) {{}}
|
318
|
+
let(:validator_class) do
|
319
|
+
klass = Class.new{
|
320
|
+
include Veto.validator
|
321
|
+
}
|
322
|
+
|
323
|
+
klass.validates :title, options
|
324
|
+
klass
|
325
|
+
end
|
326
|
+
|
327
|
+
context 'when outer conditions pass' do
|
328
|
+
context 'when inner conditions pass' do
|
329
|
+
let(:options) {{:not_null => {:with => true, :if => true}, :exact_length => {:with => 4, :if => true}, :if => true}}
|
330
|
+
|
331
|
+
it 'performs validation' do
|
332
|
+
validator.valid?.must_equal false
|
333
|
+
validator.errors.full_messages.must_equal ["title is not present", "title is not 4 characters"]
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
context 'when inner conditions fail' do
|
338
|
+
let(:options) {{:not_null => {:with => true, :if => false}, :exact_length => {:with => 4, :if => true}, :if => true}}
|
339
|
+
|
340
|
+
it 'skips individual validator' do
|
341
|
+
validator.valid?.must_equal false
|
342
|
+
validator.errors.full_messages.must_equal ["title is not 4 characters"]
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
context 'when outer conditions fail' do
|
348
|
+
let(:options) {{:not_null => {:with => true, :if => true}, :exact_length => {:with => 4, :if => true}, :if => false}}
|
349
|
+
|
350
|
+
it 'skips validates block' do
|
351
|
+
validator.valid?.must_equal true
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
describe 'custom attribute validator class' do
|
358
|
+
let(:entity){ stub(:email_address => 'blah') }
|
359
|
+
let(:validator_class) do
|
360
|
+
klass = Class.new{
|
361
|
+
include Veto.validator
|
362
|
+
|
363
|
+
class EmailValidator < ::Veto::AttributeValidator
|
364
|
+
def validate entity, attribute, value, errors, options={}
|
365
|
+
unless value.to_s =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
|
366
|
+
errors.add(attribute, "is not a valid email address")
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
validates :email_address, :email => true
|
372
|
+
}
|
373
|
+
end
|
374
|
+
|
375
|
+
it 'uses custom validator' do
|
376
|
+
validator.valid?.must_equal false
|
377
|
+
validator.errors.full_messages.must_equal ["email_address is not a valid email address"]
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/validator'
|
3
|
+
|
4
|
+
describe Veto::Validator do
|
5
|
+
let(:entity){ stub }
|
6
|
+
let(:validator_class) { Class.new{ include Veto::Validator } }
|
7
|
+
let(:validator) { validator_class.new(entity) }
|
8
|
+
|
9
|
+
describe '::builder' do
|
10
|
+
it 'returns builder' do
|
11
|
+
validator_class.send(:builder).must_be_instance_of Veto::Builder
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '::with_options' do
|
16
|
+
it 'delegates to builder' do
|
17
|
+
builder = stub
|
18
|
+
validator_class.expects(:builder).returns(builder)
|
19
|
+
builder.expects(:with_options).with('args')
|
20
|
+
validator_class.with_options('args')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '::validates' do
|
25
|
+
it 'delegates to builder' do
|
26
|
+
builder = stub
|
27
|
+
validator_class.expects(:builder).returns(builder)
|
28
|
+
builder.expects(:validates).with('args')
|
29
|
+
validator_class.validates('args')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '::validate' do
|
34
|
+
it 'delegates to builder' do
|
35
|
+
builder = stub
|
36
|
+
validator_class.expects(:builder).returns(builder)
|
37
|
+
builder.expects(:validate).with('args')
|
38
|
+
validator_class.validate('args')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '::validate_with' do
|
43
|
+
it 'adds validator to validators array' do
|
44
|
+
validator = stub
|
45
|
+
validator_class.validate_with validator
|
46
|
+
validator_class.validators.must_equal [validator]
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'adds validators to validators array' do
|
50
|
+
validator = stub
|
51
|
+
validator_class.validate_with [validator, validator]
|
52
|
+
validator_class.validators.must_equal [validator, validator]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '::validators' do
|
57
|
+
it 'returns validators list' do
|
58
|
+
validator_class.validators.must_equal []
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '::valid?' do
|
63
|
+
it 'initializes new instance and delegates to instance method' do
|
64
|
+
validator_class.expects(:new).with(entity).returns(entity)
|
65
|
+
entity.expects(:valid?)
|
66
|
+
validator_class.valid?(entity)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '::validate!' do
|
71
|
+
it 'initializes new instance and delegates to instance method' do
|
72
|
+
validator_class.expects(:new).with(entity).returns(entity)
|
73
|
+
entity.expects(:validate!)
|
74
|
+
validator_class.validate!(entity)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#valid?' do
|
79
|
+
context 'when entity is valid' do
|
80
|
+
it 'returns true' do
|
81
|
+
errors = stub(:empty? => true)
|
82
|
+
validator.expects(:errors => errors)
|
83
|
+
validator.valid?.must_equal true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when entity is invalid' do
|
88
|
+
it 'returns false' do
|
89
|
+
errors = stub(:empty? => false)
|
90
|
+
validator.expects(:errors => errors)
|
91
|
+
validator.valid?.must_equal false
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#validate!' do
|
97
|
+
context 'when entity is valid' do
|
98
|
+
it 'returns true' do
|
99
|
+
validator.expects(:valid?).returns(true)
|
100
|
+
validator.validate!.must_be_nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when entity is invalid' do
|
105
|
+
it 'returns false' do
|
106
|
+
errors = stub(:full_messages => '')
|
107
|
+
validator.expects(:valid?).returns(false)
|
108
|
+
validator.expects(:errors => errors)
|
109
|
+
proc { validator.validate! }.must_raise ::Veto::InvalidEntity
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#errors' do
|
115
|
+
it 'returns errors object' do
|
116
|
+
validator.errors.must_be_instance_of Veto::Errors
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/validators/exact_length_validator'
|
3
|
+
require 'veto/errors'
|
4
|
+
|
5
|
+
describe Veto::ExactLengthValidator do
|
6
|
+
let(:errors){ Veto::Errors.new }
|
7
|
+
let(:entity) { Object.new }
|
8
|
+
let(:attribute) { :title }
|
9
|
+
let(:value) { 'blahblah' }
|
10
|
+
let(:options) {{:with => 10}}
|
11
|
+
let(:validator){ Veto::ExactLengthValidator.new(stub, stub) }
|
12
|
+
let(:result){ validator.validate(entity, attribute, value, errors, options) }
|
13
|
+
|
14
|
+
describe '#validate' do
|
15
|
+
before { result }
|
16
|
+
|
17
|
+
context 'when value exact length' do
|
18
|
+
let(:value) { 'abcdefghij' }
|
19
|
+
it { errors[:title].must_be_nil }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when value is too short' do
|
23
|
+
let(:value) { 'short' }
|
24
|
+
it { errors[:title].must_equal ["is not 10 characters"] }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when value is too long' do
|
28
|
+
let(:value) { 'this title is wayyyy to long' }
|
29
|
+
it { errors[:title].must_equal ["is not 10 characters"] }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when value is nil' do
|
33
|
+
let(:value) { nil }
|
34
|
+
it { errors[:title].must_equal ["is not 10 characters"] }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/validators/format_validator'
|
3
|
+
require 'veto/errors'
|
4
|
+
|
5
|
+
describe Veto::FormatValidator do
|
6
|
+
let(:errors){ Veto::Errors.new }
|
7
|
+
let(:entity) { Object.new }
|
8
|
+
let(:attribute) { :title }
|
9
|
+
let(:value) { 'blahblah' }
|
10
|
+
let(:options) {{:with => /^\d+$/}}
|
11
|
+
let(:validator){ Veto::FormatValidator.new(stub, stub) }
|
12
|
+
let(:result){ validator.validate(entity, attribute, value, errors, options) }
|
13
|
+
|
14
|
+
describe '#validate' do
|
15
|
+
before { result }
|
16
|
+
|
17
|
+
context 'when value matches pattern' do
|
18
|
+
let(:value) { 123 }
|
19
|
+
it { errors[:title].must_be_nil }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when value does not match' do
|
23
|
+
let(:value) { 'abc' }
|
24
|
+
it { errors[:title].must_equal ["is not valid"] }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when value is nil' do
|
28
|
+
let(:value) { nil }
|
29
|
+
it { errors[:title].must_equal ["is not valid"] }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/validators/inclusion_validator'
|
3
|
+
require 'veto/errors'
|
4
|
+
|
5
|
+
describe Veto::InclusionValidator do
|
6
|
+
let(:errors){ Veto::Errors.new }
|
7
|
+
let(:entity) { Object.new }
|
8
|
+
let(:attribute) { :title }
|
9
|
+
let(:value) { 'blahblah' }
|
10
|
+
let(:options) {{:in => %w(cat dog bird rabbit)}}
|
11
|
+
let(:validator){ Veto::InclusionValidator.new(stub, stub) }
|
12
|
+
let(:result){ validator.validate(entity, attribute, value, errors, options) }
|
13
|
+
|
14
|
+
describe '#validate' do
|
15
|
+
before { result }
|
16
|
+
|
17
|
+
context 'when set is array' do
|
18
|
+
let(:options) {{:in => %w(cat dog bird rabbit)}}
|
19
|
+
|
20
|
+
context 'when value is in set' do
|
21
|
+
let(:value) { 'cat' }
|
22
|
+
it { errors[:title].must_be_nil }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when value is not in set' do
|
26
|
+
let(:value) { 'goat' }
|
27
|
+
it { errors[:title].must_equal ["is not in set: [\"cat\", \"dog\", \"bird\", \"rabbit\"]"]}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when set is range' do
|
32
|
+
let(:options) {{:in => (10..20)}}
|
33
|
+
|
34
|
+
context 'when value is in set' do
|
35
|
+
let(:value) { 11 }
|
36
|
+
it { errors[:title].must_be_nil }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when value is not in set' do
|
40
|
+
let(:value) { 5 }
|
41
|
+
it { errors[:title].must_equal ["is not in set: 10..20"] }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/validators/integer_validator'
|
3
|
+
require 'veto/errors'
|
4
|
+
|
5
|
+
describe Veto::IntegerValidator do
|
6
|
+
let(:errors){ Veto::Errors.new }
|
7
|
+
let(:entity) { Object.new }
|
8
|
+
let(:attribute) { :title }
|
9
|
+
let(:value) { 'blahblah' }
|
10
|
+
let(:options) {{:with => {}}}
|
11
|
+
let(:validator){ Veto::IntegerValidator.new(stub, stub) }
|
12
|
+
let(:result){ validator.validate(entity, attribute, value, errors, options) }
|
13
|
+
|
14
|
+
describe '#validate' do
|
15
|
+
before { result }
|
16
|
+
|
17
|
+
context 'when value is integer' do
|
18
|
+
let(:value) { 123 }
|
19
|
+
it { errors[:title].must_be_nil }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when value is float' do
|
23
|
+
let(:value) { 123.4 }
|
24
|
+
it { errors[:title].must_equal ["is not a number"]}
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when value is string' do
|
28
|
+
let(:value) { 'abc' }
|
29
|
+
it { errors[:title].must_equal ["is not a number"]}
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when value is nil' do
|
33
|
+
let(:value) { nil }
|
34
|
+
it { errors[:title].must_equal ["is not a number"]}
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when value is everything else' do
|
38
|
+
let(:value) { ['array'] }
|
39
|
+
it { errors[:title].must_equal ["is not a number"]}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/validators/length_range_validator'
|
3
|
+
require 'veto/errors'
|
4
|
+
|
5
|
+
describe Veto::LengthRangeValidator do
|
6
|
+
let(:errors){ Veto::Errors.new }
|
7
|
+
let(:entity) { Object.new }
|
8
|
+
let(:attribute) { :title }
|
9
|
+
let(:value) { 'blahblah' }
|
10
|
+
let(:options) {{:in => (1..10)}}
|
11
|
+
let(:validator){ Veto::LengthRangeValidator.new(attribute, options) }
|
12
|
+
let(:result){ validator.validate(entity, attribute, value, errors, options) }
|
13
|
+
|
14
|
+
describe '#validate' do
|
15
|
+
before { result }
|
16
|
+
|
17
|
+
context 'when range is array' do
|
18
|
+
let(:options) {{:in => [5, 8, 15]}}
|
19
|
+
|
20
|
+
context 'when value length is in array' do
|
21
|
+
let(:value) { 'abcde' }
|
22
|
+
it { errors[:title].must_be_nil }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when value length is not in array' do
|
26
|
+
let(:value) { 'abc' }
|
27
|
+
it { errors[:title].must_equal ["is too short or too long"] }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when value length is nil' do
|
31
|
+
let(:value) { nil }
|
32
|
+
it { errors[:title].must_equal ["is too short or too long"] }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when range is range' do
|
37
|
+
let(:options) {{:in => (5..10)}}
|
38
|
+
|
39
|
+
context 'when value length is in range' do
|
40
|
+
let(:value) { 'abcdef' }
|
41
|
+
it { errors[:title].must_be_nil }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when value length is not in range' do
|
45
|
+
let(:value) { 'abc' }
|
46
|
+
it { errors[:title].must_equal ["is too short or too long"] }
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when value length is nil' do
|
50
|
+
let(:value) { nil }
|
51
|
+
it { errors[:title].must_equal ["is too short or too long"] }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|