mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Extended unit testing for roof class
This commit is contained in:
parent
66a18cf39d
commit
d5495ef775
3 changed files with 75 additions and 23 deletions
|
|
@ -3,16 +3,28 @@ from typing import Dict, Union
|
|||
|
||||
|
||||
class RoofAttributes:
|
||||
ROOF_TYPES = ['pitched', 'roof room', 'loft', 'flat', 'thatched', 'at rafters', 'assumed']
|
||||
DWELLING_ABOVE = ["another dwelling above", "other premises above"]
|
||||
|
||||
def __init__(self, description: str):
|
||||
"""
|
||||
:param description: Description of the roof.
|
||||
"""
|
||||
self.description: str = description
|
||||
|
||||
self.description: str = description.lower()
|
||||
|
||||
if not description or not any(
|
||||
rt in self.description for rt in self.ROOF_TYPES + self.DWELLING_ABOVE + ["average thermal transmittance"]
|
||||
):
|
||||
raise ValueError('Invalid description')
|
||||
|
||||
def process(self) -> Dict[str, Union[float, str, bool, None]]:
|
||||
|
||||
if not self.description:
|
||||
raise ValueError("Description is empty")
|
||||
|
||||
result: Dict[str, Union[float, str, bool, None]] = {}
|
||||
description = self.description.lower()
|
||||
description = self.description
|
||||
|
||||
# thermal transmittance
|
||||
match = re.search(r"average thermal transmittance (-?\d+\.\d+)\s(w/m-¦k)", description)
|
||||
|
|
@ -26,9 +38,8 @@ class RoofAttributes:
|
|||
result['thermal_transmittance_unit'] = None
|
||||
|
||||
# roof type
|
||||
roof_types = ['pitched', 'roof room', 'loft', 'flat', 'thatched', 'at rafters', 'assumed']
|
||||
|
||||
for rt in roof_types:
|
||||
for rt in self.ROOF_TYPES:
|
||||
result[f'is_{rt.replace(" ", "_")}'] = rt in description
|
||||
# Remove the roof type from the description
|
||||
description = description.replace(rt, "")
|
||||
|
|
@ -36,7 +47,7 @@ class RoofAttributes:
|
|||
result["has_dwelling_above"] = (
|
||||
"another dwelling above" in description or "other premises above" in description
|
||||
)
|
||||
for dwelling_above in ["another dwelling above", "other premises above"]:
|
||||
for dwelling_above in self.DWELLING_ABOVE:
|
||||
description = description.replace(dwelling_above, "")
|
||||
|
||||
result["is_valid"] = "invalid" not in description
|
||||
|
|
|
|||
33
epc_data/tests/test_epc_clean.py
Normal file
33
epc_data/tests/test_epc_clean.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import pytest
|
||||
import pickle
|
||||
from epc_data.EpcClean import EpcClean
|
||||
from pathlib import Path
|
||||
from epc_data.tests.test_data.test_roof_attributes_cases import clean_roof_test_cases
|
||||
from epc_data.attributes.RoofAttributes import RoofAttributes
|
||||
|
||||
# For local testing
|
||||
if __file__ == "<input>":
|
||||
input_data_path = Path("./epc_data/tests/test_data/EpcClean_inputs.obj")
|
||||
else:
|
||||
current_file_path = Path(__file__)
|
||||
input_data_path = current_file_path.parent / 'test_data' / 'EpcClean_inputs.obj'
|
||||
|
||||
|
||||
class TestEpcClean:
|
||||
|
||||
@staticmethod
|
||||
def load_data(path):
|
||||
with open(path, "rb") as file:
|
||||
return pickle.load(file)
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup_class(self):
|
||||
self.cleaner = EpcClean(self.load_data(input_data_path))
|
||||
|
||||
def test_clean(self):
|
||||
self.cleaner.clean()
|
||||
assert len(self.cleaner.cleaned["roof-description"]) == len(self.cleaner.unique_vals["roof-description"])
|
||||
|
||||
def test__init_empty_cleaned_obj(self):
|
||||
self.cleaner._init_empty_cleaned_obj()
|
||||
assert all([len(values) == 0 for values in self.cleaner.cleaned.values()])
|
||||
|
|
@ -13,24 +13,7 @@ else:
|
|||
input_data_path = current_file_path.parent / 'test_data' / 'EpcClean_inputs.obj'
|
||||
|
||||
|
||||
class TestEpcClean:
|
||||
|
||||
@staticmethod
|
||||
def load_data(path):
|
||||
with open(path, "rb") as file:
|
||||
return pickle.load(file)
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup_class(self):
|
||||
self.cleaner = EpcClean(self.load_data(input_data_path))
|
||||
|
||||
def test_clean(self):
|
||||
self.cleaner.clean()
|
||||
assert len(self.cleaner.cleaned["roof-description"]) == len(self.cleaner.unique_vals["roof-description"])
|
||||
|
||||
def test__init_empty_cleaned_obj(self):
|
||||
self.cleaner._init_empty_cleaned_obj()
|
||||
assert all([len(values) == 0 for values in self.cleaner.cleaned.values()])
|
||||
class TestRoofAttributes:
|
||||
|
||||
def test_clean_roof(self):
|
||||
result = RoofAttributes('Pitched, 270 mm loft insulation').process()
|
||||
|
|
@ -84,3 +67,28 @@ class TestEpcClean:
|
|||
|
||||
for k in expected_output:
|
||||
assert result[k] == expected_output[k]
|
||||
|
||||
def test_clean_roof_invalid(self):
|
||||
with pytest.raises(ValueError):
|
||||
RoofAttributes('').process()
|
||||
with pytest.raises(ValueError):
|
||||
RoofAttributes('nonsense string').process()
|
||||
|
||||
def test_clean_roof_edge_cases(self):
|
||||
# Insulation thickness edge case
|
||||
assert RoofAttributes('Pitched, 99999 mm loft insulation').process()['insulation_thickness'] == "99999"
|
||||
assert RoofAttributes('Pitched, 1 mm loft insulation').process()['insulation_thickness'] == "1"
|
||||
|
||||
# Special characters in the description - implement this later
|
||||
# result = RoofAttributes('Pitched, **270** mm loft insulation').process()
|
||||
# assert result['insulation_thickness'] == 270
|
||||
|
||||
def test_clean_roof_type(self):
|
||||
for roof_type in ['pitched', 'roof room', 'loft', 'flat', 'thatched', 'at rafters', 'assumed']:
|
||||
result = RoofAttributes(f'{roof_type}, 200 mm insulation').process()
|
||||
assert result[f'is_{roof_type.replace(" ", "_")}'] is True
|
||||
|
||||
def test_clean_roof_thermal_transmittance(self):
|
||||
result = RoofAttributes('Pitched, 200 mm insulation, average thermal transmittance 0.13 w/m-¦k').process()
|
||||
assert result['thermal_transmittance'] == 0.13
|
||||
assert result['thermal_transmittance_unit'] == 'w/m-¦k'
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue