import pytest from pathlib import Path from genesis.data_models import StructuredSource from genesis.parsers.source_aggregator import SourceParser from tests.docx_helpers import make_rule_doc, new_document, save_document from tests.excel_helpers import new_workbook, save_workbook def _xlsx(tmp_path, name: str = "source.xlsx") -> str: wb = new_workbook({"機能一覧": [["機能ID", "機能名"], ["A001", "社員登録"]]}) path = tmp_path / name wb.save(path) return str(path) def test_parse_full_assembly(tmp_path): xlsx = _xlsx(tmp_path) template = save_document(tmp_path, new_document()) rule = make_rule_doc(tmp_path, [("H1", "1. 機能一覧の書き方")]) instr = make_rule_doc(tmp_path, [("H1", "2. 機能一覧の作成手順")]) result = SourceParser().parse( requirement_paths=[xlsx], template_path=template, write_instruction_paths=[instr], rule_paths=[rule], ) assert isinstance(result, StructuredSource) assert len(result.tables) == 1 assert result.template is not None assert result.template.file_name == "source.docx" assert len(result.rule_docs) == 2 assert all(r.category == "write" for r in result.rule_docs) assert result.image_analyses == [] assert result.existing_system is None def test_parse_without_template_and_rules(tmp_path): xlsx = _xlsx(tmp_path) result = SourceParser().parse(requirement_paths=[xlsx]) assert len(result.tables) == 1 assert result.template is None assert result.rule_docs == [] def test_parse_missing_requirement_file(tmp_path): with pytest.raises(FileNotFoundError): SourceParser().parse(requirement_paths=[tmp_path / "missing.xlsx"]) def test_parse_missing_template_file(tmp_path): xlsx = _xlsx(tmp_path) with pytest.raises(FileNotFoundError): SourceParser().parse(requirement_paths=[xlsx], template_path=tmp_path / "missing.docx") def test_parse_unknown_extension_in_requirements(tmp_path): bad = tmp_path / "note.txt" bad.write_text("hello", encoding="utf-8") with pytest.raises(ValueError, match="不支持的文件类型"): SourceParser().parse(requirement_paths=[bad]) def test_parse_unknown_extension_in_rules(tmp_path): bad = tmp_path / "note.txt" bad.write_text("hello", encoding="utf-8") with pytest.raises(ValueError, match="不支持的文件类型"): SourceParser().parse(rule_paths=[bad]) def test_parse_unknown_extension_in_template(tmp_path): bad = tmp_path / "note.txt" bad.write_text("hello", encoding="utf-8") with pytest.raises(ValueError, match="不支持的文件类型"): SourceParser().parse(template_path=bad) def test_parse_missing_rule_file(tmp_path): with pytest.raises(FileNotFoundError): SourceParser().parse(rule_paths=[tmp_path / "missing.docx"]) def test_parse_extensionless_requirement(tmp_path): bad = tmp_path / "note" bad.write_text("hello", encoding="utf-8") with pytest.raises(ValueError, match="无扩展名"): SourceParser().parse(requirement_paths=[bad]) def test_parse_extensionless_rule(tmp_path): bad = tmp_path / "note" bad.write_text("hello", encoding="utf-8") with pytest.raises(ValueError, match="无扩展名"): SourceParser().parse(rule_paths=[bad]) # ---------- T7: DRY _validate_path helper(I8) ---------- def test_validate_path_rejects_bad_extension(tmp_path): from genesis.parsers.source_aggregator import _validate_path bad = tmp_path / "note.txt" bad.write_text("x", encoding="utf-8") with pytest.raises(ValueError, match="不支持的文件类型"): _validate_path(bad, (".xlsx",)) def test_validate_path_rejects_missing_file(tmp_path): from genesis.parsers.source_aggregator import _validate_path with pytest.raises(FileNotFoundError): _validate_path(tmp_path / "missing.xlsx", (".xlsx",)) def test_validate_path_returns_resolved_path(tmp_path): from genesis.parsers.source_aggregator import _validate_path good = tmp_path / "ok.xlsx" good.write_bytes(b"x") result = _validate_path(str(good), (".xlsx",)) assert isinstance(result, Path) assert result.suffix.lower() == ".xlsx"