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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c09e98d77f8312b241a686e9754c64868f3168cd
4
- data.tar.gz: 37c8aa03c7b3c20f1297521e1ad028450ef1dbe9
3
+ metadata.gz: 090872e4eabd4666b863192705b856a9bed17f95
4
+ data.tar.gz: d663a4d178b532eedea87e3b9e103e11c618169a
5
5
  SHA512:
6
- metadata.gz: c4eaccae952cb463de80492d3e5903e0f597dfed795ccdd2929c253ba4efd27a4b97b07527f6eef6b9f4ba3a0c943ab6c305ada987586f4d52c9a47d8adfb9b4
7
- data.tar.gz: c126e71608055b4747d7556548a268021ba388fbccf77893408e5b6e166d9c9d53ca25a1e4da4a78416a4893f6797bf81a56c73795097302a776528679cae2ca
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
+ ```
@@ -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 = %{Expected schema; value was: #{data.inspect}.}
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 = %{Expected "#{field}" to be of type "#{friendly_types}"; value was: #{value.inspect}.}
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 cycle detected: #{ref_stack.sort.join(", ")}.}
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 = %{Data did not match all subschemas of "allOf" condition.}
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 = %{Data did not match any subschema of "anyOf" condition.}
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 = %{Expected data to match "#{schema.format}" format, value was: #{data}.}
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 = %{Expected data to be a member of enum #{schema.enum}, value was: #{data}.}
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
- message = %{Extra keys in object: #{extra.sort.join(", ")}.}
223
- errors << ValidationError.new(schema, path, message)
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 = %{Expected array to have at least #{schema.items.count} item(s), had #{data.size} item(s).}
233
- errors << ValidationError.new(schema, path, message)
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 = %{Expected array to have no more than #{schema.items.count} item(s), had #{data.size} item(s).}
237
- errors << ValidationError.new(schema, path, message)
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 = %{Expected data to be smaller than maximum #{schema.max} (exclusive: #{schema.max_exclusive?}), value was: #{data}.}
265
- errors << ValidationError.new(schema, path, message)
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 = %{Expected array to have no more than #{schema.max_items} item(s), had #{data.size} item(s).}
276
- errors << ValidationError.new(schema, path, message)
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 = %{Expected string to have a maximum length of #{schema.max_length}, was #{data.length} character(s) long.}
287
- errors << ValidationError.new(schema, path, message)
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 = %{Expected object to have a maximum of #{schema.max_properties} property/ies; it had #{data.keys.size}.}
298
- errors << ValidationError.new(schema, path, message)
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 = %{Expected data to be larger than minimum #{schema.min} (exclusive: #{schema.min_exclusive?}), value was: #{data}.}
311
- errors << ValidationError.new(schema, path, message)
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 = %{Expected array to have at least #{schema.min_items} item(s), had #{data.size} item(s).}
322
- errors << ValidationError.new(schema, path, message)
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 = %{Expected string to have a minimum length of #{schema.min_length}, was #{data.length} character(s) long.}
333
- errors << ValidationError.new(schema, path, message)
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 = %{Expected object to have a minimum of #{schema.min_properties} property/ies; it had #{data.keys.size}.}
344
- errors << ValidationError.new(schema, path, message)
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 = %{Expected data to be a multiple of #{schema.multiple_of}, value was: #{data}.}
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 = %{Data did not match exactly one subschema of "oneOf" condition.}
367
- errors << ValidationError.new(schema, path, message)
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 = %{Data matched subschema of "not" condition.}
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 = %{Expected string to match pattern "#{schema.pattern.inspect}", value was: #{data}.}
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 = %{Missing required keys "#{missing.sort.join(", ")}" in object; keys are "#{data.keys.sort.join(", ")}".}
427
- errors << ValidationError.new(schema, path, message)
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 = %{Expected data to be of type "#{schema.type.join("/")}"; value was: #{data.inspect}.}
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 = %{Expected array items to be unique, but duplicate items were found.}
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 errors,
225
- %{Expected "id" to be of type "string"; value was: 4.}
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 errors,
232
- %{Expected "title" to be of type "string"; value was: 4.}
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 errors,
239
- %{Expected "description" to be of type "string"; value was: 4.}
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 errors,
246
- %{Expected "type" to be of type "array/string"; value was: 4.}
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 errors, %{Unknown types: double, float.}
256
+ assert_includes error_messages, %{Unknown types: double, float.}
257
+ assert_includes error_types, :unknown_type
253
258
  end
254
259
 
255
- def errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 [], errors
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 errors,
184
- %{Couldn't resolve pointer "#/definitions/nope".}
185
- assert_includes errors,
186
- %{Couldn't resolve references: #/definitions/nope.}
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 errors,
194
+ assert_includes error_messages,
195
195
  %{Couldn't resolve references: /schemata/user#/definitions/name.}
196
- assert_includes errors, %{Couldn't resolve URI: /schemata/user.}
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 errors, %{Reference cycle detected: #{properties}.}
208
- assert_includes errors, %{Couldn't resolve references: #{properties}.}
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 errors
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
- %{Expected data to be a member of enum ["private", "public"], value was: personal.}
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
- %{Expected data to be of type "object"; value was: 4.}
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
- %{Expected string to match pattern "/^[a-z][a-z\\-]*[a-z]$/", value was: 1337.}
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
- %{Expected array to have at least 2 item(s), had 1 item(s).}
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
- %{Expected array to have no more than 2 item(s), had 3 item(s).}
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
- %{Expected data to be a member of enum ["http", "https"], value was: 1337.}
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
- %{Expected array to have no more than 10 item(s), had 11 item(s).}
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
- %{Expected array to have at least 1 item(s), had 0 item(s).}
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
- %{Expected array items to be unique, but duplicate items were found.}
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
- %{Expected data to be smaller than maximum 10 (exclusive: false), value was: 11.}
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
- %{Expected data to be smaller than maximum 10 (exclusive: true), value was: 10.}
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
- %{Expected data to be smaller than maximum 10.0 (exclusive: false), value was: 10.1.}
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
- %{Expected data to be smaller than maximum 10.0 (exclusive: true), value was: 10.0.}
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
- %{Expected data to be larger than minimum 1 (exclusive: false), value was: 0.}
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
- %{Expected data to be larger than minimum 0.0 (exclusive: false), value was: -0.01.}
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
- %{Expected data to be larger than minimum 0.0 (exclusive: true), value was: 0.0.}
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
- %{Expected data to be a multiple of 2, value was: 1.}
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
- %{Expected data to be a multiple of 0.01, value was: 0.005.}
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, %{Extra keys in object: foo.}
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
- %{Expected data to be of type "boolean"; value was: 4.}
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
- %{Missing required keys "ssl" in object; keys are "name, production".}
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, %{Expected data to be larger than minimum 20.0 (exclusive: false), value was: 10.0.}
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, %{Expected object to have a maximum of 0 property/ies; it had 1.}
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, %{Expected object to have a minimum of 2 property/ies; it had 1.}
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
- %{Expected data to be of type "null/string"; value was: 456.}
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
- %{Missing required keys "name" in object; keys are "".}
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
- %{Missing required keys "#{missing.join(", ")}" in object; keys are "extra_key, matches_pattern, name".}
432
- assert_includes error_messages, %{Extra keys in object: extra_key.}
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
- %{Expected string to have a minimum length of 3, was 2 character(s) long.}
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
- %{Data did not match any subschema of "anyOf" condition.}
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
- %{Data did not match exactly one subschema of "oneOf" condition.}
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
- %{Data matched subschema of "not" condition.}
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
- %{Expected data to match "date-time" format, value was: 2014-05-13T08:42:40.}
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
- %{Expected data to match "email" format, value was: @example.com.}
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
- %{Expected data to match "hostname" format, value was: @example.com.}
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
- %{Expected data to match "ipv4" format, value was: 1.2.3.4.5.}
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
- %{Expected data to match "ipv6" format, value was: 1::3:4:5:6:7:8:9.}
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
- %{Expected data to match "regex" format, value was: ^owner($.}
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
- %{Expected data to match "uri" format, value was: http://.}
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
- %{Expected data to match "uuid" format, value was: 123.}
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
- %{Expected string to have a maximum length of 3, was 4 character(s) long.}
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
- %{Expected string to have a minimum length of 3, was 2 character(s) long.}
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
- %{Expected string to match pattern "/^[a-z][a-z0-9-]{3,30}$/", value was: ab.}
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
@@ -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.message },
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, %{Expected schema; value was: 4.}
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.2.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-08-25 00:00:00.000000000 Z
11
+ date: 2014-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest