json_schema 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|