vanguard 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +17 -0
  5. data/Gemfile +7 -0
  6. data/Gemfile.devtools +56 -0
  7. data/Guardfile +18 -0
  8. data/LICENSE +21 -0
  9. data/README.md +80 -0
  10. data/Rakefile +2 -0
  11. data/TODO +3 -0
  12. data/config/flay.yml +3 -0
  13. data/config/flog.yml +2 -0
  14. data/config/mutant.yml +3 -0
  15. data/config/reek.yml +99 -0
  16. data/config/roodi.yml +26 -0
  17. data/config/yardstick.yml +2 -0
  18. data/lib/vanguard.rb +85 -0
  19. data/lib/vanguard/builder.rb +14 -0
  20. data/lib/vanguard/builder/nullary.rb +182 -0
  21. data/lib/vanguard/dsl.rb +43 -0
  22. data/lib/vanguard/dsl/evaluator.rb +197 -0
  23. data/lib/vanguard/evaluator.rb +72 -0
  24. data/lib/vanguard/instance_methods.rb +76 -0
  25. data/lib/vanguard/matcher.rb +19 -0
  26. data/lib/vanguard/matcher/binary.rb +59 -0
  27. data/lib/vanguard/matcher/binary/and.rb +20 -0
  28. data/lib/vanguard/matcher/binary/or.rb +20 -0
  29. data/lib/vanguard/matcher/binary/xor.rb +22 -0
  30. data/lib/vanguard/matcher/nullary.rb +27 -0
  31. data/lib/vanguard/matcher/nullary/equality.rb +46 -0
  32. data/lib/vanguard/matcher/nullary/format.rb +126 -0
  33. data/lib/vanguard/matcher/nullary/greater_than.rb +45 -0
  34. data/lib/vanguard/matcher/nullary/identity.rb +50 -0
  35. data/lib/vanguard/matcher/nullary/inclusion.rb +67 -0
  36. data/lib/vanguard/matcher/nullary/less_than.rb +48 -0
  37. data/lib/vanguard/matcher/nullary/primitive.rb +47 -0
  38. data/lib/vanguard/matcher/nullary/proc.rb +44 -0
  39. data/lib/vanguard/matcher/nullary/value.rb +32 -0
  40. data/lib/vanguard/matcher/unary.rb +45 -0
  41. data/lib/vanguard/matcher/unary/attribute.rb +49 -0
  42. data/lib/vanguard/matcher/unary/not.rb +25 -0
  43. data/lib/vanguard/result.rb +93 -0
  44. data/lib/vanguard/rule.rb +43 -0
  45. data/lib/vanguard/rule/guard.rb +103 -0
  46. data/lib/vanguard/rule/nullary.rb +81 -0
  47. data/lib/vanguard/rule/nullary/attribute.rb +69 -0
  48. data/lib/vanguard/rule/nullary/attribute/absence.rb +19 -0
  49. data/lib/vanguard/rule/nullary/attribute/format.rb +46 -0
  50. data/lib/vanguard/rule/nullary/attribute/inclusion.rb +62 -0
  51. data/lib/vanguard/rule/nullary/attribute/length.rb +184 -0
  52. data/lib/vanguard/rule/nullary/attribute/predicate.rb +10 -0
  53. data/lib/vanguard/rule/nullary/attribute/presence.rb +32 -0
  54. data/lib/vanguard/rule/nullary/attribute/presence/not_blank.rb +0 -0
  55. data/lib/vanguard/rule/nullary/attribute/presence/not_nil.rb +0 -0
  56. data/lib/vanguard/rule/nullary/attribute/primitive.rb +35 -0
  57. data/lib/vanguard/rule/nullary/confirmation.rb +210 -0
  58. data/lib/vanguard/support/blank.rb +29 -0
  59. data/lib/vanguard/validator.rb +116 -0
  60. data/lib/vanguard/validator/builder.rb +52 -0
  61. data/lib/vanguard/violation.rb +84 -0
  62. data/spec/integration/vanguard/dsl/guard_spec.rb +58 -0
  63. data/spec/integration/vanguard/dsl/validates_absence_of_spec.rb +19 -0
  64. data/spec/integration/vanguard/dsl/validates_acceptance_of_spec.rb +19 -0
  65. data/spec/integration/vanguard/dsl/validates_confirmation_of_spec.rb +27 -0
  66. data/spec/integration/vanguard/dsl/validates_format_of_spec.rb +79 -0
  67. data/spec/integration/vanguard/dsl/validates_inclusion_of_spec.rb +23 -0
  68. data/spec/integration/vanguard/dsl/validates_length_of_spec.rb +77 -0
  69. data/spec/integration/vanguard/dsl/validates_presence_of_spec.rb +19 -0
  70. data/spec/integration/vanguard/dsl/validates_value_of_spec.rb +30 -0
  71. data/spec/integration/vanguard/validator_spec.rb +57 -0
  72. data/spec/rcov.opts +6 -0
  73. data/spec/shared/dsl_spec.rb +73 -0
  74. data/spec/spec_helper.rb +3 -0
  75. data/spec/suite.rb +10 -0
  76. data/spec/unit/vanguard/support/blank_spec.rb +72 -0
  77. data/vanguard.gemspec +23 -0
  78. metadata +190 -0
@@ -0,0 +1,10 @@
1
+ module Vanguard
2
+ class Rule
3
+ class Nullary
4
+ class Attribute
5
+ class Predicate < self
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ #encoding: utf-8
2
+
3
+ module Vanguard
4
+ class Rule
5
+ class Nullary
6
+ class Attribute
7
+
8
+ # Rule for testing attribute presance
9
+ class Presence < self
10
+ TYPE = :presence
11
+ MATCHER = Matcher::Unary::NOT.new(Matcher::Nullary::BLANK)
12
+ register :validates_presence_of
13
+
14
+ private
15
+
16
+ # Initalize object
17
+ #
18
+ # @param [Symbol] attribute_name
19
+ # @param [Matcher] matcher
20
+ #
21
+ # @return [undefined]
22
+ #
23
+ # @api private
24
+ #
25
+ def initialize(attribute_name, matcher = MATCHER)
26
+ super
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ #encoding: utf-8
2
+
3
+ module Vanguard
4
+ class Rule
5
+ class Nullary
6
+ class Attribute
7
+
8
+ # Rule for testing primitives
9
+ class Primitive < self
10
+ TYPE = :primitive
11
+
12
+ # Builder for primitive rules
13
+ class Builder < Nullary::Builder
14
+ REQUIRED_OPTIONS = [:primitive].freeze
15
+
16
+ private
17
+
18
+ # Return matcher
19
+ #
20
+ # @return [MAtcher]
21
+ #
22
+ # @api private
23
+ #
24
+ def matcher
25
+ Matcher::Nullary::Primitive.new(options.fetch(:primitive))
26
+ end
27
+ memoize :matcher
28
+ end
29
+
30
+ register :validates_primitive_of
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,210 @@
1
+ #encoding: utf-8
2
+
3
+ module Vanguard
4
+ class Rule
5
+ class Nullary
6
+
7
+ # For for testing attribute confirmations
8
+ class Confirmation < self
9
+ include Equalizer.new(:attribute_name, :confirmation_attribute_name)
10
+
11
+ TYPE = :confirmation
12
+
13
+ # Builder for confirmation
14
+ class Builder < Nullary::Builder
15
+ OPTIONS = [:confirm]
16
+
17
+ # Abstract base class for confirmation attribute name generators
18
+ class Confirm
19
+ include Adamantium::Flat, AbstractType
20
+
21
+ Vanguard.singleton_constant(self, :DEFAULT) do
22
+
23
+ # Return confirmation attribute name
24
+ #
25
+ # @param [Symbol] attribute_name
26
+ #
27
+ # @return [Symbol]
28
+ #
29
+ # @api private
30
+ #
31
+ def confirmation_attribute_name(attribute_name)
32
+ :"#{attribute_name}_confirmation"
33
+ end
34
+
35
+ end
36
+
37
+ # Build confirm object
38
+ #
39
+ # @return [Confirm]
40
+ #
41
+ # @api private
42
+ #
43
+ def self.build(value)
44
+ case value
45
+ when value.respond_to?(:call)
46
+ Block.new(value)
47
+ when Symbol, String
48
+ Static.new(value.to_sym)
49
+ else
50
+ raise "Cannot build confirm option from: #{value.inspect}"
51
+ end
52
+ end
53
+
54
+ # Confirm attribute from block
55
+ class Block
56
+
57
+ # Return confirmation attribute name
58
+ #
59
+ # @param [Symbol] attribute_name
60
+ #
61
+ # @return [Symbol]
62
+ #
63
+ # @api private
64
+ #
65
+ def confirmation_attribute_name(attribute_name)
66
+ @block.call(attribute_name)
67
+ end
68
+
69
+ private
70
+
71
+ # Initialize object
72
+ #
73
+ # @param [Proc] block
74
+ #
75
+ # @return [undefined]
76
+ #
77
+ # @api private
78
+ def initialize(block)
79
+ @block = block
80
+ end
81
+ end
82
+
83
+ # Static confirmation attribute
84
+ class Static
85
+
86
+ # Return confirmation attribute name
87
+ #
88
+ # @param [Symbol] _attribute_name
89
+ #
90
+ # @return [Symbol]
91
+ #
92
+ # @api private
93
+ #
94
+ def confirmation_attribute_name(_attribute_name)
95
+ @confirmation_attribute_name
96
+ end
97
+
98
+ private
99
+
100
+ # Initialize object
101
+ #
102
+ # @param [Symbol] confirmation_attribute_name
103
+ #
104
+ # @return [undefined]
105
+ #
106
+ # @api private
107
+ #
108
+ def initialize(confirmation_attribute_name)
109
+ @confirmation_attribute_name = confirmation_attribute_name
110
+ end
111
+ end
112
+ end
113
+
114
+ private
115
+
116
+ # Return rule
117
+ #
118
+ # @param [Symbol] attribute_name
119
+ #
120
+ # @api private
121
+ #
122
+ def rule(attribute_name)
123
+ klass.new(attribute_name, confirm_option.confirmation_attribute_name(attribute_name))
124
+ end
125
+
126
+ # Return confirm object
127
+ #
128
+ # @return [Confirm]
129
+ #
130
+ # @api private
131
+ #
132
+ def confirm_option
133
+ option = options.fetch(:confirm) do
134
+ return Confirm::DEFAULT
135
+ end
136
+
137
+ Confirm.build(option)
138
+ end
139
+ memoize :confirm_option
140
+ end
141
+
142
+ register :validates_confirmation_of
143
+
144
+ # Return attribute name
145
+ #
146
+ # @return [Symbol]
147
+ #
148
+ # @api private
149
+ #
150
+ attr_reader :attribute_name
151
+
152
+ # Return confirmation attribute name
153
+ #
154
+ # @return [Symbol]
155
+ #
156
+ # @api private
157
+ #
158
+ attr_reader :confirmation_attribute_name
159
+
160
+ # Initialize object
161
+ #
162
+ # @param [Symbol] attribute_name
163
+ # @param [Symbol] confirmation_attribute_name
164
+ #
165
+ # @return [undefined]
166
+ #
167
+ # @api private
168
+ #
169
+ def initialize(attribute_name, confirmation_attribute_name)
170
+ @attribute_name,
171
+ @confirmation_attribute_name =
172
+ attribute_name,
173
+ confirmation_attribute_name
174
+ end
175
+
176
+ # Evaluator for confirmation rule
177
+ class Evaluator < Vanguard::Evaluator
178
+ # Test if value is valid?
179
+ #
180
+ # @return [true]
181
+ # if value is valid
182
+ #
183
+ # @return [false]
184
+ # if value is valid
185
+ #
186
+ # @api private
187
+ #
188
+ def valid?
189
+ value.eql?(confirmation_value)
190
+ end
191
+ memoize :valid?
192
+
193
+ private
194
+
195
+ # Return confirmation value
196
+ #
197
+ # @return [Object]
198
+ #
199
+ # @api private
200
+ #
201
+ def confirmation_value
202
+ resource.public_send(rule.confirmation_attribute_name)
203
+ end
204
+ memoize :confirmation_value
205
+ end
206
+
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,29 @@
1
+ module Vanguard
2
+
3
+ # Determines whether the specified +value+ is blank
4
+ #
5
+ # @param [Object] value
6
+ #
7
+ # @return [true]
8
+ # if object is fale empty or a whitespace string
9
+ #
10
+ # @return [false]
11
+ # otherwise
12
+ #
13
+ # @api private
14
+ #
15
+ def self.blank?(value)
16
+ case value
17
+ when ::NilClass, ::FalseClass
18
+ true
19
+ when ::TrueClass, ::Numeric
20
+ false
21
+ when ::Array, ::Hash
22
+ value.empty?
23
+ when ::String
24
+ value !~ /\S/
25
+ else
26
+ value.nil? || (value.respond_to?(:empty?) && value.empty?)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,116 @@
1
+ module Vanguard
2
+ # Validator compsed from many rules
3
+ class Validator
4
+ include Adamantium, Enumerable
5
+
6
+ # Run validator on resource
7
+ #
8
+ # @param [Resource] resource
9
+ #
10
+ # @return [Result]
11
+ #
12
+ # @api private
13
+ #
14
+ def call(resource)
15
+ Result.new(self, resource)
16
+ end
17
+
18
+ # Build validator
19
+ #
20
+ # @return [Validator]
21
+ #
22
+ # @api private
23
+ #
24
+ def self.build(&block)
25
+ Builder.new(&block).validator
26
+ end
27
+
28
+ # Return rules set with rule added
29
+ #
30
+ # @param [Rule] rule
31
+ #
32
+ # @return [Validator]
33
+ #
34
+ # @api private
35
+ #
36
+ def add(rule)
37
+ self.class.new(rules.dup << rule)
38
+ end
39
+
40
+ # Return rules on attribute name
41
+ #
42
+ # @param [Symbol] attribute_name
43
+ #
44
+ # @return [Enumerable<Rule>]
45
+ #
46
+ # @api private
47
+ #
48
+ def on(attribute_name)
49
+ rules.select { |rule| rule.attribute_name == attribute_name }
50
+ end
51
+
52
+ # Return rules
53
+ #
54
+ # @return [Set<Rule>]
55
+ #
56
+ # @api private
57
+ #
58
+ attr_reader :rules
59
+
60
+ # Enumerate rules
61
+ #
62
+ # @return [self]
63
+ # if block given
64
+ #
65
+ # @return [Enumerator]
66
+ # otherwise
67
+ #
68
+ # @api private
69
+ #
70
+ def each
71
+ return to_enum unless block_given?
72
+
73
+ rules.each { |rule| yield rule }
74
+
75
+ self
76
+ end
77
+
78
+ private
79
+
80
+ # Initialize object
81
+ #
82
+ # @param [Enumerable<Rule>] rules
83
+ #
84
+ # @return [undefined]
85
+ #
86
+ # @api private
87
+ #
88
+ def initialize(rules)
89
+ @rules = rules.to_set
90
+ end
91
+
92
+ Vanguard.singleton_constant(self, :EMPTY) do
93
+
94
+ # Return rule set with added rule
95
+ #
96
+ # @param [Rule] rule
97
+ #
98
+ # @api private
99
+ #
100
+ def add(rule)
101
+ Validator.new([rule])
102
+ end
103
+
104
+ private
105
+
106
+ # Initialize object
107
+ #
108
+ # @return [undefined]
109
+ #
110
+ # @api private
111
+ #
112
+ def initialize; end
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,52 @@
1
+ module Vanguard
2
+ class Validator
3
+ class Builder
4
+ include Vanguard::DSL
5
+
6
+ # Return rules
7
+ #
8
+ # @return [Enumerator<Rule>]
9
+ #
10
+ # @api private
11
+ #
12
+ attr_reader :rules
13
+
14
+ # Initialize object
15
+ #
16
+ # @return [undefined]
17
+ #
18
+ # @api private
19
+ #
20
+ def initialize(&block)
21
+ @rules = []
22
+ if block_given?
23
+ instance_exec(&block)
24
+ end
25
+ end
26
+
27
+ # Add rule
28
+ #
29
+ # @param [Rule] rule
30
+ #
31
+ # @return [self]
32
+ #
33
+ # @api private
34
+ #
35
+ def add(rule)
36
+ @rules << rule
37
+ self
38
+ end
39
+
40
+ # Return validator
41
+ #
42
+ # @return [Validator]
43
+ #
44
+ # @api private
45
+ #
46
+ def validator
47
+ Validator.new(rules)
48
+ end
49
+
50
+ end
51
+ end
52
+ end