Skip to content

Commit

Permalink
Cope with the suite permuting of remotes.
Browse files Browse the repository at this point in the history
This new-but-similarly-messy logic comes modified from Bowtie
(which itself may need to be modified there, we'll see).

`jsonschema_suite remotes` is somewhat semantically broken (as it
doesn't really help with not emitting schemas which aren't valid under
the version under test), so it's time to give up and use the other
filesystem mechanism of walking the remotes directory.

Refs: json-schema-org/JSON-Schema-Test-Suite#753
  • Loading branch information
Julian committed Jan 31, 2025
1 parent 9be918e commit e1f3137
Showing 1 changed file with 42 additions and 33 deletions.
75 changes: 42 additions & 33 deletions jsonschema/tests/_suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import json
import os
import re
import subprocess
import sys
import unittest

Expand All @@ -21,11 +20,14 @@
if TYPE_CHECKING:
from collections.abc import Iterable, Mapping, Sequence

from referencing.jsonschema import Schema
import pyperf

from jsonschema.validators import _VALIDATORS
import jsonschema

MAGIC_REMOTE_URL = "http://localhost:1234"

_DELIMITERS = re.compile(r"[\W\- ]+")


Expand All @@ -51,38 +53,7 @@ def _find_suite():
class Suite:

_root: Path = field(factory=_find_suite)
_remotes: referencing.jsonschema.SchemaRegistry = field(init=False)

def __attrs_post_init__(self):
jsonschema_suite = self._root.joinpath("bin", "jsonschema_suite")
argv = [sys.executable, str(jsonschema_suite), "remotes"]
remotes = subprocess.check_output(argv).decode("utf-8")

resources = json.loads(remotes)

li = "http://localhost:1234/locationIndependentIdentifierPre2019.json"
li4 = "http://localhost:1234/locationIndependentIdentifierDraft4.json"

registry = Registry().with_resources(
[
(
li,
referencing.jsonschema.DRAFT7.create_resource(
contents=resources.pop(li),
),
),
(
li4,
referencing.jsonschema.DRAFT4.create_resource(
contents=resources.pop(li4),
),
),
],
).with_contents(
resources.items(),
default_specification=referencing.jsonschema.DRAFT202012,
)
object.__setattr__(self, "_remotes", registry)

def benchmark(self, runner: pyperf.Runner): # pragma: no cover
for name, Validator in _VALIDATORS.items():
Expand All @@ -92,10 +63,18 @@ def benchmark(self, runner: pyperf.Runner): # pragma: no cover
)

def version(self, name) -> Version:
Validator = _VALIDATORS[name]
uri: str = Validator.ID_OF(Validator.META_SCHEMA) # type: ignore[assignment]
specification = referencing.jsonschema.specification_with(uri)

registry = Registry().with_contents(
remotes_in(root=self._root / "remotes", name=name, uri=uri),
default_specification=specification,
)
return Version(
name=name,
path=self._root / "tests" / name,
remotes=self._remotes,
remotes=registry,
)


Expand Down Expand Up @@ -187,6 +166,36 @@ def benchmark(self, runner: pyperf.Runner, **kwargs): # pragma: no cover
)


def remotes_in(
root: Path,
name: str,
uri: str,
) -> Iterable[tuple[str, Schema]]:
# This messy logic is because the test suite is terrible at indicating
# what remotes are needed for what drafts, and mixes in schemas which
# have no $schema and which are invalid under earlier versions, in with
# other schemas which are needed for tests.

for each in root.rglob("*.json"):
schema = json.loads(each.read_text())

relative = str(each.relative_to(root)).replace("\\", "/")

if (
( # invalid boolean schema
name in {"draft3", "draft4"}
and each.stem == "tree"
) or
( # draft<NotThisDialect>/*.json
"$schema" not in schema
and relative.startswith("draft")
and not relative.startswith(name)
)
):
continue
yield f"{MAGIC_REMOTE_URL}/{relative}", schema


@frozen(repr=False)
class _Test:

Expand Down

0 comments on commit e1f3137

Please sign in to comment.