json_schema 0.2.0 → 0.3.0
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/README.md +11 -3
- data/lib/json_schema/parser.rb +5 -5
- data/lib/json_schema/reference_expander.rb +6 -6
- data/lib/json_schema/schema_error.rb +5 -5
- data/lib/json_schema/validator.rb +93 -46
- data/test/json_schema/parser_test.rb +19 -10
- data/test/json_schema/reference_expander_test.rb +32 -24
- data/test/json_schema/validator_test.rb +112 -75
- data/test/json_schema_test.rb +2 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 090872e4eabd4666b863192705b856a9bed17f95
|
4
|
+
data.tar.gz: d663a4d178b532eedea87e3b9e103e11c618169a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab37926ea68afd15a71c4ca1be9ee265b990caf1e24901c031ea094bea806b671472cd65cec3225f420ba1baed6ec3acc41063b505d6eda3a95bbb028c20664b
|
7
|
+
data.tar.gz: 2345cc253f9cb16f2f542234f0c705a4d97e256beb55c1cba45b190be570b46c7691193ca01b176f13c702bc2356e9e300e63dcfe17532ab714e27500ba3397b
|
data/README.md
CHANGED
@@ -15,11 +15,11 @@ validate-schema schema.json data.json
|
|
15
15
|
require "json"
|
16
16
|
require "json_schema"
|
17
17
|
|
18
|
-
# parse the schema
|
18
|
+
# parse the schema - raise SchemaError if it's invalid
|
19
19
|
schema_data = JSON.parse(File.read("schema.json"))
|
20
20
|
schema = JsonSchema.parse!(schema_data)
|
21
21
|
|
22
|
-
# validate some data
|
22
|
+
# validate some data - raise ValidationError if it doesn't conform
|
23
23
|
data = JSON.parse(File.read("data.json"))
|
24
24
|
schema.validate!(data)
|
25
25
|
|
@@ -29,6 +29,14 @@ schema.links.each do |link|
|
|
29
29
|
end
|
30
30
|
```
|
31
31
|
|
32
|
+
Errors have a `message` (for humans), and `type` (for machines).
|
33
|
+
`ValidationError`s also include a `path`, a JSON pointer to the location in
|
34
|
+
the supplied document which violated the schema. See [errors](docs/errors.md)
|
35
|
+
for more info.
|
36
|
+
|
37
|
+
Non-bang methods return a two-element array, with `true`/`false` at index 0
|
38
|
+
to indicate pass/fail, and an array of errors at index 1 (if any).
|
39
|
+
|
32
40
|
## Development
|
33
41
|
|
34
42
|
Run the test suite with:
|
@@ -42,4 +50,4 @@ Or run specific suites or tests with:
|
|
42
50
|
```
|
43
51
|
ruby -Ilib -Itest test/json_schema/validator_test.rb
|
44
52
|
ruby -Ilib -Itest test/json_schema/validator_test.rb -n /anyOf/
|
45
|
-
```
|
53
|
+
```
|
data/lib/json_schema/parser.rb
CHANGED
@@ -108,8 +108,8 @@ module JsonSchema
|
|
108
108
|
if !data.is_a?(Hash)
|
109
109
|
# it would be nice to make this message more specific/nicer (at best it
|
110
110
|
# points to the wrong schema)
|
111
|
-
message = %{
|
112
|
-
@errors << SchemaError.new(parent, message)
|
111
|
+
message = %{#{data.inspect} is not a valid schema.}
|
112
|
+
@errors << SchemaError.new(parent, message, :schema_not_found)
|
113
113
|
elsif ref = data["$ref"]
|
114
114
|
schema = Schema.new
|
115
115
|
schema.fragment = fragment
|
@@ -314,7 +314,7 @@ module JsonSchema
|
|
314
314
|
if schema.type
|
315
315
|
if !(bad_types = schema.type - ALLOWED_TYPES).empty?
|
316
316
|
message = %{Unknown types: #{bad_types.sort.join(", ")}.}
|
317
|
-
@errors << SchemaError.new(schema, message)
|
317
|
+
@errors << SchemaError.new(schema, message, :unknown_type)
|
318
318
|
end
|
319
319
|
end
|
320
320
|
end
|
@@ -324,8 +324,8 @@ module JsonSchema
|
|
324
324
|
types.map { |t| FRIENDLY_TYPES[t] || t }.sort.uniq.join("/")
|
325
325
|
value = schema.data[field]
|
326
326
|
if !value.nil? && !types.any? { |t| value.is_a?(t) }
|
327
|
-
message = %{
|
328
|
-
@errors << SchemaError.new(schema, message)
|
327
|
+
message = %{#{value.inspect} is not a valid "#{field}", must be a #{friendly_types}.}
|
328
|
+
@errors << SchemaError.new(schema, message, :invalid_type)
|
329
329
|
nil
|
330
330
|
else
|
331
331
|
value
|
@@ -25,7 +25,7 @@ module JsonSchema
|
|
25
25
|
refs = unresolved_refs(schema).sort
|
26
26
|
if refs.count > 0
|
27
27
|
message = %{Couldn't resolve references: #{refs.to_a.join(", ")}.}
|
28
|
-
@errors << SchemaError.new(schema, message)
|
28
|
+
@errors << SchemaError.new(schema, message, :unresolved_references)
|
29
29
|
end
|
30
30
|
|
31
31
|
@errors.count == 0
|
@@ -73,8 +73,8 @@ module JsonSchema
|
|
73
73
|
|
74
74
|
# detects a reference cycle
|
75
75
|
if ref_stack.include?(ref)
|
76
|
-
message = %{Reference
|
77
|
-
@errors << SchemaError.new(ref_schema, message)
|
76
|
+
message = %{Reference loop detected: #{ref_stack.sort.join(", ")}.}
|
77
|
+
@errors << SchemaError.new(ref_schema, message, :loop_detected)
|
78
78
|
return false
|
79
79
|
end
|
80
80
|
|
@@ -128,7 +128,7 @@ module JsonSchema
|
|
128
128
|
# couldn't resolve pointer within known schema; that's an error
|
129
129
|
if data.nil?
|
130
130
|
message = %{Couldn't resolve pointer "#{ref.pointer}".}
|
131
|
-
@errors << SchemaError.new(resolved_schema, message)
|
131
|
+
@errors << SchemaError.new(resolved_schema, message, :unresolved_pointer)
|
132
132
|
return
|
133
133
|
end
|
134
134
|
|
@@ -159,7 +159,7 @@ module JsonSchema
|
|
159
159
|
else
|
160
160
|
message =
|
161
161
|
%{Reference resolution over #{scheme} is not currently supported.}
|
162
|
-
@errors << SchemaError.new(ref_schema, message)
|
162
|
+
@errors << SchemaError.new(ref_schema, message, :scheme_not_supported)
|
163
163
|
nil
|
164
164
|
end
|
165
165
|
# absolute
|
@@ -182,7 +182,7 @@ module JsonSchema
|
|
182
182
|
resolve_pointer(ref_schema, schema)
|
183
183
|
else
|
184
184
|
message = %{Couldn't resolve URI: #{uri.to_s}.}
|
185
|
-
@errors << SchemaError.new(ref_schema, message)
|
185
|
+
@errors << SchemaError.new(ref_schema, message, :unresolved_pointer)
|
186
186
|
nil
|
187
187
|
end
|
188
188
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
module JsonSchema
|
2
2
|
class SchemaError
|
3
|
-
attr_accessor :message
|
4
|
-
attr_accessor :schema
|
3
|
+
attr_accessor :message, :schema, :type
|
5
4
|
|
6
5
|
def self.aggregate(errors)
|
7
6
|
errors.map(&:to_s)
|
8
7
|
end
|
9
8
|
|
10
|
-
def initialize(schema, message)
|
9
|
+
def initialize(schema, message, type)
|
11
10
|
@schema = schema
|
12
11
|
@message = message
|
12
|
+
@type = type
|
13
13
|
end
|
14
14
|
|
15
15
|
def to_s
|
@@ -20,8 +20,8 @@ module JsonSchema
|
|
20
20
|
class ValidationError < SchemaError
|
21
21
|
attr_accessor :path
|
22
22
|
|
23
|
-
def initialize(schema, path, message)
|
24
|
-
super(schema, message)
|
23
|
+
def initialize(schema, path, message, type)
|
24
|
+
super(schema, message, type)
|
25
25
|
@path = path
|
26
26
|
end
|
27
27
|
|
@@ -45,7 +45,7 @@ module JsonSchema
|
|
45
45
|
true
|
46
46
|
else
|
47
47
|
message = %{Validation loop detected.}
|
48
|
-
errors << ValidationError.new(schema, path, message)
|
48
|
+
errors << ValidationError.new(schema, path, message, :loop_detected)
|
49
49
|
false
|
50
50
|
end
|
51
51
|
=end
|
@@ -143,8 +143,8 @@ module JsonSchema
|
|
143
143
|
valid = schema.all_of.all? do |subschema|
|
144
144
|
validate_data(subschema, data, errors, path)
|
145
145
|
end
|
146
|
-
message = %{
|
147
|
-
errors << ValidationError.new(schema, path, message) if !valid
|
146
|
+
message = %{Not all subschemas of "allOf" matched.}
|
147
|
+
errors << ValidationError.new(schema, path, message, :all_of_failed) if !valid
|
148
148
|
valid
|
149
149
|
end
|
150
150
|
|
@@ -154,8 +154,8 @@ module JsonSchema
|
|
154
154
|
validate_data(subschema, data, [], path)
|
155
155
|
end
|
156
156
|
if !valid
|
157
|
-
message = %{
|
158
|
-
errors << ValidationError.new(schema, path, message)
|
157
|
+
message = %{No subschema in "anyOf" matched.}
|
158
|
+
errors << ValidationError.new(schema, path, message, :any_of_failed)
|
159
159
|
end
|
160
160
|
valid
|
161
161
|
end
|
@@ -197,8 +197,8 @@ module JsonSchema
|
|
197
197
|
if valid
|
198
198
|
true
|
199
199
|
else
|
200
|
-
message = %{
|
201
|
-
errors << ValidationError.new(schema, path, message)
|
200
|
+
message = %{#{data} is not a valid #{schema.format}.}
|
201
|
+
errors << ValidationError.new(schema, path, message, :invalid_format)
|
202
202
|
false
|
203
203
|
end
|
204
204
|
end
|
@@ -208,8 +208,8 @@ module JsonSchema
|
|
208
208
|
if schema.enum.include?(data)
|
209
209
|
true
|
210
210
|
else
|
211
|
-
message = %{
|
212
|
-
errors << ValidationError.new(schema, path, message)
|
211
|
+
message = %{#{data} is not a member of #{schema.enum}.}
|
212
|
+
errors << ValidationError.new(schema, path, message, :invalid_type)
|
213
213
|
false
|
214
214
|
end
|
215
215
|
end
|
@@ -219,8 +219,12 @@ module JsonSchema
|
|
219
219
|
if extra.empty?
|
220
220
|
true
|
221
221
|
else
|
222
|
-
|
223
|
-
|
222
|
+
|
223
|
+
message = %{"#{extra.sort.join('", "')}" } +
|
224
|
+
(extra.length == 1 ? "is not a" : "are not") +
|
225
|
+
%{ permitted key} +
|
226
|
+
(extra.length == 1 ? "." : "s.")
|
227
|
+
errors << ValidationError.new(schema, path, message, :invalid_keys)
|
224
228
|
false
|
225
229
|
end
|
226
230
|
end
|
@@ -229,12 +233,20 @@ module JsonSchema
|
|
229
233
|
return true unless schema.items
|
230
234
|
if schema.items.is_a?(Array)
|
231
235
|
if data.size < schema.items.count
|
232
|
-
message = %{
|
233
|
-
|
236
|
+
message = %{#{schema.items.count} item} +
|
237
|
+
(schema.items.count == 1 ? "" : "s") +
|
238
|
+
%{ required; only #{data.size} } +
|
239
|
+
(data.size == 1 ? "was" : "were") +
|
240
|
+
%{ supplied.}
|
241
|
+
errors << ValidationError.new(schema, path, message, :min_items_failed)
|
234
242
|
false
|
235
243
|
elsif data.size > schema.items.count && !schema.additional_items?
|
236
|
-
message = %{
|
237
|
-
|
244
|
+
message = %{No more than #{schema.items.count} item} +
|
245
|
+
(schema.items.count == 1 ? " is" : "s are") +
|
246
|
+
%{ allowed; #{data.size} } +
|
247
|
+
(data.size > 1 ? "were" : "was") +
|
248
|
+
%{ supplied.}
|
249
|
+
errors << ValidationError.new(schema, path, message, :max_items_failed)
|
238
250
|
false
|
239
251
|
else
|
240
252
|
valid = true
|
@@ -261,8 +273,10 @@ module JsonSchema
|
|
261
273
|
elsif !schema.max_exclusive? && data <= schema.max
|
262
274
|
true
|
263
275
|
else
|
264
|
-
message = %{
|
265
|
-
|
276
|
+
message = %{#{data} must be less than} +
|
277
|
+
(schema.max_exclusive? ? "" : " or equal to") +
|
278
|
+
%{ #{schema.max}.}
|
279
|
+
errors << ValidationError.new(schema, path, message, :max_failed)
|
266
280
|
false
|
267
281
|
end
|
268
282
|
end
|
@@ -272,8 +286,12 @@ module JsonSchema
|
|
272
286
|
if data.size <= schema.max_items
|
273
287
|
true
|
274
288
|
else
|
275
|
-
message = %{
|
276
|
-
|
289
|
+
message = %{No more than #{schema.max_items} item} +
|
290
|
+
(schema.max_items == 1 ? " is" : "s are") +
|
291
|
+
%{ allowed; #{data.size} } +
|
292
|
+
(data.size == 1 ? "was" : "were")+
|
293
|
+
%{ supplied.}
|
294
|
+
errors << ValidationError.new(schema, path, message, :max_items_failed)
|
277
295
|
false
|
278
296
|
end
|
279
297
|
end
|
@@ -283,8 +301,12 @@ module JsonSchema
|
|
283
301
|
if data.length <= schema.max_length
|
284
302
|
true
|
285
303
|
else
|
286
|
-
message = %{
|
287
|
-
|
304
|
+
message = %{Only #{schema.max_length} character} +
|
305
|
+
(schema.max_length == 1 ? " is" : "s are") +
|
306
|
+
%{ allowed; #{data.length} } +
|
307
|
+
(data.length == 1 ? "was" : "were") +
|
308
|
+
%{ supplied.}
|
309
|
+
errors << ValidationError.new(schema, path, message, :max_length_failed)
|
288
310
|
false
|
289
311
|
end
|
290
312
|
end
|
@@ -294,8 +316,12 @@ module JsonSchema
|
|
294
316
|
if data.keys.size <= schema.max_properties
|
295
317
|
true
|
296
318
|
else
|
297
|
-
message = %{
|
298
|
-
|
319
|
+
message = %{No more than #{schema.max_properties} propert} +
|
320
|
+
(schema.max_properties == 1 ? "y is" : "ies are") +
|
321
|
+
%{ allowed; #{data.keys.size} } +
|
322
|
+
(data.keys.size == 1 ? "was" : "were") +
|
323
|
+
%{ supplied.}
|
324
|
+
errors << ValidationError.new(schema, path, message, :max_properties_failed)
|
299
325
|
false
|
300
326
|
end
|
301
327
|
end
|
@@ -307,8 +333,10 @@ module JsonSchema
|
|
307
333
|
elsif !schema.min_exclusive? && data >= schema.min
|
308
334
|
true
|
309
335
|
else
|
310
|
-
message = %{
|
311
|
-
|
336
|
+
message = %{#{data} must be greater than} +
|
337
|
+
(schema.min_exclusive? ? "" : " or equal to") +
|
338
|
+
%{ #{schema.min}.}
|
339
|
+
errors << ValidationError.new(schema, path, message, :min_failed)
|
312
340
|
false
|
313
341
|
end
|
314
342
|
end
|
@@ -318,8 +346,12 @@ module JsonSchema
|
|
318
346
|
if data.size >= schema.min_items
|
319
347
|
true
|
320
348
|
else
|
321
|
-
message = %{
|
322
|
-
|
349
|
+
message = %{#{schema.min_items} item} +
|
350
|
+
(schema.min_items == 1 ? "" : "s") +
|
351
|
+
%{ required; only #{data.size} } +
|
352
|
+
(data.size == 1 ? "was" : "were") +
|
353
|
+
%{ supplied.}
|
354
|
+
errors << ValidationError.new(schema, path, message, :min_items_failed)
|
323
355
|
false
|
324
356
|
end
|
325
357
|
end
|
@@ -329,8 +361,12 @@ module JsonSchema
|
|
329
361
|
if data.length >= schema.min_length
|
330
362
|
true
|
331
363
|
else
|
332
|
-
message = %{
|
333
|
-
|
364
|
+
message = %{At least #{schema.min_length} character} +
|
365
|
+
(schema.min_length == 1 ? " is" : "s are") +
|
366
|
+
%{ required; only #{data.length} } +
|
367
|
+
(data.length == 1 ? "was" : "were") +
|
368
|
+
%{ supplied.}
|
369
|
+
errors << ValidationError.new(schema, path, message, :min_length_failed)
|
334
370
|
false
|
335
371
|
end
|
336
372
|
end
|
@@ -340,8 +376,12 @@ module JsonSchema
|
|
340
376
|
if data.keys.size >= schema.min_properties
|
341
377
|
true
|
342
378
|
else
|
343
|
-
message = %{
|
344
|
-
|
379
|
+
message = %{At least #{schema.max_properties} propert}+
|
380
|
+
(schema.max_properties == 1 ? "y is" : "ies are") +
|
381
|
+
%{ required; #{data.keys.size} }+
|
382
|
+
(data.keys.size == 1 ? "was" : "were") +
|
383
|
+
%{ supplied.}
|
384
|
+
errors << ValidationError.new(schema, path, message, :min_properties_failed)
|
345
385
|
false
|
346
386
|
end
|
347
387
|
end
|
@@ -351,8 +391,8 @@ module JsonSchema
|
|
351
391
|
if data % schema.multiple_of == 0
|
352
392
|
true
|
353
393
|
else
|
354
|
-
message = %{
|
355
|
-
errors << ValidationError.new(schema, path, message)
|
394
|
+
message = %{#{data} is not a multiple of #{schema.multiple_of}.}
|
395
|
+
errors << ValidationError.new(schema, path, message, :multiple_of_failed)
|
356
396
|
false
|
357
397
|
end
|
358
398
|
end
|
@@ -363,8 +403,13 @@ module JsonSchema
|
|
363
403
|
validate_data(subschema, data, [], path)
|
364
404
|
end
|
365
405
|
if num_valid != 1
|
366
|
-
message =
|
367
|
-
|
406
|
+
message =
|
407
|
+
if num_valid == 0
|
408
|
+
%{No subschema in "oneOf" matched.}
|
409
|
+
else
|
410
|
+
%{More than one subschema in "oneOf" matched.}
|
411
|
+
end
|
412
|
+
errors << ValidationError.new(schema, path, message, :one_of_failed)
|
368
413
|
end
|
369
414
|
num_valid == 1
|
370
415
|
end
|
@@ -375,8 +420,8 @@ module JsonSchema
|
|
375
420
|
# incorrectly for the inverse condition
|
376
421
|
valid = !validate_data(schema.not, data, [], path)
|
377
422
|
if !valid
|
378
|
-
message = %{
|
379
|
-
errors << ValidationError.new(schema, path, message)
|
423
|
+
message = %{Matched "not" subschema.}
|
424
|
+
errors << ValidationError.new(schema, path, message, :not_failed)
|
380
425
|
end
|
381
426
|
valid
|
382
427
|
end
|
@@ -386,8 +431,8 @@ module JsonSchema
|
|
386
431
|
if data =~ schema.pattern
|
387
432
|
true
|
388
433
|
else
|
389
|
-
message = %{
|
390
|
-
errors << ValidationError.new(schema, path, message)
|
434
|
+
message = %{#{data} does not match #{schema.pattern.inspect}.}
|
435
|
+
errors << ValidationError.new(schema, path, message, :pattern_failed)
|
391
436
|
false
|
392
437
|
end
|
393
438
|
end
|
@@ -423,8 +468,10 @@ module JsonSchema
|
|
423
468
|
if (missing = required - data.keys).empty?
|
424
469
|
true
|
425
470
|
else
|
426
|
-
message = %{
|
427
|
-
|
471
|
+
message = %{"#{missing.sort.join('", "')}" } +
|
472
|
+
(missing.length == 1 ? "wasn't" : "weren't") +
|
473
|
+
%{ supplied.}
|
474
|
+
errors << ValidationError.new(schema, path, message, :required_failed)
|
428
475
|
false
|
429
476
|
end
|
430
477
|
end
|
@@ -442,8 +489,8 @@ module JsonSchema
|
|
442
489
|
if valid_types.any? { |t| data.is_a?(t) }
|
443
490
|
true
|
444
491
|
else
|
445
|
-
message = %{
|
446
|
-
errors << ValidationError.new(schema, path, message)
|
492
|
+
message = %{#{data.inspect} is not a #{schema.type.join("/")}.}
|
493
|
+
errors << ValidationError.new(schema, path, message, :invalid_type)
|
447
494
|
false
|
448
495
|
end
|
449
496
|
end
|
@@ -453,8 +500,8 @@ module JsonSchema
|
|
453
500
|
if data.size == data.uniq.size
|
454
501
|
true
|
455
502
|
else
|
456
|
-
message = %{
|
457
|
-
errors << ValidationError.new(schema, path, message)
|
503
|
+
message = %{Duplicate items are not allowed.}
|
504
|
+
errors << ValidationError.new(schema, path, message, :unique_items_failed)
|
458
505
|
false
|
459
506
|
end
|
460
507
|
end
|
@@ -463,7 +510,7 @@ module JsonSchema
|
|
463
510
|
|
464
511
|
HOSTNAME_PATTERN = /^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?$/
|
465
512
|
|
466
|
-
DATE_TIME_PATTERN = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-2][0-9]:[0-5][0-9]:[0-5][0-9](Z|[\-+][0-9]{2}:[0-5][0-9])$/
|
513
|
+
DATE_TIME_PATTERN = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-2][0-9]:[0-5][0-9]:[0-5][0-9](\.[0-9]+)?(Z|[\-+][0-9]{2}:[0-5][0-9])$/
|
467
514
|
|
468
515
|
# from: http://stackoverflow.com/a/17871737
|
469
516
|
IPV4_PATTERN = /^((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])$/
|
@@ -221,41 +221,50 @@ describe JsonSchema::Parser do
|
|
221
221
|
it "errors on non-string ids" do
|
222
222
|
schema_sample["id"] = 4
|
223
223
|
refute parse
|
224
|
-
assert_includes
|
225
|
-
%{
|
224
|
+
assert_includes error_messages,
|
225
|
+
%{4 is not a valid "id", must be a string.}
|
226
|
+
assert_includes error_types, :invalid_type
|
226
227
|
end
|
227
228
|
|
228
229
|
it "errors on non-string titles" do
|
229
230
|
schema_sample["title"] = 4
|
230
231
|
refute parse
|
231
|
-
assert_includes
|
232
|
-
%{
|
232
|
+
assert_includes error_messages,
|
233
|
+
%{4 is not a valid "title", must be a string.}
|
234
|
+
assert_includes error_types, :invalid_type
|
233
235
|
end
|
234
236
|
|
235
237
|
it "errors on non-string descriptions" do
|
236
238
|
schema_sample["description"] = 4
|
237
239
|
refute parse
|
238
|
-
assert_includes
|
239
|
-
%{
|
240
|
+
assert_includes error_messages,
|
241
|
+
%{4 is not a valid "description", must be a string.}
|
242
|
+
assert_includes error_types, :invalid_type
|
240
243
|
end
|
241
244
|
|
242
245
|
it "errors on non-array and non-string types" do
|
243
246
|
schema_sample["type"] = 4
|
244
247
|
refute parse
|
245
|
-
assert_includes
|
246
|
-
%{
|
248
|
+
assert_includes error_messages,
|
249
|
+
%{4 is not a valid "type", must be a array/string.}
|
250
|
+
assert_includes error_types, :invalid_type
|
247
251
|
end
|
248
252
|
|
249
253
|
it "errors on unknown types" do
|
250
254
|
schema_sample["type"] = ["float", "double"]
|
251
255
|
refute parse
|
252
|
-
assert_includes
|
256
|
+
assert_includes error_messages, %{Unknown types: double, float.}
|
257
|
+
assert_includes error_types, :unknown_type
|
253
258
|
end
|
254
259
|
|
255
|
-
def
|
260
|
+
def error_messages
|
256
261
|
@parser.errors.map { |e| e.message }
|
257
262
|
end
|
258
263
|
|
264
|
+
def error_types
|
265
|
+
@parser.errors.map { |e| e.type }
|
266
|
+
end
|
267
|
+
|
259
268
|
def parse
|
260
269
|
@parser = JsonSchema::Parser.new
|
261
270
|
@parser.parse(schema_sample)
|
@@ -5,7 +5,7 @@ require "json_schema"
|
|
5
5
|
describe JsonSchema::ReferenceExpander do
|
6
6
|
it "expands references" do
|
7
7
|
expand
|
8
|
-
assert_equal [],
|
8
|
+
assert_equal [], error_messages
|
9
9
|
|
10
10
|
# this was always a fully-defined property
|
11
11
|
referenced = @schema.definitions["app"]
|
@@ -27,7 +27,7 @@ describe JsonSchema::ReferenceExpander do
|
|
27
27
|
|
28
28
|
it "will expand anyOf" do
|
29
29
|
expand
|
30
|
-
assert_equal [],
|
30
|
+
assert_equal [], error_messages
|
31
31
|
schema = @schema.properties["app"].definitions["contrived_plus"]
|
32
32
|
assert_equal 3, schema.any_of[0].min_length
|
33
33
|
assert_equal 5, schema.any_of[1].min_length
|
@@ -35,7 +35,7 @@ describe JsonSchema::ReferenceExpander do
|
|
35
35
|
|
36
36
|
it "will expand allOf" do
|
37
37
|
expand
|
38
|
-
assert_equal [],
|
38
|
+
assert_equal [], error_messages
|
39
39
|
schema = @schema.properties["app"].definitions["contrived_plus"]
|
40
40
|
assert_equal 30, schema.all_of[0].max_length
|
41
41
|
assert_equal 3, schema.all_of[1].min_length
|
@@ -43,7 +43,7 @@ describe JsonSchema::ReferenceExpander do
|
|
43
43
|
|
44
44
|
it "will expand dependencies" do
|
45
45
|
expand
|
46
|
-
assert_equal [],
|
46
|
+
assert_equal [], error_messages
|
47
47
|
schema = @schema.properties["app"].dependencies["ssl"].properties["name"]
|
48
48
|
assert_equal ["string"], schema.type
|
49
49
|
end
|
@@ -55,7 +55,7 @@ describe JsonSchema::ReferenceExpander do
|
|
55
55
|
}
|
56
56
|
)
|
57
57
|
expand
|
58
|
-
assert_equal [],
|
58
|
+
assert_equal [], error_messages
|
59
59
|
schema = @schema.properties["app"].properties["flags"].items
|
60
60
|
assert_equal ["string"], schema.type
|
61
61
|
end
|
@@ -68,7 +68,7 @@ describe JsonSchema::ReferenceExpander do
|
|
68
68
|
]
|
69
69
|
)
|
70
70
|
expand
|
71
|
-
assert_equal [],
|
71
|
+
assert_equal [], error_messages
|
72
72
|
schema0 = @schema.properties["app"].properties["flags"].items[0]
|
73
73
|
schema1 = @schema.properties["app"].properties["flags"].items[0]
|
74
74
|
assert_equal ["string"], schema0.type
|
@@ -77,7 +77,7 @@ describe JsonSchema::ReferenceExpander do
|
|
77
77
|
|
78
78
|
it "will expand oneOf" do
|
79
79
|
expand
|
80
|
-
assert_equal [],
|
80
|
+
assert_equal [], error_messages
|
81
81
|
schema = @schema.properties["app"].definitions["contrived_plus"]
|
82
82
|
assert_equal /^(foo|aaa)$/, schema.one_of[0].pattern
|
83
83
|
assert_equal /^(foo|zzz)$/, schema.one_of[1].pattern
|
@@ -85,7 +85,7 @@ describe JsonSchema::ReferenceExpander do
|
|
85
85
|
|
86
86
|
it "will expand not" do
|
87
87
|
expand
|
88
|
-
assert_equal [],
|
88
|
+
assert_equal [], error_messages
|
89
89
|
schema = @schema.properties["app"].definitions["contrived_plus"]
|
90
90
|
assert_equal /^$/, schema.not.pattern
|
91
91
|
end
|
@@ -95,14 +95,14 @@ describe JsonSchema::ReferenceExpander do
|
|
95
95
|
"additionalProperties" => { "$ref" => "#" }
|
96
96
|
)
|
97
97
|
expand
|
98
|
-
assert_equal [],
|
98
|
+
assert_equal [], error_messages
|
99
99
|
schema = @schema.additional_properties
|
100
100
|
assert_equal ["object"], schema.type
|
101
101
|
end
|
102
102
|
|
103
103
|
it "will expand patternProperties" do
|
104
104
|
expand
|
105
|
-
assert_equal [],
|
105
|
+
assert_equal [], error_messages
|
106
106
|
# value ([1]) of the #first tuple in hash
|
107
107
|
schema = @schema.properties["app"].definitions["roles"].
|
108
108
|
pattern_properties.first[1]
|
@@ -111,14 +111,14 @@ describe JsonSchema::ReferenceExpander do
|
|
111
111
|
|
112
112
|
it "will expand hyperschema link schemas" do
|
113
113
|
expand
|
114
|
-
assert_equal [],
|
114
|
+
assert_equal [], error_messages
|
115
115
|
schema = @schema.properties["app"].links[0].schema.properties["name"]
|
116
116
|
assert_equal ["string"], schema.type
|
117
117
|
end
|
118
118
|
|
119
119
|
it "will expand hyperschema link targetSchemas" do
|
120
120
|
expand
|
121
|
-
assert_equal [],
|
121
|
+
assert_equal [], error_messages
|
122
122
|
schema = @schema.properties["app"].links[0].target_schema.properties["name"]
|
123
123
|
assert_equal ["string"], schema.type
|
124
124
|
end
|
@@ -130,7 +130,7 @@ describe JsonSchema::ReferenceExpander do
|
|
130
130
|
"app2" => { "$ref" => "#/definitions/app" },
|
131
131
|
)
|
132
132
|
expand
|
133
|
-
assert_equal [],
|
133
|
+
assert_equal [], error_messages
|
134
134
|
schema = @schema.properties["app0"]
|
135
135
|
assert_equal ["object"], schema.type
|
136
136
|
end
|
@@ -140,14 +140,14 @@ describe JsonSchema::ReferenceExpander do
|
|
140
140
|
"app" => { "$ref" => "#" }
|
141
141
|
)
|
142
142
|
expand
|
143
|
-
assert_equal [],
|
143
|
+
assert_equal [], error_messages
|
144
144
|
schema = @schema.properties["app"]
|
145
145
|
assert_equal ["object"], schema.type
|
146
146
|
end
|
147
147
|
|
148
148
|
it "builds appropriate JSON Pointers for expanded references" do
|
149
149
|
expand
|
150
|
-
assert_equal [],
|
150
|
+
assert_equal [], error_messages
|
151
151
|
|
152
152
|
# the *referenced* schema should still have a proper pointer
|
153
153
|
schema = @schema.definitions["app"].definitions["name"]
|
@@ -180,10 +180,10 @@ describe JsonSchema::ReferenceExpander do
|
|
180
180
|
"app" => { "$ref" => "#/definitions/nope" }
|
181
181
|
)
|
182
182
|
refute expand
|
183
|
-
assert_includes
|
184
|
-
|
185
|
-
assert_includes
|
186
|
-
|
183
|
+
assert_includes error_messages, %{Couldn't resolve pointer "#/definitions/nope".}
|
184
|
+
assert_includes error_types, :unresolved_pointer
|
185
|
+
assert_includes error_messages, %{Couldn't resolve references: #/definitions/nope.}
|
186
|
+
assert_includes error_types, :unresolved_references
|
187
187
|
end
|
188
188
|
|
189
189
|
it "errors on a URI that can't be resolved" do
|
@@ -191,9 +191,11 @@ describe JsonSchema::ReferenceExpander do
|
|
191
191
|
"app" => { "$ref" => "/schemata/user#/definitions/name" }
|
192
192
|
)
|
193
193
|
refute expand
|
194
|
-
assert_includes
|
194
|
+
assert_includes error_messages,
|
195
195
|
%{Couldn't resolve references: /schemata/user#/definitions/name.}
|
196
|
-
|
196
|
+
assert_includes error_types, :unresolved_references
|
197
|
+
assert_includes error_messages, %{Couldn't resolve URI: /schemata/user.}
|
198
|
+
assert_includes error_types, :unresolved_pointer
|
197
199
|
end
|
198
200
|
|
199
201
|
it "errors on a reference cycle" do
|
@@ -204,14 +206,20 @@ describe JsonSchema::ReferenceExpander do
|
|
204
206
|
)
|
205
207
|
refute expand
|
206
208
|
properties = "#/properties/app0, #/properties/app1, #/properties/app2"
|
207
|
-
assert_includes
|
208
|
-
assert_includes
|
209
|
+
assert_includes error_messages, %{Reference loop detected: #{properties}.}
|
210
|
+
assert_includes error_types, :loop_detected
|
211
|
+
assert_includes error_messages, %{Couldn't resolve references: #{properties}.}
|
212
|
+
assert_includes error_types, :unresolved_references
|
209
213
|
end
|
210
214
|
|
211
|
-
def
|
215
|
+
def error_messages
|
212
216
|
@expander.errors.map { |e| e.message }
|
213
217
|
end
|
214
218
|
|
219
|
+
def error_types
|
220
|
+
@expander.errors.map { |e| e.type }
|
221
|
+
end
|
222
|
+
|
215
223
|
def pointer(path)
|
216
224
|
JsonPointer.evaluate(schema_sample, path)
|
217
225
|
end
|
@@ -22,7 +22,8 @@ describe JsonSchema::Validator do
|
|
22
22
|
data_sample["visibility"] = "personal"
|
23
23
|
refute validate
|
24
24
|
assert_includes error_messages,
|
25
|
-
%{
|
25
|
+
%{personal is not a member of ["private", "public"].}
|
26
|
+
assert_includes error_types, :invalid_type
|
26
27
|
end
|
27
28
|
|
28
29
|
it "validates type successfully" do
|
@@ -39,8 +40,8 @@ describe JsonSchema::Validator do
|
|
39
40
|
)
|
40
41
|
@data_sample = 4
|
41
42
|
refute validate
|
42
|
-
assert_includes error_messages,
|
43
|
-
|
43
|
+
assert_includes error_messages, %{4 is not a object.}
|
44
|
+
assert_includes error_types, :invalid_type
|
44
45
|
end
|
45
46
|
|
46
47
|
it "validates items with list successfully" do
|
@@ -62,7 +63,8 @@ describe JsonSchema::Validator do
|
|
62
63
|
data_sample["flags"] = ["1337"]
|
63
64
|
refute validate
|
64
65
|
assert_includes error_messages,
|
65
|
-
%{
|
66
|
+
%{1337 does not match /^[a-z][a-z\\-]*[a-z]$/.}
|
67
|
+
assert_includes error_types, :pattern_failed
|
66
68
|
end
|
67
69
|
|
68
70
|
it "validates items with tuple successfully" do
|
@@ -98,7 +100,8 @@ describe JsonSchema::Validator do
|
|
98
100
|
data_sample["flags"] = ["cedar"]
|
99
101
|
refute validate
|
100
102
|
assert_includes error_messages,
|
101
|
-
%{
|
103
|
+
%{2 items required; only 1 was supplied.}
|
104
|
+
assert_includes error_types, :min_items_failed
|
102
105
|
end
|
103
106
|
|
104
107
|
it "validates items with tuple unsuccessfully for too many items" do
|
@@ -112,7 +115,8 @@ describe JsonSchema::Validator do
|
|
112
115
|
data_sample["flags"] = ["cedar", "https", "websockets"]
|
113
116
|
refute validate
|
114
117
|
assert_includes error_messages,
|
115
|
-
%{
|
118
|
+
%{No more than 2 items are allowed; 3 were supplied.}
|
119
|
+
assert_includes error_types, :max_items_failed
|
116
120
|
end
|
117
121
|
|
118
122
|
it "validates items with tuple unsuccessfully for non-conforming items" do
|
@@ -126,7 +130,8 @@ describe JsonSchema::Validator do
|
|
126
130
|
data_sample["flags"] = ["cedar", "1337"]
|
127
131
|
refute validate
|
128
132
|
assert_includes error_messages,
|
129
|
-
%{
|
133
|
+
%{1337 is not a member of ["http", "https"].}
|
134
|
+
assert_includes error_types, :invalid_type
|
130
135
|
end
|
131
136
|
|
132
137
|
it "validates maxItems successfully" do
|
@@ -144,7 +149,8 @@ describe JsonSchema::Validator do
|
|
144
149
|
data_sample["flags"] = (0...11).to_a
|
145
150
|
refute validate
|
146
151
|
assert_includes error_messages,
|
147
|
-
%{
|
152
|
+
%{No more than 10 items are allowed; 11 were supplied.}
|
153
|
+
assert_includes error_types, :max_items_failed
|
148
154
|
end
|
149
155
|
|
150
156
|
it "validates minItems successfully" do
|
@@ -161,8 +167,8 @@ describe JsonSchema::Validator do
|
|
161
167
|
)
|
162
168
|
data_sample["flags"] = []
|
163
169
|
refute validate
|
164
|
-
assert_includes error_messages,
|
165
|
-
|
170
|
+
assert_includes error_messages, %{1 item required; only 0 were supplied.}
|
171
|
+
assert_includes error_types, :min_items_failed
|
166
172
|
end
|
167
173
|
|
168
174
|
it "validates uniqueItems successfully" do
|
@@ -179,8 +185,8 @@ describe JsonSchema::Validator do
|
|
179
185
|
)
|
180
186
|
data_sample["flags"] = ["websockets", "websockets"]
|
181
187
|
refute validate
|
182
|
-
assert_includes error_messages,
|
183
|
-
|
188
|
+
assert_includes error_messages, %{Duplicate items are not allowed.}
|
189
|
+
assert_includes error_types, :unique_items_failed
|
184
190
|
end
|
185
191
|
|
186
192
|
it "validates maximum for an integer with exclusiveMaximum false" do
|
@@ -190,8 +196,8 @@ describe JsonSchema::Validator do
|
|
190
196
|
)
|
191
197
|
data_sample["id"] = 11
|
192
198
|
refute validate
|
193
|
-
assert_includes error_messages,
|
194
|
-
|
199
|
+
assert_includes error_messages, %{11 must be less than or equal to 10.}
|
200
|
+
assert_includes error_types, :max_failed
|
195
201
|
end
|
196
202
|
|
197
203
|
it "validates maximum for an integer with exclusiveMaximum true" do
|
@@ -201,8 +207,8 @@ describe JsonSchema::Validator do
|
|
201
207
|
)
|
202
208
|
data_sample["id"] = 10
|
203
209
|
refute validate
|
204
|
-
assert_includes error_messages,
|
205
|
-
|
210
|
+
assert_includes error_messages, %{10 must be less than 10.}
|
211
|
+
assert_includes error_types, :max_failed
|
206
212
|
end
|
207
213
|
|
208
214
|
it "validates maximum for a number with exclusiveMaximum false" do
|
@@ -212,8 +218,8 @@ describe JsonSchema::Validator do
|
|
212
218
|
)
|
213
219
|
data_sample["cost"] = 10.1
|
214
220
|
refute validate
|
215
|
-
assert_includes error_messages,
|
216
|
-
|
221
|
+
assert_includes error_messages, %{10.1 must be less than or equal to 10.0.}
|
222
|
+
assert_includes error_types, :max_failed
|
217
223
|
end
|
218
224
|
|
219
225
|
it "validates maximum for a number with exclusiveMaximum true" do
|
@@ -223,8 +229,8 @@ describe JsonSchema::Validator do
|
|
223
229
|
)
|
224
230
|
data_sample["cost"] = 10.0
|
225
231
|
refute validate
|
226
|
-
assert_includes error_messages,
|
227
|
-
|
232
|
+
assert_includes error_messages, %{10.0 must be less than 10.0.}
|
233
|
+
assert_includes error_types, :max_failed
|
228
234
|
end
|
229
235
|
|
230
236
|
it "validates minimum for an integer with exclusiveMaximum false" do
|
@@ -234,8 +240,8 @@ describe JsonSchema::Validator do
|
|
234
240
|
)
|
235
241
|
data_sample["id"] = 0
|
236
242
|
refute validate
|
237
|
-
assert_includes error_messages,
|
238
|
-
|
243
|
+
assert_includes error_messages, %{0 must be greater than or equal to 1.}
|
244
|
+
assert_includes error_types, :min_failed
|
239
245
|
end
|
240
246
|
|
241
247
|
it "validates minimum for an integer with exclusiveMaximum true" do
|
@@ -245,8 +251,7 @@ describe JsonSchema::Validator do
|
|
245
251
|
)
|
246
252
|
data_sample["id"] = 1
|
247
253
|
refute validate
|
248
|
-
assert_includes error_messages,
|
249
|
-
%{Expected data to be larger than minimum 1 (exclusive: true), value was: 1.}
|
254
|
+
assert_includes error_messages, %{1 must be greater than 1.}
|
250
255
|
end
|
251
256
|
|
252
257
|
it "validates minimum for a number with exclusiveMaximum false" do
|
@@ -257,7 +262,8 @@ describe JsonSchema::Validator do
|
|
257
262
|
data_sample["cost"] = -0.01
|
258
263
|
refute validate
|
259
264
|
assert_includes error_messages,
|
260
|
-
%{
|
265
|
+
%{-0.01 must be greater than or equal to 0.0.}
|
266
|
+
assert_includes error_types, :min_failed
|
261
267
|
end
|
262
268
|
|
263
269
|
it "validates minimum for a number with exclusiveMaximum true" do
|
@@ -267,8 +273,8 @@ describe JsonSchema::Validator do
|
|
267
273
|
)
|
268
274
|
data_sample["cost"] = 0.0
|
269
275
|
refute validate
|
270
|
-
assert_includes error_messages,
|
271
|
-
|
276
|
+
assert_includes error_messages, %{0.0 must be greater than 0.0.}
|
277
|
+
assert_includes error_types, :min_failed
|
272
278
|
end
|
273
279
|
|
274
280
|
it "validates multipleOf for an integer" do
|
@@ -277,8 +283,8 @@ describe JsonSchema::Validator do
|
|
277
283
|
)
|
278
284
|
data_sample["id"] = 1
|
279
285
|
refute validate
|
280
|
-
assert_includes error_messages,
|
281
|
-
|
286
|
+
assert_includes error_messages, %{1 is not a multiple of 2.}
|
287
|
+
assert_includes error_types, :multiple_of_failed
|
282
288
|
end
|
283
289
|
|
284
290
|
it "validates multipleOf for a number" do
|
@@ -287,8 +293,8 @@ describe JsonSchema::Validator do
|
|
287
293
|
)
|
288
294
|
data_sample["cost"] = 0.005
|
289
295
|
refute validate
|
290
|
-
assert_includes error_messages,
|
291
|
-
|
296
|
+
assert_includes error_messages, %{0.005 is not a multiple of 0.01.}
|
297
|
+
assert_includes error_types, :multiple_of_failed
|
292
298
|
end
|
293
299
|
|
294
300
|
it "validates additionalProperties boolean successfully" do
|
@@ -309,7 +315,23 @@ describe JsonSchema::Validator do
|
|
309
315
|
data_sample["foo"] = "bar"
|
310
316
|
data_sample["matches_pattern"] = "yes!"
|
311
317
|
refute validate
|
312
|
-
assert_includes error_messages, %{
|
318
|
+
assert_includes error_messages, %{"foo" is not a permitted key.}
|
319
|
+
assert_includes error_types, :invalid_keys
|
320
|
+
end
|
321
|
+
|
322
|
+
it "validates additionalProperties boolean unsuccessfully with multiple failures" do
|
323
|
+
pointer("#/definitions/app").merge!(
|
324
|
+
"additionalProperties" => false,
|
325
|
+
"patternProperties" => {
|
326
|
+
"^matches" => {}
|
327
|
+
}
|
328
|
+
)
|
329
|
+
data_sample["foo"] = "bar"
|
330
|
+
data_sample["baz"] = "blah"
|
331
|
+
data_sample["matches_pattern"] = "yes!"
|
332
|
+
refute validate
|
333
|
+
assert_includes error_messages, %{"baz", "foo" are not permitted keys.}
|
334
|
+
assert_includes error_types, :invalid_keys
|
313
335
|
end
|
314
336
|
|
315
337
|
it "validates additionalProperties schema successfully" do
|
@@ -334,8 +356,8 @@ describe JsonSchema::Validator do
|
|
334
356
|
data_sample["foo"] = 4
|
335
357
|
data_sample["matches_pattern"] = "yes!"
|
336
358
|
refute validate
|
337
|
-
assert_includes error_messages,
|
338
|
-
|
359
|
+
assert_includes error_messages, %{4 is not a boolean.}
|
360
|
+
assert_includes error_types, :invalid_type
|
339
361
|
end
|
340
362
|
|
341
363
|
it "validates simple dependencies" do
|
@@ -345,7 +367,7 @@ describe JsonSchema::Validator do
|
|
345
367
|
data_sample["production"] = true
|
346
368
|
refute validate
|
347
369
|
assert_includes error_messages,
|
348
|
-
%{
|
370
|
+
%{"ssl" wasn't supplied.}
|
349
371
|
end
|
350
372
|
|
351
373
|
it "validates schema dependencies" do
|
@@ -361,7 +383,8 @@ describe JsonSchema::Validator do
|
|
361
383
|
data_sample["cost"] = 10.0
|
362
384
|
data_sample["ssl"] = true
|
363
385
|
refute validate
|
364
|
-
assert_includes error_messages, %{
|
386
|
+
assert_includes error_messages, %{10.0 must be greater than or equal to 20.0.}
|
387
|
+
assert_includes error_types, :min_failed
|
365
388
|
end
|
366
389
|
|
367
390
|
it "validates maxProperties" do
|
@@ -370,7 +393,8 @@ describe JsonSchema::Validator do
|
|
370
393
|
)
|
371
394
|
data_sample["name"] = "cloudnasium"
|
372
395
|
refute validate
|
373
|
-
assert_includes error_messages, %{
|
396
|
+
assert_includes error_messages, %{No more than 0 properties are allowed; 1 was supplied.}
|
397
|
+
assert_includes error_types, :max_properties_failed
|
374
398
|
end
|
375
399
|
|
376
400
|
it "validates minProperties" do
|
@@ -379,7 +403,8 @@ describe JsonSchema::Validator do
|
|
379
403
|
)
|
380
404
|
data_sample["name"] = "cloudnasium"
|
381
405
|
refute validate
|
382
|
-
assert_includes error_messages, %{
|
406
|
+
assert_includes error_messages, %{At least 10 properties are required; 1 was supplied.}
|
407
|
+
assert_includes error_types, :min_properties_failed
|
383
408
|
end
|
384
409
|
|
385
410
|
it "validates patternProperties" do
|
@@ -395,8 +420,8 @@ describe JsonSchema::Validator do
|
|
395
420
|
"KEY" => 456
|
396
421
|
}
|
397
422
|
refute validate
|
398
|
-
assert_includes error_messages,
|
399
|
-
|
423
|
+
assert_includes error_messages, %{456 is not a null/string.}
|
424
|
+
assert_includes error_types, :invalid_type
|
400
425
|
end
|
401
426
|
|
402
427
|
it "validates required" do
|
@@ -405,8 +430,8 @@ describe JsonSchema::Validator do
|
|
405
430
|
)
|
406
431
|
data_sample.delete("name")
|
407
432
|
refute validate
|
408
|
-
assert_includes error_messages,
|
409
|
-
|
433
|
+
assert_includes error_messages, %{"name" wasn't supplied.}
|
434
|
+
assert_includes error_types, :required_failed
|
410
435
|
end
|
411
436
|
|
412
437
|
it "validates strictProperties successfully" do
|
@@ -427,9 +452,9 @@ describe JsonSchema::Validator do
|
|
427
452
|
data_sample["matches_pattern"] = "yes!"
|
428
453
|
refute validate
|
429
454
|
missing = @schema.properties.keys.sort - ["name"]
|
430
|
-
assert_includes error_messages,
|
431
|
-
|
432
|
-
assert_includes
|
455
|
+
assert_includes error_messages, %{"#{missing.join('", "')}" weren't supplied.}
|
456
|
+
assert_includes error_messages, %{"extra_key" is not a permitted key.}
|
457
|
+
assert_includes error_types, :invalid_keys
|
433
458
|
end
|
434
459
|
|
435
460
|
it "validates allOf" do
|
@@ -441,8 +466,8 @@ describe JsonSchema::Validator do
|
|
441
466
|
)
|
442
467
|
data_sample["contrived"] = "ab"
|
443
468
|
refute validate
|
444
|
-
assert_includes error_messages,
|
445
|
-
|
469
|
+
assert_includes error_messages, %{At least 3 characters are required; only 2 were supplied.}
|
470
|
+
assert_includes error_types, :all_of_failed
|
446
471
|
end
|
447
472
|
|
448
473
|
it "validates anyOf" do
|
@@ -454,8 +479,8 @@ describe JsonSchema::Validator do
|
|
454
479
|
)
|
455
480
|
data_sample["contrived"] = "ab"
|
456
481
|
refute validate
|
457
|
-
assert_includes error_messages,
|
458
|
-
|
482
|
+
assert_includes error_messages, %{No subschema in "anyOf" matched.}
|
483
|
+
assert_includes error_types, :any_of_failed
|
459
484
|
end
|
460
485
|
|
461
486
|
it "validates oneOf" do
|
@@ -467,8 +492,8 @@ describe JsonSchema::Validator do
|
|
467
492
|
)
|
468
493
|
data_sample["contrived"] = "foo"
|
469
494
|
refute validate
|
470
|
-
assert_includes error_messages,
|
471
|
-
|
495
|
+
assert_includes error_messages, %{More than one subschema in "oneOf" matched.}
|
496
|
+
assert_includes error_types, :one_of_failed
|
472
497
|
end
|
473
498
|
|
474
499
|
it "validates not" do
|
@@ -477,8 +502,8 @@ describe JsonSchema::Validator do
|
|
477
502
|
)
|
478
503
|
data_sample["contrived"] = ""
|
479
504
|
refute validate
|
480
|
-
assert_includes error_messages,
|
481
|
-
|
505
|
+
assert_includes error_messages, %{Matched "not" subschema.}
|
506
|
+
assert_includes error_types, :not_failed
|
482
507
|
end
|
483
508
|
|
484
509
|
it "validates date-time format successfully" do
|
@@ -497,14 +522,22 @@ describe JsonSchema::Validator do
|
|
497
522
|
assert validate
|
498
523
|
end
|
499
524
|
|
525
|
+
it "validates date-time format with time fraction successfully" do
|
526
|
+
pointer("#/definitions/app/definitions/owner").merge!(
|
527
|
+
"format" => "date-time"
|
528
|
+
)
|
529
|
+
data_sample["owner"] = "2014-05-13T08:42:40.444Z"
|
530
|
+
assert validate
|
531
|
+
end
|
532
|
+
|
500
533
|
it "validates date-time format unsuccessfully" do
|
501
534
|
pointer("#/definitions/app/definitions/owner").merge!(
|
502
535
|
"format" => "date-time"
|
503
536
|
)
|
504
537
|
data_sample["owner"] = "2014-05-13T08:42:40"
|
505
538
|
refute validate
|
506
|
-
assert_includes error_messages,
|
507
|
-
|
539
|
+
assert_includes error_messages, %{2014-05-13T08:42:40 is not a valid date-time.}
|
540
|
+
assert_includes error_types, :invalid_format
|
508
541
|
end
|
509
542
|
|
510
543
|
it "validates email format successfully" do
|
@@ -521,8 +554,8 @@ describe JsonSchema::Validator do
|
|
521
554
|
)
|
522
555
|
data_sample["owner"] = "@example.com"
|
523
556
|
refute validate
|
524
|
-
assert_includes error_messages,
|
525
|
-
|
557
|
+
assert_includes error_messages, %{@example.com is not a valid email.}
|
558
|
+
assert_includes error_types, :invalid_format
|
526
559
|
end
|
527
560
|
|
528
561
|
it "validates hostname format successfully" do
|
@@ -539,8 +572,8 @@ describe JsonSchema::Validator do
|
|
539
572
|
)
|
540
573
|
data_sample["owner"] = "@example.com"
|
541
574
|
refute validate
|
542
|
-
assert_includes error_messages,
|
543
|
-
|
575
|
+
assert_includes error_messages, %{@example.com is not a valid hostname.}
|
576
|
+
assert_includes error_types, :invalid_format
|
544
577
|
end
|
545
578
|
|
546
579
|
it "validates ipv4 format successfully" do
|
@@ -557,8 +590,8 @@ describe JsonSchema::Validator do
|
|
557
590
|
)
|
558
591
|
data_sample["owner"] = "1.2.3.4.5"
|
559
592
|
refute validate
|
560
|
-
assert_includes error_messages,
|
561
|
-
|
593
|
+
assert_includes error_messages, %{1.2.3.4.5 is not a valid ipv4.}
|
594
|
+
assert_includes error_types, :invalid_format
|
562
595
|
end
|
563
596
|
|
564
597
|
it "validates ipv6 format successfully" do
|
@@ -575,8 +608,8 @@ describe JsonSchema::Validator do
|
|
575
608
|
)
|
576
609
|
data_sample["owner"] = "1::3:4:5:6:7:8:9"
|
577
610
|
refute validate
|
578
|
-
assert_includes error_messages,
|
579
|
-
|
611
|
+
assert_includes error_messages, %{1::3:4:5:6:7:8:9 is not a valid ipv6.}
|
612
|
+
assert_includes error_types, :invalid_format
|
580
613
|
end
|
581
614
|
|
582
615
|
it "validates regex format successfully" do
|
@@ -593,8 +626,8 @@ describe JsonSchema::Validator do
|
|
593
626
|
)
|
594
627
|
data_sample["owner"] = "^owner($"
|
595
628
|
refute validate
|
596
|
-
assert_includes error_messages,
|
597
|
-
|
629
|
+
assert_includes error_messages, %{^owner($ is not a valid regex.}
|
630
|
+
assert_includes error_types, :invalid_format
|
598
631
|
end
|
599
632
|
|
600
633
|
it "validates absolute uri format successfully" do
|
@@ -619,8 +652,8 @@ describe JsonSchema::Validator do
|
|
619
652
|
)
|
620
653
|
data_sample["owner"] = "http://"
|
621
654
|
refute validate
|
622
|
-
assert_includes error_messages,
|
623
|
-
|
655
|
+
assert_includes error_messages, %{http:// is not a valid uri.}
|
656
|
+
assert_includes error_types, :invalid_format
|
624
657
|
end
|
625
658
|
|
626
659
|
it "validates uuid format successfully" do
|
@@ -637,8 +670,8 @@ describe JsonSchema::Validator do
|
|
637
670
|
)
|
638
671
|
data_sample["owner"] = "123"
|
639
672
|
refute validate
|
640
|
-
assert_includes error_messages,
|
641
|
-
|
673
|
+
assert_includes error_messages, %{123 is not a valid uuid.}
|
674
|
+
assert_includes error_types, :invalid_format
|
642
675
|
end
|
643
676
|
|
644
677
|
it "validates maxLength" do
|
@@ -647,8 +680,8 @@ describe JsonSchema::Validator do
|
|
647
680
|
)
|
648
681
|
data_sample["name"] = "abcd"
|
649
682
|
refute validate
|
650
|
-
assert_includes error_messages,
|
651
|
-
|
683
|
+
assert_includes error_messages, %{Only 3 characters are allowed; 4 were supplied.}
|
684
|
+
assert_includes error_types, :max_length_failed
|
652
685
|
end
|
653
686
|
|
654
687
|
it "validates minLength" do
|
@@ -657,8 +690,8 @@ describe JsonSchema::Validator do
|
|
657
690
|
)
|
658
691
|
data_sample["name"] = "ab"
|
659
692
|
refute validate
|
660
|
-
assert_includes error_messages,
|
661
|
-
|
693
|
+
assert_includes error_messages, %{At least 3 characters are required; only 2 were supplied.}
|
694
|
+
assert_includes error_types, :min_length_failed
|
662
695
|
end
|
663
696
|
|
664
697
|
it "validates pattern" do
|
@@ -667,8 +700,8 @@ describe JsonSchema::Validator do
|
|
667
700
|
)
|
668
701
|
data_sample["name"] = "ab"
|
669
702
|
refute validate
|
670
|
-
assert_includes error_messages,
|
671
|
-
|
703
|
+
assert_includes error_messages, %{ab does not match /^[a-z][a-z0-9-]{3,30}$/.}
|
704
|
+
assert_includes error_types, :pattern_failed
|
672
705
|
end
|
673
706
|
|
674
707
|
it "builds appropriate JSON Pointers to bad data" do
|
@@ -699,6 +732,10 @@ describe JsonSchema::Validator do
|
|
699
732
|
@validator.errors.map { |e| e.message }
|
700
733
|
end
|
701
734
|
|
735
|
+
def error_types
|
736
|
+
@validator.errors.map { |e| e.type }
|
737
|
+
end
|
738
|
+
|
702
739
|
def pointer(path)
|
703
740
|
JsonPointer.evaluate(schema_sample, path)
|
704
741
|
end
|
data/test/json_schema_test.rb
CHANGED
@@ -15,8 +15,7 @@ describe JsonSchema do
|
|
15
15
|
)
|
16
16
|
schema, errors = JsonSchema.parse(schema_sample)
|
17
17
|
refute schema
|
18
|
-
assert_includes errors.map { |e| e.
|
19
|
-
%{Expected schema; value was: 4.}
|
18
|
+
assert_includes errors.map { |e| e.type }, :schema_not_found
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
@@ -32,7 +31,7 @@ describe JsonSchema do
|
|
32
31
|
e = assert_raises(RuntimeError) do
|
33
32
|
JsonSchema.parse!(schema_sample)
|
34
33
|
end
|
35
|
-
assert_includes e.message, %{
|
34
|
+
assert_includes e.message, %{4 is not a valid schema.}
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandur
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|