"""Behaviour of the Package Scorer: composing Simulation Overlays onto a baseline EpcPropertyData and scoring the result on the deterministic SAP10 calculator. The reusable compute primitive (ADR-0016). Elmhurst before/after cascade pins land with #1154 once the cert parses; here we exercise the real calculator on a hand-built EPD. """ from datatypes.epc.domain.epc_property_data import ( BuildingPartIdentifier, EpcPropertyData, ) from domain.modelling.scoring.package_scorer import PackageScorer, Score from domain.modelling.simulation import BuildingPartOverlay, EpcSimulation from domain.sap10_calculator.calculator import Sap10Calculator, SapResult from tests.domain.sap10_calculator.worksheet._elmhurst_worksheet_000490 import ( build_epc, ) _CAVITY_FILL = EpcSimulation( building_parts={ BuildingPartIdentifier.MAIN: BuildingPartOverlay(wall_insulation_type=2) } ) def test_filling_the_main_cavity_improves_sap() -> None: # Arrange baseline: EpcPropertyData = build_epc() # MAIN: uninsulated cavity scorer = PackageScorer(Sap10Calculator()) # Act base: Score = scorer.score(baseline, []) filled: Score = scorer.score(baseline, [_CAVITY_FILL]) # Assert assert filled.sap_continuous > base.sap_continuous def test_empty_package_scores_the_unmodified_baseline() -> None: # Arrange baseline: EpcPropertyData = build_epc() calculator = Sap10Calculator() direct: SapResult = calculator.calculate(baseline) # Act score: Score = PackageScorer(calculator).score(baseline, []) # Assert assert abs(score.sap_continuous - direct.sap_score_continuous) <= 1e-9 assert abs(score.co2_kg_per_yr - direct.co2_kg_per_yr) <= 1e-9 assert ( abs(score.primary_energy_kwh_per_yr - direct.primary_energy_kwh_per_yr) <= 1e-9 ) def test_score_carries_the_scored_sap_result_for_billing() -> None: # Arrange — the post-package SapResult must ride on the Score so Bill # Derivation can price the simulated end-state without a second calculate # (ADR-0014 amendment). baseline: EpcPropertyData = build_epc() scorer = PackageScorer(Sap10Calculator()) # Act filled: Score = scorer.score(baseline, [_CAVITY_FILL]) # Assert — the SapResult is the one the Score's headline figures came from. assert filled.sap_result is not None assert ( abs(filled.sap_result.sap_score_continuous - filled.sap_continuous) <= 1e-9 )