arm-tabular-parser/api/tests/unit/test_golden_helpers.py
Andrey Epifancev bc143ef140 test: golden-снимки, линтер координат, покрытие словарей; make golden-update
- golden_helpers, scripts/golden_update.py (--check), test_golden на 66 ОСВ и синтетике; make golden-update/golden-check/test-fixtures
- тест покрытия словарей (R-22): счётчик срабатываний Pattern; из osv_headers.yaml удалены неиспользуемые service_columns kpp/code/quantity/currency
- синтетика s14–s16 в генераторе и таблице ожиданий; skip вместо падения при отсутствии osv/synthetic (T11.1); комментарий R-21 в s07 (T11.2)
- линтер: предел адреса 10 вместо 4 (T3.1), обращение cell(3, 4) (T3.8); реальные файлы не фиксируют BU/RUB (T3.9)
- README: golden-процесс; отмечены Task 12 и пункты 4.2, 4.3

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-05 15:28:41 +04:00

78 lines
2.9 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.

"""Помощники golden-снимков: нормализация volatile-полей, путь снимка, формат записи (design D-10)."""
import json
from pathlib import Path
from golden_helpers import SNAPSHOT_DIR, golden_path, normalize_result, snapshot_text, unified_diff
def _result() -> dict:
return {
"schema_version": "1.1",
"job_id": "00000000-0000-0000-0000-000000000000",
"file_id": "00000000-0000-0000-0000-000000000000",
"service": {"name": "tabular-parser", "version": "0.1.0"},
"status": "done",
"metrics": {"duration_ms": 12, "rows": 7, "warnings": ["б", "а"]},
"documents": [{"z": 1, "a": 2}],
}
def test_normalize_removes_exactly_the_volatile_fields() -> None:
normalized = normalize_result(_result())
assert "job_id" not in normalized
assert "file_id" not in normalized
assert normalized["service"] == {"name": "tabular-parser"}
assert normalized["metrics"] == {"rows": 7, "warnings": ["б", "а"]}
assert normalized["documents"] == [{"z": 1, "a": 2}]
def test_normalize_keeps_key_and_warning_order_and_does_not_mutate_input() -> None:
source = _result()
normalized = normalize_result(source)
assert list(normalized) == ["schema_version", "service", "status", "metrics", "documents"]
assert list(normalized["documents"][0]) == ["z", "a"]
assert normalized["metrics"]["warnings"] == ["б", "а"]
assert source == _result()
def test_normalize_tolerates_missing_volatile_fields() -> None:
assert normalize_result({"status": "error"}) == {"status": "error"}
def test_golden_path_mirrors_osv_tree_without_extension(tmp_path: Path) -> None:
root = tmp_path
file = root / "osv" / "rb" / "2025-Q1" / "ОСВ сч 60.xlsx"
assert golden_path(root, file) == root / "golden" / SNAPSHOT_DIR / "rb" / "2025-Q1" / "ОСВ сч 60.json"
synthetic = root / "osv" / "synthetic" / "s01.xlsx"
assert golden_path(root, synthetic) == root / "golden" / SNAPSHOT_DIR / "synthetic" / "s01.json"
def test_golden_path_keeps_dots_inside_the_name(tmp_path: Path) -> None:
file = tmp_path / "osv" / "a" / "сч 62 за 3 квартал 2024 г..xls"
assert golden_path(tmp_path, file).name == "сч 62 за 3 квартал 2024 г..json"
def test_snapshot_text_is_utf8_json_with_indent_and_trailing_newline() -> None:
text = snapshot_text({"имя": "ОСВ", "n": ["1"]})
assert text.endswith("}\n")
assert "ОСВ" in text
assert json.loads(text) == {"имя": "ОСВ", "n": ["1"]}
assert text.startswith('{\n "имя"')
def test_unified_diff_names_files_and_shows_changed_lines() -> None:
diff = unified_diff("a\nb\n", "a\nc\n", name="снимок.json")
assert "--- снимок.json (в fixtures)" in diff
assert "+++ снимок.json (разбор сейчас)" in diff
assert "-b" in diff
assert "+c" in diff
assert unified_diff("a\n", "a\n", name="x") == ""