import json from datetime import date from decimal import Decimal as D import arm_statements from arm_statements.model import Cell, DocumentType, Evidence, FormCandidate, HeaderCells, Source from arm_statements.serialize import candidate_from_dict, to_jsonable from arm_statements.tests.builders import excel, ocr def test_candidate_roundtrip_through_json() -> None: cand = FormCandidate( source=Source.EXCEL, locator="sheet:Баланс", type_hint=DocumentType.BALANCE, evidence=Evidence(okud=Cell("0710001", None, 100.0, "Баланс!F3"), title=None), header=HeaderCells(report_date=Cell("30.09.2025", date(2025, 9, 30), 100.0, "Баланс!C5")), rows=((Cell("106 311", D("106311"), 100.0, "Баланс!D27"), None, Cell("да", True, 100.0, "Баланс!F27")),), ) data = json.loads(json.dumps(to_jsonable(cand), ensure_ascii=False)) assert data["rows"][0][0]["value"] == {"decimal": "106311"} assert data["header"]["report_date"]["value"] == {"date": "2025-09-30"} assert candidate_from_dict(data) == cand def test_excel_builder_refs_follow_excel_quoting() -> None: cand = excel([("Баланс", [["", "", "", "1110"]]), ("Бухгалтерский баланс. Лист 1", [["", "", "1150"]])]) assert cand.rows[0][3] is not None and cand.rows[0][3].ref == "Баланс!D1" assert cand.rows[1][2] is not None and cand.rows[1][2].ref == "'Бухгалтерский баланс. Лист 1'!C1" assert cand.segment_breaks == (1,) assert cand.locator == "sheet:Баланс,Бухгалтерский баланс. Лист 1" def test_ocr_builder_cells() -> None: cand = ocr([["Выручка", ("[190 :", 25.0), None]]) cell = cand.rows[0][1] assert cell == Cell("[190 :", None, 25.0, "row:0") assert cand.rows[0][2] is None and cand.source is Source.OCR PUBLIC = { "Source", "DocumentType", "FormVariant", "Edition", "PeriodKind", "LineStatus", "Severity", "DocStatus", "EnvelopeStatus", "SignForm", "CellValue", "Cell", "Evidence", "HeaderCells", "HEADER_FIELDS", "StatementWarning", "FormCandidate", "HeaderField", "DateField", "StatementHeader", "StatementColumn", "StatementValue", "StatementLine", "FailedRelation", "StatementChecks", "StatementDocument", "CandidateResult", "NormalizationResult", "Rules", "RulesError", "load_rules", "default_rules", "normalize_candidate", "normalize", "parse_header", "type_hint", "continuation_type", "sheet_joins", "parse_code", "parse_amount", "parse_date", "resolve_relative", "fix_lookalikes", "make_warning", "StatusInput", "StatusLine", "StatusValue", "document_status", "envelope_status", "StoredForm", "StoredColumn", "StoredLine", "StoredValue", "StoredWarning", "RecomputeResult", "recompute", "to_jsonable", "candidate_from_dict", "statements_version", "WarningCode", "choose_edition", "status_input", "status_input_from_contract", "to_contract", "warning_to_contract", "code_column", "amount_columns", "normalize_label", "normalize_caption", "is_continuation", } def test_public_api() -> None: assert set(arm_statements.__all__) == PUBLIC assert len(arm_statements.__all__) == len(set(arm_statements.__all__)) assert all(hasattr(arm_statements, name) for name in PUBLIC)