core/tests/test_foundational_families.py

173 lines
5.8 KiB
Python

from __future__ import annotations
import ast
from dataclasses import FrozenInstanceError
from pathlib import Path
import pytest
import generate.foundational_families as foundational_families
from generate.foundational_families import (
FoundationalFamilySpec,
get_foundational_family,
get_foundational_family_by_relation_type,
iter_foundational_families,
require_foundational_family,
)
EXPECTED_FAMILY_IDS = (
"binding.quantity_entity",
"state_change.transition",
"state_change.unary_delta",
)
def test_registry_contains_only_the_two_approved_specs_in_deterministic_order() -> None:
families = iter_foundational_families()
assert isinstance(families, tuple)
assert tuple(family.family_id for family in families) == EXPECTED_FAMILY_IDS
assert tuple(family.family_id for family in iter_foundational_families()) == (
EXPECTED_FAMILY_IDS
)
def test_public_family_accessors() -> None:
quantity = get_foundational_family("binding.quantity_entity")
state_change = require_foundational_family("state_change.transition")
unary_delta = require_foundational_family("state_change.unary_delta")
assert quantity is not None
assert quantity.family_id == "binding.quantity_entity"
assert state_change.family_id == "state_change.transition"
assert unary_delta.family_id == "state_change.unary_delta"
assert get_foundational_family("missing.family") is None
with pytest.raises(KeyError, match="missing.family"):
require_foundational_family("missing.family")
def test_lookup_by_primary_relation_type() -> None:
quantity = get_foundational_family_by_relation_type("quantity_entity")
state_change = get_foundational_family_by_relation_type("state_change")
unary_delta = get_foundational_family_by_relation_type("unary_delta")
assert quantity is get_foundational_family("binding.quantity_entity")
assert state_change is get_foundational_family("state_change.transition")
assert unary_delta is get_foundational_family("state_change.unary_delta")
assert get_foundational_family_by_relation_type("missing_relation") is None
def test_registry_keys_are_unique() -> None:
families = iter_foundational_families()
family_ids = tuple(family.family_id for family in families)
relation_types = tuple(family.primary_relation_type for family in families)
assert len(family_ids) == len(set(family_ids))
assert len(relation_types) == len(set(relation_types))
def test_specs_are_frozen_and_only_authorized_slices_are_implemented() -> None:
for family in iter_foundational_families():
assert isinstance(family, FoundationalFamilySpec)
assert family.serving_allowed is False
assert "not serving" in family.serving_status.lower()
with pytest.raises(FrozenInstanceError):
family.display_name = "mutated" # type: ignore[misc]
assert require_foundational_family(
"binding.quantity_entity"
).implementation_authorized is True
assert require_foundational_family(
"state_change.transition"
).implementation_authorized is False
assert require_foundational_family(
"state_change.unary_delta"
).implementation_authorized is True
def test_required_adr_0224_fields_are_populated() -> None:
required_fields = (
"family_id",
"display_name",
"status",
"related_adrs",
"domains",
"summary",
"surface_chunk_patterns",
"semantic_neighborhood",
"construction_signatures",
"required_roles",
"optional_roles",
"hazards_confusers",
"frame_representation",
"contract_readiness_criteria",
"verification_style",
"refusal_conditions",
"cross_domain_evidence",
"current_state",
"target_state",
"serving_status",
"primary_relation_type",
"future_adapter",
)
for family in iter_foundational_families():
assert all(getattr(family, field) for field in required_fields)
assert "ADR-0224" in family.related_adrs
assert family.hazards_confusers
assert family.refusal_conditions
assert family.current_state != family.target_state
def test_each_family_has_at_least_two_non_math_evidence_examples() -> None:
math_domains = {
"arithmetic",
"arithmetic_quantitative",
"arithmetic_proportional",
"mathematics",
}
for family in iter_foundational_families():
non_math_evidence = tuple(
evidence
for evidence in family.cross_domain_evidence
if evidence.domain not in math_domains
)
assert len(non_math_evidence) >= 2
assert all(evidence.example for evidence in non_math_evidence)
assert all(evidence.expected_roles for evidence in non_math_evidence)
def test_registry_module_has_no_markdown_or_filesystem_loading_surface() -> None:
source_path = Path(foundational_families.__file__)
tree = ast.parse(source_path.read_text(encoding="utf-8"))
imported_modules = {
alias.name
for node in ast.walk(tree)
if isinstance(node, ast.Import)
for alias in node.names
}
imported_from_modules = {
node.module
for node in ast.walk(tree)
if isinstance(node, ast.ImportFrom) and node.module is not None
}
called_names = {
node.func.id
for node in ast.walk(tree)
if isinstance(node, ast.Call) and isinstance(node.func, ast.Name)
}
called_attributes = {
node.func.attr
for node in ast.walk(tree)
if isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute)
}
assert "pathlib" not in imported_modules | imported_from_modules
assert "markdown" not in imported_modules | imported_from_modules
assert "open" not in called_names
assert not ({"read_text", "read_bytes"} & called_attributes)