diff --git a/tests/test_phase5_e2e.py b/tests/test_phase5_e2e.py new file mode 100644 index 0000000..67ea653 --- /dev/null +++ b/tests/test_phase5_e2e.py @@ -0,0 +1,54 @@ +import pytest +from types import SimpleNamespace +from pathlib import Path + +from docx import Document + +from genesis.data_models import StructuredSource +from genesis.parsers.word_template_parser import WordTemplateParser +from genesis.qa.qa_loop import QALoop + + +class FakeEngine: + def chat_structured(self, *, session_id, prompt, variables, schema, retry_count=2): + cid = variables.get("title", "x") + return SimpleNamespace( + data={ + "title": cid, + "blocks": [ + {"type": "heading", "level": 2, "text": f"{cid} 小节"}, + {"type": "paragraph", "text": "由 FakeLLM 生成的充分说明内容,满足写入规则要求。"}, + {"type": "table", "caption": "示例表", "rows": [["列1", "列2"], ["值1", "值2"]]}, + ], + }, + status="ok", + ) + + +def _all_text(doc: Document) -> str: + parts = [p.text for p in doc.paragraphs] + for tbl in doc.tables: + for row in tbl.rows: + for cell in row.cells: + parts.append(cell.text) + return "\n".join(parts) + + +def test_phase5_e2e_fake_llm(tmp_path): + template = Path("samples/phase5-slice/template.docx") + if not template.exists(): + pytest.skip("样本模板缺失,跳过 e2e") + parsed = WordTemplateParser().parse(str(template)) + ss = StructuredSource( + template=parsed, tables=[], rule_docs=[], image_analyses=[], existing_system=None, comments=[] + ) + out = tmp_path / "e2e_out.docx" + loop = QALoop(max_rounds=2) + report = loop.run( + ss, str(out), samples_dir="nonexistent_dir_xyz", engine=FakeEngine(), template_path=str(template) + ) + assert report.passed is True + loaded = Document(str(out)) + text = _all_text(loaded) + assert "由 FakeLLM 生成的充分说明内容" in text + assert "示例表" in text