"""Keep the frontend-contract tests from drifting back to formatting checks. 211 of the backend test files read frontend sources and assert on literal substrings. That reds the suite on renames and copy changes without proving anything about behaviour, and it is why the suite was failing on main. This guard blocks the two patterns that caused the failures: counting occurrences of a code fragment (a formatting rule) and asserting an exact number of hook calls. New wiring assertions belong in ``tests/frontend_contract.py``; anything about what a user sees belongs in a frontend component test, where the rendered output can be checked. """ from __future__ import annotations import re from pathlib import Path TESTS_DIR = Path(__file__).resolve().parent # Counting a quoted *code* fragment — one containing a bracket, an arrow or a # semicolon — is the pattern to block. Counting values in a list, or counting # how often a URL was requested, are ordinary behavioural assertions. COUNT_ASSERTION = re.compile( r"""assert\s+\w+\.count\(\s*["'][^"']*[(){}=;][^"']*["']\s*\)\s*[=!<>]=""", ) # Tests that predate the guard and still count call sites. The list must only # ever shrink; a new entry means a new formatting test was written. KNOWN_COUNT_ASSERTIONS: set[str] = set() def _test_sources() -> list[tuple[Path, str]]: return [ (path, path.read_text(encoding="utf-8")) for path in sorted(TESTS_DIR.glob("test_*.py")) if path.name != Path(__file__).name ] def test_no_test_counts_occurrences_of_a_source_fragment() -> None: offenders = { path.name for path, source in _test_sources() if COUNT_ASSERTION.search(source) } unexpected = sorted(offenders - KNOWN_COUNT_ASSERTIONS) assert not unexpected, ( "These tests assert on how often a code fragment appears, which is a " f"formatting rule rather than a contract: {unexpected}. Use " "tests/frontend_contract.py to assert on wiring instead." ) def test_the_known_offender_list_does_not_grow_stale() -> None: """A file listed as an exception must still exist and still offend.""" offenders = { path.name for path, source in _test_sources() if COUNT_ASSERTION.search(source) } stale = sorted(KNOWN_COUNT_ASSERTIONS - offenders) assert not stale, f"Remove these from KNOWN_COUNT_ASSERTIONS; they are clean now: {stale}" def test_frontend_contract_helpers_are_available() -> None: from tests.frontend_contract import assert_calls, assert_mentions, assert_wired source = "const total = analyzeSelection(bbox, areaIdForSelection(bbox))" assert_wired(source, "analyzeSelection") assert_calls(source, "analyzeSelection", first_argument="bbox") assert_mentions(source, "AREAIDFORSELECTION")