fix(statements): убрать лишний пропуск явных соотношений §7, тесты на «отсутствующий код = 0»

Удалён пропуск явных правил, когда в колонке нет членов правой части: спека statement-checks
требует считать отсутствующий код нулём, при ненулевой цели — жёсткое нарушение.
Тест плана test_per_column_and_null_as_zero противоречил спеке (1600 = 1700 без строки 1700 — нарушение)
и заменён двумя тестами по спеке.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
This commit is contained in:
Andrey Epifancev 2026-10-07 11:07:54 +04:00
parent 6eb708f760
commit 4126a44e0e
2 changed files with 17 additions and 12 deletions

View File

@ -188,11 +188,6 @@ def run_checks(
for rule in [*explicit, *sublines]:
if rule not in sublines and rule.target not in amounts:
continue
# Для явных правил (не подстроки): пропустить, если целевой есть, но ни одного члена нет
if rule not in sublines:
term_codes = {code for _, code in rule.terms}
if not any(code in amounts for code in term_codes):
continue
holds, expected, actual = _holds(amounts, rule, rules.tolerance)
if holds:
continue

View File

@ -73,14 +73,24 @@ def test_sublines_soft() -> None:
assert report.failed == ()
def test_per_column_and_null_as_zero() -> None:
report = run_checks(
"BALANCE",
_lines(("1100", {0: "300", 1: None}), ("1200", {0: "600", 1: "5"}), ("1600", {0: "900", 1: "5"})),
[0, 1],
RULES,
def test_target_present_no_terms_hard_failure() -> None:
# Спека: отсутствующий код = 0; если цель присутствует но членов нет, это нарушение
# Правило 1600 = 1100 + 1200, в колонке только 1600=1000 → 1600 ≠ 0, жёсткое нарушение
report = run_checks("BALANCE", _lines(("1600", {0: "1000"})), [0], RULES)
assert any(
item.relation == "1600 = 1100 + 1200" and item.expected == D("1000") and item.actual == D("0")
for item in report.failed
)
def test_target_without_self_sum_hard_failure() -> None:
# Спека: пропуск только если цель отсутствует; если цель есть, правило проверяется
# Правило 1600 = 1700, в колонке только 1600=1000 (нет 1300, 1400, 1500) → нарушение
report = run_checks("BALANCE", _lines(("1600", {0: "1000"})), [0], RULES)
assert any(
item.relation == "1600 = 1700" and item.expected == D("1000") and item.actual == D("0")
for item in report.failed
)
assert report.failed == ()
@pytest.mark.parametrize(