Тесты синтетики: s28 — строка 13 в предупреждении и остаётся COUNTERPARTY без ИНН; поправлена шапка generate.py (H.3, T5.2)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-13 15:50:10 +04:00
parent 6d97fa2c94
commit ce776f6ab7
2 changed files with 12 additions and 5 deletions

View File

@ -2,10 +2,9 @@
Файлы s01…s13 — по одному сценарию спеки `osv-parsing` на файл, s14…s16 — записи словарей, которых нет в реальных Файлы s01…s13 — по одному сценарию спеки `osv-parsing` на файл, s14…s16 — записи словарей, которых нет в реальных
ОСВ (R-22), s17…s19 — ИНН в тексте названия, ИНН строкой выше и «ИНН/КПП» в одной ячейке (issue #9), s20…s27 — восемь ОСВ (R-22), s17…s19 — ИНН в тексте названия, ИНН строкой выше и «ИНН/КПП» в одной ячейке (issue #9), s20…s27 — восемь
раскладок строки ИНН, s28 — ИНН с неверной контрольной суммой (#35); описание — раскладок строки ИНН, s28 — ИНН с неверной контрольной суммой (#35); описание — `osv/synthetic/README.md` в репозитории
`osv/synthetic/README.md` в репозитории fixtures. Генератор самодостаточен (openpyxl + fixtures. Генератор самодостаточен (openpyxl + `xlsb_writer`) и детерминирован: повторный запуск даёт те же байты —
`xlsb_writer`) и детерминирован: повторный запуск даёт те же байты — метки времени книги и zip постоянны, порядок метки времени книги и zip постоянны, порядок записи фиксирован.
записи фиксирован.
Суммы арифметически согласованы по построению: у листа дерева сальдо на конец вычисляется из начала и оборотов, у Суммы арифметически согласованы по построению: у листа дерева сальдо на конец вычисляется из начала и оборотов, у
родителя — сумма детей по колонкам; поэтому все файлы, кроме `s10_broken_sum`, сходятся по §1.4. Позиции колонок и родителя — сумма детей по колонкам; поэтому все файлы, кроме `s10_broken_sum`, сходятся по §1.4. Позиции колонок и
@ -660,7 +659,7 @@ def inn_rows_tree(node: Node, layout: InnLayout, *, sums: bool) -> Node:
Колонки ИНН нет, в названии ИНН не пишется.""" Колонки ИНН нет, в названии ИНН не пишется."""
kids: list[Node] = [] kids: list[Node] = []
for kid in node.kids: for kid in node.kids:
kid = inn_rows_tree(kid, layout, sums=sums) # noqa: PLW2901 - узел заменяется своей копией с строками ИНН kid = inn_rows_tree(kid, layout, sums=sums) # noqa: PLW2901 - узел заменяется своей копией со строками ИНН
if kid.inn is None or kid.indicator: if kid.inn is None or kid.indicator:
kids.append(kid) kids.append(kid)
continue continue

View File

@ -37,6 +37,7 @@ INN_LAYOUT_FILES = (
"s27_inn_below_sibling_blank.xlsx", "s27_inn_below_sibling_blank.xlsx",
) )
INN_BAD_CHECKSUM_FILE = "s28_inn_bad_checksum.xlsx" INN_BAD_CHECKSUM_FILE = "s28_inn_bad_checksum.xlsx"
TYPO_ROW = 13 # строка «7701234567» с неверной контрольной суммой в s28
EXPECTED_NAMES = [ EXPECTED_NAMES = [
"s01_variant2_header.xlsx", "s01_variant2_header.xlsx",
"s02_no_outline_indent.xlsx", "s02_no_outline_indent.xlsx",
@ -590,6 +591,13 @@ def test_s28_bad_checksum_inn_row_stays_a_row_and_needs_check(fixtures_dir: Path
"похожа на ИНН 7701234567" in warning and "контрольная сумма не сходится" in warning "похожа на ИНН 7701234567" in warning and "контрольная сумма не сходится" in warning
for warning in warnings_of(outcome) for warning in warnings_of(outcome)
) )
# решение 20: предупреждение названо для строки 13, строка остаётся COUNTERPARTY без ИНН, в OTHER не уходит
assert any(f"строка {TYPO_ROW}: похожа на ИНН 7701234567" in warning for warning in warnings_of(outcome))
typo_rows = [row for row in doc.rows if row.row_number == TYPO_ROW]
assert [(row.row_value, row.group_type, row.counterparty_inn) for row in typo_rows] == [
("7701234567", "COUNTERPARTY", None)
]
assert not [row for row in doc.rows if row.group_type == "OTHER"]
def test_s19_inn_kpp_cell_gives_inn_only(fixtures_dir: Path) -> None: def test_s19_inn_kpp_cell_gives_inn_only(fixtures_dir: Path) -> None: