|
import pytest |
|
|
|
from referencing import Registry, Resource, Specification |
|
import referencing.jsonschema |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"uri, expected", |
|
[ |
|
( |
|
"https://json-schema.org/draft/2020-12/schema", |
|
referencing.jsonschema.DRAFT202012, |
|
), |
|
( |
|
"https://json-schema.org/draft/2019-09/schema", |
|
referencing.jsonschema.DRAFT201909, |
|
), |
|
( |
|
"http://json-schema.org/draft-07/schema#", |
|
referencing.jsonschema.DRAFT7, |
|
), |
|
( |
|
"http://json-schema.org/draft-06/schema#", |
|
referencing.jsonschema.DRAFT6, |
|
), |
|
( |
|
"http://json-schema.org/draft-04/schema#", |
|
referencing.jsonschema.DRAFT4, |
|
), |
|
( |
|
"http://json-schema.org/draft-03/schema#", |
|
referencing.jsonschema.DRAFT3, |
|
), |
|
], |
|
) |
|
def test_schemas_with_explicit_schema_keywords_are_detected(uri, expected): |
|
""" |
|
The $schema keyword in JSON Schema is a dialect identifier. |
|
""" |
|
contents = {"$schema": uri} |
|
resource = Resource.from_contents(contents) |
|
assert resource == Resource(contents=contents, specification=expected) |
|
|
|
|
|
def test_unknown_dialect(): |
|
dialect_id = "http://example.com/unknown-json-schema-dialect-id" |
|
with pytest.raises(referencing.jsonschema.UnknownDialect) as excinfo: |
|
Resource.from_contents({"$schema": dialect_id}) |
|
assert excinfo.value.uri == dialect_id |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"id, specification", |
|
[ |
|
("$id", referencing.jsonschema.DRAFT202012), |
|
("$id", referencing.jsonschema.DRAFT201909), |
|
("$id", referencing.jsonschema.DRAFT7), |
|
("$id", referencing.jsonschema.DRAFT6), |
|
("id", referencing.jsonschema.DRAFT4), |
|
("id", referencing.jsonschema.DRAFT3), |
|
], |
|
) |
|
def test_id_of_mapping(id, specification): |
|
uri = "http://example.com/some-schema" |
|
assert specification.id_of({id: uri}) == uri |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"specification", |
|
[ |
|
referencing.jsonschema.DRAFT202012, |
|
referencing.jsonschema.DRAFT201909, |
|
referencing.jsonschema.DRAFT7, |
|
referencing.jsonschema.DRAFT6, |
|
], |
|
) |
|
@pytest.mark.parametrize("value", [True, False]) |
|
def test_id_of_bool(specification, value): |
|
assert specification.id_of(value) is None |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"specification", |
|
[ |
|
referencing.jsonschema.DRAFT202012, |
|
referencing.jsonschema.DRAFT201909, |
|
referencing.jsonschema.DRAFT7, |
|
referencing.jsonschema.DRAFT6, |
|
], |
|
) |
|
@pytest.mark.parametrize("value", [True, False]) |
|
def test_anchors_in_bool(specification, value): |
|
assert list(specification.anchors_in(value)) == [] |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"specification", |
|
[ |
|
referencing.jsonschema.DRAFT202012, |
|
referencing.jsonschema.DRAFT201909, |
|
referencing.jsonschema.DRAFT7, |
|
referencing.jsonschema.DRAFT6, |
|
], |
|
) |
|
@pytest.mark.parametrize("value", [True, False]) |
|
def test_subresources_of_bool(specification, value): |
|
assert list(specification.subresources_of(value)) == [] |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"uri, expected", |
|
[ |
|
( |
|
"https://json-schema.org/draft/2020-12/schema", |
|
referencing.jsonschema.DRAFT202012, |
|
), |
|
( |
|
"https://json-schema.org/draft/2019-09/schema", |
|
referencing.jsonschema.DRAFT201909, |
|
), |
|
( |
|
"http://json-schema.org/draft-07/schema#", |
|
referencing.jsonschema.DRAFT7, |
|
), |
|
( |
|
"http://json-schema.org/draft-06/schema#", |
|
referencing.jsonschema.DRAFT6, |
|
), |
|
( |
|
"http://json-schema.org/draft-04/schema#", |
|
referencing.jsonschema.DRAFT4, |
|
), |
|
( |
|
"http://json-schema.org/draft-03/schema#", |
|
referencing.jsonschema.DRAFT3, |
|
), |
|
], |
|
) |
|
def test_specification_with(uri, expected): |
|
assert referencing.jsonschema.specification_with(uri) == expected |
|
|
|
|
|
@pytest.mark.parametrize( |
|
"uri, expected", |
|
[ |
|
( |
|
"http://json-schema.org/draft-07/schema", |
|
referencing.jsonschema.DRAFT7, |
|
), |
|
( |
|
"http://json-schema.org/draft-06/schema", |
|
referencing.jsonschema.DRAFT6, |
|
), |
|
( |
|
"http://json-schema.org/draft-04/schema", |
|
referencing.jsonschema.DRAFT4, |
|
), |
|
( |
|
"http://json-schema.org/draft-03/schema", |
|
referencing.jsonschema.DRAFT3, |
|
), |
|
], |
|
) |
|
def test_specification_with_no_empty_fragment(uri, expected): |
|
assert referencing.jsonschema.specification_with(uri) == expected |
|
|
|
|
|
def test_specification_with_unknown_dialect(): |
|
dialect_id = "http://example.com/unknown-json-schema-dialect-id" |
|
with pytest.raises(referencing.jsonschema.UnknownDialect) as excinfo: |
|
referencing.jsonschema.specification_with(dialect_id) |
|
assert excinfo.value.uri == dialect_id |
|
|
|
|
|
def test_specification_with_default(): |
|
dialect_id = "http://example.com/unknown-json-schema-dialect-id" |
|
specification = referencing.jsonschema.specification_with( |
|
dialect_id, |
|
default=Specification.OPAQUE, |
|
) |
|
assert specification is Specification.OPAQUE |
|
|
|
|
|
|
|
|
|
def test_lookup_trivial_dynamic_ref(): |
|
one = referencing.jsonschema.DRAFT202012.create_resource( |
|
{"$dynamicAnchor": "foo"}, |
|
) |
|
resolver = Registry().with_resource("http://example.com", one).resolver() |
|
resolved = resolver.lookup("http://example.com#foo") |
|
assert resolved.contents == one.contents |
|
|
|
|
|
def test_multiple_lookup_trivial_dynamic_ref(): |
|
TRUE = referencing.jsonschema.DRAFT202012.create_resource(True) |
|
root = referencing.jsonschema.DRAFT202012.create_resource( |
|
{ |
|
"$id": "http://example.com", |
|
"$dynamicAnchor": "fooAnchor", |
|
"$defs": { |
|
"foo": { |
|
"$id": "foo", |
|
"$dynamicAnchor": "fooAnchor", |
|
"$defs": { |
|
"bar": True, |
|
"baz": { |
|
"$dynamicAnchor": "fooAnchor", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
) |
|
resolver = ( |
|
Registry() |
|
.with_resources( |
|
[ |
|
("http://example.com", root), |
|
("http://example.com/foo/", TRUE), |
|
("http://example.com/foo/bar", root), |
|
], |
|
) |
|
.resolver() |
|
) |
|
|
|
first = resolver.lookup("http://example.com") |
|
second = first.resolver.lookup("foo/") |
|
resolver = second.resolver.lookup("bar").resolver |
|
fourth = resolver.lookup("#fooAnchor") |
|
assert fourth.contents == root.contents |
|
|
|
|
|
def test_multiple_lookup_dynamic_ref_to_nondynamic_ref(): |
|
one = referencing.jsonschema.DRAFT202012.create_resource( |
|
{"$anchor": "fooAnchor"}, |
|
) |
|
two = referencing.jsonschema.DRAFT202012.create_resource( |
|
{ |
|
"$id": "http://example.com", |
|
"$dynamicAnchor": "fooAnchor", |
|
"$defs": { |
|
"foo": { |
|
"$id": "foo", |
|
"$dynamicAnchor": "fooAnchor", |
|
"$defs": { |
|
"bar": True, |
|
"baz": { |
|
"$dynamicAnchor": "fooAnchor", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
) |
|
resolver = ( |
|
Registry() |
|
.with_resources( |
|
[ |
|
("http://example.com", two), |
|
("http://example.com/foo/", one), |
|
("http://example.com/foo/bar", two), |
|
], |
|
) |
|
.resolver() |
|
) |
|
|
|
first = resolver.lookup("http://example.com") |
|
second = first.resolver.lookup("foo/") |
|
resolver = second.resolver.lookup("bar").resolver |
|
fourth = resolver.lookup("#fooAnchor") |
|
assert fourth.contents == two.contents |
|
|
|
|
|
def test_lookup_trivial_recursive_ref(): |
|
one = referencing.jsonschema.DRAFT201909.create_resource( |
|
{"$recursiveAnchor": True}, |
|
) |
|
resolver = Registry().with_resource("http://example.com", one).resolver() |
|
first = resolver.lookup("http://example.com") |
|
resolved = referencing.jsonschema.lookup_recursive_ref( |
|
resolver=first.resolver, |
|
) |
|
assert resolved.contents == one.contents |
|
|
|
|
|
def test_lookup_recursive_ref_to_bool(): |
|
TRUE = referencing.jsonschema.DRAFT201909.create_resource(True) |
|
registry = Registry({"http://example.com": TRUE}) |
|
resolved = referencing.jsonschema.lookup_recursive_ref( |
|
resolver=registry.resolver(base_uri="http://example.com"), |
|
) |
|
assert resolved.contents == TRUE.contents |
|
|
|
|
|
def test_multiple_lookup_recursive_ref_to_bool(): |
|
TRUE = referencing.jsonschema.DRAFT201909.create_resource(True) |
|
root = referencing.jsonschema.DRAFT201909.create_resource( |
|
{ |
|
"$id": "http://example.com", |
|
"$recursiveAnchor": True, |
|
"$defs": { |
|
"foo": { |
|
"$id": "foo", |
|
"$recursiveAnchor": True, |
|
"$defs": { |
|
"bar": True, |
|
"baz": { |
|
"$recursiveAnchor": True, |
|
"$anchor": "fooAnchor", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
) |
|
resolver = ( |
|
Registry() |
|
.with_resources( |
|
[ |
|
("http://example.com", root), |
|
("http://example.com/foo/", TRUE), |
|
("http://example.com/foo/bar", root), |
|
], |
|
) |
|
.resolver() |
|
) |
|
|
|
first = resolver.lookup("http://example.com") |
|
second = first.resolver.lookup("foo/") |
|
resolver = second.resolver.lookup("bar").resolver |
|
fourth = referencing.jsonschema.lookup_recursive_ref(resolver=resolver) |
|
assert fourth.contents == root.contents |
|
|
|
|
|
def test_multiple_lookup_recursive_ref_with_nonrecursive_ref(): |
|
one = referencing.jsonschema.DRAFT201909.create_resource( |
|
{"$recursiveAnchor": True}, |
|
) |
|
two = referencing.jsonschema.DRAFT201909.create_resource( |
|
{ |
|
"$id": "http://example.com", |
|
"$recursiveAnchor": True, |
|
"$defs": { |
|
"foo": { |
|
"$id": "foo", |
|
"$recursiveAnchor": True, |
|
"$defs": { |
|
"bar": True, |
|
"baz": { |
|
"$recursiveAnchor": True, |
|
"$anchor": "fooAnchor", |
|
}, |
|
}, |
|
}, |
|
}, |
|
}, |
|
) |
|
three = referencing.jsonschema.DRAFT201909.create_resource( |
|
{"$recursiveAnchor": False}, |
|
) |
|
resolver = ( |
|
Registry() |
|
.with_resources( |
|
[ |
|
("http://example.com", three), |
|
("http://example.com/foo/", two), |
|
("http://example.com/foo/bar", one), |
|
], |
|
) |
|
.resolver() |
|
) |
|
|
|
first = resolver.lookup("http://example.com") |
|
second = first.resolver.lookup("foo/") |
|
resolver = second.resolver.lookup("bar").resolver |
|
fourth = referencing.jsonschema.lookup_recursive_ref(resolver=resolver) |
|
assert fourth.contents == two.contents |
|
|
|
|
|
def test_empty_registry(): |
|
assert referencing.jsonschema.EMPTY_REGISTRY == Registry() |
|
|