Spaces:
Runtime error
Runtime error
| """ | |
| 测试:核心循环引擎 | |
| ================== | |
| 测试 LoopState, DailyStatus, PregoPalLoop | |
| """ | |
| import sys | |
| sys.path.insert(0, '.') | |
| import json | |
| import datetime | |
| from pathlib import Path | |
| from loop import LoopState, DailyStatus, PregoPalLoop, _TRANSITIONS, PRESETS_DIR, STATUS_FILE | |
| class TestLoopState: | |
| """测试状态枚举""" | |
| def test_all_states_defined(self): | |
| """所有状态应被定义""" | |
| assert LoopState.LAUNCH.value == "launch" | |
| assert LoopState.FAMILY_QUIZ.value == "family_quiz" | |
| assert LoopState.SUMMARIZE.value == "summarize" | |
| assert LoopState.ANALYZE.value == "analyze" | |
| assert LoopState.BRIEF.value == "brief" | |
| assert LoopState.INTERACT.value == "interact" | |
| assert LoopState.THREE_DAY.value == "three_day" | |
| assert LoopState.CONSOLIDATE.value == "consolidate" | |
| assert LoopState.DONE.value == "done" | |
| def test_state_count(self): | |
| """应有 9 个状态""" | |
| assert len(LoopState) == 9 | |
| class TestTransitions: | |
| """测试状态转移表""" | |
| def test_launch_transitions(self): | |
| """LAUNCH 应有 2 个转移""" | |
| assert (LoopState.LAUNCH, "need_summary") in _TRANSITIONS | |
| assert (LoopState.LAUNCH, "already_done") in _TRANSITIONS | |
| def test_full_flow(self): | |
| """完整流程应能到达 DONE""" | |
| state = LoopState.LAUNCH | |
| events = ["need_summary", "ok", "ok", "ok", "ok", "day_ended", "ok"] | |
| for event in events: | |
| next_state = _TRANSITIONS.get((state, event)) | |
| assert next_state is not None, f"No transition from {state} on '{event}'" | |
| state = next_state | |
| assert state == LoopState.DONE | |
| def test_three_day_flow(self): | |
| """触发三天总结的流程""" | |
| state = LoopState.LAUNCH | |
| events = ["need_summary", "ok", "ok", "ok", "ok", "day_ended", "need_3day", "ok"] | |
| for event in events: | |
| next_state = _TRANSITIONS.get((state, event)) | |
| assert next_state is not None | |
| state = next_state | |
| assert state == LoopState.DONE | |
| def test_already_done_flow(self): | |
| """今日已完成的流程""" | |
| state = LoopState.LAUNCH | |
| next_state = _TRANSITIONS.get((state, "already_done")) | |
| assert next_state == LoopState.INTERACT | |
| class TestDailyStatus: | |
| """测试状态位管理""" | |
| def setup_method(self): | |
| self._backup = None | |
| if STATUS_FILE.exists(): | |
| self._backup = STATUS_FILE.read_text(encoding='utf-8') | |
| def teardown_method(self): | |
| if self._backup: | |
| STATUS_FILE.write_text(self._backup, encoding='utf-8') | |
| elif STATUS_FILE.exists(): | |
| STATUS_FILE.unlink() | |
| def test_load_empty(self): | |
| """空文件应返回空字典""" | |
| if STATUS_FILE.exists(): | |
| STATUS_FILE.unlink() | |
| status = DailyStatus.load() | |
| assert status == {} | |
| def test_mark_summary_done(self): | |
| """标记总结完成""" | |
| DailyStatus.mark_summary_done() | |
| today = datetime.date.today().isoformat() | |
| status = DailyStatus.load() | |
| assert status[today]["summary_done"] is True | |
| def test_is_today_done(self): | |
| """检查今日是否完成""" | |
| DailyStatus.mark_summary_done() | |
| assert DailyStatus.is_today_done() is True | |
| def test_mark_day_ended(self): | |
| """标记今日结束""" | |
| DailyStatus.mark_day_ended() | |
| today = datetime.date.today().isoformat() | |
| status = DailyStatus.load() | |
| assert status[today]["day_ended"] is True | |
| def test_get_last_summary_date(self): | |
| """获取最近总结日期""" | |
| DailyStatus.mark_summary_done() | |
| last = DailyStatus.get_last_summary_date() | |
| assert last == datetime.date.today().isoformat() | |
| def test_days_since_last_summary(self): | |
| """距离上次总结的天数""" | |
| DailyStatus.mark_summary_done() | |
| days = DailyStatus.days_since_last_summary() | |
| assert days == 0 | |
| def test_should_three_day_summary_false(self): | |
| """刚总结完不应触发三天总结""" | |
| DailyStatus.mark_summary_done() | |
| assert DailyStatus.should_three_day_summary() is False | |
| class TestPregoPalLoop: | |
| """测试循环引擎""" | |
| def test_loop_initialization(self): | |
| """初始化应处于 LAUNCH 状态""" | |
| loop = PregoPalLoop() | |
| assert loop.state == LoopState.LAUNCH | |
| def test_default_plugins_registered(self): | |
| """应注册所有默认插件""" | |
| loop = PregoPalLoop() | |
| plugins = loop.plugins.get_all() | |
| plugin_names = [p.name() for p in plugins] | |
| assert "family_recipe_quiz" in plugin_names | |
| assert "weight_quiz" in plugin_names | |
| assert "diet_summary" in plugin_names | |
| assert "weight_check" in plugin_names | |
| assert "family_memory" in plugin_names | |
| assert "dri_analysis" in plugin_names | |
| assert "briefing_generator" in plugin_names | |
| assert "three_day_summary" in plugin_names | |
| assert "preset_writer" in plugin_names | |
| def test_plugin_count(self): | |
| """应有 9 个默认插件""" | |
| loop = PregoPalLoop() | |
| assert len(loop.plugins.get_all()) == 9 | |
| def test_get_briefing_empty(self): | |
| """初始简报应为空""" | |
| loop = PregoPalLoop() | |
| assert loop.get_briefing() == {} | |
| def test_get_thinking_keywords(self): | |
| """初始思考关键词""" | |
| loop = PregoPalLoop() | |
| assert loop.get_thinking_keywords() == "" | |
| def test_get_errors_empty(self): | |
| """初始错误列表为空""" | |
| loop = PregoPalLoop() | |
| assert loop.get_errors() == [] | |