test: MIXED 混合样本 + 端到端段落验证

This commit is contained in:
lhl
2026-08-09 04:13:01 +08:00
parent bc79945352
commit 75925168c7
3 changed files with 23 additions and 1 deletions
+1
View File
@@ -35,3 +35,4 @@
| 2026-08-09 03:59 | Agent 实现 | 里程碑2.5 Task9 实现:段落分割器 split_paragraphsMIXED 完整段落解析第一步,纯函数)。新建 src/genesis/parsers/paragraph_splitter.py_is_blank_row 行空白判定 + split_paragraphs(matrix)→list[(start,end)] 含端点 0-based,以全空行为界返回段落区间,空矩阵→[])与 tests/test_paragraph_splitter.py5 用例:空矩阵/单段落无空行/中间空行分割/尾部空行不产生多余段落/前导空行从首个非空行开始);TDD 验证 REDModuleNotFoundError: No module named 'genesis.parsers.paragraph_splitter')→ GREEN5 passed);pytest 全量 46 passed41 baseline + 5 新增);不依赖 openpyxl 与 data_models;提交 34ef28b | src/genesis/parsers/paragraph_splitter.py, tests/test_paragraph_splitter.py | deepseek-v4-flash-free | | 2026-08-09 03:59 | Agent 实现 | 里程碑2.5 Task9 实现:段落分割器 split_paragraphsMIXED 完整段落解析第一步,纯函数)。新建 src/genesis/parsers/paragraph_splitter.py_is_blank_row 行空白判定 + split_paragraphs(matrix)→list[(start,end)] 含端点 0-based,以全空行为界返回段落区间,空矩阵→[])与 tests/test_paragraph_splitter.py5 用例:空矩阵/单段落无空行/中间空行分割/尾部空行不产生多余段落/前导空行从首个非空行开始);TDD 验证 REDModuleNotFoundError: No module named 'genesis.parsers.paragraph_splitter')→ GREEN5 passed);pytest 全量 46 passed41 baseline + 5 新增);不依赖 openpyxl 与 data_models;提交 34ef28b | src/genesis/parsers/paragraph_splitter.py, tests/test_paragraph_splitter.py | deepseek-v4-flash-free |
| 2026-08-09 04:20 | Agent 实现 | 里程碑2.5 Task10 实现:data_models 扩展 MixedParagraph/MixedSheet 段落容器,并新增 ExcelParseResult.mixed 字段(默认空列表)。TDD:先追加 3 个测试(字段存在性与默认行为)确认 REDImportError: cannot import name 'MixedParagraph'),再在 data_models.py 末尾追加两个 dataclass(顶部 from typing 加 Literal、dataclasses 加 field),excel_parser.py 更新导入并为 ExcelParseResult 加 mixed 字段,确认 GREEN3 passed),全量 pytest 49 passed46 baseline + 3)。未修改既有类与字段,仅追加。 | src/genesis/data_models.py, src/genesis/parsers/excel_parser.py, tests/test_excel_parser.py | deepseek-v4-flash-free | | 2026-08-09 04:20 | Agent 实现 | 里程碑2.5 Task10 实现:data_models 扩展 MixedParagraph/MixedSheet 段落容器,并新增 ExcelParseResult.mixed 字段(默认空列表)。TDD:先追加 3 个测试(字段存在性与默认行为)确认 REDImportError: cannot import name 'MixedParagraph'),再在 data_models.py 末尾追加两个 dataclass(顶部 from typing 加 Literal、dataclasses 加 field),excel_parser.py 更新导入并为 ExcelParseResult 加 mixed 字段,确认 GREEN3 passed),全量 pytest 49 passed46 baseline + 3)。未修改既有类与字段,仅追加。 | src/genesis/data_models.py, src/genesis/parsers/excel_parser.py, tests/test_excel_parser.py | deepseek-v4-flash-free |
| 2026-08-09 04:06 | Agent 实现 | 里程碑2.5 Task11 实现:MIXED 完整段落装配(分割→逐段最优解析)。excel_parser.py 新增 MIXED 分支:整表先 forward_fill(合并单元格)再按段切片;对每段 classify_sheetTABLE 段用 find_header_row(seg)(段内相对,<0 回落 0)并抽出段内子 map seg_fmt_map(物理行 pr→段内 pr-s,修复 formatting_map 坐标错位)传给 extract_tableheader_row=header_row);非表格段归 FREE_TEXT(防二次 MIXED 递归),走 extract_text_blocks + build_free_text_table 构造 kind="free_text"。MixedParagraph 段落追加到 MixedSheet 并进 result.mixed,表/自由文本表进 result.tables。原 else 分支保留为 TABLE 专用,既有 TABLE/FREE_TEXT 路径不变。TDD:先追加 2 测试(段落分割/碎片捕获、表格段不在物理行 0 时的取消线回填)确认 REDresult.mixed 空 + IndexError),再实现确认 GREEN9 passed),全量 pytest 51 passed49 baseline + 2)。提交见 git log | src/genesis/parsers/excel_parser.py, tests/test_excel_parser.py | deepseek-v4-flash-free | | 2026-08-09 04:06 | Agent 实现 | 里程碑2.5 Task11 实现:MIXED 完整段落装配(分割→逐段最优解析)。excel_parser.py 新增 MIXED 分支:整表先 forward_fill(合并单元格)再按段切片;对每段 classify_sheetTABLE 段用 find_header_row(seg)(段内相对,<0 回落 0)并抽出段内子 map seg_fmt_map(物理行 pr→段内 pr-s,修复 formatting_map 坐标错位)传给 extract_tableheader_row=header_row);非表格段归 FREE_TEXT(防二次 MIXED 递归),走 extract_text_blocks + build_free_text_table 构造 kind="free_text"。MixedParagraph 段落追加到 MixedSheet 并进 result.mixed,表/自由文本表进 result.tables。原 else 分支保留为 TABLE 专用,既有 TABLE/FREE_TEXT 路径不变。TDD:先追加 2 测试(段落分割/碎片捕获、表格段不在物理行 0 时的取消线回填)确认 REDresult.mixed 空 + IndexError),再实现确认 GREEN9 passed),全量 pytest 51 passed49 baseline + 2)。提交见 git log | src/genesis/parsers/excel_parser.py, tests/test_excel_parser.py | deepseek-v4-flash-free |
| 2026-08-09 09:40 | 测试验证 | 里程碑2.5 Task12 实现:混合型样本 + 端到端验证。生成 samples/要件定義_混合型.xlsx(機能一覧 表格:表头+3 数据行,空行后接「・改修ポイント」「■対象期間」两条连续碎片文本,无空行);tests/test_real_samples.py 追加 test_mixed_sample_segments_detected(断言 mixed 段落数==2、kinds==["table","free_text"]、表格段第一批数据行機能ID=="F101"、table.rows==3、碎片段 text 含 改修ポイント/対象期間)。验证:real_samples 全绿 4 passed3 baseline+1 新增,无 skip);pytest 全量 52 passed51 baseline + 1);实际样本 split_paragraphs 产出两段(0,3)+(5,6)(表格段+碎片段)。提交见 git log | samples/要件定義_混合型.xlsx, tests/test_real_samples.py, _AI_USAGE_LOG.md | deepseek-v4-flash-free |
Binary file not shown.
+22 -1
View File
@@ -36,4 +36,25 @@ def test_free_text_sample_detected():
if not p.exists(): if not p.exists():
pytest.skip("样本缺失") pytest.skip("样本缺失")
result = ExcelParser().parse(p) result = ExcelParser().parse(p)
assert any(t.extraction_method == "llm_from_free_text" for t in result.tables) assert any(t.extraction_method == "llm_from_free_text" for t in result.tables)
def test_mixed_sample_segments_detected():
p = _x("要件定義_混合型.xlsx")
if not p.exists():
pytest.skip("样本缺失")
result = ExcelParser().parse(p)
by_name = {t.name: t for t in result.tables}
assert "機能一覧" in by_name
assert result.mixed, "混合样本应产出段落"
mixed = result.mixed[0]
assert len(mixed.paragraphs) == 2 # 表格段 + 碎片段(・/■ 连续)
assert [p.kind for p in mixed.paragraphs] == ["table", "free_text"]
# 表格段无碎片污染
table = [p.table for p in mixed.paragraphs if p.kind == "table"][0]
assert table.rows[0]["機能ID"].value == "F101"
assert len(table.rows) == 3
# 碎片段含 ・ 与 ■ 两行文本
ft = [p for p in mixed.paragraphs if p.kind == "free_text"][0]
assert "改修ポイント" in (ft.text or "")
assert "対象期間" in (ft.text or "")