- 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
61 lines
2.7 KiB
Python
61 lines
2.7 KiB
Python
"""Доступ к реальным данным из `../fixtures` (отдельный репозиторий, внутренний доступ)."""
|
||
|
||
import os
|
||
from pathlib import Path
|
||
|
||
FIXTURES_ENV = "ARM_KA_FIXTURES"
|
||
OSV_EXTENSIONS = frozenset({".xls", ".xlsx", ".xlsb"})
|
||
_SYNTHETIC = "synthetic"
|
||
|
||
|
||
def resolve_fixtures_dir() -> Path:
|
||
"""Каталог фикстур: `ARM_KA_FIXTURES` или соседний с репозиторием `fixtures/` (workspace)."""
|
||
override = os.environ.get(FIXTURES_ENV)
|
||
if override:
|
||
return Path(override)
|
||
return Path(__file__).resolve().parents[3] / "fixtures"
|
||
|
||
|
||
def fixtures_skip_reason() -> str | None:
|
||
"""Причина пропуска тестов на фикстурах (None — каталог доступен). Текст называет переменную и путь (OQ-81)."""
|
||
root = resolve_fixtures_dir()
|
||
if (root / "osv").is_dir():
|
||
return None
|
||
return f"каталог фикстур не найден: {root} (задайте {FIXTURES_ENV}=<путь к репозиторию fixtures>)"
|
||
|
||
|
||
def synthetic_skip_reason() -> str | None:
|
||
"""Причина пропуска тестов на синтетике: каталог fixtures есть, но `osv/synthetic` отсутствует или пуст
|
||
(например, fixtures на main до слияния ветки с синтетикой). `None` — файлы есть или нет самих fixtures (тогда
|
||
причину даёт `fixtures_skip_reason`)."""
|
||
root = resolve_fixtures_dir()
|
||
if not (root / "osv").is_dir() or synthetic_files(root):
|
||
return None
|
||
return f"нет синтетики: {root / 'osv' / _SYNTHETIC} отсутствует или пуст (сгенерируйте: см. README fixtures)"
|
||
|
||
|
||
def osv_fixture_files(root: Path) -> list[Path]:
|
||
"""Все `*.xls/*.xlsx/*.xlsb` под `root/osv`, кроме каталога synthetic; отсортированы."""
|
||
osv = root / "osv"
|
||
if not osv.is_dir():
|
||
return []
|
||
synthetic = osv / _SYNTHETIC
|
||
return sorted(
|
||
path
|
||
for path in osv.rglob("*")
|
||
if path.is_file() and path.suffix.lower() in OSV_EXTENSIONS and synthetic not in path.parents
|
||
)
|
||
|
||
|
||
def synthetic_files(root: Path) -> list[Path]:
|
||
"""Файлы Excel `root/osv/synthetic/*.xls|xlsx|xlsb` (скрытые и пояснения вроде `README.md` не считаются);
|
||
отсортированы."""
|
||
directory = root / "osv" / _SYNTHETIC
|
||
if not directory.is_dir():
|
||
return []
|
||
return sorted(
|
||
path
|
||
for path in directory.iterdir()
|
||
if path.is_file() and not path.name.startswith(".") and path.suffix.lower() in OSV_EXTENSIONS
|
||
)
|