初始化提交

This commit is contained in:
chenxin committed 2026-08-21 16:00:13 +08:00
commit 887c1f449e
963 files changed
+166869

No files matched your search

@@ -0,0 +1,116 @@
"""时态快照测试。"""
from datetime import UTC, datetime
from app.modules.time_sense.duration import OfflineThresholds
from app.modules.time_sense.snapshot import (
AnniversaryRef,
LocationContext,
SnapshotInput,
compute_snapshot,
)
def _input(**overrides):
base = {
"now": datetime(2026, 7, 3, 2, 42, tzinfo=UTC),
"timezone": "Asia/Shanghai",
"location": LocationContext(timezone="Asia/Shanghai", city="上海"),
"anniversaries": [],
"acquaintance_anchor": datetime(2025, 9, 19, tzinfo=UTC),
"last_active_at": datetime(2026, 7, 3, 2, 0, tzinfo=UTC),
"home_timezone": "Asia/Shanghai",
"offline_thresholds": OfflineThresholds(),
}
base.update(overrides)
return SnapshotInput(**base)
def test_snapshot_basic_fields():
snap = compute_snapshot(_input())
assert snap.timezone == "Asia/Shanghai"
# 上海 UTC+8,02:42 UTC -> 10:42 本地
assert snap.local_hour == 10
assert snap.shichen in {"辰", "巳"} # 7-11 点区间
assert snap.day_period in {"上午"}
assert snap.weekday is not None
def test_snapshot_acquaintance_and_offline():
snap = compute_snapshot(_input())
assert snap.acquaintance.total_days > 280
assert snap.offline.band == "active"
def test_snapshot_home_tz_diff_zero():
snap = compute_snapshot(_input())
assert snap.home_tz_diff_minutes == 0
def test_snapshot_next_milestone_from_anniversary():
# 下一个相识周年:相识日 2025-09-19,到 2026-07-03 距下一周年(2026-09-19)约 78 天
anni = AnniversaryRef(
id="anniv_1",
name="相识纪念日",
calendar="solar",
date_iso="2025-09-19",
recurs_yearly=True,
kind="anniversary",
)
snap = compute_snapshot(_input(anniversaries=[anni]))
assert snap.next_milestone is not None
assert snap.next_milestone.name == "相识纪念日"
assert 70 < snap.next_milestone.days_until < 85
def test_snapshot_active_milestone_today():
# 相识日恰好今天(构造一个今日命中的纪念日)
today = datetime(2026, 7, 3, tzinfo=UTC)
anni = AnniversaryRef(
id="anniv_birthday",
name="小明生日",
calendar="solar",
date_iso="2026-07-03",
recurs_yearly=False,
kind="birthday",
)
snap = compute_snapshot(_input(anniversaries=[anni], acquaintance_anchor=today))
assert any(m.name == "小明生日" for m in snap.active_milestones)
assert snap.next_milestone is None or snap.next_milestone.name != "小明生日"
def test_snapshot_lunar_present():
snap = compute_snapshot(_input())
# 农历字段非空(lunar_python 可用时)
assert snap.lunar is not None
assert snap.lunar.year_ganzhi == "丙午"
def test_snapshot_2_29_anniversary_in_non_leap_year():
# 2/29 周年在非闰年不应崩溃,且应回退到 2/28 后能算出下一周年
anni = AnniversaryRef(
id="anniv_leap",
name="闰年相识",
calendar="solar",
date_iso="2024-02-29",
recurs_yearly=True,
kind="anniversary",
)
snap = compute_snapshot(_input(anniversaries=[anni]))
assert snap.next_milestone is not None
assert snap.next_milestone.name == "闰年相识"
def test_snapshot_recurring_milestone_today():
# recurs_yearly=True 且月日命中今天:应进入 active_milestones
anni = AnniversaryRef(
id="anniv_today",
name="今日周年",
calendar="solar",
date_iso="2026-07-03",
recurs_yearly=True,
kind="anniversary",
)
snap = compute_snapshot(_input(anniversaries=[anni]))
assert any(m.id == "anniv_today" for m in snap.active_milestones)