diff --git a/datatypes/epc/domain/epc.py b/datatypes/epc/domain/epc.py index 67b69dbaa..18d72b310 100644 --- a/datatypes/epc/domain/epc.py +++ b/datatypes/epc/domain/epc.py @@ -32,6 +32,10 @@ class Epc(Enum): return cls.F return cls.G + @classmethod + def from_sap_continuous(cls, score: float) -> "Epc": + raise NotImplementedError + def sap_lower_bound(self) -> int: """The minimum SAP rating in this band — the inverse of `from_sap_score` (A → 92, B → 81, C → 69, D → 55, E → 39, F → 21, diff --git a/tests/datatypes/epc/domain/test_epc.py b/tests/datatypes/epc/domain/test_epc.py index 062a4d78b..8731c5af3 100644 --- a/tests/datatypes/epc/domain/test_epc.py +++ b/tests/datatypes/epc/domain/test_epc.py @@ -28,6 +28,20 @@ def test_band_floor_round_trips_through_from_sap_score(band: Epc) -> None: assert Epc.from_sap_score(band.sap_lower_bound()) is band +def test_a_continuous_score_bands_on_its_published_rating() -> None: + # Arrange — callers holding a continuous SAP want the band the dwelling + # would be *published* in, which means rounding half up. Rounding half to + # even (Python's `round`) drops an exact x.5 at a band floor into the band + # below: a continuous 68.5 is published SAP 69 and so band C, not band D. + + # Act / Assert — the half point carries the score into the band above. + assert Epc.from_sap_continuous(68.5) is Epc.C + assert Epc.from_sap_continuous(54.5) is Epc.D + # And either side of a floor still bands the obvious way. + assert Epc.from_sap_continuous(68.49) is Epc.D + assert Epc.from_sap_continuous(69.4) is Epc.C + + @pytest.mark.parametrize("band", list(Epc)) def test_continuous_band_floor_is_where_the_published_rating_enters_the_band( band: Epc,