veto 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +561 -0
  6. data/Rakefile +1 -0
  7. data/lib/veto/attribute_validator_factory.rb +32 -0
  8. data/lib/veto/builder.rb +65 -0
  9. data/lib/veto/conditions.rb +23 -0
  10. data/lib/veto/conditions_evaluator.rb +30 -0
  11. data/lib/veto/configuration.rb +42 -0
  12. data/lib/veto/errors.rb +35 -0
  13. data/lib/veto/exceptions.rb +5 -0
  14. data/lib/veto/model.rb +37 -0
  15. data/lib/veto/validator.rb +150 -0
  16. data/lib/veto/validators/abstract_validator.rb +15 -0
  17. data/lib/veto/validators/attribute_validator.rb +22 -0
  18. data/lib/veto/validators/custom_method_validator.rb +19 -0
  19. data/lib/veto/validators/exact_length_validator.rb +15 -0
  20. data/lib/veto/validators/format_validator.rb +15 -0
  21. data/lib/veto/validators/inclusion_validator.rb +16 -0
  22. data/lib/veto/validators/integer_validator.rb +17 -0
  23. data/lib/veto/validators/length_range_validator.rb +16 -0
  24. data/lib/veto/validators/max_length_validator.rb +15 -0
  25. data/lib/veto/validators/min_length_validator.rb +15 -0
  26. data/lib/veto/validators/not_null_validator.rb +14 -0
  27. data/lib/veto/validators/numeric_validator.rb +17 -0
  28. data/lib/veto/validators/presence_validator.rb +15 -0
  29. data/lib/veto/version.rb +3 -0
  30. data/lib/veto.rb +53 -0
  31. data/spec/attribute_validator_factory_spec.rb +72 -0
  32. data/spec/builder_spec.rb +38 -0
  33. data/spec/conditions_evaluator_spec.rb +90 -0
  34. data/spec/conditions_spec.rb +16 -0
  35. data/spec/configuration/message_spec.rb +30 -0
  36. data/spec/configuration_spec.rb +6 -0
  37. data/spec/errors_spec.rb +22 -0
  38. data/spec/model_spec.rb +67 -0
  39. data/spec/spec_helper.rb +6 -0
  40. data/spec/system/validator_spec.rb +380 -0
  41. data/spec/validator_spec.rb +119 -0
  42. data/spec/validators/exact_length_validator_spec.rb +37 -0
  43. data/spec/validators/format_validator_spec.rb +32 -0
  44. data/spec/validators/inclusion_validator_spec.rb +45 -0
  45. data/spec/validators/integer_validator_spec.rb +42 -0
  46. data/spec/validators/length_range_validator_spec.rb +55 -0
  47. data/spec/validators/max_length_validator_spec.rb +32 -0
  48. data/spec/validators/min_length_validator_spec.rb +32 -0
  49. data/spec/validators/not_null_validator_spec.rb +27 -0
  50. data/spec/validators/numeric_validator_spec.rb +42 -0
  51. data/spec/validators/presence_validator_spec.rb +47 -0
  52. data/spec/veto_spec.rb +24 -0
  53. data/veto.gemspec +24 -0
  54. 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