def test_string_fails_validation() -> None: raw_xml = '<Foo />' data = {'raw_xml': raw_xml} checker = validator.DwellingValidator( {'raw_xml': { 'type': 'xml', 'required': True }}) assert not checker.validate(data)
def test_validates_xml() -> None: raw_xml = '<Foo />' doc = element.Element.from_string(raw_xml) data = {'raw_xml': doc} checker = validator.DwellingValidator( {'raw_xml': { 'type': 'xml', 'required': True }}) assert checker.validate(data)
def test_heated_floor_area_snippet(house: element.Element) -> None: output = snippets.snip_house(house) checker = validator.DwellingValidator( {'heated_floor': { 'type': 'xml', 'coerce': 'parse_xml' }}, allow_unknown=True) doc = {'windows': output.heated_floor_area} assert checker.validate(doc)
def test_coerce_to_xml() -> None: raw_xml = '<Foo />' data = {'raw_xml': raw_xml} checker = validator.DwellingValidator( {'raw_xml': { 'type': 'xml', 'required': True, 'coerce': 'parse_xml' }}) assert checker.validate(data) assert isinstance(checker.document['raw_xml'], element.Element)
def from_row(cls, row: typing.Dict[str, typing.Any]) -> 'ParsedDwellingDataRow': checker = validator.DwellingValidator(cls._SCHEMA, allow_unknown=True) if not checker.validate(row): error_keys = ', '.join(checker.errors.keys()) raise InvalidInputDataError(f'Validator failed on keys: {error_keys}') parsed = checker.document codes = code.Codes.from_data(parsed['codes']) foundations = [] foundations.extend( [basement.Basement.from_data(basement_node) for basement_node in parsed['basements']] ) foundations.extend( [basement.Basement.from_data(crawlspace_node) for crawlspace_node in parsed['crawlspaces']] ) foundations.extend( [basement.Basement.from_data(slab_node) for slab_node in parsed['slabs']] ) return ParsedDwellingDataRow( eval_id=parsed['EVAL_ID'], eval_type=EvaluationType.from_code(parsed['EVAL_TYPE']), entry_date=parsed['ENTRYDATE'].date(), creation_date=parsed['CREATIONDATE'], modification_date=parsed['MODIFICATIONDATE'], year_built=parsed['YEARBUILT'], city=parsed['CLIENTCITY'], region=Region.from_data(parsed['HOUSEREGION']), forward_sortation_area=parsed['forwardSortationArea'], ceilings=[ceiling.Ceiling.from_data(ceiling_node) for ceiling_node in parsed['ceilings']], floors=[floor.Floor.from_data(floor_node) for floor_node in parsed['floors']], walls=[wall.Wall.from_data(wall_node, codes.wall) for wall_node in parsed['walls']], doors=[door.Door.from_data(door_node) for door_node in parsed['doors']], windows=[window.Window.from_data(window_node, codes.window) for window_node in parsed['windows']], heated_floor=heated_floor_area.HeatedFloorArea.from_data(parsed['heatedFloorArea']) if parsed['heatedFloorArea'] is not None else None, water_heatings=water_heating.WaterHeating.from_data(parsed['waterHeatings']) if parsed['waterHeatings'] is not None else [], ventilations=[ventilation.Ventilation.from_data(ventilation_node) for ventilation_node in parsed['ventilations']], heating_system=heating.Heating.from_data(parsed['heating_cooling']) if parsed['heating_cooling'] is not None else None, foundations=foundations, ers_rating=parsed['ersRating'], energy_upgrades=[upgrade.Upgrade.from_data(upgrade_node) for upgrade_node in parsed['upgrades']], file_id=parsed['BUILDER'], )
def test_wall_snippet(house: element.Element) -> None: output = snippets.snip_house(house) assert len(output.walls) == 3 checker = validator.DwellingValidator( { 'walls': { 'type': 'list', 'required': True, 'schema': { 'type': 'xml', 'coerce': 'parse_xml' } } }, allow_unknown=True) doc = {'walls': output.walls} assert checker.validate(doc)
def test_window_code_snippet(code: element.Element) -> None: output = snippets.snip_codes(code) assert len(output.wall) == 2 checker = validator.DwellingValidator( { 'codes': { 'type': 'list', 'required': True, 'schema': { 'type': 'xml', 'coerce': 'parse_xml' } } }, allow_unknown=True) doc = {'codes': output.window} assert checker.validate(doc)
def test_embedded_xml() -> None: raw_xml = '<Foo />' data = {'raw_xml': [raw_xml, raw_xml]} schema = { 'raw_xml': { 'type': 'list', 'required': True, 'schema': { 'type': 'xml', 'coerce': 'parse_xml' } } } checker = validator.DwellingValidator(schema) assert checker.validate(data) assert isinstance(checker.document['raw_xml'], list) assert len(checker.document['raw_xml']) == 2 assert isinstance(checker.document['raw_xml'][0], element.Element)
def test_upgrades_snippet(energy_upgrades: element.Element) -> None: output = snippets.snip_energy_upgrades(energy_upgrades) assert len(output.upgrades) == 12 checker = validator.DwellingValidator( { 'upgrades': { 'type': 'list', 'required': True, 'schema': { 'type': 'xml', 'coerce': 'parse_xml' } } }, allow_unknown=True) doc = {'upgrades': output.upgrades} assert checker.validate(doc)
class ParsedDwellingDataRow(_ParsedDwellingDataRow): _SCHEMA = { 'EVAL_ID': {'type': 'integer', 'required': True, 'coerce': int}, 'HOUSE_ID': {'type': 'integer', 'required': True, 'coerce': int}, 'EVAL_TYPE': { 'type': 'string', 'required': True, 'allowed': [eval_type.value for eval_type in EvaluationType] }, 'ENTRYDATE': {'type': 'date', 'required': True, 'coerce': parser.parse}, 'CREATIONDATE': {'type': 'datetime', 'required': True, 'coerce': parser.parse}, 'YEARBUILT': {'type': 'integer', 'required': True, 'coerce': int}, 'CLIENTCITY': {'type': 'string', 'required': True}, 'forwardSortationArea': {'type': 'string', 'required': True, 'regex': '[A-Z][0-9][A-Z]'}, 'HOUSEREGION': {'type': 'string', 'required': True}, 'BUILDER': {'type': 'string', 'required': True}, 'upgrades': { 'type': 'list', 'required': True, 'schema': { 'type': 'xml', 'coerce': 'parse_xml', } }, 'MODIFICATIONDATE': {'type': 'datetime', 'nullable': True, 'required': True, 'coerce': parser.parse}, 'HEATEDFLOORAREA': {'type': 'float', 'nullable': True, 'coerce': float}, 'TYPEOFHOUSE': {'type': 'string', 'nullable': True}, 'EGHRATING': {'type': 'integer', 'nullable': True, 'coerce': int}, 'UGRRATING': {'type': 'integer', 'nullable': True, 'coerce': int}, 'ERSRATING': {'type': 'integer', 'nullable': True, 'coerce': int}, 'UGRERSRATING': {'type': 'integer', 'nullable': True, 'coerce': int}, 'ERSGHG': {'type': 'float', 'nullable': True, 'coerce': float}, 'UGRERSGHG': {'type': 'float', 'nullable': True, 'coerce': float}, 'ERSENERGYINTENSITY': {'type': 'float', 'nullable': True, 'coerce': float}, 'UGRERSENERGYINTENSITY': {'type': 'float', 'nullable': True, 'coerce': float}, 'EGHDESHTLOSS': {'type': 'float', 'nullable': True, 'coerce': float}, 'UGRDESHTLOSS': {'type': 'float', 'nullable': True, 'coerce': float}, 'WALLDEF': {'type': 'string', 'nullable': True, 'required': True}, 'UGRWALLDEF': {'type': 'string', 'nullable': True, 'required': True}, 'EGHHLWALLS': {'type': 'float', 'nullable': True, 'required': True, 'coerce': float}, 'UGRHLWALLS': {'type': 'float', 'nullable': True, 'required': True, 'coerce': float}, } _CHECKER = validator.DwellingValidator(_SCHEMA, allow_unknown=True) @classmethod def from_row(cls, row: typing.Dict[str, typing.Any]) -> 'ParsedDwellingDataRow': if not cls._CHECKER.validate(row): error_keys = ', '.join(cls._CHECKER.errors.keys()) raise InvalidInputDataError(f'Validator failed on keys: {error_keys}') parsed = cls._CHECKER.document return ParsedDwellingDataRow( house_id=parsed['HOUSE_ID'], eval_id=parsed['EVAL_ID'], file_id=parsed['BUILDER'], eval_type=EvaluationType.from_code(parsed['EVAL_TYPE']), entry_date=parsed['ENTRYDATE'].date(), creation_date=parsed['CREATIONDATE'], modification_date=parsed['MODIFICATIONDATE'], year_built=parsed['YEARBUILT'], city=parsed['CLIENTCITY'], region=Region.from_data(parsed['HOUSEREGION']), forward_sortation_area=parsed['forwardSortationArea'], energy_upgrades=[upgrade.Upgrade.from_data(upgrade_node) for upgrade_node in parsed['upgrades']], heated_floor_area=parsed['HEATEDFLOORAREA'], house_type=parsed['TYPEOFHOUSE'], egh_rating=measurement.Measurement( measurement=parsed['EGHRATING'], upgrade=parsed['UGRRATING'], ), ers_rating=measurement.Measurement( measurement=parsed['ERSRATING'], upgrade=parsed['UGRERSRATING'], ), greenhouse_gas_emissions=measurement.Measurement( measurement=parsed['ERSGHG'], upgrade=parsed['UGRERSGHG'], ), energy_intensity=measurement.Measurement( measurement=parsed['ERSENERGYINTENSITY'], upgrade=parsed['UGRERSENERGYINTENSITY'], ), walls=measurement.Measurement( measurement=walls.Wall.from_data( parsed['WALLDEF'], parsed['EGHHLWALLS'], ), upgrade=walls.Wall.from_data( parsed['UGRWALLDEF'], parsed['UGRHLWALLS'], ), ), design_heat_loss=measurement.Measurement( measurement=parsed['EGHDESHTLOSS'], upgrade=parsed['UGRDESHTLOSS'], ), )