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