"""HII gauge-rain aggregate: pure-function tests (no DB).""" import numpy as np import pandas as pd from src.ml import hii_rain def _hourly(start, n): return pd.date_range(start, periods=n, freq="h") def test_compare_identical_series_has_zero_bias(): idx = _hourly("2026-08-12", 200) rng = np.random.default_rng(1) rain = pd.Series(rng.exponential(0.5, len(idx)), index=idx) out = hii_rain.compare_with_openmeteo(rain, rain.copy(), window_h=24) assert out["overlap_hours"] == 200 assert out["bias_mm"] == 0.0 assert out["mae_mm"] == 0.0 assert out["corr"] > 0.999 def test_compare_reports_constant_bias(): idx = _hourly("2026-08-12", 100) gauge = pd.Series(1.0, index=idx) model = pd.Series(1.5, index=idx) # model wetter by 0.5 mm/h out = hii_rain.compare_with_openmeteo(gauge, model, window_h=24) assert abs(out["bias_mm"] - 12.0) < 1e-9 # 0.5 mm/h x 24 h def test_compare_uses_overlap_only(): gauge = pd.Series(1.0, index=_hourly("2026-08-12", 100)) model = pd.Series(1.0, index=_hourly("2026-08-14", 100)) # 52 h overlap out = hii_rain.compare_with_openmeteo(gauge, model, window_h=24) assert out["overlap_hours"] == 52 def test_compare_no_overlap(): gauge = pd.Series(1.0, index=_hourly("2026-01-01", 10)) model = pd.Series(1.0, index=_hourly("2026-06-01", 10)) assert hii_rain.compare_with_openmeteo(gauge, model) == {"overlap_hours": 0} def test_load_gauge_mean_without_db_returns_none(monkeypatch): monkeypatch.setattr(hii_rain, "resolve_db_url", lambda *a, **k: None) assert hii_rain.load_gauge_mean() is None