import json import math import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[2] / "reports/site-models/cedar-gate/2026-10-21" def seg_dist(p, a, b): dx, dy = b[0] - a[0], b[1] - a[1] l2 = dx * dx + dy * dy t = 0 if not l2 else max(0, min(1, ((p[0] - a[0]) * dx + (p[1] - a[1]) * dy) / l2)) return math.hypot(p[0] - a[0] - t * dx, p[1] - a[1] - t * dy) class CedarGateServices(unittest.TestCase): @classmethod def setUpClass(cls): cls.s = json.loads((ROOT / "services.json").read_text()) cls.report = json.loads((ROOT / "services-extraction.json").read_text()) def test_pipes_join_known_structures_and_fall_downhill(self): sw = {x["name"] for x in self.s["stormwater"]["structures"]} for p in self.s["stormwater"]["pipes"]: self.assertIn(p["from"], sw); self.assertIn(p["to"], sw) self.assertGreaterEqual(p["ilFrom"], p["ilTo"]); self.assertGreater(p["length"], 0); self.assertGreater(p["dia"], 0) sr = {x["id"] for x in self.s["sewer"]["manholes"]} for p in self.s["sewer"]["pipes"]: self.assertIn(p["from"], sr); self.assertIn(p["to"], sr) self.assertGreaterEqual(p["ilFrom"], p["ilTo"]) def test_sizes_match_the_plan_labels(self): dia = sorted(p["dia"] for p in self.s["stormwater"]["pipes"] if p["run"] == 1) self.assertEqual(dia, [675, 750, 750, 825, 1350, 1350, 1500, 1500, 1500]) # the eight SW-M1 plan labels plus the short outlet pipe self.assertTrue(all(p["dia"] in (160, 250) for p in self.s["sewer"]["pipes"])) def test_structures_sit_on_their_plan_routes(self): routes = [r for r in self.s["planRoutes"] if r["service"] == "stormwater"] for q in self.s["stormwater"]["structures"]: d = min(seg_dist((q["e"], q["n"]), r["pts"][i], r["pts"][i + 1]) for r in routes for i in range(len(r["pts"]) - 1)) self.assertLess(d, 3.5, q["name"]) def test_superseded_sewer_copies_are_dropped(self): titles = [r["title"] for r in self.report["runs"] if r["kind"] == "sewer"] self.assertEqual(sorted(titles), ["SE-2", "SE-3", "SE-M1"]) self.assertTrue(all(r["verifiedOnIssuedSheets"] for r in self.report["runs"] if r["kind"] == "sewer")) self.assertEqual(len(self.report["discarded"]), 3) if __name__ == "__main__": unittest.main()