Skip to content

Commit e15c5b4

Browse files
Merge pull request #135 from davishmcclurg/next
2.0.0
2 parents be345af + db29755 commit e15c5b4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+69683
-1940
lines changed

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
# Changelog
22

3+
## [2.0.0] - XXXX-XX-XX
4+
5+
For 2.0.0, much of the codebase was rewritten to simplify support for the two new JSON Schema draft versions (2019-09 and 2020-12). The major change is moving each keyword into its own class and organizing them into vocabularies. [Output formats](https://json-schema.org/draft/2020-12/json-schema-core.html#section-12) and [annotations](https://json-schema.org/draft/2020-12/json-schema-core.html#section-7.7) from the new drafts are also supported. The known breaking changes are listed below, but there may be others that haven't been identified.
6+
7+
### Breaking Changes
8+
9+
- The default meta schema is now Draft 2020-12. Other meta schemas can be specified using `meta_schema`.
10+
- Schemas use `json-schemer://schema` as the default base URI. Relative `$id` and `$ref` values are joined to the default base URI and are always absolute. For example, the schema `{ '$id' => 'foo', '$ref' => 'bar' }` uses `json-schemer://schema/foo` as the base URI and passes `json-schemer://schema/bar` to the ref resolver. For relative refs, `URI#path` can be used in the ref resolver to access the relative portion, ie: `URI('json-schemer://schema/bar').path => "/bar"`.
11+
- Property validation hooks (`before_property_validation` and `after_property_validation`) run immediately before and after `properties` validation. Previously, `before_property_validation` ran before all "object" validations (`dependencies`, `patternProperties`, `additionalProperties`, etc) and `after_property_validation` was called after them.
12+
- `insert_property_defaults` now inserts defaults in conditional subschemas when possible (if there's only one default or if there's only one unique default from a valid subtree).
13+
- Error output
14+
- Special characters in `schema_pointer` are no longer percent encoded (eg, `definitions/foo\"bar` instead of `/definitions/foo%22bar`)
15+
- Keyword validation order changed so errors may be returned in a different order (eg, `items` errors before `contains`).
16+
- Array `dependencies` return `"type": "dependencies"` errors instead of `"required"` and point to the schema that contains the `dependencies` keyword.
17+
- `not` errors point to the schema that contains the `not` keyword (instead of the schema defined by the `not` keyword).
18+
- Custom keyword errors are now always wrapped in regular error hashes. Returned strings are used to set `type`:
19+
```
20+
>> JSONSchemer.schema({ 'x' => 'y' }, :keywords => { 'x' => proc { false } }).validate({}).to_a
21+
=> [{"data"=>{}, "data_pointer"=>"", "schema"=>{"x"=>"y"}, "schema_pointer"=>"", "root_schema"=>{"x"=>"y"}, "type"=>"x"}]
22+
>> JSONSchemer.schema({ 'x' => 'y' }, :keywords => { 'x' => proc { 'wrong!' } }).validate({}).to_a
23+
=> [{"data"=>{}, "data_pointer"=>"", "schema"=>{"x"=>"y"}, "schema_pointer"=>"", "root_schema"=>{"x"=>"y"}, "type"=>"wrong!"}]
24+
```
25+
26+
[2.0.0]: https://github.com/davishmcclurg/json_schemer/releases/tag/v2.0.0
27+
328
## [1.0.0] - 2023-05-26
429
530
### Breaking Changes

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
json_schemer (1.0.3)
4+
json_schemer (2.0.0)
55
hana (~> 1.3)
66
regexp_parser (~> 2.0)
77
simpleidn (~> 0.2)

JSON-Schema-Test-Suite/tests/draft-next/dynamicRef.json

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -207,45 +207,75 @@
207207
"schema": {
208208
"$schema": "https://json-schema.org/draft/next/schema",
209209
"$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main",
210-
"$defs": {
211-
"inner": {
212-
"$id": "inner",
213-
"$dynamicAnchor": "foo",
214-
"title": "inner",
215-
"additionalProperties": {
216-
"$dynamicRef": "#foo"
217-
}
210+
"propertyDependencies": {
211+
"kindOfList": {
212+
"numbers": { "$ref": "numberList" },
213+
"strings": { "$ref": "stringList" }
218214
}
219215
},
220-
"if": {
221-
"propertyNames": {
222-
"pattern": "^[a-m]"
216+
"$defs": {
217+
"genericList": {
218+
"$id": "genericList",
219+
"properties": {
220+
"list": {
221+
"items": { "$dynamicRef": "#itemType" }
222+
}
223+
}
224+
},
225+
"numberList": {
226+
"$id": "numberList",
227+
"$defs": {
228+
"itemType": {
229+
"$dynamicAnchor": "itemType",
230+
"type": "number"
231+
}
232+
},
233+
"$ref": "genericList"
234+
},
235+
"stringList": {
236+
"$id": "stringList",
237+
"$defs": {
238+
"itemType": {
239+
"$dynamicAnchor": "itemType",
240+
"type": "string"
241+
}
242+
},
243+
"$ref": "genericList"
223244
}
224-
},
225-
"then": {
226-
"title": "any type of node",
227-
"$id": "anyLeafNode",
228-
"$dynamicAnchor": "foo",
229-
"$ref": "inner"
230-
},
231-
"else": {
232-
"title": "integer node",
233-
"$id": "integerNode",
234-
"$dynamicAnchor": "foo",
235-
"type": [ "object", "integer" ],
236-
"$ref": "inner"
237245
}
238246
},
239247
"tests": [
240248
{
241-
"description": "recurse to anyLeafNode - floats are allowed",
242-
"data": { "alpha": 1.1 },
249+
"description": "number list with number values",
250+
"data": {
251+
"kindOfList": "numbers",
252+
"list": [1.1]
253+
},
243254
"valid": true
244255
},
245256
{
246-
"description": "recurse to integerNode - floats are not allowed",
247-
"data": { "november": 1.1 },
257+
"description": "number list with string values",
258+
"data": {
259+
"kindOfList": "numbers",
260+
"list": ["foo"]
261+
},
248262
"valid": false
263+
},
264+
{
265+
"description": "string list with number values",
266+
"data": {
267+
"kindOfList": "strings",
268+
"list": [1.1]
269+
},
270+
"valid": false
271+
},
272+
{
273+
"description": "string list with string values",
274+
"data": {
275+
"kindOfList": "strings",
276+
"list": ["foo"]
277+
},
278+
"valid": true
249279
}
250280
]
251281
},

JSON-Schema-Test-Suite/tests/draft2020-12/dynamicRef.json

Lines changed: 67 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -392,45 +392,84 @@
392392
"schema": {
393393
"$schema": "https://json-schema.org/draft/2020-12/schema",
394394
"$id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main",
395+
"if": {
396+
"properties": {
397+
"kindOfList": { "const": "numbers" }
398+
},
399+
"required": ["kindOfList"]
400+
},
401+
"then": { "$ref": "numberList" },
402+
"else": { "$ref": "stringList" },
403+
395404
"$defs": {
396-
"inner": {
397-
"$id": "inner",
398-
"$dynamicAnchor": "foo",
399-
"title": "inner",
400-
"additionalProperties": {
401-
"$dynamicRef": "#foo"
405+
"genericList": {
406+
"$id": "genericList",
407+
"properties": {
408+
"list": {
409+
"items": { "$dynamicRef": "#itemType" }
410+
}
411+
},
412+
"$defs": {
413+
"defaultItemType": {
414+
"$comment": "Only needed to satisfy bookending requirement",
415+
"$dynamicAnchor": "itemType"
416+
}
402417
}
418+
},
419+
"numberList": {
420+
"$id": "numberList",
421+
"$defs": {
422+
"itemType": {
423+
"$dynamicAnchor": "itemType",
424+
"type": "number"
425+
}
426+
},
427+
"$ref": "genericList"
428+
},
429+
"stringList": {
430+
"$id": "stringList",
431+
"$defs": {
432+
"itemType": {
433+
"$dynamicAnchor": "itemType",
434+
"type": "string"
435+
}
436+
},
437+
"$ref": "genericList"
403438
}
404-
},
405-
"if": {
406-
"propertyNames": {
407-
"pattern": "^[a-m]"
408-
}
409-
},
410-
"then": {
411-
"title": "any type of node",
412-
"$id": "anyLeafNode",
413-
"$dynamicAnchor": "foo",
414-
"$ref": "inner"
415-
},
416-
"else": {
417-
"title": "integer node",
418-
"$id": "integerNode",
419-
"$dynamicAnchor": "foo",
420-
"type": [ "object", "integer" ],
421-
"$ref": "inner"
422439
}
423440
},
424441
"tests": [
425442
{
426-
"description": "recurse to anyLeafNode - floats are allowed",
427-
"data": { "alpha": 1.1 },
443+
"description": "number list with number values",
444+
"data": {
445+
"kindOfList": "numbers",
446+
"list": [1.1]
447+
},
428448
"valid": true
429449
},
430450
{
431-
"description": "recurse to integerNode - floats are not allowed",
432-
"data": { "november": 1.1 },
451+
"description": "number list with string values",
452+
"data": {
453+
"kindOfList": "numbers",
454+
"list": ["foo"]
455+
},
456+
"valid": false
457+
},
458+
{
459+
"description": "string list with number values",
460+
"data": {
461+
"kindOfList": "strings",
462+
"list": [1.1]
463+
},
433464
"valid": false
465+
},
466+
{
467+
"description": "string list with string values",
468+
"data": {
469+
"kindOfList": "strings",
470+
"list": ["foo"]
471+
},
472+
"valid": true
434473
}
435474
]
436475
},

JSON-Schema-Test-Suite/tests/draft6/ref.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,33 @@
445445
}
446446
]
447447
},
448+
{
449+
"description": "Reference an anchor with a non-relative URI",
450+
"schema": {
451+
"$id": "https://example.com/schema-with-anchor",
452+
"allOf": [{
453+
"$ref": "https://example.com/schema-with-anchor#foo"
454+
}],
455+
"definitions": {
456+
"A": {
457+
"$id": "#foo",
458+
"type": "integer"
459+
}
460+
}
461+
},
462+
"tests": [
463+
{
464+
"data": 1,
465+
"description": "match",
466+
"valid": true
467+
},
468+
{
469+
"data": "a",
470+
"description": "mismatch",
471+
"valid": false
472+
}
473+
]
474+
},
448475
{
449476
"description": "Location-independent identifier with base URI change in subschema",
450477
"schema": {

JSON-Schema-Test-Suite/tests/draft7/ref.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,33 @@
445445
}
446446
]
447447
},
448+
{
449+
"description": "Reference an anchor with a non-relative URI",
450+
"schema": {
451+
"$id": "https://example.com/schema-with-anchor",
452+
"allOf": [{
453+
"$ref": "https://example.com/schema-with-anchor#foo"
454+
}],
455+
"definitions": {
456+
"A": {
457+
"$id": "#foo",
458+
"type": "integer"
459+
}
460+
}
461+
},
462+
"tests": [
463+
{
464+
"data": 1,
465+
"description": "match",
466+
"valid": true
467+
},
468+
{
469+
"data": "a",
470+
"description": "mismatch",
471+
"valid": false
472+
}
473+
]
474+
},
448475
{
449476
"description": "Location-independent identifier with base URI change in subschema",
450477
"schema": {

0 commit comments

Comments
 (0)