vanguard 0.0.3

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 (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