vanguard 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|