diff --git a/datatypes/epc/domain/epc.py b/datatypes/epc/domain/epc.py index ae4fd8241..6c65cf0a9 100644 --- a/datatypes/epc/domain/epc.py +++ b/datatypes/epc/domain/epc.py @@ -46,3 +46,6 @@ class Epc(Enum): Epc.G: 1, } return bounds[self] + + def sap_lower_bound_continuous(self) -> float: + raise NotImplementedError diff --git a/tests/datatypes/epc/domain/test_epc.py b/tests/datatypes/epc/domain/test_epc.py index 474c5e890..062a4d78b 100644 --- a/tests/datatypes/epc/domain/test_epc.py +++ b/tests/datatypes/epc/domain/test_epc.py @@ -4,6 +4,8 @@ target).""" from __future__ import annotations +from decimal import ROUND_HALF_UP, Decimal + import pytest from datatypes.epc.domain.epc import Epc @@ -24,3 +26,27 @@ def test_sap_lower_bound_returns_the_band_floor() -> None: def test_band_floor_round_trips_through_from_sap_score(band: Epc) -> None: # Act / Assert — a band's floor scores back to that band. assert Epc.from_sap_score(band.sap_lower_bound()) is band + + +@pytest.mark.parametrize("band", list(Epc)) +def test_continuous_band_floor_is_where_the_published_rating_enters_the_band( + band: Epc, +) -> None: + # Arrange — the Optimiser judges "reached band X" on the calculator's + # *continuous* SAP, but a dwelling is in a band by its *published* rating + # (the half-up-rounded integer). The continuous floor is the point those two + # agree: the lowest continuous score whose published rating is in the band. + # Asserted against the real publishing path (round half up → from_sap_score) + # rather than an arithmetic literal, so the two cannot drift apart. + def published_band(continuous: float) -> Epc: + rounded = int(Decimal(continuous).quantize(Decimal("1"), rounding=ROUND_HALF_UP)) + return Epc.from_sap_score(rounded) + + # Act + continuous_floor: float = band.sap_lower_bound_continuous() + + # Assert — at the floor the dwelling publishes into the band; a hair below + # it publishes into a worse one. (Band G has no worse band to fall into.) + assert published_band(continuous_floor) is band + if band is not Epc.G: + assert published_band(continuous_floor - 0.01) is not band