saving
This commit is contained in:
92
tests/integration/test_manual_in_banister.py
Normal file
92
tests/integration/test_manual_in_banister.py
Normal file
@@ -0,0 +1,92 @@
|
||||
"""Integration: manual_activities flow through into the Banister PMC.
|
||||
|
||||
The contract is that `daily_training_load_series(..., include_manual=True)`
|
||||
unions manual rows into the same Series the PMC consumes, so adding a
|
||||
strength session lifts CTL on that day and the days following — same
|
||||
recursion, no special case.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from openrun.model import banister, daily_training_load_series
|
||||
|
||||
|
||||
def _add_activity(conn, aid: int, when: str, atype: str, training_load: float) -> None:
|
||||
conn.execute(
|
||||
"""INSERT INTO activities
|
||||
(activity_id, start_time_local, activity_type, training_load, raw, fetched_at)
|
||||
VALUES (?, ?, ?, ?, '{}', 'now')""",
|
||||
(aid, when, atype, training_load),
|
||||
)
|
||||
|
||||
|
||||
def _add_manual(conn, when: str, atype: str, training_load: float) -> None:
|
||||
conn.execute(
|
||||
"""INSERT INTO manual_activities
|
||||
(activity_date, activity_type, training_load, source, imported_at)
|
||||
VALUES (?, ?, ?, 'test', datetime('now'))""",
|
||||
(when, atype, training_load),
|
||||
)
|
||||
|
||||
|
||||
def test_include_manual_increases_daily_sum(tmp_conn) -> None:
|
||||
_add_activity(tmp_conn, aid=1, when="2026-05-01 06:00:00", atype="running", training_load=50.0)
|
||||
_add_manual(tmp_conn, when="2026-05-01", atype="running", training_load=30.0)
|
||||
tmp_conn.commit()
|
||||
|
||||
without = daily_training_load_series(tmp_conn)
|
||||
with_manual = daily_training_load_series(tmp_conn, include_manual=True)
|
||||
|
||||
assert without.iloc[0] == 50.0
|
||||
assert with_manual.iloc[0] == 80.0
|
||||
|
||||
|
||||
def test_manual_only_day_appears_when_included(tmp_conn) -> None:
|
||||
"""A day with only a manual row is invisible without the flag and appears with it."""
|
||||
_add_manual(tmp_conn, when="2026-05-02", atype="running", training_load=25.0)
|
||||
tmp_conn.commit()
|
||||
|
||||
without = daily_training_load_series(tmp_conn)
|
||||
with_manual = daily_training_load_series(tmp_conn, include_manual=True)
|
||||
assert without.empty
|
||||
assert with_manual.loc[pd.Timestamp("2026-05-02")] == 25.0
|
||||
|
||||
|
||||
def test_manual_load_lifts_banister_ctl_monotonically(tmp_conn) -> None:
|
||||
"""For two otherwise-identical worlds, the one with extra manual TL must
|
||||
show strictly higher CTL on the day the manual session was logged and on
|
||||
every following day (the EWMA carries forward)."""
|
||||
_add_activity(tmp_conn, aid=1, when="2026-05-01 06:00:00", atype="running", training_load=50.0)
|
||||
_add_activity(tmp_conn, aid=2, when="2026-05-03 06:00:00", atype="running", training_load=60.0)
|
||||
tmp_conn.commit()
|
||||
|
||||
base = banister(daily_training_load_series(tmp_conn))
|
||||
|
||||
_add_manual(tmp_conn, when="2026-05-02", atype="running", training_load=40.0)
|
||||
tmp_conn.commit()
|
||||
with_manual = banister(daily_training_load_series(tmp_conn, include_manual=True))
|
||||
|
||||
# 2026-05-01 is unchanged (manual is in the future at that point).
|
||||
assert with_manual.loc["2026-05-01", "CTL"] == base.loc["2026-05-01", "CTL"]
|
||||
# 2026-05-02 onward is strictly larger.
|
||||
for d in ("2026-05-02", "2026-05-03"):
|
||||
assert with_manual.loc[d, "CTL"] > base.loc[d, "CTL"]
|
||||
|
||||
|
||||
def test_activity_type_filter_excludes_other_manual_rows(tmp_conn) -> None:
|
||||
"""Manual rows whose type is not in activity_types stay out of the series."""
|
||||
_add_manual(tmp_conn, when="2026-05-02", atype="strength", training_load=100.0)
|
||||
tmp_conn.commit()
|
||||
out = daily_training_load_series(tmp_conn, include_manual=True)
|
||||
assert out.empty
|
||||
|
||||
|
||||
def test_manual_same_day_as_garmin_row_sums(tmp_conn) -> None:
|
||||
"""A manual row and a Garmin row on the same day must combine, not overwrite."""
|
||||
_add_activity(tmp_conn, aid=1, when="2026-05-01 18:00:00", atype="running", training_load=70.0)
|
||||
_add_manual(tmp_conn, when="2026-05-01", atype="running", training_load=30.0)
|
||||
tmp_conn.commit()
|
||||
s = daily_training_load_series(tmp_conn, include_manual=True)
|
||||
assert s.loc[pd.Timestamp("2026-05-01")] == 100.0
|
||||
Reference in New Issue
Block a user