"""WriterState 测试(P5-T5)。""" from genesis.writer.writer_state import WriterState from genesis.writer.models import ChapterContent, ContentBlock from genesis.eval.scorer import EvalReport def _content(cid, version=1): return ChapterContent(chapter_id=cid, version=version, title="x", blocks=[]) def _report(failed): return EvalReport( dimensions=[], total_score=0.0, passed=False, failed_chapters=failed, ) def test_initial_state_empty(): st = WriterState(["a", "b"]) assert st.needs_regeneration() == ["a", "b"] def test_record_success_clears_need(): st = WriterState(["a"]) st.record_success(_content("a")) assert st.needs_regeneration() == [] def test_failed_eval_marks_regeneration(): st = WriterState(["a"]) st.record_success(_content("a")) st.record_eval("a", _report(["a"])) assert st.needs_regeneration() == ["a"] # ---------- 章间引用摘要(design.md §6.9) ---------- def _content_with_table(cid, title, headers, nrows): rows = [[str(i) for _ in headers] for i in range(nrows)] return ChapterContent(chapter_id=cid, version=1, title=title, blocks=[ ContentBlock(block_id="b1", type="table", headers=headers, rows=rows), ]) def test_summary_of_includes_title_and_table_structure(): st = WriterState(["a"]) st.record_success(_content_with_table("a", "機能一覧", ["機能ID", "機能名"], 3)) s = st.summary_of("a") assert "a" in s and "機能一覧" in s assert "機能ID" in s and "機能名" in s assert "3" in s def test_summary_of_none_when_not_generated(): st = WriterState(["a"]) assert st.summary_of("a") is None def test_summaries_before_respects_order(): st = WriterState(["a", "b", "c"]) st.record_success(_content_with_table("a", "第一章", ["ID"], 1)) st.record_success(_content_with_table("b", "第二章", ["ID"], 2)) before_c = st.summaries_before("c") assert "第一章" in before_c and "第二章" in before_c assert st.summaries_before("a") == "" def test_summaries_before_unknown_chapter_empty(): st = WriterState(["a"]) assert st.summaries_before("zzz") == ""