Model/tests/harness/test_cohort.py
Khalim Conn-Kowlessar 8b5ab1c59e feat(modelling): turnkey offline cohort script (tables + CSV)
CertResult now carries its Plan (with flat baseline/post-SAP/measures
properties), and `format_cohort_csv` renders one browsable row per cert
(SAP transition, band, measures, cost, bill saving, valuation %, error).
`scripts/run_modelling_cohort.py` is turnkey: no args runs the committed
golden cohort, prints a sense-check table for the first measure-bearing
certs (a capped preview so a large dump doesn't flood the terminal), the
summary, and writes modelling_cohort.csv (gitignored). Point it at the
EPC dump when it lands.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 09:30:53 +00:00

50 lines
1.6 KiB
Python

"""Run a directory of API-shaped EPC JSONs through Modelling, offline."""
from __future__ import annotations
from pathlib import Path
from harness.cohort import (
CertResult,
format_cohort_csv,
format_cohort_summary,
run_cohort,
)
_GOLDEN = (
Path(__file__).resolve().parents[1]
/ "domain/sap10_calculator/rdsap/fixtures/golden"
)
def test_run_cohort_models_each_api_json_offline() -> None:
# Arrange — two real API-shaped EPC certs (identical to the EPC response).
paths: list[Path] = sorted(_GOLDEN.glob("*.json"))[:2]
assert len(paths) == 2
# Act — no database, no network.
results: list[CertResult] = run_cohort(paths, goal_band="C")
# Assert — one result per cert, each either modelled or carrying its error.
assert len(results) == 2
for result in results:
assert result.name
assert result.error is not None or result.measures >= 0
# The summary renders without raising and counts the cohort.
summary: str = format_cohort_summary(results)
assert "2" in summary
def test_cohort_carries_each_plan_and_renders_a_csv() -> None:
# Arrange / Act
paths: list[Path] = sorted(_GOLDEN.glob("*.json"))[:3]
results: list[CertResult] = run_cohort(paths)
# Assert — each cert either modelled (carries its Plan) or errored.
for result in results:
assert (result.plan is not None) != (result.error is not None)
# CSV: a header row plus one row per cert, browsable in a spreadsheet.
csv: str = format_cohort_csv(results)
lines: list[str] = csv.splitlines()
assert lines[0].startswith("cert,")
assert len(lines) == len(results) + 1