from dataclasses import asdict from genesis.data_models import ( CellComment, CellFormatting, CellValue, ChangeAnalysis, ChangeElement, ChangeType, Confidence, ElementType, ExcelTable, ExtractionMethod, ImageAnalysis, ImpactReport, ImpactWarning, ParsedTemplate, Provenance, RelationType, RuleDocument, SheetType, StructuredSource, ) def test_sheettype_has_8_members(): assert len(SheetType) == 8 assert SheetType.FUNCTION.value == "FUNCTION" assert SheetType.GENERIC.value == "GENERIC" def test_value_enum_members(): assert ElementType.FUNCTION.value == "機能" assert RelationType.USE.value == "利用" assert Confidence.HIGH.value == "high" assert ExtractionMethod.OPENPYXL.value == "openpyxl" def test_cellformatting_defaults(): fmt = CellFormatting() assert fmt.strikethrough is False assert fmt.font_color is None assert fmt.bg_color is None def test_cellvalue_forward_reference_works(): """CellValue 引用后置定义的 CellFormatting/CellComment(future.annotations 落地)""" prov = Provenance(file_name="f.xlsx", sheet_name="S", row=1, column="A", column_header="h") cv = CellValue( value="x", provenance=prov, formatting=CellFormatting(strikethrough=True), comment=CellComment(author="reviewer", text="check", source_uri="f.xlsx#S!A1"), ) assert cv.formatting.strikethrough is True assert cv.comment.author == "reviewer" def test_excel_table_references_sheettype(): table = ExcelTable( name="機能一覧", detected_type=SheetType.FUNCTION, extraction_method=ExtractionMethod.OPENPYXL.value, headers=["機能ID", "機能名"], rows=[], ) assert table.detected_type is SheetType.FUNCTION assert table.extraction_method == "openpyxl" def test_structured_source_assembles_all(): source = StructuredSource( tables=[], template=ParsedTemplate(file_name="t.docx", sections=[], placeholders={}, styles={}), rule_docs=[RuleDocument( file_name="記入規則.docx", category="write", markdown_content="# 規則", source_path="samples/記入規則.docx", file_type="word", hash="abc", )], image_analyses=[ImageAnalysis( image_ref="img1", description="画面遷移図", confidence=0.9, source_uri="f.xlsx#S!A1", sheet_name="S", anchor_cell="A1", status="recognized", )], existing_system=None, comments=[], ) assert source.rule_docs[0].category == "write" assert source.image_analyses[0].nearby_text == "" def test_asdict_serializable(): prov = Provenance(file_name="f.xlsx", sheet_name="S", row=1, column="A", column_header="h") d = asdict(CellValue(value=1, provenance=prov)) assert d["provenance"]["row"] == 1 # ---------- Impact Agent MVP 数据模型(2026-08-23) ---------- def test_changetype_members(): assert ChangeType.NEW.value == "新規" assert ChangeType.MODIFIED.value == "変更" assert ChangeType.DELETED.value == "削除" assert ChangeType.UNCHANGED.value == "不变" def test_change_element_defaults(): el = ChangeElement(element_id="F001", element_type="機能", name="止损风控", change_type=ChangeType.NEW) assert el.existing_mapping == [] assert el.impacted_existing == [] assert el.evidence == "" assert el.status == "ok" def test_change_analysis_holds_lists(): ca = ChangeAnalysis( project_type="enhancement", new_elements=[ChangeElement("F001", "機能", "止损风控", ChangeType.NEW)], modified_elements=[], deleted_elements=[], unchanged_elements=[], warnings=[ImpactWarning(element_id="F002", issue="无法定位修改对象")], ) assert ca.project_type == "enhancement" assert ca.new_elements[0].element_id == "F001" assert ca.warnings[0].issue == "无法定位修改对象" def test_impact_report_defaults(): report = ImpactReport(metadata={"version": "v1"}) assert report.change_analysis is None assert report.summary == {} def test_impact_report_holds_analysis(): ca = ChangeAnalysis(project_type="enhancement", new_elements=[], modified_elements=[], deleted_elements=[], unchanged_elements=[], warnings=[]) report = ImpactReport(metadata={"version": "v1"}, change_analysis=ca, summary={"new": 0}) assert report.change_analysis.project_type == "enhancement" assert report.summary["new"] == 0 def test_structured_source_impact_report_default_none(): """StructuredSource 新增 impact_report 字段,缺省 None(门控未提供时保持 None)。""" source = StructuredSource( tables=[], template=None, rule_docs=[], image_analyses=[], existing_system=None, comments=[], ) assert source.impact_report is None