"""Schema-grounded structural field matrices for all contract artifacts.""" from __future__ import annotations import json import re from copy import deepcopy from pathlib import Path from typing import Any, Mapping from jsonschema import Draft202012Validator Json = Any SCHEMAS = { "scene": "scene-1.0.schema.json", "entities": "entities-1.0.schema.json", "presentation": "presentation-1.0.schema.json", "connector_binding": "connector-binding-1.0.schema.json", "normalized_product": "normalized-product-1.schema.json", } def _resolve(root: Mapping[str, Any], schema: Mapping[str, Any]) -> Mapping[str, Any]: reference = schema.get("$ref") if not isinstance(reference, str) or not reference.startswith("#/"): return schema current: Any = root for part in reference[2:].split("/"): current = current[part.replace("~1", "/").replace("~0", "~")] return current def _wrapper(root: Mapping[str, Any], pointer: str) -> dict[str, Any]: if pointer == "#": return deepcopy(dict(root)) return { "$schema": "https://json-schema.org/draft/2020-12/schema", "$ref": pointer, "$defs": deepcopy(root.get("$defs", {})), } def _string_example(schema: Mapping[str, Any]) -> str: pattern = str(schema.get("pattern", "")) if pattern == "^sha256:[0-9a-f]{64}$": return "sha256:" + "0" * 64 if pattern.startswith("^appearance/evaluated/"): return "appearance/evaluated/" + "0" * 64 if pattern.startswith("^entity/"): return "entity/face/0" for candidate in ("a", "x", "root", "entity/face/0"): if not pattern or re.fullmatch(pattern, candidate): return candidate raise AssertionError(f"no structural string example for pattern {pattern!r}") def _accepts_null(root: Mapping[str, Any], schema: Mapping[str, Any]) -> bool: wrapper = deepcopy(dict(schema)) wrapper["$defs"] = deepcopy(root.get("$defs", {})) return Draft202012Validator(wrapper).is_valid(None) def _nonnull_example(root: Mapping[str, Any], schema: Mapping[str, Any]) -> Json: resolved = _resolve(root, schema) if "oneOf" in resolved: for branch in resolved["oneOf"]: if not _accepts_null(root, branch): return _example(root, branch, prefer_nonnull=True) types = resolved.get("type") if isinstance(types, list): draft = dict(resolved) draft["type"] = next(item for item in types if item != "null") return _example(root, draft, prefer_nonnull=True) return _example(root, resolved, prefer_nonnull=True) def _condition_matches( root: Mapping[str, Any], condition: Mapping[str, Any], value: Json ) -> bool: schema = deepcopy(dict(condition)) schema["$defs"] = deepcopy(root.get("$defs", {})) return Draft202012Validator(schema).is_valid(value) def _example( root: Mapping[str, Any], schema: Mapping[str, Any], *, overrides: Mapping[str, Json] | None = None, prefer_nonnull: bool = False, ) -> Json: resolved = _resolve(root, schema) if "const" in resolved: return deepcopy(resolved["const"]) if "enum" in resolved: return deepcopy(resolved["enum"][0]) for union_key in ("oneOf", "anyOf"): if union_key in resolved and not ( resolved.get("type") == "object" or "properties" in resolved ): branches = resolved[union_key] if prefer_nonnull: branches = sorted( branches, key=lambda branch: _accepts_null(root, branch), ) return _example(root, branches[0], prefer_nonnull=prefer_nonnull) types = resolved.get("type") if isinstance(types, list): if "null" in types and not prefer_nonnull: return None types = next(item for item in types if item != "null") if types == "object" or "properties" in resolved: properties = resolved.get("properties", {}) result = { field: _example(root, properties.get(field, {})) for field in resolved.get("required", []) } if overrides: result.update(deepcopy(dict(overrides))) for branch in resolved.get("anyOf", []): branch_required = branch.get("required", []) if branch_required: for field in branch_required: result.setdefault(field, _example(root, properties.get(field, {}))) break for condition in resolved.get("allOf", []): then = condition.get("then") if isinstance(then, dict) and _condition_matches( root, condition.get("if", {}), result ): for field in then.get("required", []): result.setdefault(field, _example(root, properties.get(field, {}))) return result if types == "array" or "prefixItems" in resolved: result = [_example(root, item) for item in resolved.get("prefixItems", [])] minimum = resolved.get("minItems", 0) while len(result) < minimum: result.append(_example(root, resolved.get("items", {}))) return result if types == "string": return _string_example(resolved) if types == "integer": return int(resolved.get("minimum", 0)) if types == "number": if "exclusiveMinimum" in resolved: return resolved["exclusiveMinimum"] + 1 return resolved.get("minimum", 0) if types == "boolean": return False if types == "null": return None return {} def _closed_records(schema: Mapping[str, Any]) -> list[tuple[str, Mapping[str, Any]]]: result: dict[str, Mapping[str, Any]] = {} if schema.get("type") == "object" and schema.get("additionalProperties") is False: result["#"] = schema def visit(value: Any, pointer: str) -> None: if not isinstance(value, dict): return if value.get("type") == "object" and value.get("additionalProperties") is False: result[pointer] = value for key in ("properties", "items", "oneOf", "anyOf", "allOf"): child = value.get(key) if isinstance(child, dict): for name, nested in child.items(): visit(nested, f"{pointer}/{key}/{name}") elif isinstance(child, list): for index, nested in enumerate(child): visit(nested, f"{pointer}/{key}/{index}") for name, definition in schema.get("$defs", {}).items(): visit(definition, f"#/$defs/{name}") return list(result.items()) def _mutate(base: Json, operation: str, field: str, value: Json = None) -> Json: result = deepcopy(base) if operation == "delete": del result[field] else: result[field] = deepcopy(value) return result def _record_matrix( artifact: str, root: Mapping[str, Any], pointer: str, schema: Mapping[str, Any], *, overrides: Mapping[str, Json] | None = None, variant: str = "base", ) -> dict[str, Any]: validator = Draft202012Validator(_wrapper(root, pointer)) base = _example(root, schema, overrides=overrides) if not validator.is_valid(base): errors = [error.message for error in validator.iter_errors(base)] raise AssertionError( f"invalid generated {artifact} {pointer} {variant}: {errors}" ) properties = schema.get("properties", {}) cases: list[dict[str, Any]] = [ {"mutations": [], "name": "base_valid", "valid": True} ] for field in base: cases.append( { "mutations": [{"operation": "delete", "path": [field]}], "name": f"missing_{field}", "valid": validator.is_valid(_mutate(base, "delete", field)), } ) cases.append( { "mutations": [ {"operation": "set", "path": ["unknown"], "value": True} ], "name": "unknown_field", "valid": validator.is_valid(_mutate(base, "set", "unknown", True)), } ) optional = [field for field in properties if field not in base] for field in optional: present = _example(root, properties[field]) cases.append( { "mutations": [ {"operation": "set", "path": [field], "value": present} ], "name": f"optional_{field}_present", "valid": validator.is_valid(_mutate(base, "set", field, present)), } ) if optional: all_present = deepcopy(base) mutations = [] for field in optional: present = _example(root, properties[field]) all_present[field] = present mutations.append( {"operation": "set", "path": [field], "value": present} ) cases.append( { "mutations": mutations, "name": "optional_fields_all_present", "valid": validator.is_valid(all_present), } ) for field, field_schema in properties.items(): if field in base and base[field] is None and _accepts_null(root, field_schema): nonnull = _nonnull_example(root, field_schema) cases.append( { "mutations": [ {"operation": "set", "path": [field], "value": nonnull} ], "name": f"nullable_{field}_nonnull", "valid": validator.is_valid( _mutate(base, "set", field, nonnull) ), } ) return { "artifact": artifact, "base": base, "cases": cases, "schema_pointer": pointer, "variant": variant, } def build_schema_field_matrices(schema_dir: Path) -> list[dict[str, Any]]: """Build declarative matrices for every closed object and discriminator.""" matrices: list[dict[str, Any]] = [] for artifact, filename in SCHEMAS.items(): root = json.loads(schema_dir.joinpath(filename).read_text(encoding="utf-8")) for pointer, schema in _closed_records(root): discriminator = next( ( (field, field_schema["enum"]) for field, field_schema in schema.get("properties", {}).items() if isinstance(field_schema, dict) and len(field_schema.get("enum", [])) > 1 ), None, ) variants: list[tuple[str, Mapping[str, Json] | None]] = [("base", None)] if discriminator is not None: field, values = discriminator variants = [ (f"{field}={value}", {field: value}) for value in values ] if artifact == "normalized_product" and pointer == "#/$defs/connector": variants = [] for anchor_name in ( "geometryAnchor", "placementAnchor", "forwardedAnchor", ): anchor = _example(root, root["$defs"][anchor_name]) variants.append( (f"anchor={anchor['anchor_kind']}", {"anchor": anchor}) ) for variant, overrides in variants: matrices.append( _record_matrix( artifact, root, pointer, schema, overrides=overrides, variant=variant, ) ) identities = [ (matrix["artifact"], matrix["schema_pointer"], matrix["variant"]) for matrix in matrices ] if len(identities) != len(set(identities)): raise AssertionError("duplicate schema field matrix identity") return matrices