schemacop 2.4.7 → 3.0.0.rc0
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 +4 -4
- data/.gitignore +3 -0
- data/.rubocop.yml +25 -1
- data/.travis.yml +2 -1
- data/CHANGELOG.md +8 -0
- data/README.md +41 -708
- data/README_V2.md +775 -0
- data/README_V3.md +683 -0
- data/Rakefile +8 -12
- data/VERSION +1 -1
- data/lib/schemacop.rb +35 -37
- data/lib/schemacop/base_schema.rb +37 -0
- data/lib/schemacop/railtie.rb +10 -0
- data/lib/schemacop/schema.rb +1 -60
- data/lib/schemacop/schema2.rb +22 -0
- data/lib/schemacop/schema3.rb +21 -0
- data/lib/schemacop/scoped_env.rb +25 -13
- data/lib/schemacop/v2.rb +26 -0
- data/lib/schemacop/{caster.rb → v2/caster.rb} +16 -2
- data/lib/schemacop/{collector.rb → v2/collector.rb} +5 -2
- data/lib/schemacop/{dupper.rb → v2/dupper.rb} +1 -1
- data/lib/schemacop/{field_node.rb → v2/field_node.rb} +4 -3
- data/lib/schemacop/v2/node.rb +142 -0
- data/lib/schemacop/{node_resolver.rb → v2/node_resolver.rb} +1 -1
- data/lib/schemacop/{node_supporting_field.rb → v2/node_supporting_field.rb} +8 -10
- data/lib/schemacop/{node_supporting_type.rb → v2/node_supporting_type.rb} +6 -3
- data/lib/schemacop/{node_with_block.rb → v2/node_with_block.rb} +3 -2
- data/lib/schemacop/v2/root_node.rb +6 -0
- data/lib/schemacop/v2/validator/array_validator.rb +32 -0
- data/lib/schemacop/{validator → v2/validator}/boolean_validator.rb +1 -1
- data/lib/schemacop/v2/validator/float_validator.rb +7 -0
- data/lib/schemacop/v2/validator/hash_validator.rb +37 -0
- data/lib/schemacop/v2/validator/integer_validator.rb +7 -0
- data/lib/schemacop/{validator → v2/validator}/nil_validator.rb +1 -1
- data/lib/schemacop/v2/validator/number_validator.rb +21 -0
- data/lib/schemacop/v2/validator/object_validator.rb +29 -0
- data/lib/schemacop/v2/validator/string_validator.rb +39 -0
- data/lib/schemacop/{validator → v2/validator}/symbol_validator.rb +1 -1
- data/lib/schemacop/v3.rb +45 -0
- data/lib/schemacop/v3/all_of_node.rb +27 -0
- data/lib/schemacop/v3/any_of_node.rb +28 -0
- data/lib/schemacop/v3/array_node.rb +219 -0
- data/lib/schemacop/v3/boolean_node.rb +16 -0
- data/lib/schemacop/v3/combination_node.rb +45 -0
- data/lib/schemacop/v3/context.rb +17 -0
- data/lib/schemacop/v3/dsl_scope.rb +46 -0
- data/lib/schemacop/v3/global_context.rb +114 -0
- data/lib/schemacop/v3/hash_node.rb +217 -0
- data/lib/schemacop/v3/integer_node.rb +13 -0
- data/lib/schemacop/v3/is_not_node.rb +32 -0
- data/lib/schemacop/v3/node.rb +214 -0
- data/lib/schemacop/v3/node_registry.rb +49 -0
- data/lib/schemacop/v3/number_node.rb +18 -0
- data/lib/schemacop/v3/numeric_node.rb +76 -0
- data/lib/schemacop/v3/object_node.rb +40 -0
- data/lib/schemacop/v3/one_of_node.rb +28 -0
- data/lib/schemacop/v3/reference_node.rb +49 -0
- data/lib/schemacop/v3/result.rb +58 -0
- data/lib/schemacop/v3/string_node.rb +124 -0
- data/lib/schemacop/v3/symbol_node.rb +13 -0
- data/schemacop.gemspec +24 -27
- data/test/lib/test_helper.rb +152 -0
- data/test/schemas/nested/group.rb +6 -0
- data/test/schemas/user.rb +7 -0
- data/test/unit/schemacop/v2/casting_test.rb +120 -0
- data/test/unit/schemacop/v2/collector_test.rb +47 -0
- data/test/unit/schemacop/v2/custom_check_test.rb +95 -0
- data/test/unit/schemacop/v2/custom_if_test.rb +97 -0
- data/test/unit/schemacop/v2/defaults_test.rb +95 -0
- data/test/unit/schemacop/v2/empty_test.rb +16 -0
- data/test/unit/schemacop/v2/nil_dis_allow_test.rb +43 -0
- data/test/unit/schemacop/v2/node_resolver_test.rb +28 -0
- data/test/unit/schemacop/v2/short_forms_test.rb +351 -0
- data/test/unit/schemacop/v2/types_test.rb +88 -0
- data/test/unit/schemacop/v2/validator_array_test.rb +99 -0
- data/test/unit/schemacop/v2/validator_boolean_test.rb +17 -0
- data/test/unit/schemacop/v2/validator_float_test.rb +59 -0
- data/test/unit/schemacop/v2/validator_hash_test.rb +95 -0
- data/test/unit/schemacop/v2/validator_integer_test.rb +48 -0
- data/test/unit/schemacop/v2/validator_nil_test.rb +15 -0
- data/test/unit/schemacop/v2/validator_number_test.rb +62 -0
- data/test/unit/schemacop/v2/validator_object_test.rb +141 -0
- data/test/unit/schemacop/v2/validator_string_test.rb +78 -0
- data/test/unit/schemacop/v2/validator_symbol_test.rb +18 -0
- data/test/unit/schemacop/v3/all_of_node_test.rb +199 -0
- data/test/unit/schemacop/v3/any_of_node_test.rb +218 -0
- data/test/unit/schemacop/v3/array_node_test.rb +805 -0
- data/test/unit/schemacop/v3/boolean_node_test.rb +126 -0
- data/test/unit/schemacop/v3/global_context_test.rb +164 -0
- data/test/unit/schemacop/v3/hash_node_test.rb +775 -0
- data/test/unit/schemacop/v3/integer_node_test.rb +323 -0
- data/test/unit/schemacop/v3/is_not_node_test.rb +173 -0
- data/test/unit/schemacop/v3/node_test.rb +148 -0
- data/test/unit/schemacop/v3/number_node_test.rb +292 -0
- data/test/unit/schemacop/v3/object_node_test.rb +170 -0
- data/test/unit/schemacop/v3/one_of_node_test.rb +187 -0
- data/test/unit/schemacop/v3/reference_node_test.rb +351 -0
- data/test/unit/schemacop/v3/string_node_test.rb +334 -0
- data/test/unit/schemacop/v3/symbol_node_test.rb +75 -0
- metadata +152 -145
- data/doc/Schemacop.html +0 -146
- data/doc/Schemacop/ArrayValidator.html +0 -329
- data/doc/Schemacop/BooleanValidator.html +0 -145
- data/doc/Schemacop/Caster.html +0 -379
- data/doc/Schemacop/Collector.html +0 -787
- data/doc/Schemacop/Dupper.html +0 -214
- data/doc/Schemacop/Exceptions.html +0 -115
- data/doc/Schemacop/Exceptions/InvalidSchemaError.html +0 -124
- data/doc/Schemacop/Exceptions/ValidationError.html +0 -124
- data/doc/Schemacop/FieldNode.html +0 -421
- data/doc/Schemacop/FloatValidator.html +0 -158
- data/doc/Schemacop/HashValidator.html +0 -293
- data/doc/Schemacop/IntegerValidator.html +0 -158
- data/doc/Schemacop/NilValidator.html +0 -145
- data/doc/Schemacop/Node.html +0 -1438
- data/doc/Schemacop/NodeResolver.html +0 -258
- data/doc/Schemacop/NodeSupportingField.html +0 -590
- data/doc/Schemacop/NodeSupportingType.html +0 -612
- data/doc/Schemacop/NodeWithBlock.html +0 -289
- data/doc/Schemacop/NumberValidator.html +0 -232
- data/doc/Schemacop/ObjectValidator.html +0 -298
- data/doc/Schemacop/RootNode.html +0 -171
- data/doc/Schemacop/Schema.html +0 -699
- data/doc/Schemacop/StringValidator.html +0 -295
- data/doc/Schemacop/SymbolValidator.html +0 -145
- data/doc/ScopedEnv.html +0 -351
- data/doc/_index.html +0 -379
- data/doc/class_list.html +0 -51
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -58
- data/doc/css/style.css +0 -496
- data/doc/file.README.html +0 -833
- data/doc/file_list.html +0 -56
- data/doc/frames.html +0 -17
- data/doc/index.html +0 -833
- data/doc/inheritance.graphml +0 -524
- data/doc/inheritance.pdf +0 -825
- data/doc/js/app.js +0 -303
- data/doc/js/full_list.js +0 -216
- data/doc/js/jquery.js +0 -4
- data/doc/method_list.html +0 -587
- data/doc/top-level-namespace.html +0 -112
- data/lib/schemacop/node.rb +0 -139
- data/lib/schemacop/root_node.rb +0 -4
- data/lib/schemacop/validator/array_validator.rb +0 -30
- data/lib/schemacop/validator/float_validator.rb +0 -5
- data/lib/schemacop/validator/hash_validator.rb +0 -35
- data/lib/schemacop/validator/integer_validator.rb +0 -5
- data/lib/schemacop/validator/number_validator.rb +0 -19
- data/lib/schemacop/validator/object_validator.rb +0 -27
- data/lib/schemacop/validator/string_validator.rb +0 -37
- data/test/casting_test.rb +0 -118
- data/test/collector_test.rb +0 -45
- data/test/custom_check_test.rb +0 -93
- data/test/custom_if_test.rb +0 -95
- data/test/defaults_test.rb +0 -93
- data/test/empty_test.rb +0 -14
- data/test/nil_dis_allow_test.rb +0 -41
- data/test/node_resolver_test.rb +0 -26
- data/test/short_forms_test.rb +0 -349
- data/test/test_helper.rb +0 -13
- data/test/types_test.rb +0 -84
- data/test/validator_array_test.rb +0 -97
- data/test/validator_boolean_test.rb +0 -15
- data/test/validator_float_test.rb +0 -57
- data/test/validator_hash_test.rb +0 -93
- data/test/validator_integer_test.rb +0 -46
- data/test/validator_nil_test.rb +0 -13
- data/test/validator_number_test.rb +0 -60
- data/test/validator_object_test.rb +0 -139
- data/test/validator_string_test.rb +0 -76
- data/test/validator_symbol_test.rb +0 -16
@@ -0,0 +1,805 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Schemacop
|
4
|
+
module V3
|
5
|
+
class ArrayNodeTest < V3Test
|
6
|
+
EXP_INVALID_TYPE = 'Invalid type, expected "array".'.freeze
|
7
|
+
|
8
|
+
def test_basic
|
9
|
+
schema :array
|
10
|
+
assert_json(type: :array)
|
11
|
+
assert_validation []
|
12
|
+
assert_validation [nil, nil]
|
13
|
+
assert_validation [2234, 'foo', :bar]
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_in_object
|
17
|
+
schema { ary! :items }
|
18
|
+
assert_json(
|
19
|
+
type: :object,
|
20
|
+
properties: {
|
21
|
+
items: { type: :array }
|
22
|
+
},
|
23
|
+
required: %i[items],
|
24
|
+
additionalProperties: false
|
25
|
+
)
|
26
|
+
|
27
|
+
assert_validation items: []
|
28
|
+
assert_validation items: [nil]
|
29
|
+
assert_validation items: [2234, 'foo', :bar]
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_object_contents
|
33
|
+
schema :array do
|
34
|
+
hsh do
|
35
|
+
str! :name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
assert_json(
|
40
|
+
type: :array,
|
41
|
+
items: [
|
42
|
+
{
|
43
|
+
type: :object,
|
44
|
+
properties: { name: { type: :string } },
|
45
|
+
required: %i[name],
|
46
|
+
additionalProperties: false
|
47
|
+
}
|
48
|
+
],
|
49
|
+
additionalItems: false
|
50
|
+
)
|
51
|
+
|
52
|
+
assert_validation [{ name: 'Foo' }]
|
53
|
+
assert_validation [{ name: 'Foo' }, { name: 'Bar' }] do
|
54
|
+
error '/', 'Array has 2 items but must have exactly 1.'
|
55
|
+
end
|
56
|
+
assert_validation [123] do
|
57
|
+
error '/[0]', 'Invalid type, expected "object".'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_type
|
62
|
+
schema :array
|
63
|
+
|
64
|
+
assert_json(type: :array)
|
65
|
+
|
66
|
+
assert_validation 42 do
|
67
|
+
error '/', EXP_INVALID_TYPE
|
68
|
+
end
|
69
|
+
|
70
|
+
schema { ary! :foo }
|
71
|
+
|
72
|
+
assert_json(
|
73
|
+
type: :object,
|
74
|
+
properties: {
|
75
|
+
foo: { type: :array }
|
76
|
+
},
|
77
|
+
required: %i[foo],
|
78
|
+
additionalProperties: false
|
79
|
+
)
|
80
|
+
|
81
|
+
assert_validation foo: 42 do
|
82
|
+
error '/foo', EXP_INVALID_TYPE
|
83
|
+
end
|
84
|
+
|
85
|
+
assert_validation foo: {} do
|
86
|
+
error '/foo', EXP_INVALID_TYPE
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_min_items
|
91
|
+
schema :array, min_items: 0
|
92
|
+
|
93
|
+
assert_json(type: :array, minItems: 0)
|
94
|
+
assert_validation []
|
95
|
+
assert_validation [1]
|
96
|
+
|
97
|
+
schema :array, min_items: 1
|
98
|
+
|
99
|
+
assert_json(type: :array, minItems: 1)
|
100
|
+
assert_validation [1]
|
101
|
+
assert_validation [1, 2]
|
102
|
+
assert_validation [] do
|
103
|
+
error '/', 'Array has 0 items but needs at least 1.'
|
104
|
+
end
|
105
|
+
|
106
|
+
schema :array, min_items: 5
|
107
|
+
assert_json(type: :array, minItems: 5)
|
108
|
+
|
109
|
+
assert_validation [1, 2, 3, 4] do
|
110
|
+
error '/', 'Array has 4 items but needs at least 5.'
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_max_items
|
115
|
+
schema :array, max_items: 0
|
116
|
+
|
117
|
+
assert_json(type: :array, maxItems: 0)
|
118
|
+
assert_validation []
|
119
|
+
|
120
|
+
schema :array, max_items: 1
|
121
|
+
|
122
|
+
assert_json(type: :array, maxItems: 1)
|
123
|
+
assert_validation [1]
|
124
|
+
assert_validation [1, 2] do
|
125
|
+
error '/', 'Array has 2 items but needs at most 1.'
|
126
|
+
end
|
127
|
+
|
128
|
+
schema :array, max_items: 5
|
129
|
+
|
130
|
+
assert_json(type: :array, maxItems: 5)
|
131
|
+
assert_validation [1, 2, 3, 4, 5, 6] do
|
132
|
+
error '/', 'Array has 6 items but needs at most 5.'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_min_max_items
|
137
|
+
schema :array, min_items: 2, max_items: 4
|
138
|
+
|
139
|
+
assert_json(type: :array, minItems: 2, maxItems: 4)
|
140
|
+
assert_validation [1, 2]
|
141
|
+
assert_validation [1, 2, 3]
|
142
|
+
assert_validation [1, 2, 3, 4]
|
143
|
+
|
144
|
+
assert_validation [1] do
|
145
|
+
error '/', 'Array has 1 items but needs at least 2.'
|
146
|
+
end
|
147
|
+
|
148
|
+
assert_validation [1, 2, 3, 4, 5] do
|
149
|
+
error '/', 'Array has 5 items but needs at most 4.'
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_unique_items
|
154
|
+
schema :array, unique_items: true
|
155
|
+
|
156
|
+
assert_json(type: :array, uniqueItems: true)
|
157
|
+
assert_validation [1, 2]
|
158
|
+
assert_validation [1, 2, :foo, 'bar', 'foo']
|
159
|
+
|
160
|
+
assert_validation [1, 1] do
|
161
|
+
error '/', 'Array has duplicate items.'
|
162
|
+
end
|
163
|
+
|
164
|
+
assert_validation [:foo, :foo] do
|
165
|
+
error '/', 'Array has duplicate items.'
|
166
|
+
end
|
167
|
+
|
168
|
+
assert_validation [1, 2, :foo, 'bar', 'foo'].as_json do
|
169
|
+
error '/', 'Array has duplicate items.'
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_single_item_tuple
|
174
|
+
schema :array do
|
175
|
+
str
|
176
|
+
end
|
177
|
+
|
178
|
+
assert_json(
|
179
|
+
type: :array,
|
180
|
+
items: [
|
181
|
+
{ type: :string }
|
182
|
+
],
|
183
|
+
additionalItems: false
|
184
|
+
)
|
185
|
+
|
186
|
+
assert_validation [] do
|
187
|
+
error '/', 'Array has 0 items but must have exactly 1.'
|
188
|
+
end
|
189
|
+
assert_validation %w[foo]
|
190
|
+
assert_validation %w[foo bar] do
|
191
|
+
error '/', 'Array has 2 items but must have exactly 1.'
|
192
|
+
end
|
193
|
+
|
194
|
+
assert_validation ['foo', :bar] do
|
195
|
+
error '/', 'Array has 2 items but must have exactly 1.'
|
196
|
+
end
|
197
|
+
|
198
|
+
assert_validation %i[foo] do
|
199
|
+
error '/[0]', 'Invalid type, expected "string".'
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_multiple_item_tuple
|
204
|
+
schema :array do
|
205
|
+
str
|
206
|
+
int
|
207
|
+
hsh do
|
208
|
+
str! :name
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
assert_json(
|
213
|
+
type: :array,
|
214
|
+
items: [
|
215
|
+
{ type: :string },
|
216
|
+
{ type: :integer },
|
217
|
+
{ type: :object, properties: { name: { type: :string } }, required: %i[name], additionalProperties: false }
|
218
|
+
],
|
219
|
+
additionalItems: false
|
220
|
+
)
|
221
|
+
|
222
|
+
assert_validation(['foo', 42, { name: 'Hello' }])
|
223
|
+
|
224
|
+
assert_validation [] do
|
225
|
+
error '/', 'Array has 0 items but must have exactly 3.'
|
226
|
+
end
|
227
|
+
|
228
|
+
assert_validation ['foo'] do
|
229
|
+
error '/', 'Array has 1 items but must have exactly 3.'
|
230
|
+
end
|
231
|
+
|
232
|
+
assert_validation([42, 42, { name: 'Hello' }]) do
|
233
|
+
error '/[0]', 'Invalid type, expected "string".'
|
234
|
+
end
|
235
|
+
|
236
|
+
assert_validation(['foo', 42, { namex: 'Hello' }]) do
|
237
|
+
error '/[2]/name', 'Value must be given.'
|
238
|
+
error '/[2]', 'Obsolete property "namex".'
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def test_additional_items_true
|
243
|
+
schema :array, additional_items: true do
|
244
|
+
str
|
245
|
+
int
|
246
|
+
end
|
247
|
+
|
248
|
+
assert_json(
|
249
|
+
type: :array,
|
250
|
+
items: [
|
251
|
+
{ type: :string },
|
252
|
+
{ type: :integer }
|
253
|
+
],
|
254
|
+
additionalItems: true
|
255
|
+
)
|
256
|
+
|
257
|
+
assert_validation(['foo', 42])
|
258
|
+
assert_validation(['foo', 42, 'additional'])
|
259
|
+
assert_validation(['foo', 42, 42])
|
260
|
+
|
261
|
+
assert_cast(['Foo', 42], ['Foo', 42])
|
262
|
+
assert_cast(['Foo', 42, 42], ['Foo', 42, 42])
|
263
|
+
assert_cast(['Foo', 42, :bar], ['Foo', 42, :bar])
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_additional_items_true_casting
|
267
|
+
schema :array, additional_items: true do
|
268
|
+
str format: :date
|
269
|
+
int
|
270
|
+
end
|
271
|
+
|
272
|
+
assert_json(
|
273
|
+
type: :array,
|
274
|
+
items: [
|
275
|
+
{ type: :string, format: :date },
|
276
|
+
{ type: :integer }
|
277
|
+
],
|
278
|
+
additionalItems: true
|
279
|
+
)
|
280
|
+
|
281
|
+
assert_validation(['1990-01-01', 42])
|
282
|
+
assert_validation(['1990-01-01', 42, 'additional'])
|
283
|
+
assert_validation(['1990-01-01', 42, 42])
|
284
|
+
|
285
|
+
assert_cast(['1990-01-01', 42], [Date.new(1990, 1, 1), 42])
|
286
|
+
assert_cast(['1990-01-01', 42, '2010-01-01'], [Date.new(1990, 1, 1), 42, '2010-01-01'])
|
287
|
+
assert_cast(['1990-01-01', 42, :bar], [Date.new(1990, 1, 1), 42, :bar])
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_additional_items_single
|
291
|
+
schema :array do
|
292
|
+
str
|
293
|
+
add :integer
|
294
|
+
end
|
295
|
+
|
296
|
+
assert_json(
|
297
|
+
type: :array,
|
298
|
+
items: [
|
299
|
+
{ type: :string }
|
300
|
+
],
|
301
|
+
additionalItems: { type: :integer }
|
302
|
+
)
|
303
|
+
|
304
|
+
assert_validation(['foo'])
|
305
|
+
assert_validation(['foo', 42])
|
306
|
+
assert_validation(['foo', 42, 42])
|
307
|
+
assert_validation(['foo', :foo]) do
|
308
|
+
error '/[1]', 'Invalid type, expected "integer".'
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_additional_items_schema
|
313
|
+
schema :array, additional_items: true do
|
314
|
+
str
|
315
|
+
int
|
316
|
+
add :string
|
317
|
+
end
|
318
|
+
|
319
|
+
assert_json(
|
320
|
+
type: :array,
|
321
|
+
items: [
|
322
|
+
{ type: :string },
|
323
|
+
{ type: :integer }
|
324
|
+
],
|
325
|
+
additionalItems: { type: :string }
|
326
|
+
)
|
327
|
+
|
328
|
+
assert_validation(['foo', 42])
|
329
|
+
assert_validation(['foo', 42, 'additional', 'another'])
|
330
|
+
assert_validation(['foo', 42, 'additional', 42, 'another']) do
|
331
|
+
error '/[3]', 'Invalid type, expected "string".'
|
332
|
+
end
|
333
|
+
|
334
|
+
assert_cast(['foo', 42], ['foo', 42])
|
335
|
+
assert_cast(['foo', 42, 'bar'], ['foo', 42, 'bar'])
|
336
|
+
end
|
337
|
+
|
338
|
+
def test_additional_items_schema_casting
|
339
|
+
schema :array, additional_items: true do
|
340
|
+
str
|
341
|
+
int
|
342
|
+
add :string, format: :date
|
343
|
+
end
|
344
|
+
|
345
|
+
assert_json(
|
346
|
+
type: :array,
|
347
|
+
items: [
|
348
|
+
{ type: :string },
|
349
|
+
{ type: :integer }
|
350
|
+
],
|
351
|
+
additionalItems: { type: :string, format: :date }
|
352
|
+
)
|
353
|
+
|
354
|
+
assert_validation(['foo', 42])
|
355
|
+
assert_validation(['foo', 42, '1990-01-01'])
|
356
|
+
assert_validation(['foo', 42, '1990-01-01', 42]) do
|
357
|
+
error '/[3]', 'Invalid type, expected "string".'
|
358
|
+
end
|
359
|
+
assert_validation(['foo', 42, '1990-01-01', 'foo']) do
|
360
|
+
error '/[3]', 'String does not match format "date".'
|
361
|
+
end
|
362
|
+
|
363
|
+
assert_cast(['foo', 42], ['foo', 42])
|
364
|
+
assert_cast(['foo', 42, '1990-01-01'], ['foo', 42, Date.new(1990, 1, 1)])
|
365
|
+
end
|
366
|
+
|
367
|
+
def test_additional_items_schema_oneof_casting
|
368
|
+
schema :array, additional_items: true do
|
369
|
+
str
|
370
|
+
int
|
371
|
+
add :one_of do
|
372
|
+
str format: :date
|
373
|
+
str format: :integer
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
assert_json(
|
378
|
+
type: :array,
|
379
|
+
items: [
|
380
|
+
{ type: :string },
|
381
|
+
{ type: :integer }
|
382
|
+
],
|
383
|
+
additionalItems: {
|
384
|
+
oneOf: [
|
385
|
+
{ type: :string, format: :date },
|
386
|
+
{ type: :string, format: :integer }
|
387
|
+
]
|
388
|
+
}
|
389
|
+
)
|
390
|
+
|
391
|
+
assert_validation(['foo', 42])
|
392
|
+
assert_validation(['foo', 42, '1990-01-01'])
|
393
|
+
assert_validation(['foo', 42, '1990-01-01', 42]) do
|
394
|
+
error '/[3]', 'Matches 0 definitions but should match exactly 1.'
|
395
|
+
end
|
396
|
+
assert_validation(['foo', 42, '1990-01-01', 'foo']) do
|
397
|
+
error '/[3]', 'Matches 0 definitions but should match exactly 1.'
|
398
|
+
end
|
399
|
+
|
400
|
+
assert_cast(['foo', 42], ['foo', 42])
|
401
|
+
assert_cast(['foo', 42, '1990-01-01'], ['foo', 42, Date.new(1990, 1, 1)])
|
402
|
+
assert_cast(['foo', 42, '1337'], ['foo', 42, 1337])
|
403
|
+
end
|
404
|
+
|
405
|
+
def test_additional_items_schema_hash_casting
|
406
|
+
schema :array, additional_items: true do
|
407
|
+
str
|
408
|
+
int
|
409
|
+
add :hash do
|
410
|
+
str! :foo, format: :date
|
411
|
+
sym? :bar
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
assert_json(
|
416
|
+
type: :array,
|
417
|
+
items: [
|
418
|
+
{ type: :string },
|
419
|
+
{ type: :integer }
|
420
|
+
],
|
421
|
+
additionalItems: {
|
422
|
+
properties: {
|
423
|
+
foo: {
|
424
|
+
type: :string,
|
425
|
+
format: :date
|
426
|
+
},
|
427
|
+
bar: {}
|
428
|
+
},
|
429
|
+
additionalProperties: false,
|
430
|
+
type: :object,
|
431
|
+
required: [
|
432
|
+
:foo
|
433
|
+
]
|
434
|
+
}
|
435
|
+
)
|
436
|
+
|
437
|
+
assert_validation(['foo', 42])
|
438
|
+
assert_validation(['foo', 42, { foo: '1990-01-01' }])
|
439
|
+
assert_validation(['foo', 42, { foo: '1990-01-01', bar: :baz }])
|
440
|
+
|
441
|
+
assert_validation(['foo', 42, { foo: 1234 }]) do
|
442
|
+
error '/[2]/foo', 'Invalid type, expected "string".'
|
443
|
+
end
|
444
|
+
assert_validation(['foo', 42, { foo: 'String' }]) do
|
445
|
+
error '/[2]/foo', 'String does not match format "date".'
|
446
|
+
end
|
447
|
+
|
448
|
+
assert_cast(['foo', 42], ['foo', 42])
|
449
|
+
assert_cast(['foo', 42, { foo: '1990-01-01' }], ['foo', 42, { foo: Date.new(1990, 1, 1) }])
|
450
|
+
assert_cast(['foo', 42, { foo: '1990-01-01', bar: :baz }], ['foo', 42, { foo: Date.new(1990, 1, 1), bar: :baz }])
|
451
|
+
end
|
452
|
+
|
453
|
+
def test_multiple_add_in_schema
|
454
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
455
|
+
'You can only use "add" once to specify additional items.' do
|
456
|
+
schema :array do
|
457
|
+
add :integer
|
458
|
+
add :string
|
459
|
+
end
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
def test_contains
|
464
|
+
schema :array do
|
465
|
+
cont :string
|
466
|
+
end
|
467
|
+
|
468
|
+
assert_json(
|
469
|
+
type: :array,
|
470
|
+
contains: {
|
471
|
+
type: :string
|
472
|
+
}
|
473
|
+
)
|
474
|
+
|
475
|
+
assert_validation(%w[foo bar])
|
476
|
+
assert_validation(['foo', 42])
|
477
|
+
assert_validation(['foo'])
|
478
|
+
|
479
|
+
assert_validation([]) do
|
480
|
+
error '/', 'At least one entry must match schema {"type"=>"string"}.'
|
481
|
+
end
|
482
|
+
|
483
|
+
assert_validation([234, :foo]) do
|
484
|
+
error '/', 'At least one entry must match schema {"type"=>"string"}.'
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
def test_contains_int
|
489
|
+
schema :array do
|
490
|
+
cont :integer
|
491
|
+
end
|
492
|
+
|
493
|
+
assert_validation(['foo', 1, :bar])
|
494
|
+
assert_cast(['foo', 1, :bar], ['foo', 1, :bar])
|
495
|
+
end
|
496
|
+
|
497
|
+
def test_contains_with_casting
|
498
|
+
schema :array do
|
499
|
+
cont :string, format: :date
|
500
|
+
end
|
501
|
+
|
502
|
+
assert_validation(nil)
|
503
|
+
assert_validation(['1990-01-01'])
|
504
|
+
|
505
|
+
assert_cast(['1990-01-01'], [Date.new(1990, 1, 1)])
|
506
|
+
assert_cast(%w[1990-01-01 123], [Date.new(1990, 1, 1), '123'])
|
507
|
+
assert_cast(%w[1990-01-01 123 2010-01-01], [Date.new(1990, 1, 1), '123', Date.new(2010, 1, 1)])
|
508
|
+
end
|
509
|
+
|
510
|
+
def test_defaults
|
511
|
+
schema :array, default: [1, 2, 3]
|
512
|
+
|
513
|
+
assert_cast nil, [1, 2, 3]
|
514
|
+
|
515
|
+
assert_json(
|
516
|
+
type: :array,
|
517
|
+
default: [1, 2, 3]
|
518
|
+
)
|
519
|
+
|
520
|
+
schema :array do
|
521
|
+
hsh do
|
522
|
+
str? :name, default: 'John'
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
assert_json(
|
527
|
+
type: :array,
|
528
|
+
items: [
|
529
|
+
{
|
530
|
+
type: :object,
|
531
|
+
properties: {
|
532
|
+
name: { type: :string, default: 'John' }
|
533
|
+
},
|
534
|
+
additionalProperties: false
|
535
|
+
}
|
536
|
+
],
|
537
|
+
additionalItems: false
|
538
|
+
)
|
539
|
+
|
540
|
+
assert_cast [{}], [{ name: 'John' }]
|
541
|
+
end
|
542
|
+
|
543
|
+
def test_enum_schema
|
544
|
+
schema :array, enum: [1, 2, 'foo', :bar, { qux: 42 }, [1, 2], %w[a b]]
|
545
|
+
|
546
|
+
assert_json({
|
547
|
+
type: :array,
|
548
|
+
enum: [1, 2, 'foo', :bar, { qux: 42 }, [1, 2], %w[a b]]
|
549
|
+
})
|
550
|
+
|
551
|
+
assert_validation(nil)
|
552
|
+
assert_validation([1, 2])
|
553
|
+
assert_validation(%w[a b])
|
554
|
+
|
555
|
+
# Even we put those types in the enum, they need to fail the validations,
|
556
|
+
# as they are not arrays
|
557
|
+
assert_validation('foo') do
|
558
|
+
error '/', 'Invalid type, expected "array".'
|
559
|
+
end
|
560
|
+
assert_validation(1) do
|
561
|
+
error '/', 'Invalid type, expected "array".'
|
562
|
+
end
|
563
|
+
assert_validation(:bar) do
|
564
|
+
error '/', 'Invalid type, expected "array".'
|
565
|
+
end
|
566
|
+
assert_validation({ qux: 42 }) do
|
567
|
+
error '/', 'Invalid type, expected "array".'
|
568
|
+
end
|
569
|
+
|
570
|
+
# These need to fail validation, as they are not in the enum list
|
571
|
+
assert_validation([1, 2, 3]) do
|
572
|
+
error '/', 'Value not included in enum [1, 2, "foo", :bar, {:qux=>42}, [1, 2], ["a", "b"]].'
|
573
|
+
end
|
574
|
+
assert_validation([]) do
|
575
|
+
error '/', 'Value not included in enum [1, 2, "foo", :bar, {:qux=>42}, [1, 2], ["a", "b"]].'
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
def test_with_generic_keywords
|
580
|
+
schema :array, enum: [1, 'foo', [1, 2, 3]],
|
581
|
+
title: 'Array schema',
|
582
|
+
description: 'Array schema holding generic keywords',
|
583
|
+
examples: [
|
584
|
+
[1, 2, 3]
|
585
|
+
]
|
586
|
+
|
587
|
+
assert_json({
|
588
|
+
type: :array,
|
589
|
+
enum: [1, 'foo', [1, 2, 3]],
|
590
|
+
title: 'Array schema',
|
591
|
+
description: 'Array schema holding generic keywords',
|
592
|
+
examples: [
|
593
|
+
[1, 2, 3]
|
594
|
+
]
|
595
|
+
})
|
596
|
+
end
|
597
|
+
|
598
|
+
# Helper function that checks for the min_items and max_items options if the option is
|
599
|
+
# an integer or something else, in which case it needs to raise
|
600
|
+
def validate_self_should_error(value_to_check)
|
601
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
602
|
+
'Option "min_items" must be an "integer"' do
|
603
|
+
schema :array, min_items: value_to_check
|
604
|
+
end
|
605
|
+
|
606
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
607
|
+
'Option "max_items" must be an "integer"' do
|
608
|
+
schema :array, max_items: value_to_check
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
def test_validate_self
|
613
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
614
|
+
'Option "min_items" can\'t be greater than "max_items".' do
|
615
|
+
schema :array, min_items: 5, max_items: 4
|
616
|
+
end
|
617
|
+
|
618
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
619
|
+
'Option "unique_items" must be a "boolean".' do
|
620
|
+
schema :array, unique_items: 4
|
621
|
+
end
|
622
|
+
|
623
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
624
|
+
'Option "unique_items" must be a "boolean".' do
|
625
|
+
schema :array, unique_items: 'false'
|
626
|
+
end
|
627
|
+
|
628
|
+
validate_self_should_error(1.0)
|
629
|
+
validate_self_should_error(4r)
|
630
|
+
validate_self_should_error(true)
|
631
|
+
validate_self_should_error(false)
|
632
|
+
validate_self_should_error(Object.new)
|
633
|
+
validate_self_should_error((4 + 6i))
|
634
|
+
validate_self_should_error('13')
|
635
|
+
validate_self_should_error('Lorem ipsum')
|
636
|
+
end
|
637
|
+
|
638
|
+
def test_list
|
639
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
640
|
+
'You can only use "list" once.' do
|
641
|
+
schema :array do
|
642
|
+
list :integer
|
643
|
+
list :symbol
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
648
|
+
'Can\'t use "list" and normal items.' do
|
649
|
+
schema :array do
|
650
|
+
list :integer
|
651
|
+
int
|
652
|
+
end
|
653
|
+
end
|
654
|
+
|
655
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
656
|
+
'Can\'t use "list" and additional items.' do
|
657
|
+
schema :array do
|
658
|
+
list :integer
|
659
|
+
add :symbol
|
660
|
+
end
|
661
|
+
end
|
662
|
+
|
663
|
+
schema :array do
|
664
|
+
list :integer
|
665
|
+
end
|
666
|
+
|
667
|
+
assert_validation([])
|
668
|
+
assert_validation([1])
|
669
|
+
assert_validation([1, 2, 3, 4, 5, 6])
|
670
|
+
|
671
|
+
assert_validation([1, :foo, 'bar']) do
|
672
|
+
error '/[1]', 'Invalid type, expected "integer".'
|
673
|
+
error '/[2]', 'Invalid type, expected "integer".'
|
674
|
+
end
|
675
|
+
end
|
676
|
+
|
677
|
+
def test_list_casting
|
678
|
+
schema :array do
|
679
|
+
list :string, format: :date
|
680
|
+
end
|
681
|
+
|
682
|
+
assert_json(
|
683
|
+
type: :array,
|
684
|
+
items: {
|
685
|
+
type: :string,
|
686
|
+
format: :date
|
687
|
+
}
|
688
|
+
)
|
689
|
+
|
690
|
+
assert_validation(nil)
|
691
|
+
assert_validation(['1990-01-01'])
|
692
|
+
assert_validation(%w[1990-01-01 2020-01-01])
|
693
|
+
assert_validation(['foo']) do
|
694
|
+
error '/[0]', 'String does not match format "date".'
|
695
|
+
end
|
696
|
+
|
697
|
+
assert_cast(['1990-01-01'], [Date.new(1990, 1, 1)])
|
698
|
+
end
|
699
|
+
|
700
|
+
def test_simple_contains
|
701
|
+
schema :array do
|
702
|
+
cont :integer, minimum: 3
|
703
|
+
end
|
704
|
+
|
705
|
+
assert_json(
|
706
|
+
type: :array,
|
707
|
+
contains: {
|
708
|
+
type: :integer,
|
709
|
+
minimum: 3
|
710
|
+
}
|
711
|
+
)
|
712
|
+
|
713
|
+
assert_validation(nil)
|
714
|
+
assert_validation([]) do
|
715
|
+
error '/', 'At least one entry must match schema {"type"=>"integer", "minimum"=>3}.'
|
716
|
+
end
|
717
|
+
assert_validation([1, 2]) do
|
718
|
+
error '/', 'At least one entry must match schema {"type"=>"integer", "minimum"=>3}.'
|
719
|
+
end
|
720
|
+
assert_validation([1, 2, 3])
|
721
|
+
end
|
722
|
+
|
723
|
+
def test_contains_with_list
|
724
|
+
schema :array do
|
725
|
+
list :integer, minimum: 2
|
726
|
+
cont :integer, minimum: 5
|
727
|
+
end
|
728
|
+
|
729
|
+
assert_json(
|
730
|
+
type: :array,
|
731
|
+
contains: {
|
732
|
+
type: :integer,
|
733
|
+
minimum: 5
|
734
|
+
},
|
735
|
+
items: {
|
736
|
+
type: :integer,
|
737
|
+
minimum: 2
|
738
|
+
}
|
739
|
+
)
|
740
|
+
|
741
|
+
assert_validation(nil)
|
742
|
+
assert_validation([]) do
|
743
|
+
error '/', 'At least one entry must match schema {"type"=>"integer", "minimum"=>5}.'
|
744
|
+
end
|
745
|
+
assert_validation([1]) do
|
746
|
+
error '/', 'At least one entry must match schema {"type"=>"integer", "minimum"=>5}.'
|
747
|
+
error '/[0]', 'Value must have a minimum of 2.'
|
748
|
+
end
|
749
|
+
assert_validation([2]) do
|
750
|
+
error '/', 'At least one entry must match schema {"type"=>"integer", "minimum"=>5}.'
|
751
|
+
end
|
752
|
+
|
753
|
+
assert_validation([2, 3, 5])
|
754
|
+
end
|
755
|
+
|
756
|
+
def test_contains_need_casting
|
757
|
+
schema :array do
|
758
|
+
cont :string, format: :date
|
759
|
+
end
|
760
|
+
|
761
|
+
assert_json(
|
762
|
+
type: :array,
|
763
|
+
contains: {
|
764
|
+
type: :string,
|
765
|
+
format: :date
|
766
|
+
}
|
767
|
+
)
|
768
|
+
|
769
|
+
assert_validation(nil)
|
770
|
+
assert_validation(['1990-01-01'])
|
771
|
+
assert_validation(['1990-01-01', 1234])
|
772
|
+
|
773
|
+
assert_cast(['1990-01-01'], [Date.new(1990, 1, 1)])
|
774
|
+
assert_cast(%w[1990-01-01 123], [Date.new(1990, 1, 1), '123'])
|
775
|
+
assert_cast(%w[1990-01-01 123 2010-01-01], [Date.new(1990, 1, 1), '123', Date.new(2010, 1, 1)])
|
776
|
+
end
|
777
|
+
|
778
|
+
def test_contains_with_list_casting
|
779
|
+
schema :array do
|
780
|
+
list :string
|
781
|
+
cont :string, format: :date
|
782
|
+
end
|
783
|
+
|
784
|
+
assert_json(
|
785
|
+
type: :array,
|
786
|
+
items: {
|
787
|
+
type: :string
|
788
|
+
},
|
789
|
+
contains: {
|
790
|
+
type: :string,
|
791
|
+
format: :date
|
792
|
+
}
|
793
|
+
)
|
794
|
+
|
795
|
+
assert_validation(nil)
|
796
|
+
assert_validation(['foo']) do
|
797
|
+
error '/', 'At least one entry must match schema {"type"=>"string", "format"=>"date"}.'
|
798
|
+
end
|
799
|
+
assert_validation(%w[foo 1990-01-01])
|
800
|
+
|
801
|
+
assert_cast(%w[foo 1990-01-01], ['foo', Date.new(1990, 1, 1)])
|
802
|
+
end
|
803
|
+
end
|
804
|
+
end
|
805
|
+
end
|