101 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import math
import pytest
from arm_statements import Cell, DocumentType, Source, default_rules
from src.normalizer.ocr.adapter import TableStructureError, confidence_of, header_cells, table_candidate
RULES = default_rules()
DATA_OCR = {
"label": {"form_name": "Бухгалтерская отчетность", "confidence": 100.0},
"organization": {"form_name": "ООО «Пример»", "confidence": 100.0},
"inn": {"form_name": "3|1 21 2|", "confidence": 61.538464},
"units": {"form_name": "тыс. руб.", "confidence": 100.0},
"date": {"form_name": "", "confidence": 0.0},
}
def row(index: object, *cells: tuple[object, object, object]) -> dict[str, object]:
return {"row_index": index, "cells": [{"column_index": c, "value": v, "confidence": p} for c, v, p in cells]}
def table(label: str, *rows: dict[str, object]) -> dict[str, object]:
return {"label": {"form_name": label, "confidence": 100.0}, "rows": list(rows)}
def test_header_is_copied_from_json() -> None:
h = header_cells(DATA_OCR)
assert h.organization_name == Cell("ООО «Пример»", None, 100.0, "data_ocr.organization")
assert h.inn == Cell("3|1 21 2|", None, 61.538464, "data_ocr.inn")
assert h.units == Cell("тыс. руб.", None, 100.0, "data_ocr.units")
assert (h.report_date, h.okud, h.okpo, h.okopf, h.okfs, h.okei, h.address) == (None,) * 7
def test_grid_by_row_and_column_index() -> None:
t = table(
"Бухгалтерский баланс",
row(9, (0, "Итого", 100.0)),
row(8, (1, "[190 :", 25.0), (0, "Прочие", 100.0), (4, "", 0.0), (5, None, 100.0)),
)
cand = table_candidate("j.json", 0, t, header_cells(DATA_OCR), RULES)
assert (cand.source, cand.locator, cand.type_hint) == (Source.OCR, "file:j.json;table:0", DocumentType.BALANCE)
assert cand.segment_breaks == () and cand.warnings == ()
assert cand.evidence.okud is None
assert cand.evidence.title == Cell("Бухгалтерский баланс", None, 100.0, "table:0.label")
assert cand.rows == (
(
Cell("Прочие", None, 100.0, "row:8"),
Cell("[190 :", None, 25.0, "row:8"),
None,
None,
Cell("", None, 0.0, "row:8"),
Cell("", None, 100.0, "row:8"),
),
(Cell("Итого", None, 100.0, "row:9"), None, None, None, None, None),
)
assert cand.header == header_cells(DATA_OCR)
def test_multiline_text_is_kept() -> None:
t = table("Бухгалтерский баланс", row(93, (1, "1500\n1700", 78.0), (2, "917 775\n2 371 333", 100.0)))
cand = table_candidate("j.json", 0, t, header_cells(DATA_OCR), RULES)
assert cand.rows[0][1] == Cell("1500\n1700", None, 78.0, "row:93")
def test_income_label_and_unknown_label() -> None:
income = table_candidate("j.json", 1, table("Отчет о финансовых результатах"), header_cells(DATA_OCR), RULES)
assert income.type_hint is DocumentType.INCOME and income.rows == ()
blank = table_candidate(
"j.json", 2, {"label": {"form_name": " ", "confidence": 0.0}, "rows": []}, header_cells(DATA_OCR), RULES
)
assert (blank.evidence.title, blank.type_hint) == (None, None)
@pytest.mark.parametrize(
("raw", "expected"),
[(25, 25.0), (150.0, 100.0), (-3, 0.0), (math.nan, 0.0), (math.inf, 0.0), ("100", 0.0), (True, 0.0), (None, 0.0)],
)
def test_confidence_of(raw: object, expected: float) -> None:
assert confidence_of(raw) == expected
@pytest.mark.parametrize(
"broken",
[
"не объект",
{"label": {}, "rows": "x"},
table("ББ", {"cells": []}),
table("ББ", row(True, (0, "a", 100.0))),
table("ББ", row(1, (0, "a", 100.0)), row(1, (0, "b", 100.0))),
table("ББ", {"row_index": 0, "cells": "x"}),
table("ББ", row(0, ("1", "a", 100.0))),
table("ББ", row(0, (-1, "a", 100.0))),
table("ББ", row(0, (1, "a", 100.0), (1, "b", 100.0))),
table("ББ", row(0, (True, "a", 100.0))),
table("ББ", {"row_index": 0, "cells": ["не объект"]}),
],
)
def test_broken_structure_raises(broken: object) -> None:
with pytest.raises(TableStructureError):
table_candidate("j.json", 0, broken, header_cells(DATA_OCR), RULES)