Files
ServerKit/backend/tests/test_error_shape_ratchet.py
Juan DenisandClaude Fable 5 39a6e35d42 test(contracts): ratchet the four remaining adoption populations
Backend: hand-shaped {'error': ...} bodies in app/api get an AST census
and ceiling (1159) — milestone B's migrate-when-touched policy made
enforceable. Frontend: check-frontend-boundaries.mjs gains adoption
ceilings for raw api.* calls in pages (460, E1), per-page toast.error
extraction (264, E1), form-group blocks (343, F2), and unencoded query
interpolations in services/api (97, C4-interim) — totals that may only go
down, with a slack guard so a ceiling cannot drift above reality.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 00:13:59 -04:00

72 lines
2.6 KiB
Python

"""The hand-shaped-error-body ratchet (plan 76, milestone B closure).
The conversion itself is migrate-when-touched (invariant 9); this ceiling is
what makes that policy real — see ``error_shape_census.py`` for the contract.
"""
from error_shape_census import census, count_file, read_ceiling, total
def test_the_count_is_at_or_below_the_ceiling():
found = census()
count = total(found)
ceiling = read_ceiling()
worst = sorted(found, key=lambda p: -len(found[p]))[:5]
assert count <= ceiling, (
f'{count} hand-shaped error bodies in app/api, ceiling is {ceiling}.\n'
f'Raise a typed error from app.exceptions instead — the global handler '
f'owns the body, the status, and the request id.\n'
f'Heaviest files: ' + ', '.join(f'{p} ({len(found[p])})' for p in worst)
)
def test_the_ceiling_is_not_stale():
count, ceiling = total(), read_ceiling()
assert ceiling - count <= 25, (
f'ceiling {ceiling} is {ceiling - count} above the actual {count}; '
f'run `python tests/error_shape_census.py --update`'
)
class TestTheCensusCountsTheRightThings:
"""A miscounting ratchet is worse than none: it reads green either way."""
def _count(self, tmp_path, source):
path = tmp_path / 'sample.py'
path.write_text(source, encoding='utf-8')
return len(count_file(str(path)))
def test_counts_a_jsonified_error_body(self, tmp_path):
assert self._count(tmp_path, (
"def handler():\n"
" return jsonify({'error': 'nope'}), 404\n"
)) == 1
def test_counts_a_bare_dict_error_body(self, tmp_path):
assert self._count(tmp_path, (
"def handler():\n"
" return {'error': 'nope'}, 400\n"
)) == 1
def test_does_not_count_a_success_body(self, tmp_path):
assert self._count(tmp_path, (
"def handler():\n"
" return jsonify({'success': True, 'data': []}), 200\n"
)) == 0
def test_does_not_count_a_typed_raise(self, tmp_path):
"""What the migration produces must not read as debt."""
assert self._count(tmp_path, (
"def handler():\n"
" raise NotFoundError('nope')\n"
)) == 0
def test_does_not_count_a_variable_body(self, tmp_path):
"""`return body, status` where body was built elsewhere is out of
scope for a syntactic census — the recorder helpers return those."""
assert self._count(tmp_path, (
"def handler():\n"
" body, status = unexpected_response(exc)\n"
" return body, status\n"
)) == 0