Model/tests/domain/modelling/test_window_extraction_001431.py
Khalim Conn-Kowlessar f68cea27c9 fix(extractor): capture all 17 openable §11 windows on cert 001431
The Modelling glazing overlay's draught-proofing recompute (RdSAP 10 §8.1 —
a count over openable windows + doors) needs every openable window captured
with its draught_proofed flag. cert 001431's §11 lodges 17 windows but only
14 surfaced, via two distinct gaps:

1. Extractor (_extract_windows_from_layout): the one "Double glazing, known
   data" row whose §11 Data-Source cell is "BFRC data" was rejected — it is
   laid out as a standalone keyword line with the U-value on the next line
   and lodges no Frame Type/Factor/Gap cells, so it never matched the joined
   "<source> <U>" Manufacturer-line shape. Now anchored by a standalone
   data-source form, with the RdSAP 10 §3.7 default frame factor (0.7) for
   the absent frame cell.

2. Mapper (_is_elmhurst_roof_window): the two "Double pre 2002" rows
   (U 3.1 / 3.4 > 3.0) were reclassified as roof windows by the U-value
   backstop even though both are lodged on an "External wall". A window
   lodged on a wall is vertical by definition; guard the U-value backstop so
   it only fires when location/BP give no roof signal. The backstop's only
   pinned cert (000516 W6) hand-builds its sap_roof_windows and so is
   unaffected.

With both closed: 17 sap_windows, 0 misrouted to sap_roof_windows, 14
draught-proofed — reconstructing Elmhurst's lodged 84% (16/19 = (14 windows
+ 2 doors) / (17 windows + 2 doors)). Full calculator + modelling +
orchestration suites green (1885 pass); the 2 glazing draught-proofing
xfails remain (the overlay recompute is the glazing agent's front).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 14:33:25 +00:00

52 lines
2.2 KiB
Python

"""Window-extraction completeness pin for cert 001431.
The Modelling glazing overlay's draught-proofing recompute (RdSAP 10 §8.1 — a
count over openable windows + doors) needs every openable §11 window captured
with its `draught_proofed` flag. The Elmhurst Summary §11 block lodges 17
openable windows; two extraction gaps previously surfaced only 14:
1. The extractor rejected the one "Double glazing, known data" row whose
data-source cell is "BFRC data" (laid out as its own line, with no frame
factor) — it does not fit the `<data-source> <U>` Manufacturer-line shape.
2. The mapper's `_is_elmhurst_roof_window` reclassified the two "Double pre
2002" rows (U 3.1 / 3.4 > 3.0) as roof windows, even though both are
lodged on an "External wall" — a false positive of the U-value backstop.
With both closed, all 17 windows are `sap_windows` (none mis-routed to
`sap_roof_windows`), and 14 carry `draught_proofed=True` — reconstructing
Elmhurst's lodged 84% draught-proofing (16/19 = (14 windows + 2 doors) /
(17 windows + 2 doors)).
"""
from __future__ import annotations
from datatypes.epc.domain.epc_property_data import EpcPropertyData
from tests.domain.modelling._elmhurst_recommendation import (
parse_recommendation_summary,
)
def test_all_17_openable_windows_captured_on_001431() -> None:
# Arrange / Act
epc: EpcPropertyData = parse_recommendation_summary(
"double_glazing_001431_before.pdf"
)
# Assert — every openable §11 window is captured as a vertical window;
# none of the wall-lodged rows leak into the roof-window list.
assert len(epc.sap_windows) == 17
assert not epc.sap_roof_windows # None or empty — no wall window misrouted
def test_draughtproofing_count_reconstructs_lodged_84_percent() -> None:
# Arrange / Act
epc: EpcPropertyData = parse_recommendation_summary(
"double_glazing_001431_before.pdf"
)
# Assert — 14 of the 17 openable windows are draught-proofed, the numerator
# behind Elmhurst's lodged 84% (with the 2 lodged draught-proofed doors).
draughtproofed: int = sum(
1 for window in epc.sap_windows if window.draught_proofed
)
assert draughtproofed == 14