From b6172987bdc4ef7beea2e057647b25ded72a486b Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Thu, 23 Jul 2026 13:26:19 +0000 Subject: [PATCH] =?UTF-8?q?Carry=20the=20sloping-ceiling=20insulation=20de?= =?UTF-8?q?pth=20into=20the=20overlay=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- tests/domain/epc/test_roof_type_overlay.py | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/domain/epc/test_roof_type_overlay.py b/tests/domain/epc/test_roof_type_overlay.py index aab9f9cd7..23d39890a 100644 --- a/tests/domain/epc/test_roof_type_overlay.py +++ b/tests/domain/epc/test_roof_type_overlay.py @@ -160,6 +160,46 @@ def test_pitched_unknown_loft_drives_the_pitched_age_band_default() -> None: assert overlay.roof_insulation_thickness is None +_SLOPING_CEILING_THICKNESS_MEMBERS: list[tuple[RoofType, int]] = [ + (RoofType.PITCHED_SLOPING_CEILING_12MM, 12), + (RoofType.PITCHED_SLOPING_CEILING_25MM, 25), + (RoofType.PITCHED_SLOPING_CEILING_50MM, 50), + (RoofType.PITCHED_SLOPING_CEILING_75MM, 75), + (RoofType.PITCHED_SLOPING_CEILING_100MM, 100), + (RoofType.PITCHED_SLOPING_CEILING_125MM, 125), + (RoofType.PITCHED_SLOPING_CEILING_150MM, 150), + (RoofType.PITCHED_SLOPING_CEILING_175MM, 175), + (RoofType.PITCHED_SLOPING_CEILING_200MM, 200), + (RoofType.PITCHED_SLOPING_CEILING_225MM, 225), + (RoofType.PITCHED_SLOPING_CEILING_250MM, 250), + (RoofType.PITCHED_SLOPING_CEILING_270MM, 270), + (RoofType.PITCHED_SLOPING_CEILING_300MM, 300), + (RoofType.PITCHED_SLOPING_CEILING_350MM, 350), + (RoofType.PITCHED_SLOPING_CEILING_400MM, 400), + (RoofType.PITCHED_SLOPING_CEILING_400_PLUS, 400), +] + + +@pytest.mark.parametrize(("member", "expected_mm"), _SLOPING_CEILING_THICKNESS_MEMBERS) +def test_every_sloping_ceiling_thickness_member_carries_its_depth( + member: RoofType, expected_mm: int +) -> None: + # ADR-0066: a known-depth sloping ceiling scores on Table 17 col (1a) + # "insulated slope" — the depth must reach the overlay (via + # `roof_insulation_thickness`) alongside the sloping-ceiling shape, so a + # landlord-stored member scores its slope, not the age-band default. `400+` + # carries 400 (the top tabulated row). + + # Act + simulation = roof_overlay_for(member.value, 0) + + # Assert + assert simulation is not None + overlay = simulation.building_parts[BuildingPartIdentifier.MAIN] + assert overlay.roof_construction_type == "Pitched, sloping ceiling" + assert overlay.roof_insulation_thickness == expected_mm + + def test_sloping_ceiling_as_built_defers_to_the_age_band_default() -> None: # ADR-0066: a pitched sloping ceiling has no loft void, so "as built" defers # the U-value to the construction age band (Table 18 col (3) via the