mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Fix 11 pre-existing test failures from the absorbed PR
Two unrelated breakages surfaced after merging the PR into this branch; neither was caused by the appliances/cooking work. test_appendix_u.py (9 failures) — signature drift + wrong methodology label. The climate lookups were renamed `external_temperature_c(region=…)` → `(region_or_climate, month)` when PostcodeClimate support landed for the demand cascade, but the tests still passed `region=`. The expected values match our SAP 10.2 _TABLE_U1/U2/U3 exactly (UK-avg Jan 4.3 °C, Thames Jul 17.9 °C, solar Jul 189 W/m², Shetland Jan wind 9.5 m/s), so these are valid 10.2 coverage — fixed the call signature to positional and corrected the mislabelled "SAP 10.3" docstrings to SAP 10.2 (we track 10.2 deliberately). Also converted pytest.approx → abs(x-y)<=tol per the repo convention; pyright on the file drops 48 → 0. test_table_32.py (2 failures) — the parametrised "match PDF p.95" test pinned heating oil (code 4) = 7.64 and FAME (code 73) = 5.44, but the table deliberately diverges from the PDF for these two carriers: oil = 5.44 (Slice S0380.131, two independent lodging engines agree the PDF 7.64 is the outlier) and FAME = 7.64 (Slice S0380.168). Updated the two expected values to the worksheet-canonical figures the table actually uses, with inline citations + a docstring note on the divergence. Full calculator + property_baseline + heating-corpus suites: 1748 pass, 0 fail. pyright net-improving on both files. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
beae12aee8
commit
a5d889e143
2 changed files with 47 additions and 35 deletions
|
|
@ -1,6 +1,6 @@
|
|||
"""Tests for SAP 10.3 Appendix U climate-data lookups.
|
||||
"""Tests for SAP 10.2 Appendix U climate-data lookups.
|
||||
|
||||
Reference: SAP 10.3 specification (DESNZ/BRE, 13-01-2026), Appendix U:
|
||||
Reference: SAP 10.2 specification (BRE, 14-03-2025), Appendix U:
|
||||
Table U1 mean external temperature, Table U2 wind speed, Table U3 mean
|
||||
global solar irradiance on a horizontal plane and monthly solar declination.
|
||||
22 regions (0 = UK average, 1-21 = SAP climate regions) by 12 months.
|
||||
|
|
@ -17,13 +17,13 @@ from domain.sap10_calculator.climate.appendix_u import (
|
|||
|
||||
|
||||
def test_external_temperature_uk_average_january_returns_table_u1_value() -> None:
|
||||
# Arrange — SAP 10.3 Appendix U Table U1: Region 0 (UK average), January.
|
||||
# Arrange — SAP 10.2 Appendix U Table U1: Region 0 (UK average), January.
|
||||
|
||||
# Act
|
||||
result = external_temperature_c(region=0, month=1)
|
||||
result = external_temperature_c(0, month=1)
|
||||
|
||||
# Assert
|
||||
assert result == pytest.approx(4.3, abs=0.05)
|
||||
assert abs(result - 4.3) <= 0.05
|
||||
|
||||
|
||||
def test_external_temperature_thames_july_returns_named_region_value() -> None:
|
||||
|
|
@ -31,10 +31,10 @@ def test_external_temperature_thames_july_returns_named_region_value() -> None:
|
|||
# in summer — sanity check that named regions diverge from region 0.
|
||||
|
||||
# Act
|
||||
result = external_temperature_c(region=1, month=7)
|
||||
result = external_temperature_c(1, month=7)
|
||||
|
||||
# Assert
|
||||
assert result == pytest.approx(17.9, abs=0.05)
|
||||
assert abs(result - 17.9) <= 0.05
|
||||
|
||||
|
||||
def test_wind_speed_uk_average_january_returns_table_u2_value() -> None:
|
||||
|
|
@ -42,10 +42,10 @@ def test_wind_speed_uk_average_january_returns_table_u2_value() -> None:
|
|||
# SAP infiltration calc (worksheet lines 9-16).
|
||||
|
||||
# Act
|
||||
result = wind_speed_m_per_s(region=0, month=1)
|
||||
result = wind_speed_m_per_s(0, month=1)
|
||||
|
||||
# Assert
|
||||
assert result == pytest.approx(5.1, abs=0.05)
|
||||
assert abs(result - 5.1) <= 0.05
|
||||
|
||||
|
||||
def test_horizontal_solar_irradiance_uk_average_july_returns_table_u3_value() -> None:
|
||||
|
|
@ -53,10 +53,10 @@ def test_horizontal_solar_irradiance_uk_average_july_returns_table_u3_value() ->
|
|||
# for global horizontal irradiance in the UK.
|
||||
|
||||
# Act
|
||||
result = horizontal_solar_irradiance_w_per_m2(region=0, month=7)
|
||||
result = horizontal_solar_irradiance_w_per_m2(0, month=7)
|
||||
|
||||
# Assert
|
||||
assert result == pytest.approx(189.0, abs=0.5)
|
||||
assert abs(result - 189.0) <= 0.5
|
||||
|
||||
|
||||
def test_horizontal_solar_irradiance_southern_england_brighter_than_shetland() -> None:
|
||||
|
|
@ -64,12 +64,12 @@ def test_horizontal_solar_irradiance_southern_england_brighter_than_shetland() -
|
|||
# Jun -> 190. Higher-latitude regions get less June irradiance.
|
||||
|
||||
# Act
|
||||
south = horizontal_solar_irradiance_w_per_m2(region=3, month=6)
|
||||
shetland = horizontal_solar_irradiance_w_per_m2(region=20, month=6)
|
||||
south = horizontal_solar_irradiance_w_per_m2(3, month=6)
|
||||
shetland = horizontal_solar_irradiance_w_per_m2(20, month=6)
|
||||
|
||||
# Assert
|
||||
assert south == pytest.approx(235.0, abs=0.5)
|
||||
assert shetland == pytest.approx(190.0, abs=0.5)
|
||||
assert abs(south - 235.0) <= 0.5
|
||||
assert abs(shetland - 190.0) <= 0.5
|
||||
assert south > shetland
|
||||
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ def test_solar_declination_winter_solstice_returns_table_u3_value() -> None:
|
|||
result = solar_declination_deg(month=12)
|
||||
|
||||
# Assert
|
||||
assert result == pytest.approx(-23.0, abs=0.05)
|
||||
assert abs(result - -23.0) <= 0.05
|
||||
|
||||
|
||||
def test_solar_declination_summer_solstice_positive_value() -> None:
|
||||
|
|
@ -91,7 +91,7 @@ def test_solar_declination_summer_solstice_positive_value() -> None:
|
|||
result = solar_declination_deg(month=6)
|
||||
|
||||
# Assert
|
||||
assert result == pytest.approx(23.1, abs=0.05)
|
||||
assert abs(result - 23.1) <= 0.05
|
||||
|
||||
|
||||
def test_external_temperature_out_of_range_region_raises_value_error() -> None:
|
||||
|
|
@ -101,9 +101,9 @@ def test_external_temperature_out_of_range_region_raises_value_error() -> None:
|
|||
|
||||
# Act / Assert
|
||||
with pytest.raises(ValueError, match="region"):
|
||||
external_temperature_c(region=22, month=1)
|
||||
external_temperature_c(22, month=1)
|
||||
with pytest.raises(ValueError, match="region"):
|
||||
external_temperature_c(region=-1, month=1)
|
||||
external_temperature_c(-1, month=1)
|
||||
|
||||
|
||||
def test_region_21_northern_ireland_returns_table_u1_value() -> None:
|
||||
|
|
@ -112,10 +112,10 @@ def test_region_21_northern_ireland_returns_table_u1_value() -> None:
|
|||
# Table U1 row 21 July -> 15.0 °C.
|
||||
|
||||
# Act
|
||||
result = external_temperature_c(region=21, month=7)
|
||||
result = external_temperature_c(21, month=7)
|
||||
|
||||
# Assert
|
||||
assert result == pytest.approx(15.0, abs=0.05)
|
||||
assert abs(result - 15.0) <= 0.05
|
||||
|
||||
|
||||
def test_out_of_range_month_raises_value_error_on_every_lookup() -> None:
|
||||
|
|
@ -124,11 +124,11 @@ def test_out_of_range_month_raises_value_error_on_every_lookup() -> None:
|
|||
|
||||
# Act / Assert
|
||||
with pytest.raises(ValueError, match="month"):
|
||||
external_temperature_c(region=0, month=0)
|
||||
external_temperature_c(0, month=0)
|
||||
with pytest.raises(ValueError, match="month"):
|
||||
wind_speed_m_per_s(region=0, month=13)
|
||||
wind_speed_m_per_s(0, month=13)
|
||||
with pytest.raises(ValueError, match="month"):
|
||||
horizontal_solar_irradiance_w_per_m2(region=0, month=0)
|
||||
horizontal_solar_irradiance_w_per_m2(0, month=0)
|
||||
with pytest.raises(ValueError, match="month"):
|
||||
solar_declination_deg(month=13)
|
||||
|
||||
|
|
@ -139,10 +139,10 @@ def test_wind_speed_shetland_january_higher_than_thames() -> None:
|
|||
# populated for the upper region indices, not silently aliasing to row 0.
|
||||
|
||||
# Act
|
||||
shetland = wind_speed_m_per_s(region=20, month=1)
|
||||
thames = wind_speed_m_per_s(region=1, month=1)
|
||||
shetland = wind_speed_m_per_s(20, month=1)
|
||||
thames = wind_speed_m_per_s(1, month=1)
|
||||
|
||||
# Assert
|
||||
assert shetland == pytest.approx(9.5, abs=0.05)
|
||||
assert thames == pytest.approx(4.2, abs=0.05)
|
||||
assert abs(shetland - 9.5) <= 0.05
|
||||
assert abs(thames - 4.2) <= 0.05
|
||||
assert shetland > thames
|
||||
|
|
|
|||
|
|
@ -31,10 +31,16 @@ from domain.sap10_calculator.tables.table_32 import (
|
|||
(5, 12.19, "bottled LPG (secondary)"),
|
||||
(9, 3.48, "LPG subject to Special Condition 11F"),
|
||||
(7, 7.60, "biogas (including anaerobic digestion)"),
|
||||
# Liquid fuels
|
||||
(4, 7.64, "heating oil"),
|
||||
# Liquid fuels. Heating oil (4) and FAME (73) deliberately diverge
|
||||
# from the RdSAP 10 PDF p.95 (which lists 7.64 / 5.44) — the table
|
||||
# uses the operationally-canonical Elmhurst-worksheet values per
|
||||
# Slice S0380.131 (oil 7.64→5.44, two independent lodging engines
|
||||
# agree) and Slice S0380.168 (FAME 5.44→7.64, oil 3/4 worksheets).
|
||||
# See tables/table_32.py codes 4 / 73 + project-oil-price-spec-
|
||||
# divergence.
|
||||
(4, 5.44, "heating oil (worksheet-canonical, S0380.131)"),
|
||||
(71, 7.64, "bio-liquid HVO"),
|
||||
(73, 5.44, "bio-liquid FAME"),
|
||||
(73, 7.64, "bio-liquid FAME (worksheet-canonical, S0380.168)"),
|
||||
(75, 6.10, "B30K"),
|
||||
(76, 47.0, "bioethanol"),
|
||||
# Solid fuels
|
||||
|
|
@ -80,10 +86,16 @@ from domain.sap10_calculator.tables.table_32 import (
|
|||
def test_table_32_unit_prices_match_rdsap10_pdf_page_95(
|
||||
fuel_code: int, expected_p_per_kwh: float, fuel_name: str
|
||||
) -> None:
|
||||
"""RdSAP10 Table 32 unit prices, sourced verbatim from PDF page 95.
|
||||
These differ from SAP10.2 Table 12 by carrier (mains gas 3.64→3.48,
|
||||
heating oil 4.94→7.64, std electricity 16.49→13.19, etc.) — see
|
||||
`tables/table_32.py` docstring for the spec citation."""
|
||||
"""RdSAP10 Table 32 unit prices, sourced from PDF page 95. These
|
||||
differ from SAP10.2 Table 12 by carrier (mains gas 3.64→3.48, std
|
||||
electricity 16.49→13.19, etc.) — see `tables/table_32.py` docstring
|
||||
for the spec citation.
|
||||
|
||||
Two codes deliberately diverge from the PDF and use the Elmhurst-
|
||||
worksheet-canonical price instead (the PDF row is the outlier):
|
||||
heating oil (4) = 5.44 not 7.64 (Slice S0380.131), bio-liquid FAME
|
||||
(73) = 7.64 not 5.44 (Slice S0380.168). See project-oil-price-spec-
|
||||
divergence."""
|
||||
# Arrange
|
||||
# Act
|
||||
actual = unit_price_p_per_kwh(fuel_code)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue