schemacop 1.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.rubocop.yml +59 -1
- data/CHANGELOG.md +10 -0
- data/README.md +389 -199
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/doc/Schemacop.html +41 -130
- data/doc/Schemacop/ArrayValidator.html +329 -0
- data/doc/Schemacop/BooleanValidator.html +145 -0
- data/doc/Schemacop/Collector.html +535 -0
- data/doc/Schemacop/Exceptions.html +39 -39
- data/doc/Schemacop/Exceptions/InvalidSchemaError.html +124 -0
- data/doc/Schemacop/Exceptions/ValidationError.html +124 -0
- data/doc/Schemacop/FieldNode.html +409 -0
- data/doc/Schemacop/FloatValidator.html +158 -0
- data/doc/Schemacop/HashValidator.html +263 -0
- data/doc/Schemacop/IntegerValidator.html +158 -0
- data/doc/Schemacop/NilValidator.html +145 -0
- data/doc/Schemacop/Node.html +1426 -0
- data/doc/Schemacop/NodeResolver.html +242 -0
- data/doc/Schemacop/NodeSupportingField.html +590 -0
- data/doc/Schemacop/NodeSupportingType.html +614 -0
- data/doc/Schemacop/NodeWithBlock.html +289 -0
- data/doc/Schemacop/NumberValidator.html +232 -0
- data/doc/Schemacop/ObjectValidator.html +288 -0
- data/doc/Schemacop/RootNode.html +171 -0
- data/doc/Schemacop/Schema.html +697 -0
- data/doc/Schemacop/StringValidator.html +295 -0
- data/doc/ScopedEnv.html +351 -0
- data/doc/_index.html +190 -47
- data/doc/class_list.html +24 -31
- data/doc/css/full_list.css +32 -31
- data/doc/css/style.css +244 -91
- data/doc/file.README.html +428 -232
- data/doc/file_list.html +26 -30
- data/doc/frames.html +7 -16
- data/doc/index.html +428 -232
- data/doc/inheritance.graphml +524 -0
- data/doc/inheritance.pdf +825 -0
- data/doc/js/app.js +106 -77
- data/doc/js/full_list.js +170 -135
- data/doc/method_list.html +494 -38
- data/doc/top-level-namespace.html +36 -36
- data/lib/schemacop.rb +22 -7
- data/lib/schemacop/collector.rb +34 -0
- data/lib/schemacop/exceptions.rb +2 -8
- data/lib/schemacop/field_node.rb +26 -0
- data/lib/schemacop/node.rb +127 -0
- data/lib/schemacop/node_resolver.rb +14 -0
- data/lib/schemacop/node_supporting_field.rb +62 -0
- data/lib/schemacop/node_supporting_type.rb +112 -0
- data/lib/schemacop/node_with_block.rb +16 -0
- data/lib/schemacop/root_node.rb +4 -0
- data/lib/schemacop/schema.rb +61 -0
- data/lib/schemacop/scoped_env.rb +18 -0
- data/lib/schemacop/validator/array_validator.rb +30 -0
- data/lib/schemacop/validator/boolean_validator.rb +5 -0
- data/lib/schemacop/validator/float_validator.rb +5 -0
- data/lib/schemacop/validator/hash_validator.rb +18 -0
- data/lib/schemacop/validator/integer_validator.rb +5 -0
- data/lib/schemacop/validator/nil_validator.rb +5 -0
- data/lib/schemacop/validator/number_validator.rb +19 -0
- data/lib/schemacop/validator/object_validator.rb +21 -0
- data/lib/schemacop/validator/string_validator.rb +37 -0
- data/schemacop.gemspec +7 -5
- data/test/custom_check_test.rb +86 -0
- data/test/custom_if_test.rb +95 -0
- data/test/nil_dis_allow_test.rb +41 -0
- data/test/short_forms_test.rb +316 -0
- data/test/test_helper.rb +6 -0
- data/test/types_test.rb +83 -0
- data/test/validator_array_test.rb +97 -0
- data/test/validator_boolean_test.rb +15 -0
- data/test/validator_float_test.rb +57 -0
- data/test/validator_hash_test.rb +71 -0
- data/test/validator_integer_test.rb +46 -0
- data/test/validator_nil_test.rb +13 -0
- data/test/validator_number_test.rb +60 -0
- data/test/validator_object_test.rb +87 -0
- data/test/validator_string_test.rb +76 -0
- metadata +78 -14
- data/doc/Schemacop/Exceptions/Base.html +0 -127
- data/doc/Schemacop/Exceptions/InvalidSchema.html +0 -141
- data/doc/Schemacop/Exceptions/Validation.html +0 -142
- data/doc/Schemacop/MethodValidation.html +0 -120
- data/doc/Schemacop/MethodValidation/ClassMethods.html +0 -196
- data/doc/Schemacop/Validator.html +0 -254
- data/lib/schemacop/validator.rb +0 -145
- data/test/schemacop_validator_test.rb +0 -257
@@ -1,254 +0,0 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
-
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
-
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
-
<head>
|
5
|
-
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
6
|
-
<title>
|
7
|
-
Class: Schemacop::Validator
|
8
|
-
|
9
|
-
— Documentation by YARD 0.8.7.6
|
10
|
-
|
11
|
-
</title>
|
12
|
-
|
13
|
-
<link rel="stylesheet" href="../css/style.css" type="text/css" charset="utf-8" />
|
14
|
-
|
15
|
-
<link rel="stylesheet" href="../css/common.css" type="text/css" charset="utf-8" />
|
16
|
-
|
17
|
-
<script type="text/javascript" charset="utf-8">
|
18
|
-
hasFrames = window.top.frames.main ? true : false;
|
19
|
-
relpath = '../';
|
20
|
-
framesUrl = "../frames.html#!Schemacop/Validator.html";
|
21
|
-
</script>
|
22
|
-
|
23
|
-
|
24
|
-
<script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
|
25
|
-
|
26
|
-
<script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
|
27
|
-
|
28
|
-
|
29
|
-
</head>
|
30
|
-
<body>
|
31
|
-
<div id="header">
|
32
|
-
<div id="menu">
|
33
|
-
|
34
|
-
<a href="../_index.html">Index (V)</a> »
|
35
|
-
<span class='title'><span class='object_link'><a href="../Schemacop.html" title="Schemacop (module)">Schemacop</a></span></span>
|
36
|
-
»
|
37
|
-
<span class="title">Validator</span>
|
38
|
-
|
39
|
-
|
40
|
-
<div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
|
41
|
-
</div>
|
42
|
-
|
43
|
-
<div id="search">
|
44
|
-
|
45
|
-
<a class="full_list_link" id="class_list_link"
|
46
|
-
href="../class_list.html">
|
47
|
-
Class List
|
48
|
-
</a>
|
49
|
-
|
50
|
-
<a class="full_list_link" id="method_list_link"
|
51
|
-
href="../method_list.html">
|
52
|
-
Method List
|
53
|
-
</a>
|
54
|
-
|
55
|
-
<a class="full_list_link" id="file_list_link"
|
56
|
-
href="../file_list.html">
|
57
|
-
File List
|
58
|
-
</a>
|
59
|
-
|
60
|
-
</div>
|
61
|
-
<div class="clear"></div>
|
62
|
-
</div>
|
63
|
-
|
64
|
-
<iframe id="search_frame"></iframe>
|
65
|
-
|
66
|
-
<div id="content"><h1>Class: Schemacop::Validator
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
</h1>
|
71
|
-
|
72
|
-
<dl class="box">
|
73
|
-
|
74
|
-
<dt class="r1">Inherits:</dt>
|
75
|
-
<dd class="r1">
|
76
|
-
<span class="inheritName">Object</span>
|
77
|
-
|
78
|
-
<ul class="fullTree">
|
79
|
-
<li>Object</li>
|
80
|
-
|
81
|
-
<li class="next">Schemacop::Validator</li>
|
82
|
-
|
83
|
-
</ul>
|
84
|
-
<a href="#" class="inheritanceTree">show all</a>
|
85
|
-
|
86
|
-
</dd>
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
<dt class="r2 last">Defined in:</dt>
|
97
|
-
<dd class="r2 last">lib/schemacop/validator.rb</dd>
|
98
|
-
|
99
|
-
</dl>
|
100
|
-
<div class="clear"></div>
|
101
|
-
|
102
|
-
|
103
|
-
<h2>Constant Summary</h2>
|
104
|
-
|
105
|
-
<dl class="constants">
|
106
|
-
|
107
|
-
<dt id="TYPE_ALIASES-constant" class="">TYPE_ALIASES =
|
108
|
-
|
109
|
-
</dt>
|
110
|
-
<dd><pre class="code"><span class='lbrace'>{</span>
|
111
|
-
<span class='label'>hash:</span> <span class='lbracket'>[</span><span class='const'>Hash</span><span class='rbracket'>]</span><span class='comma'>,</span>
|
112
|
-
<span class='label'>array:</span> <span class='lbracket'>[</span><span class='const'>Array</span><span class='rbracket'>]</span><span class='comma'>,</span>
|
113
|
-
<span class='label'>string:</span> <span class='lbracket'>[</span><span class='const'>String</span><span class='rbracket'>]</span><span class='comma'>,</span>
|
114
|
-
<span class='label'>integer:</span> <span class='lbracket'>[</span><span class='const'>Integer</span><span class='rbracket'>]</span><span class='comma'>,</span>
|
115
|
-
<span class='label'>boolean:</span> <span class='lbracket'>[</span><span class='const'>TrueClass</span><span class='comma'>,</span> <span class='const'>FalseClass</span><span class='rbracket'>]</span>
|
116
|
-
<span class='rbrace'>}</span></pre></dd>
|
117
|
-
|
118
|
-
</dl>
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
<h2>
|
129
|
-
Class Method Summary
|
130
|
-
<small>(<a href="#" class="summary_toggle">collapse</a>)</small>
|
131
|
-
</h2>
|
132
|
-
|
133
|
-
<ul class="summary">
|
134
|
-
|
135
|
-
<li class="public ">
|
136
|
-
<span class="summary_signature">
|
137
|
-
|
138
|
-
<a href="#validate%21-class_method" title="validate! (class method)">+ (void) <strong>validate!</strong>(schema, data) </a>
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
</span>
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
<span class="summary_desc"><div class='inline'><p>Validates <code>data</code> against <code>schema</code> and throws an exception on missmatch.</p>
|
153
|
-
</div></span>
|
154
|
-
|
155
|
-
</li>
|
156
|
-
|
157
|
-
|
158
|
-
</ul>
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
<div id="class_method_details" class="method_details_list">
|
164
|
-
<h2>Class Method Details</h2>
|
165
|
-
|
166
|
-
|
167
|
-
<div class="method_details first">
|
168
|
-
<h3 class="signature first" id="validate!-class_method">
|
169
|
-
|
170
|
-
+ (<tt>void</tt>) <strong>validate!</strong>(schema, data)
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
</h3><div class="docstring">
|
177
|
-
<div class="discussion">
|
178
|
-
<p class="note returns_void">This method returns an undefined value.</p><p>Validates <code>data</code> against <code>schema</code> and throws an exception on missmatch.</p>
|
179
|
-
|
180
|
-
|
181
|
-
</div>
|
182
|
-
</div>
|
183
|
-
<div class="tags">
|
184
|
-
<p class="tag_title">Parameters:</p>
|
185
|
-
<ul class="param">
|
186
|
-
|
187
|
-
<li>
|
188
|
-
|
189
|
-
<span class='name'>schema</span>
|
190
|
-
|
191
|
-
|
192
|
-
<span class='type'>(<tt>Hash</tt>)</span>
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
—
|
197
|
-
<div class='inline'><p>The schema to validate against</p>
|
198
|
-
</div>
|
199
|
-
|
200
|
-
</li>
|
201
|
-
|
202
|
-
<li>
|
203
|
-
|
204
|
-
<span class='name'>data</span>
|
205
|
-
|
206
|
-
|
207
|
-
<span class='type'>(<tt>Object</tt>)</span>
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
—
|
212
|
-
<div class='inline'><p>The data to validate</p>
|
213
|
-
</div>
|
214
|
-
|
215
|
-
</li>
|
216
|
-
|
217
|
-
</ul>
|
218
|
-
|
219
|
-
|
220
|
-
</div><table class="source_code">
|
221
|
-
<tr>
|
222
|
-
<td>
|
223
|
-
<pre class="lines">
|
224
|
-
|
225
|
-
|
226
|
-
16
|
227
|
-
17
|
228
|
-
18
|
229
|
-
19</pre>
|
230
|
-
</td>
|
231
|
-
<td>
|
232
|
-
<pre class="code"><span class="info file"># File 'lib/schemacop/validator.rb', line 16</span>
|
233
|
-
|
234
|
-
<span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='id identifier rubyid_schema'>schema</span><span class='comma'>,</span> <span class='id identifier rubyid_data'>data</span><span class='rparen'>)</span>
|
235
|
-
<span class='id identifier rubyid_new'>new</span><span class='lparen'>(</span><span class='id identifier rubyid_schema'>schema</span><span class='comma'>,</span> <span class='id identifier rubyid_data'>data</span><span class='rparen'>)</span>
|
236
|
-
<span class='kw'>return</span> <span class='kw'>nil</span>
|
237
|
-
<span class='kw'>end</span></pre>
|
238
|
-
</td>
|
239
|
-
</tr>
|
240
|
-
</table>
|
241
|
-
</div>
|
242
|
-
|
243
|
-
</div>
|
244
|
-
|
245
|
-
</div>
|
246
|
-
|
247
|
-
<div id="footer">
|
248
|
-
Generated on Thu Oct 6 19:45:02 2016 by
|
249
|
-
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
250
|
-
0.8.7.6 (ruby-2.3.1).
|
251
|
-
</div>
|
252
|
-
|
253
|
-
</body>
|
254
|
-
</html>
|
data/lib/schemacop/validator.rb
DELETED
@@ -1,145 +0,0 @@
|
|
1
|
-
module Schemacop
|
2
|
-
class Validator
|
3
|
-
TYPE_ALIASES = {
|
4
|
-
hash: [Hash],
|
5
|
-
array: [Array],
|
6
|
-
string: [String],
|
7
|
-
integer: [Integer],
|
8
|
-
boolean: [TrueClass, FalseClass]
|
9
|
-
}
|
10
|
-
|
11
|
-
# Validates `data` against `schema` and throws an exception on missmatch.
|
12
|
-
#
|
13
|
-
# @param [Hash] schema The schema to validate against
|
14
|
-
# @param [Object] data The data to validate
|
15
|
-
# @return [void]
|
16
|
-
def self.validate!(schema, data)
|
17
|
-
new(schema, data)
|
18
|
-
return nil
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def initialize(schema, data)
|
24
|
-
validate_branch '', schema, data
|
25
|
-
end
|
26
|
-
|
27
|
-
def prepare_schema(schema)
|
28
|
-
schema = { types: schema } unless schema.is_a?(Hash)
|
29
|
-
schema = schema.dup
|
30
|
-
|
31
|
-
if schema.include?(:type)
|
32
|
-
schema[:types] = schema.delete(:type)
|
33
|
-
else
|
34
|
-
schema[:types] = :array unless schema[:array].nil?
|
35
|
-
schema[:types] = :hash unless schema[:hash].nil?
|
36
|
-
end
|
37
|
-
|
38
|
-
schema[:types] = [*schema[:types]]
|
39
|
-
schema[:types].map! do |type|
|
40
|
-
alias_type = TYPE_ALIASES.select { |_, v| v.include?(type) }.keys.first
|
41
|
-
type = alias_type unless alias_type.nil?
|
42
|
-
type
|
43
|
-
end
|
44
|
-
|
45
|
-
schema[:types].each do |type|
|
46
|
-
if type == :hash
|
47
|
-
if schema.include?(:fields)
|
48
|
-
schema[:hash] = schema.delete(:fields)
|
49
|
-
end
|
50
|
-
|
51
|
-
schema[:hash] = schema[:hash] || {}
|
52
|
-
if schema[:hash].is_a?(Hash)
|
53
|
-
schema[:hash].each do |key, value|
|
54
|
-
schema[:hash][key] = prepare_schema(value)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
schema[:array] = prepare_schema(schema[:array]) if type == :array
|
60
|
-
end
|
61
|
-
|
62
|
-
schema
|
63
|
-
end
|
64
|
-
|
65
|
-
def assign_data_type(type)
|
66
|
-
if type.is_a?(Symbol)
|
67
|
-
fail Exceptions::InvalidSchema, "Type alias #{type} is not supported." if TYPE_ALIASES[type].nil?
|
68
|
-
TYPE_ALIASES[type]
|
69
|
-
elsif type.is_a?(String)
|
70
|
-
type.to_s.classify.safe_constantize
|
71
|
-
else
|
72
|
-
type
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def validate_branch(path, schema, data)
|
77
|
-
schema = prepare_schema(schema)
|
78
|
-
|
79
|
-
# ---------------------------------------------------------------
|
80
|
-
# Type validation
|
81
|
-
# ---------------------------------------------------------------
|
82
|
-
supported_types = schema[:types].map { |type| assign_data_type type }.flatten
|
83
|
-
|
84
|
-
# ---------------------------------------------------------------
|
85
|
-
# Check root path rules
|
86
|
-
# ---------------------------------------------------------------
|
87
|
-
if path.empty?
|
88
|
-
supported_types << NilClass if schema[:null] == true
|
89
|
-
|
90
|
-
if schema.include? :require
|
91
|
-
fail Exceptions::InvalidSchema, "The :require property can't be used on top level of schema."
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
if schema[:types].present? && !supported_types.any? { |t| data.is_a?(t) }
|
96
|
-
fail Exceptions::Validation, "Property at path #{path} must be of type #{supported_types.inspect}."
|
97
|
-
end
|
98
|
-
|
99
|
-
# ---------------------------------------------------------------
|
100
|
-
# Check for allowed values
|
101
|
-
# ---------------------------------------------------------------
|
102
|
-
if schema[:allowed_values] && !schema[:allowed_values].include?(data)
|
103
|
-
fail Exceptions::Validation, "Value #{data.inspect} of property at path #{path} is not valid. Valid are: #{schema[:allowed_values].inspect}."
|
104
|
-
end
|
105
|
-
|
106
|
-
# ---------------------------------------------------------------
|
107
|
-
# Validate children
|
108
|
-
# ---------------------------------------------------------------
|
109
|
-
if data.is_a?(Hash)
|
110
|
-
data = HashWithIndifferentAccess.new data
|
111
|
-
|
112
|
-
unless schema.include? :hash
|
113
|
-
fail Exceptions::InvalidSchema, "Missing schema entry :hash at path #{path}."
|
114
|
-
end
|
115
|
-
|
116
|
-
schema_keys = schema[:hash].keys.collect(&:to_s)
|
117
|
-
unless schema_keys.empty?
|
118
|
-
data_keys = data.keys.collect(&:to_s)
|
119
|
-
|
120
|
-
unless (obsolete_keys = data_keys - schema_keys).empty?
|
121
|
-
fail Exceptions::Validation, "Obsolete keys at path #{path}: #{obsolete_keys.inspect}."
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
schema[:hash].each do |sub_key, sub_schema|
|
126
|
-
if sub_schema[:required] != false && !data.include?(sub_key)
|
127
|
-
fail Exceptions::Validation, "Missing property at path #{path}.#{sub_key}."
|
128
|
-
end
|
129
|
-
|
130
|
-
if data[sub_key].nil?
|
131
|
-
unless sub_schema[:null] == true
|
132
|
-
fail Exceptions::Validation, "Property at path #{path}.#{sub_key} can't be null."
|
133
|
-
end
|
134
|
-
else
|
135
|
-
validate_branch("#{path}.#{sub_key}", sub_schema, data[sub_key])
|
136
|
-
end
|
137
|
-
end
|
138
|
-
elsif schema[:types].include?(:array)
|
139
|
-
data.each_with_index do |value, index|
|
140
|
-
validate_branch("#{path}[#{index}]", schema[:array], value)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
@@ -1,257 +0,0 @@
|
|
1
|
-
require 'minitest/autorun'
|
2
|
-
require 'schemacop'
|
3
|
-
|
4
|
-
# rubocop: disable Metrics/ClassLength
|
5
|
-
class SchemacopValidatorTest < Minitest::Test
|
6
|
-
def test_top_level_schema
|
7
|
-
assert_schema({ type: :integer }, 1)
|
8
|
-
assert_schema({ type: :hash, null: true }, nil)
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_short_type_schema
|
12
|
-
assert_schema({ type: :array, array: :string }, %w(Hello world))
|
13
|
-
assert_schema({ type: [Array], array: :string }, %w(Hello world))
|
14
|
-
assert_schema({ array: :string }, %w(Hello world))
|
15
|
-
assert_schema({ hash: { first_name: :string, last_name: :string } }, first_name: 'John', last_name: 'Doe')
|
16
|
-
|
17
|
-
assert_schema_failure({ type: :array, array: :integer }, %w(Hello world))
|
18
|
-
assert_schema_failure({ type: Array, array: :string }, [1, 2, 3])
|
19
|
-
assert_schema_failure({ type: [Array], array: :integer }, %w(Hello world))
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_many_types_schema
|
23
|
-
assert_schema({ type: [String, :integer] }, 'Hello world')
|
24
|
-
assert_schema({ type: [:string, 'integer'] }, 123)
|
25
|
-
assert_schema({ type: String }, 'Hello world')
|
26
|
-
assert_schema({ type: :string }, 'Hello world')
|
27
|
-
assert_schema({ type: :array, array: :string }, %w(John Doe))
|
28
|
-
assert_schema({ type: :hash, hash: { name: :string } }, name: 'John Doe')
|
29
|
-
assert_schema({ type: [:array, :hash], array: { type: :string }, hash: { name: :string } }, name: 'John Doe')
|
30
|
-
assert_schema({ type: [:array, :hash], array: { type: :string }, hash: { name: :string } }, %w(John Doe))
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_unify_schema
|
34
|
-
schema_rules = {
|
35
|
-
hash: {
|
36
|
-
id: [Integer, String],
|
37
|
-
name: :string,
|
38
|
-
meta: {
|
39
|
-
hash: {
|
40
|
-
groups: { array: :integer },
|
41
|
-
birthday: Date,
|
42
|
-
comment: {
|
43
|
-
type: :string,
|
44
|
-
required: false,
|
45
|
-
null: true
|
46
|
-
}
|
47
|
-
}
|
48
|
-
}
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
assert_schema(schema_rules, id: 123, name: 'John Doe', meta: { groups: [1, 2, 3], birthday: Date.today, comment: 'Hello world' })
|
53
|
-
assert_schema(schema_rules, id: 'XYZ', name: 'John Doe', meta: { groups: [1, 2, 3], birthday: Date.today })
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_hash_without_specification
|
57
|
-
schema_rules = {
|
58
|
-
type: :hash
|
59
|
-
}
|
60
|
-
|
61
|
-
assert_schema(schema_rules, user: 'hello')
|
62
|
-
assert_schema(schema_rules, user: :world)
|
63
|
-
assert_schema(schema_rules, user: 123)
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_array_without_specification
|
67
|
-
schema_rules = {
|
68
|
-
type: :array
|
69
|
-
}
|
70
|
-
|
71
|
-
assert_schema(schema_rules, [1, 'hello', :world])
|
72
|
-
assert_schema(schema_rules, [])
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_hash_attributes_without_specification
|
76
|
-
schema_rules = {
|
77
|
-
type: :hash,
|
78
|
-
hash: {
|
79
|
-
user: { type: :hash, null: true }
|
80
|
-
}
|
81
|
-
}
|
82
|
-
|
83
|
-
assert_schema(schema_rules, user: { foo: :bar })
|
84
|
-
assert_schema(schema_rules, user: nil)
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_array_in_hash_without_specification
|
88
|
-
schema_rules = {
|
89
|
-
type: Hash,
|
90
|
-
hash: {
|
91
|
-
types: { type: :array, null: true }
|
92
|
-
}
|
93
|
-
}
|
94
|
-
|
95
|
-
assert_schema(schema_rules, types: ['test', 1, :hello])
|
96
|
-
assert_schema(schema_rules, types: [])
|
97
|
-
assert_schema(schema_rules, types: nil)
|
98
|
-
end
|
99
|
-
|
100
|
-
def test_array_in_hash_with_multiple_types
|
101
|
-
schema_rules = {
|
102
|
-
type: :hash,
|
103
|
-
hash: {
|
104
|
-
types: { type: Array, array: [Integer, String] }
|
105
|
-
}
|
106
|
-
}
|
107
|
-
|
108
|
-
assert_schema(schema_rules, types: ['test', 1])
|
109
|
-
assert_schema(schema_rules, types: [])
|
110
|
-
assert_schema_failure(schema_rules, types: ['test', 1, :hello_world])
|
111
|
-
end
|
112
|
-
|
113
|
-
def test_nested_hash_schema
|
114
|
-
schema_rules = {
|
115
|
-
type: :hash,
|
116
|
-
hash: {
|
117
|
-
name: {
|
118
|
-
type: :hash,
|
119
|
-
hash: {
|
120
|
-
first_name: { type: :string },
|
121
|
-
last_name: { type: :string }
|
122
|
-
}
|
123
|
-
}
|
124
|
-
}
|
125
|
-
}
|
126
|
-
|
127
|
-
assert_schema(schema_rules, name: { first_name: 'John', last_name: 'Doe' })
|
128
|
-
end
|
129
|
-
|
130
|
-
def test_flat_hash_old_schema
|
131
|
-
schema_rules = {
|
132
|
-
type: :hash,
|
133
|
-
fields: {
|
134
|
-
name: {
|
135
|
-
type: :string, null: true
|
136
|
-
}
|
137
|
-
}
|
138
|
-
}
|
139
|
-
|
140
|
-
assert_schema(schema_rules, name: 'John Doe')
|
141
|
-
assert_schema(schema_rules, name: '')
|
142
|
-
assert_schema(schema_rules, name: nil)
|
143
|
-
|
144
|
-
assert_schema_failure(schema_rules, name: 123)
|
145
|
-
assert_schema_failure(schema_rules, name: true)
|
146
|
-
assert_schema_failure(schema_rules, name: [])
|
147
|
-
end
|
148
|
-
|
149
|
-
def test_array_hash_old_schema
|
150
|
-
schema_rules = {
|
151
|
-
type: :array,
|
152
|
-
array: {
|
153
|
-
type: :hash,
|
154
|
-
fields: {
|
155
|
-
required: { type: :boolean },
|
156
|
-
name: { type: :string }
|
157
|
-
}
|
158
|
-
}
|
159
|
-
}
|
160
|
-
|
161
|
-
assert_schema(schema_rules, [{ name: 'John', required: true }, { name: 'Alex', required: false }])
|
162
|
-
|
163
|
-
assert_schema_failure(schema_rules, name: 'John Doe')
|
164
|
-
assert_schema_failure(schema_rules, [{ name: 'John Doe' }])
|
165
|
-
assert_schema_failure(schema_rules, [{ required: true }])
|
166
|
-
assert_schema_failure(schema_rules, [{ name: 0, required: true }])
|
167
|
-
assert_schema_failure(schema_rules, [{ name: 'John Doe', required: 'string' }])
|
168
|
-
end
|
169
|
-
|
170
|
-
def test_fields_array_old_schema
|
171
|
-
schema_rules = {
|
172
|
-
type: :hash,
|
173
|
-
fields: {
|
174
|
-
ids: {
|
175
|
-
type: :array,
|
176
|
-
array: {
|
177
|
-
type: :integer
|
178
|
-
}
|
179
|
-
}
|
180
|
-
}
|
181
|
-
}
|
182
|
-
|
183
|
-
assert_schema(schema_rules, ids: [])
|
184
|
-
assert_schema(schema_rules, ids: [1, 2, 3])
|
185
|
-
|
186
|
-
assert_schema_failure(schema_rules, ids: [1, '2'])
|
187
|
-
assert_schema_failure(schema_rules, ids: '3')
|
188
|
-
assert_schema_failure(schema_rules, ids: nil)
|
189
|
-
end
|
190
|
-
|
191
|
-
def test_validate_fields_old_schema
|
192
|
-
schema_rules = {
|
193
|
-
type: :hash,
|
194
|
-
fields: {
|
195
|
-
name: { type: :string, null: true, required: true },
|
196
|
-
age: { type: :integer, required: false, null: true },
|
197
|
-
id: { type: :integer, null: false },
|
198
|
-
ids: { type: :array, array: { type: :integer }, null: true },
|
199
|
-
currency: { type: :string, allowed_values: %w(CHF USD EUR) }
|
200
|
-
}
|
201
|
-
}
|
202
|
-
|
203
|
-
assert_schema(schema_rules, name: 'John', id: 2, ids: [1, 2, 3], currency: 'CHF')
|
204
|
-
assert_schema(schema_rules, name: nil, id: 2, ids: [1, 2, 3], currency: 'CHF')
|
205
|
-
assert_schema(schema_rules, name: nil, age: 2, id: 2, ids: nil, currency: 'CHF')
|
206
|
-
assert_schema(schema_rules, name: nil, id: 2, ids: nil, currency: 'CHF')
|
207
|
-
|
208
|
-
assert_schema_failure(schema_rules, id: 2, ids: [1, 2, 3], currency: 'CHF')
|
209
|
-
assert_schema_failure(schema_rules, name: nil, id: nil, ids: [1, 2, 3], currency: 'CHF')
|
210
|
-
assert_schema_failure(schema_rules, name: nil, id: 2, ids: [1, 2, 3], currency: 'JPN')
|
211
|
-
end
|
212
|
-
|
213
|
-
def test_nested_old_schema
|
214
|
-
schema_rules = {
|
215
|
-
type: :array,
|
216
|
-
array: {
|
217
|
-
type: :hash,
|
218
|
-
fields: {
|
219
|
-
id: { type: :integer },
|
220
|
-
hosts: {
|
221
|
-
type: :array,
|
222
|
-
array: {
|
223
|
-
type: :hash,
|
224
|
-
fields: {
|
225
|
-
hostname: { type: :string }
|
226
|
-
}
|
227
|
-
}
|
228
|
-
}
|
229
|
-
}
|
230
|
-
}
|
231
|
-
}
|
232
|
-
|
233
|
-
assert_schema schema_rules, [
|
234
|
-
{ id: 1, hosts: [{ hostname: 'localhost' }, { hostname: '127.0.0.1' }] },
|
235
|
-
{ id: 2, hosts: [{ hostname: '192.168.0.1' }, { hostname: 'somedomain.com' }] }
|
236
|
-
]
|
237
|
-
end
|
238
|
-
|
239
|
-
private
|
240
|
-
|
241
|
-
def assert_schema_failure(schema, data)
|
242
|
-
assert_raises Schemacop::Exceptions::Validation do
|
243
|
-
Schemacop.validate!(schema, data)
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
def assert_schema(schema, data)
|
248
|
-
begin
|
249
|
-
Schemacop.validate!(schema, data)
|
250
|
-
success = true
|
251
|
-
rescue
|
252
|
-
success = false
|
253
|
-
end
|
254
|
-
|
255
|
-
assert success
|
256
|
-
end
|
257
|
-
end
|