CanLex / tests /test_curated_schema.py
Beemer
Sprint tests (106 green), rewritten README, maintainer RUNBOOK, findings doc resolved
724ca05
Raw
History Blame Contribute Delete
3.86 kB
"""Schema validation of the REAL curated datasets.
test_commentary.py deliberately exercises the renderer on a minimal in-memory
dataset; nothing previously validated the actual shipped JSON, so a hand-edit
typo in the 51-jurisdiction survey surfaced only at runtime in production.
"""
import json
import unittest
from pathlib import Path
CURATED = Path(__file__).resolve().parent.parent / "data" / "curated"
VERDICTS = {"yes", "likely-yes", "likely-no", "no", "fact-specific", "depends"}
STATUSES = {"settled", "judicially-considered", "guidance-only", "no-authority"}
US_STATES = {
"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado",
"Connecticut", "Delaware", "District of Columbia", "Florida", "Georgia",
"Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky",
"Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan",
"Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada",
"New Hampshire", "New Jersey", "New Mexico", "New York",
"North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon",
"Pennsylvania", "Rhode Island", "South Carolina", "South Dakota",
"Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington",
"West Virginia", "Wisconsin", "Wyoming", "general",
}
class DispositionsSchemaTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.data = json.loads(
(CURATED / "us_dispositions.json").read_text(encoding="utf-8"))
def test_reviewed_date_present(self):
self.assertRegex(self.data.get("reviewed", ""), r"^\d{4}-\d{2}-\d{2}$")
def test_entries_have_required_keys(self):
for e in self.data["dispositions"]:
for key in ("id", "names", "is_conviction", "status", "analysis"):
self.assertIn(key, e, f"{e.get('id', '?')} missing {key}")
self.assertTrue(e["names"], f"{e['id']}: empty names")
def test_verdicts_are_legal_values(self):
for e in self.data["dispositions"]:
self.assertIn(e["is_conviction"], VERDICTS, e["id"])
self.assertIn(e["status"], STATUSES, e["id"])
for v in e.get("state_variations", []):
if v.get("is_conviction"):
self.assertIn(v["is_conviction"], VERDICTS,
f"{e['id']}/{v.get('state')}")
def test_state_names_valid(self):
for e in self.data["dispositions"]:
for v in e.get("state_variations", []):
self.assertIn(v["state"], US_STATES,
f"{e['id']}: unknown state {v['state']!r}")
def test_authorities_carry_citations(self):
for e in self.data["dispositions"]:
for a in e.get("authorities", []):
self.assertTrue(a.get("cite"), f"{e['id']}: authority no cite")
def test_renderer_accepts_every_entry(self):
from canlex.commentary import _entry_text
for e in self.data["dispositions"]:
text = _entry_text(e)
self.assertGreater(len(text), 100, e["id"])
class EquivalencySchemaTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.data = json.loads(
(CURATED / "us_equivalency.json").read_text(encoding="utf-8"))
def test_pairings_have_required_keys(self):
for p in self.data["pairings"]:
for key in ("id", "us_terms", "canadian_offence", "penalty",
"branch", "status", "analysis"):
self.assertIn(key, p, f"{p.get('id', '?')} missing {key}")
self.assertTrue(p["us_terms"], f"{p['id']}: empty us_terms")
def test_methodology_framework_present(self):
ids = {m["id"] for m in self.data.get("methodology", [])}
self.assertIn("equivalency-framework", ids)
if __name__ == "__main__":
unittest.main()