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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/Gemfile +7 -0
- data/Gemfile.devtools +56 -0
- data/Guardfile +18 -0
- data/LICENSE +21 -0
- data/README.md +80 -0
- data/Rakefile +2 -0
- data/TODO +3 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +99 -0
- data/config/roodi.yml +26 -0
- data/config/yardstick.yml +2 -0
- data/lib/vanguard.rb +85 -0
- data/lib/vanguard/builder.rb +14 -0
- data/lib/vanguard/builder/nullary.rb +182 -0
- data/lib/vanguard/dsl.rb +43 -0
- data/lib/vanguard/dsl/evaluator.rb +197 -0
- data/lib/vanguard/evaluator.rb +72 -0
- data/lib/vanguard/instance_methods.rb +76 -0
- data/lib/vanguard/matcher.rb +19 -0
- data/lib/vanguard/matcher/binary.rb +59 -0
- data/lib/vanguard/matcher/binary/and.rb +20 -0
- data/lib/vanguard/matcher/binary/or.rb +20 -0
- data/lib/vanguard/matcher/binary/xor.rb +22 -0
- data/lib/vanguard/matcher/nullary.rb +27 -0
- data/lib/vanguard/matcher/nullary/equality.rb +46 -0
- data/lib/vanguard/matcher/nullary/format.rb +126 -0
- data/lib/vanguard/matcher/nullary/greater_than.rb +45 -0
- data/lib/vanguard/matcher/nullary/identity.rb +50 -0
- data/lib/vanguard/matcher/nullary/inclusion.rb +67 -0
- data/lib/vanguard/matcher/nullary/less_than.rb +48 -0
- data/lib/vanguard/matcher/nullary/primitive.rb +47 -0
- data/lib/vanguard/matcher/nullary/proc.rb +44 -0
- data/lib/vanguard/matcher/nullary/value.rb +32 -0
- data/lib/vanguard/matcher/unary.rb +45 -0
- data/lib/vanguard/matcher/unary/attribute.rb +49 -0
- data/lib/vanguard/matcher/unary/not.rb +25 -0
- data/lib/vanguard/result.rb +93 -0
- data/lib/vanguard/rule.rb +43 -0
- data/lib/vanguard/rule/guard.rb +103 -0
- data/lib/vanguard/rule/nullary.rb +81 -0
- data/lib/vanguard/rule/nullary/attribute.rb +69 -0
- data/lib/vanguard/rule/nullary/attribute/absence.rb +19 -0
- data/lib/vanguard/rule/nullary/attribute/format.rb +46 -0
- data/lib/vanguard/rule/nullary/attribute/inclusion.rb +62 -0
- data/lib/vanguard/rule/nullary/attribute/length.rb +184 -0
- data/lib/vanguard/rule/nullary/attribute/predicate.rb +10 -0
- data/lib/vanguard/rule/nullary/attribute/presence.rb +32 -0
- data/lib/vanguard/rule/nullary/attribute/presence/not_blank.rb +0 -0
- data/lib/vanguard/rule/nullary/attribute/presence/not_nil.rb +0 -0
- data/lib/vanguard/rule/nullary/attribute/primitive.rb +35 -0
- data/lib/vanguard/rule/nullary/confirmation.rb +210 -0
- data/lib/vanguard/support/blank.rb +29 -0
- data/lib/vanguard/validator.rb +116 -0
- data/lib/vanguard/validator/builder.rb +52 -0
- data/lib/vanguard/violation.rb +84 -0
- data/spec/integration/vanguard/dsl/guard_spec.rb +58 -0
- data/spec/integration/vanguard/dsl/validates_absence_of_spec.rb +19 -0
- data/spec/integration/vanguard/dsl/validates_acceptance_of_spec.rb +19 -0
- data/spec/integration/vanguard/dsl/validates_confirmation_of_spec.rb +27 -0
- data/spec/integration/vanguard/dsl/validates_format_of_spec.rb +79 -0
- data/spec/integration/vanguard/dsl/validates_inclusion_of_spec.rb +23 -0
- data/spec/integration/vanguard/dsl/validates_length_of_spec.rb +77 -0
- data/spec/integration/vanguard/dsl/validates_presence_of_spec.rb +19 -0
- data/spec/integration/vanguard/dsl/validates_value_of_spec.rb +30 -0
- data/spec/integration/vanguard/validator_spec.rb +57 -0
- data/spec/rcov.opts +6 -0
- data/spec/shared/dsl_spec.rb +73 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/suite.rb +10 -0
- data/spec/unit/vanguard/support/blank_spec.rb +72 -0
- data/vanguard.gemspec +23 -0
- metadata +190 -0
@@ -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
|
File without changes
|
File without changes
|
@@ -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
|