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.
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,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
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'veto/configuration'
3
+
4
+ describe Veto::Configuration do
5
+ let(:configuration){ Veto::Configuration.new }
6
+ end
@@ -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
@@ -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
@@ -0,0 +1,6 @@
1
+ require 'minitest/autorun'
2
+ require 'mocha/setup'
3
+
4
+ def context *args, &block
5
+ describe *args, &block
6
+ end