Extract the PasHub detailed room-in-roof block 🟥

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-14 22:05:31 +00:00
parent f067f94ec9
commit 518c682793

View file

@ -22,6 +22,7 @@ from datatypes.epc.surveys.pashub_rdsap_site_notes import (
MainBuildingMeasurements,
MainHeating,
PvArrayDetail,
RoomInRoofSurfaceDetail,
Renewables,
RoomCountElements,
RoofSpace,
@ -705,6 +706,116 @@ class TestRenewablesPvArrays:
assert renewables.pv_arrays is None
class TestRoofSpaceRoomInRoof:
""""Are there rooms in the roof? Yes" lodges an RdSAP §3.10 detailed RIR
block (age, floor area, gables/slopes/common walls/flat ceiling as
length × height). The extractor must capture it dropped, ~32 of RIR
surfaces are billed as well-insulated loft (issue #1590 bug 5; lines
verbatim from accuracy fixture deal 499617935574, incl. the mid-block
"Page 7" break).
"""
_RIR_BLOCK = [
"Are there rooms in the roof?",
"Yes",
"Roof room age range:",
"B: 1900 - 1929",
"Floor area of room in roof:",
"32.35 m²",
"Are details of the room in roof known?",
"Yes",
"Are details of the gable walls known?",
"Gable wall 1 & 2",
"Gable wall 1 length:",
"6.64 m",
"Gable wall 1 height:",
"2.74 m",
"Page 7",
"Gable wall 1 U-Value:",
"Unknown",
"Gable wall 1 type:",
"Exposed",
"Gable wall 2 length:",
"6.64 m",
"Gable wall 2 height:",
"2.74 m",
"Gable wall 2 type:",
"Party",
"Are details of the stud walls known?",
"None",
"Are details of the slope walls known?",
"Slope 1 & 2",
"Slope 1 length:",
"4.94 m",
"Slope 1 height:",
"1.73 m",
"Slope 2 length:",
"5 m",
"Slope 2 height:",
"2.95 m",
"Are details of the common walls known?",
"Common wall 1 & 2",
"Common wall 1 length:",
"4.94 m",
"Common wall 1 height:",
"1.45 m",
"Common wall 2 length:",
"4.94 m",
"Common wall 2 height:",
"1.3 m",
"Are details of the flat ceiling known?",
"Flat ceiling 1",
"Flat ceiling 1 length:",
"4.94 m",
"Flat ceiling 1 height:",
"5.17 m",
]
def test_room_in_roof_block_is_captured(self) -> None:
# Arrange — fixture 1's roof space with the RIR block spliced in place
# of its "rooms in the roof? No" lodging.
lines = load_text_fixture()
idx = lines.index("Are there rooms in the roof?")
spliced = lines[:idx] + self._RIR_BLOCK + lines[idx + 2 :]
# Act
detail = PasHubRdSapSiteNotesExtractor(
spliced
).extract_roof_space().main_building
# Assert
assert detail.rooms_in_roof is True
rir = detail.room_in_roof
assert rir is not None
assert rir.age_range == "B: 1900 - 1929"
assert rir.floor_area_m2 == 32.35
assert rir.gables == [
RoomInRoofSurfaceDetail(length_m=6.64, height_m=2.74, gable_type="Exposed"),
RoomInRoofSurfaceDetail(length_m=6.64, height_m=2.74, gable_type="Party"),
]
assert rir.slopes == [
RoomInRoofSurfaceDetail(length_m=4.94, height_m=1.73),
RoomInRoofSurfaceDetail(length_m=5.0, height_m=2.95),
]
assert rir.common_walls == [
RoomInRoofSurfaceDetail(length_m=4.94, height_m=1.45),
RoomInRoofSurfaceDetail(length_m=4.94, height_m=1.3),
]
assert rir.flat_ceilings == [
RoomInRoofSurfaceDetail(length_m=4.94, height_m=5.17),
]
def test_no_rooms_in_roof_leaves_detail_absent(self) -> None:
# Arrange / Act — fixture 1 as lodged ("No").
detail = PasHubRdSapSiteNotesExtractor(
load_text_fixture()
).extract_roof_space().main_building
# Assert
assert detail.rooms_in_roof is False
assert detail.room_in_roof is None
class TestRoomCountElements:
@pytest.fixture
def rce(self) -> RoomCountElements: