vpp-ai-platform/skills-py/tests/test_fixtures.py

38 lines
1.4 KiB
Python
Raw Normal View History

"""Dual-side contract test (docs/11 §3.2): the same golden fixtures the TS side
validates must validate against the generated pydantic models, and the same
invalid fixtures must be rejected. Disagreement between sides fails CI."""
import importlib
from pathlib import Path
import pytest
from pydantic import BaseModel, ValidationError
ROOT = Path(__file__).resolve().parents[2] / "contracts"
def model_for(name: str) -> type[BaseModel]:
module = importlib.import_module(f"vpp_contracts.{name}")
class_name = "".join(part.capitalize() for part in name.split("_"))
return getattr(module, class_name)
def cases(dirname: str) -> list[tuple[str, Path]]:
out = []
for schema_dir in sorted((ROOT / dirname).iterdir()):
for f in sorted(schema_dir.glob("*.json")):
out.append((schema_dir.name, f))
return out
@pytest.mark.parametrize("name,path", cases("fixtures"), ids=lambda p: str(p))
def test_golden_fixture_validates(name: str, path: Path) -> None:
# JSON-mode validation — exactly how a skill service receives these objects.
model_for(name).model_validate_json(path.read_text())
@pytest.mark.parametrize("name,path", cases("fixtures-invalid"), ids=lambda p: str(p))
def test_invalid_fixture_rejected(name: str, path: Path) -> None:
with pytest.raises(ValidationError):
model_for(name).model_validate_json(path.read_text())