Building Project Files
هذا الالتزام موجود في:
ملف ثنائي غير معروض.
ملف ثنائي غير معروض.
ملف ثنائي غير معروض.
ملف ثنائي غير معروض.
ملف ثنائي غير معروض.
ملف ثنائي غير معروض.
1057
venv/lib/python3.12/site-packages/referencing/tests/test_core.py
Normal file
1057
venv/lib/python3.12/site-packages/referencing/tests/test_core.py
Normal file
تم حذف اختلاف الملف لأن الملف كبير جداً
تحميل الاختلاف
@@ -0,0 +1,34 @@
|
||||
import itertools
|
||||
|
||||
import pytest
|
||||
|
||||
from referencing import Resource, exceptions
|
||||
|
||||
|
||||
def pairs(choices):
|
||||
return itertools.combinations(choices, 2)
|
||||
|
||||
|
||||
TRUE = Resource.opaque(True)
|
||||
|
||||
|
||||
thunks = (
|
||||
lambda: exceptions.CannotDetermineSpecification(TRUE),
|
||||
lambda: exceptions.NoSuchResource("urn:example:foo"),
|
||||
lambda: exceptions.NoInternalID(TRUE),
|
||||
lambda: exceptions.InvalidAnchor(resource=TRUE, anchor="foo", ref="a#b"),
|
||||
lambda: exceptions.NoSuchAnchor(resource=TRUE, anchor="foo", ref="a#b"),
|
||||
lambda: exceptions.PointerToNowhere(resource=TRUE, ref="urn:example:foo"),
|
||||
lambda: exceptions.Unresolvable("urn:example:foo"),
|
||||
lambda: exceptions.Unretrievable("urn:example:foo"),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("one, two", pairs(each() for each in thunks))
|
||||
def test_eq_incompatible_types(one, two):
|
||||
assert one != two
|
||||
|
||||
|
||||
@pytest.mark.parametrize("thunk", thunks)
|
||||
def test_hash(thunk):
|
||||
assert thunk() in {thunk()}
|
@@ -0,0 +1,382 @@
|
||||
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()
|
@@ -0,0 +1,66 @@
|
||||
from pathlib import Path
|
||||
import json
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from referencing import Registry
|
||||
from referencing.exceptions import Unresolvable
|
||||
import referencing.jsonschema
|
||||
|
||||
|
||||
class SuiteNotFound(Exception):
|
||||
def __str__(self): # pragma: no cover
|
||||
return (
|
||||
"Cannot find the referencing suite. "
|
||||
"Set the REFERENCING_SUITE environment variable to the path to "
|
||||
"the suite, or run the test suite from alongside a full checkout "
|
||||
"of the git repository."
|
||||
)
|
||||
|
||||
|
||||
if "REFERENCING_SUITE" in os.environ: # pragma: no cover
|
||||
SUITE = Path(os.environ["REFERENCING_SUITE"]) / "tests"
|
||||
else:
|
||||
SUITE = Path(__file__).parent.parent.parent / "suite/tests"
|
||||
if not SUITE.is_dir(): # pragma: no cover
|
||||
raise SuiteNotFound()
|
||||
DIALECT_IDS = json.loads(SUITE.joinpath("specifications.json").read_text())
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_path",
|
||||
[
|
||||
pytest.param(each, id=f"{each.parent.name}-{each.stem}")
|
||||
for each in SUITE.glob("*/**/*.json")
|
||||
],
|
||||
)
|
||||
def test_referencing_suite(test_path, subtests):
|
||||
dialect_id = DIALECT_IDS[test_path.relative_to(SUITE).parts[0]]
|
||||
specification = referencing.jsonschema.specification_with(dialect_id)
|
||||
loaded = json.loads(test_path.read_text())
|
||||
registry = loaded["registry"]
|
||||
registry = Registry().with_resources(
|
||||
(uri, specification.create_resource(contents))
|
||||
for uri, contents in loaded["registry"].items()
|
||||
)
|
||||
for test in loaded["tests"]:
|
||||
with subtests.test(test=test):
|
||||
if "normalization" in test_path.stem:
|
||||
pytest.xfail("APIs need to change for proper URL support.")
|
||||
|
||||
resolver = registry.resolver(base_uri=test.get("base_uri", ""))
|
||||
|
||||
if test.get("error"):
|
||||
with pytest.raises(Unresolvable):
|
||||
resolver.lookup(test["ref"])
|
||||
else:
|
||||
resolved = resolver.lookup(test["ref"])
|
||||
assert resolved.contents == test["target"]
|
||||
|
||||
then = test.get("then")
|
||||
while then: # pragma: no cover
|
||||
with subtests.test(test=test, then=then):
|
||||
resolved = resolved.resolver.lookup(then["ref"])
|
||||
assert resolved.contents == then["target"]
|
||||
then = then.get("then")
|
@@ -0,0 +1,106 @@
|
||||
from functools import lru_cache
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from referencing import Registry, Resource, exceptions
|
||||
from referencing.jsonschema import DRAFT202012
|
||||
from referencing.retrieval import to_cached_resource
|
||||
|
||||
|
||||
class TestToCachedResource:
|
||||
def test_it_caches_retrieved_resources(self):
|
||||
contents = {"$schema": "https://json-schema.org/draft/2020-12/schema"}
|
||||
stack = [json.dumps(contents)]
|
||||
|
||||
@to_cached_resource()
|
||||
def retrieve(uri):
|
||||
return stack.pop()
|
||||
|
||||
registry = Registry(retrieve=retrieve)
|
||||
|
||||
expected = Resource.from_contents(contents)
|
||||
|
||||
got = registry.get_or_retrieve("urn:example:schema")
|
||||
assert got.value == expected
|
||||
|
||||
# And a second time we get the same value.
|
||||
again = registry.get_or_retrieve("urn:example:schema")
|
||||
assert again.value is got.value
|
||||
|
||||
def test_custom_loader(self):
|
||||
contents = {"$schema": "https://json-schema.org/draft/2020-12/schema"}
|
||||
stack = [json.dumps(contents)[::-1]]
|
||||
|
||||
@to_cached_resource(loads=lambda s: json.loads(s[::-1]))
|
||||
def retrieve(uri):
|
||||
return stack.pop()
|
||||
|
||||
registry = Registry(retrieve=retrieve)
|
||||
|
||||
expected = Resource.from_contents(contents)
|
||||
|
||||
got = registry.get_or_retrieve("urn:example:schema")
|
||||
assert got.value == expected
|
||||
|
||||
# And a second time we get the same value.
|
||||
again = registry.get_or_retrieve("urn:example:schema")
|
||||
assert again.value is got.value
|
||||
|
||||
def test_custom_from_contents(self):
|
||||
contents = {}
|
||||
stack = [json.dumps(contents)]
|
||||
|
||||
@to_cached_resource(from_contents=DRAFT202012.create_resource)
|
||||
def retrieve(uri):
|
||||
return stack.pop()
|
||||
|
||||
registry = Registry(retrieve=retrieve)
|
||||
|
||||
expected = DRAFT202012.create_resource(contents)
|
||||
|
||||
got = registry.get_or_retrieve("urn:example:schema")
|
||||
assert got.value == expected
|
||||
|
||||
# And a second time we get the same value.
|
||||
again = registry.get_or_retrieve("urn:example:schema")
|
||||
assert again.value is got.value
|
||||
|
||||
def test_custom_cache(self):
|
||||
schema = {"$schema": "https://json-schema.org/draft/2020-12/schema"}
|
||||
mapping = {
|
||||
"urn:example:1": dict(schema, foo=1),
|
||||
"urn:example:2": dict(schema, foo=2),
|
||||
"urn:example:3": dict(schema, foo=3),
|
||||
}
|
||||
|
||||
resources = {
|
||||
uri: Resource.from_contents(contents)
|
||||
for uri, contents in mapping.items()
|
||||
}
|
||||
|
||||
@to_cached_resource(cache=lru_cache(maxsize=2))
|
||||
def retrieve(uri):
|
||||
return json.dumps(mapping.pop(uri))
|
||||
|
||||
registry = Registry(retrieve=retrieve)
|
||||
|
||||
got = registry.get_or_retrieve("urn:example:1")
|
||||
assert got.value == resources["urn:example:1"]
|
||||
assert registry.get_or_retrieve("urn:example:1").value is got.value
|
||||
assert registry.get_or_retrieve("urn:example:1").value is got.value
|
||||
|
||||
got = registry.get_or_retrieve("urn:example:2")
|
||||
assert got.value == resources["urn:example:2"]
|
||||
assert registry.get_or_retrieve("urn:example:2").value is got.value
|
||||
assert registry.get_or_retrieve("urn:example:2").value is got.value
|
||||
|
||||
# This still succeeds, but evicts the first URI
|
||||
got = registry.get_or_retrieve("urn:example:3")
|
||||
assert got.value == resources["urn:example:3"]
|
||||
assert registry.get_or_retrieve("urn:example:3").value is got.value
|
||||
assert registry.get_or_retrieve("urn:example:3").value is got.value
|
||||
|
||||
# And now this fails (as we popped the value out of `mapping`)
|
||||
with pytest.raises(exceptions.Unretrievable):
|
||||
registry.get_or_retrieve("urn:example:1")
|
المرجع في مشكلة جديدة
حظر مستخدم