test(modelling): lighting before/after cascade pins (001431) at 1e-4

Slice 3 of the lighting generator (ADR-0023): two real Elmhurst before/after
cascade pins, sourced from the low_energy_lighting recommendation folder. Both
close cleanly at 1e-4 with NO xfail — lighting changes only bulb counts →
Appendix L (232), no fabric coupling (contrast glazing's draught-proofing).
  - zero existing LEDs: 20 incandescent → 20 LED
  - some existing LEDs: 5 LED + 15 incandescent → 20 LED (partial-upgrade path)
The overlay-emits-correct-counts assertion lives in the Slice 2 unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-05 12:27:36 +00:00
parent dbbfb8ea28
commit ca397e1e3f
5 changed files with 39 additions and 0 deletions

View file

@ -37,6 +37,7 @@ from domain.modelling.generators.solid_wall_recommendation import (
recommend_solid_wall,
)
from domain.modelling.generators.glazing_recommendation import recommend_glazing
from domain.modelling.generators.lighting_recommendation import recommend_lighting
from domain.modelling.scoring.overlay_applicator import apply_simulations
from domain.modelling.recommendation import MeasureOption
from domain.sap10_calculator.calculator import Sap10Calculator, SapResult
@ -537,3 +538,41 @@ def test_secondary_glazing_overlay_reproduces_the_relodged_after() -> None:
_assert_overlay_reproduces_after(
before, after, recommendation.options[0].overlay
)
def test_lighting_overlay_reproduces_the_relodged_after_zero_existing_leds() -> None:
# Arrange — a dwelling with no LEDs (20 incandescent); the after re-lodges
# all 20 as LED. Lighting only changes bulb counts → Appendix L (232), with
# no fabric coupling, so the full-SAP pin closes cleanly.
before: EpcPropertyData = parse_recommendation_summary(
"low_energy_lighting_zero_leds_001431_before.pdf"
)
after: EpcPropertyData = parse_recommendation_summary(
"low_energy_lighting_zero_leds_001431_after.pdf"
)
recommendation: Recommendation | None = recommend_lighting(before, _AnyProduct())
assert recommendation is not None
# Act / Assert
_assert_overlay_reproduces_after(
before, after, recommendation.options[0].overlay
)
def test_lighting_overlay_reproduces_the_relodged_after_some_existing_leds() -> None:
# Arrange — a dwelling with some LEDs already (5 LED + 15 incandescent); the
# after re-lodges all 20 as LED. Exercises the partial-upgrade path: the
# overlay tops led up to the total rather than starting from zero.
before: EpcPropertyData = parse_recommendation_summary(
"low_energy_lighting_some_leds_001431_before.pdf"
)
after: EpcPropertyData = parse_recommendation_summary(
"low_energy_lighting_some_leds_001431_after.pdf"
)
recommendation: Recommendation | None = recommend_lighting(before, _AnyProduct())
assert recommendation is not None
# Act / Assert
_assert_overlay_reproduces_after(
before, after, recommendation.options[0].overlay
)