from __future__ import annotations import pytest from domain.epc.property_overrides.roof_type import RoofType from domain.epc.property_overrides.roof_party_ceiling_guard import ( roof_party_ceiling_guard, ) def test_party_ceiling_marker_with_a_trailing_depth_resolves_to_the_party_ceiling_member() -> None: # Arrange — the bug: a party ceiling ("another dwelling above") carrying a # trailing loft depth the LLM misreads as an external pitched roof. description = "another dwelling above: 100mm" # Act result = roof_party_ceiling_guard(description) # Assert — it is a party ceiling (~0 heat loss), not a Pitched roof. assert result is RoofType.ADJACENT_ANOTHER_DWELLING_ABOVE @pytest.mark.parametrize( ("description", "expected"), [ ("same dwelling above: unknown", RoofType.ADJACENT_SAME_DWELLING_ABOVE), ("other premises above", RoofType.ADJACENT_OTHER_PREMISES_ABOVE), ("another premises above: 150mm", RoofType.ADJACENT_ANOTHER_PREMISES_ABOVE), # the unspaced source form and the "Another Premises Above" member value # both normalise to the same marker. ("Another Premises Above", RoofType.ADJACENT_ANOTHER_PREMISES_ABOVE), ("samedwellingabove: 300mm", RoofType.ADJACENT_SAME_DWELLING_ABOVE), ], ) def test_every_party_ceiling_marker_variant_resolves_to_its_member( description: str, expected: RoofType ) -> None: # Act result = roof_party_ceiling_guard(description) # Assert assert result is expected @pytest.mark.parametrize( "description", [ "pitched, normal loft access: 100mm", "flat: 150mm", "pitched with sloping ceiling: unknown", "roof room(s), insulated", ], ) def test_a_genuine_roof_description_is_left_to_the_llm(description: str) -> None: # A non-party-ceiling roof must return None so the LLM classifier still # resolves it — the guard only claims the markers it is certain about. # Act result = roof_party_ceiling_guard(description) # Assert assert result is None