Манифест statements_manifest.yaml по 18 реальным файлам statements-xlsx (сверен прогоном парсера, R-13, OQ-137), property-тест по манифесту, снимки форм в golden_helpers/golden_update/test_golden, словари форм в покрытии, синтетика st06 для вариантов заголовков. Мёртвые записи словаря удалены (name_caption, метки okved и okud_label) либо покрыты st06. Refs #14 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: cedd7915-2efe-41e5-988c-a9117033598b
81 lines
3.9 KiB
Python
81 lines
3.9 KiB
Python
"""Перезапись golden-снимков разбора ОСВ и форм и diff изменившихся (design D-10).
|
||
|
||
Из каталога `api/`: `ENV_FILE=.env.test .venv/bin/python scripts/golden_update.py [--check]` (то же — `make
|
||
golden-update`, из корня репозитория). Файлы — `fixtures/osv/**` включая `synthetic/`; снимки — в
|
||
`fixtures/golden/expected_osv_parse/` (зеркало `osv/`); файлы форм — `fixtures/statements-xlsx/**` (включая
|
||
`synthetic/`), снимки — в `fixtures/golden/expected_statement_parse/`. Без флага снимки перезаписываются, для
|
||
изменившихся печатается unified diff; `--check` только сравнивает (код возврата 1, если снимки расходятся с
|
||
разбором). Снимки части, для которой нет исходного каталога (`osv/synthetic` отсутствует или пуст, нет реальных
|
||
файлов), не удаляются.
|
||
|
||
Снимок — регрессия, а не оракул: перед коммитом в репозиторий fixtures просмотрите diff (`git -C ../fixtures diff`)
|
||
и убедитесь, что каждое изменение — следствие намеренной правки парсера.
|
||
"""
|
||
|
||
import argparse
|
||
import sys
|
||
from collections.abc import Sequence
|
||
from pathlib import Path
|
||
|
||
API_ROOT = Path(__file__).resolve().parents[1]
|
||
sys.path[:0] = [str(API_ROOT), str(API_ROOT / "tests")]
|
||
|
||
from fixtures_helpers import ( # noqa: E402
|
||
fixtures_skip_reason,
|
||
osv_dkb_golden_files,
|
||
osv_fixture_files,
|
||
resolve_fixtures_dir,
|
||
statement_files,
|
||
statement_synthetic_files,
|
||
synthetic_files,
|
||
)
|
||
from golden_helpers import sync_snapshots # noqa: E402
|
||
|
||
from src.parser import get_parser # noqa: E402
|
||
|
||
EXIT_OK = 0
|
||
EXIT_DIFFERS = 1
|
||
EXIT_NO_FIXTURES = 3
|
||
|
||
|
||
def main(argv: Sequence[str] | None = None) -> int:
|
||
parser = argparse.ArgumentParser(description="Golden-снимки разбора ОСВ: перезапись + diff, либо --check")
|
||
parser.add_argument("--check", action="store_true", help="только сравнить снимки с разбором, ничего не писать")
|
||
options = parser.parse_args(argv)
|
||
|
||
reason = fixtures_skip_reason()
|
||
if reason is not None:
|
||
print(reason, file=sys.stderr)
|
||
return EXIT_NO_FIXTURES
|
||
root = resolve_fixtures_dir()
|
||
files = [
|
||
*osv_fixture_files(root),
|
||
*osv_dkb_golden_files(root),
|
||
*synthetic_files(root),
|
||
*statement_files(root),
|
||
*statement_synthetic_files(root),
|
||
]
|
||
report = sync_snapshots(root, files, get_parser(), write=not options.check)
|
||
|
||
for diff in report.diffs:
|
||
sys.stdout.write(diff if diff.endswith("\n") else diff + "\n")
|
||
mode = "режим --check, ничего не записано" if options.check else "снимки записаны"
|
||
print(
|
||
f"файлов: {len(files)}; без изменений: {report.unchanged}; новых: {len(report.created)}; "
|
||
f"изменено: {len(report.changed)}; лишних снимков: {len(report.orphans)}; сохранено без исходного каталога: "
|
||
f"{len(report.protected)} ({mode})",
|
||
file=sys.stderr,
|
||
)
|
||
for orphan in report.orphans:
|
||
print(f"лишний снимок{'' if options.check else ' удалён'}: {orphan}", file=sys.stderr)
|
||
for kept in report.protected:
|
||
print(f"снимок сохранён (нет исходного каталога): {kept}", file=sys.stderr)
|
||
return EXIT_DIFFERS if options.check and report.differs else EXIT_OK
|
||
|
||
|
||
if __name__ == "__main__":
|
||
reconfigure = getattr(sys.stdout, "reconfigure", None)
|
||
if reconfigure is not None:
|
||
reconfigure(encoding="utf-8")
|
||
raise SystemExit(main())
|