Skip to content

Commit e5ca2b1

Browse files
committed
Support Schema#ref in subschemas
`resolve_ref` needs to be called on the root schema because that's where all the `resources` are stored. The behavior here is kind of confusing because the ref is resolved just like the `$ref` keyword would be in the schema, so it's dependent on the schema's base URI. That means for a subschema `ref('#')` doesn't necessarily resolve to itself (ie, if the subschema doesn't have `$id`).
1 parent be45f04 commit e5ca2b1

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Bug Fixes
66

77
- Require discriminator `propertyName` property
8+
- Support `Schema#ref` in subschemas
89

910
[2.1.0]: https://github.com/davishmcclurg/json_schemer/releases/tag/v2.1.0
1011

lib/json_schemer/schema.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def validate_schema
113113
end
114114

115115
def ref(value)
116-
resolve_ref(URI.join(base_uri, value))
116+
root.resolve_ref(URI.join(base_uri, value))
117117
end
118118

119119
def validate_instance(instance, instance_location, keyword_location, context)

test/json_schemer_test.rb

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,12 @@ def test_schema_ref
380380
'type' => 'integer',
381381
'$defs' => {
382382
'foo' => {
383+
'$id' => 'subschemer',
384+
'$defs' => {
385+
'bar' => {
386+
'required' => ['z']
387+
}
388+
},
383389
'type' => 'object',
384390
'required' => ['x', 'y'],
385391
'properties' => {
@@ -401,10 +407,20 @@ def test_schema_ref
401407

402408
refute(subschemer.valid?(1))
403409
assert_equal(
404-
[["/x", "/$defs/foo/properties/x", "string"], ["", "/$defs/foo", "required"]],
410+
[['/x', '/$defs/foo/properties/x', 'string'], ['', '/$defs/foo', 'required']],
405411
subschemer.validate({ 'x' => 1 }).map { |error| error.values_at('data_pointer', 'schema_pointer', 'type') }
406412
)
407413
assert(subschemer.valid?({ 'x' => '1', 'y' => 1 }))
414+
415+
subsubschemer = subschemer.ref('#/$defs/bar')
416+
refute(subsubschemer.valid?({ 'x' => 1 }))
417+
assert_equal(
418+
[['', '/$defs/foo/$defs/bar', 'required']],
419+
subsubschemer.validate({ 'x' => 1 }).map { |error| error.values_at('data_pointer', 'schema_pointer', 'type') }
420+
)
421+
422+
assert_equal(subschemer, subschemer.ref('#'))
423+
assert_equal(subschemer, subsubschemer.ref('#'))
408424
end
409425

410426
def test_published_meta_schemas

0 commit comments

Comments
 (0)