gendesign/backend/tests/services/scrapers/test_2464_tep_docstring_truth.py
bot-backend cdf493f345
All checks were successful
Deploy / changes (push) Successful in 9s
Deploy Trade-In / changes (push) Successful in 13s
Deploy / build-frontend (push) Has been skipped
Deploy / deploy-caddy (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy / build-backend (push) Successful in 2m23s
Deploy Trade-In / test (push) Successful in 3m56s
Deploy / build-worker (push) Successful in 4m16s
Deploy Trade-In / build-backend (push) Successful in 1m19s
Deploy / deploy (push) Successful in 1m49s
Deploy / deploy-status (push) Successful in 1s
Deploy / perimeter-smoke (push) Successful in 12s
Deploy Trade-In / deploy (push) Successful in 2m25s
Deploy Trade-In / deploy-status (push) Successful in 1s
Deploy Trade-In / perimeter-smoke (push) Successful in 11s
chore(format): нормализация под ruff 0.15.20 — 161 файл, только формат (#2864) (#3022)
2026-08-21 12:01:52 +00:00

103 lines
6.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.

"""Докстрока `_page_contains_table` не обещает защиты, которой нет (#2464).
Прежняя редакция утверждала:
«Требуем явный caption «Таблица N» — hint-только режим (оглавление,
перекрёстные ссылки) даёт false positive и подавляется.»
Кода подавления в функции никогда не было — это `bool(cap.search(text))`, то есть
обычный поиск подстроки. Строка оглавления «Таблица 11 Баланс территории ..... 34» от
настоящей подписи не отличается: падеж тот же, именительный.
Замер 20.08.2026 уточнил и сам пункт эпика: приведённый в нём пример перекрёстной
ссылки «показатели приведены в таблице 12» регекс НЕ ловит — он требует именительное
«Таблица N». Опасно ровно оглавление, а не любое упоминание. Это зафиксировано
характеризующим тестом, чтобы следующая попытка подавления целилась в признаки
оглавления, а не в падежи.
Обещание защиты, которой нет, опаснее её отсутствия: читающий не станет её
добавлять. Тот же класс, что «объявлено ≠ исполняется».
Почему подавление не реализовано, а докстрока приведена к коду: таблица
`ekb_ppt_tep` на проде пуста (0 строк) — URL в `_SEED_DOCS` заглушка, живых PDF нет,
эвристику отсева оглавления не на чем откалибровать. Правило, придуманное без
образцов, ловит ровно те случаи, которые придумали вместе с ним.
"""
from __future__ import annotations
import inspect
from app.services.scrapers import ekb_ppt_tep_parser as mod
def test_docstring_does_not_promise_suppression_that_is_absent() -> None:
"""Головной: докстрока не должна обещать подавление false positive.
На origin/main она содержит «даёт false positive и подавляется», а в теле
функции — один `cap.search(text)`. Красное значение конкретно: обещание есть,
реализации нет.
"""
doc = inspect.getdoc(mod._page_contains_table) or ""
src = inspect.getsource(mod._page_contains_table)
тело = src.split('"""')[-1]
# Ищем именно ОБЕЩАНИЕ («подавляется»), а не разговор о подавлении: новая
# редакция объясняет, почему подавление НЕ реализовано, и не должна краснеть.
обещает = "подавляется" in doc
реализует = any(kw in тело for kw in ("оглавлен", "leader", "count(", "finditer", "rsplit"))
assert not (обещает and not реализует), (
"докстрока обещает подавление false positive, а в теле только поиск "
f"подстроки:\n{тело.strip()}"
)
def test_docstring_names_the_actual_behaviour() -> None:
"""Докстрока обязана честно называть false positive, а не умалчивать о нём.
Просто убрать обещание было бы недостаточно: молчание читается как «всё
хорошо». Ловит «починку» через вычёркивание неудобной фразы.
"""
doc = (inspect.getdoc(mod._page_contains_table) or "").lower()
assert "false positive" in doc or "оглавлен" in doc, (
"докстрока не предупреждает о ложных срабатываниях на оглавлении"
)
def test_toc_line_really_is_a_false_positive() -> None:
"""Характеризующий: строка оглавления действительно проходит как подпись.
Зелёный с обеих сторон — он фиксирует ФАКТИЧЕСКОЕ поведение, о котором теперь
говорит докстрока. Если кто-то реализует подавление, тест покраснеет и
заставит обновить и докстроку, и его.
"""
оглавление = "СОДЕРЖАНИЕ\nТаблица 11 Баланс территории .......... 34\nТаблица 12 ТЭП .... 36"
assert mod._page_contains_table(оглавление, 11) is True, "оглавление обязано срабатывать"
# А вот перекрёстные ссылки в косвенных падежах регекс НЕ ловит: он требует
# именительное «Таблица N». Пункт эпика приводил «приведены в таблице 12» как
# пример false positive — замер это опроверг, и докстрока теперь говорит точнее.
for мимо in (
"Основные показатели приведены в таблице 12 настоящей записки.",
"см. Таблицу 12 ниже",
"Данные в табл. 12",
):
assert mod._page_contains_table(мимо, 12) is False, f"неожиданно сработало: {мимо!r}"
assert mod._page_contains_table("Никаких таблиц тут нет", 11) is False
def test_seed_comment_does_not_send_to_a_dead_host() -> None:
"""Комментарий сида не должен отправлять искать документ на несуществующем хосте.
`gisogd.ekburg.ru` не резолвится ни с рабочей машины, ни с прод-хоста
(проверено 20.08.2026), а прежний комментарий называл его местом, где «лежит
реальный URL». Живой портал — gisogd66.midural.ru.
"""
from pathlib import Path
src = Path(inspect.getsourcefile(mod)).resolve().parents[3]
текст = (src / "app" / "workers" / "tasks" / "ekb_ppt_tep_sync.py").read_text(encoding="utf-8")
assert "НЕ СУЩЕСТВУЕТ" in текст or "не резолв" in текст.lower(), (
"комментарий сида не предупреждает, что gisogd.ekburg.ru мёртв"
)
assert "gisogd66.midural.ru" in текст, "не назван живой портал ГИСОГД-СО"