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,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/attribute_validator_factory'
|
3
|
+
require 'veto'
|
4
|
+
|
5
|
+
describe Veto::AttributeValidatorFactory do
|
6
|
+
let(:factory) { Veto::AttributeValidatorFactory }
|
7
|
+
let(:type) { :format }
|
8
|
+
|
9
|
+
describe '::new_validator' do
|
10
|
+
let(:attribute){ :first_name }
|
11
|
+
let(:options) { {} }
|
12
|
+
let(:result) { factory.new_validator(type, attribute, options) }
|
13
|
+
|
14
|
+
context 'when type is exact_length' do
|
15
|
+
let(:type) { :exact_length }
|
16
|
+
it { result.must_be_instance_of Veto::ExactLengthValidator }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when type is format' do
|
20
|
+
let(:type) { :format }
|
21
|
+
it { result.must_be_instance_of Veto::FormatValidator }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when type is inclusion' do
|
25
|
+
let(:type) { :inclusion }
|
26
|
+
it { result.must_be_instance_of Veto::InclusionValidator }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when type is integer' do
|
30
|
+
let(:type) { :integer }
|
31
|
+
it { result.must_be_instance_of Veto::IntegerValidator }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when type is length_range' do
|
35
|
+
let(:type) { :length_range }
|
36
|
+
it { result.must_be_instance_of Veto::LengthRangeValidator }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when type is max_length' do
|
40
|
+
let(:type) { :max_length }
|
41
|
+
it { result.must_be_instance_of Veto::MaxLengthValidator }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when type is min_length' do
|
45
|
+
let(:type) { :min_length }
|
46
|
+
it { result.must_be_instance_of Veto::MinLengthValidator }
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when type is not_null' do
|
50
|
+
let(:type) { :not_null }
|
51
|
+
it { result.must_be_instance_of Veto::NotNullValidator }
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when type is numeric' do
|
55
|
+
let(:type) { :numeric }
|
56
|
+
it { result.must_be_instance_of Veto::NumericValidator }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when type is presence' do
|
60
|
+
let(:type) { :presence }
|
61
|
+
it { result.must_be_instance_of Veto::PresenceValidator }
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when type not recognized' do
|
65
|
+
let(:type) { :blah }
|
66
|
+
it 'raises error' do
|
67
|
+
e = proc{ result }.must_raise(ArgumentError)
|
68
|
+
e.message.must_equal 'Validator not found: ::Veto::BlahValidator'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# require 'spec_helper'
|
2
|
+
# require 'veto/builder'
|
3
|
+
|
4
|
+
# describe Veto::Builder do
|
5
|
+
# let(:context) {stub}
|
6
|
+
# let(:context_conditions){ {:if => :is_good?} }
|
7
|
+
# let(:builder) { Veto::Builder.new(context, context_conditions) }
|
8
|
+
|
9
|
+
# describe '#with_options' do
|
10
|
+
# it 'returns new builder instance' do
|
11
|
+
# result = builder.with_options(:if => :is_tasty?, :unless => :rotten?)
|
12
|
+
# result.must_be_instance_of Veto::Builder
|
13
|
+
# end
|
14
|
+
|
15
|
+
# it 'passes conditions to instance as new conditions context' do
|
16
|
+
# result = builder.with_options(:if => :is_tasty?, :unless => :rotten?)
|
17
|
+
# result.conditions_context.must_equal({:if=>[:is_good?, :is_tasty?], :unless=>[:rotten?]})
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# describe '#validates' do
|
22
|
+
# it 'passes list of validators to validates_with' do
|
23
|
+
# validators = stub
|
24
|
+
# Veto::Builder::ValidatesBuilder.expects(:validators).returns(validators)
|
25
|
+
# builder.expects(:validate_with).with(validators)
|
26
|
+
# builder.validates(:first_name, :presence => true, :if => 'high5')
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
# describe '#validate' do
|
31
|
+
# it 'passes list of validators to validates_with' do
|
32
|
+
# validators = stub
|
33
|
+
# builder.expects(:validate_with)
|
34
|
+
# Veto::Builder::ValidateBuilder.expects(:validators).returns(validators)
|
35
|
+
# builder.validate(:meth1, :meth2, :if => :cond1)
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
# end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/conditions_evaluator'
|
3
|
+
|
4
|
+
describe Veto::ConditionsEvaluator do
|
5
|
+
let(:conditions){}
|
6
|
+
let(:entity){Object.new}
|
7
|
+
let(:context){Object.new}
|
8
|
+
let(:evaluator) { Veto::ConditionsEvaluator.new(conditions) }
|
9
|
+
|
10
|
+
describe '::truthy?' do
|
11
|
+
let(:condition){}
|
12
|
+
let(:result) { Veto::ConditionsEvaluator.truthy?(condition, context, entity) }
|
13
|
+
|
14
|
+
context 'when condition is true' do
|
15
|
+
let(:condition) { true }
|
16
|
+
it { result.must_equal true }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when condition is false' do
|
20
|
+
let(:condition) { false }
|
21
|
+
it { result.must_equal false }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when condition is nil' do
|
25
|
+
let(:condition) { nil }
|
26
|
+
it { result.must_equal false }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when condition is 0' do
|
30
|
+
let(:condition) { 0 }
|
31
|
+
it { result.must_equal true }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when condition is string' do
|
35
|
+
let(:entity) { stub(:is_alive => true) }
|
36
|
+
let(:condition) { 'is_alive' }
|
37
|
+
it { result.must_equal true }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when condition is empty string' do
|
41
|
+
let(:condition) { '' }
|
42
|
+
it { result.must_equal false }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when condition is empty hash' do
|
46
|
+
let(:condition) { {} }
|
47
|
+
it { result.must_equal true }
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when condition is method_name symbol' do
|
51
|
+
let(:context) { stub(:active? => true) }
|
52
|
+
let(:condition) { :active? }
|
53
|
+
it { result.must_equal true }
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when condition is proc' do
|
57
|
+
let(:entity) { stub(:is_alive => true) }
|
58
|
+
let(:condition) { Proc.new{|e| e.is_alive } }
|
59
|
+
it { result.must_equal true }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '::truthy_conditions?' do
|
64
|
+
let(:conditions){}
|
65
|
+
let(:result) { Veto::ConditionsEvaluator.truthy_conditions?(conditions, context, entity) }
|
66
|
+
|
67
|
+
context 'when no conditions are assigned' do
|
68
|
+
let(:conditions){{}}
|
69
|
+
it { result.must_equal true }
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when if conditions return true' do
|
73
|
+
context 'when unless conditions return false' do
|
74
|
+
let(:conditions){{:if => [true, true], :unless => [false, false]}}
|
75
|
+
it { result.must_equal true }
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when one unless conditions returns true' do
|
79
|
+
let(:conditions){{:if => [true, true], :unless => [true, false]}}
|
80
|
+
it { result.must_equal false }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'when one if condition returns false' do
|
85
|
+
let(:conditions){{:if => [false, true], :unless => [false, false]}}
|
86
|
+
it { result.must_equal false }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/conditions'
|
3
|
+
|
4
|
+
describe Veto::Conditions do
|
5
|
+
let(:params){{:if => :condition1, :unless => :condition2}}
|
6
|
+
let(:conditions){ Veto::Conditions.new(params) }
|
7
|
+
|
8
|
+
describe '::merge' do
|
9
|
+
it 'extracts and merges condition values' do
|
10
|
+
cond1 = {:if => [:is_good?, :is_tasty?]}
|
11
|
+
cond2 = {:if => "shaking", :unless => :is_bad?, :anotherkey => 'value'}
|
12
|
+
result = Veto::Conditions.merge(cond1, cond2)
|
13
|
+
result.must_equal({:if => [:is_good?, :is_tasty?, "shaking"], :unless => [:is_bad?]})
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/configuration'
|
3
|
+
|
4
|
+
describe Veto::Configuration::Message do
|
5
|
+
let(:msg_proc){ Proc.new{'custom message'} }
|
6
|
+
let(:msg){ Veto::Configuration::Message.new }
|
7
|
+
|
8
|
+
describe '#set' do
|
9
|
+
it 'sets options on type' do
|
10
|
+
msg.send(:custom_messages).must_equal({})
|
11
|
+
msg.set(:exact_format, msg_proc)
|
12
|
+
msg.send(:custom_messages).must_equal({:exact_format => msg_proc})
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#get' do
|
17
|
+
context 'when custom_message is defined' do
|
18
|
+
it 'returns custom message' do
|
19
|
+
msg.set(:presence, msg_proc)
|
20
|
+
msg.get(:presence).must_equal 'custom message'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when custom_message is not defined' do
|
25
|
+
it 'returns default message' do
|
26
|
+
msg.get(:presence).must_equal 'is not present'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/spec/errors_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/errors'
|
3
|
+
require 'veto'
|
4
|
+
|
5
|
+
describe Veto::Errors do
|
6
|
+
let(:errors){ Veto::Errors.new }
|
7
|
+
describe '#add' do
|
8
|
+
context 'when message is string' do
|
9
|
+
it 'adds message to errors' do
|
10
|
+
errors.add(:name, 'is too long')
|
11
|
+
errors[:name].must_equal ['is too long']
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when message contains message dictionary key' do
|
16
|
+
it 'adds dictionary message to errors' do
|
17
|
+
errors.add(:name, :presence)
|
18
|
+
errors[:name].must_equal ["is not present"]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/spec/model_spec.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'veto/model'
|
3
|
+
|
4
|
+
describe Veto::Model do
|
5
|
+
let(:validator){stub}
|
6
|
+
let(:validator_class){stub(:new => validator)}
|
7
|
+
let(:entity_class) {
|
8
|
+
klass = Class.new{
|
9
|
+
include Veto::Model
|
10
|
+
attr_accessor :first_name, :last_name
|
11
|
+
}
|
12
|
+
klass.validates_with validator_class
|
13
|
+
klass
|
14
|
+
}
|
15
|
+
let(:entity){ entity_class.new }
|
16
|
+
|
17
|
+
describe '::validates_with' do
|
18
|
+
it 'assigns validator' do
|
19
|
+
obj = Object.new
|
20
|
+
entity_class.validates_with obj
|
21
|
+
entity_class.validator.must_equal obj
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '::validator' do
|
26
|
+
context 'when validator is assigned' do
|
27
|
+
it 'returns validator' do
|
28
|
+
entity_class.validator.must_equal validator_class
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when validator is not assigned' do
|
33
|
+
before { entity_class.validates_with nil }
|
34
|
+
|
35
|
+
it 'raises error' do
|
36
|
+
proc{ entity_class.validator }.must_raise ::Veto::ValidatorNotAssigned
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#validator' do
|
42
|
+
it 'initializes, memoizes, and returns validator instance' do
|
43
|
+
entity.send(:validator).must_equal validator
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#errors' do
|
48
|
+
it 'delegates method to validator' do
|
49
|
+
validator.expects(:errors)
|
50
|
+
entity.errors
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#valid?' do
|
55
|
+
it 'delegates method to validator' do
|
56
|
+
validator.expects(:valid?)
|
57
|
+
entity.valid?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#validate!' do
|
62
|
+
it 'delegates method to validator' do
|
63
|
+
validator.expects(:validate!)
|
64
|
+
entity.validate!
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|