383 lines
11 KiB
Python
383 lines
11 KiB
Python
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
|
|
|
|
|
|
# FIXME: The tests below should move to the referencing suite but I haven't yet
|
|
# figured out how to represent dynamic (& recursive) ref lookups in it.
|
|
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()
|