# retoor import ast from pathlib import Path PACKAGE = Path(__file__).resolve().parents[2] / "devplacepy" def _json_error_calls(): for path in sorted(PACKAGE.rglob("*.py")): tree = ast.parse(path.read_text(), filename=str(path)) for node in ast.walk(tree): if not isinstance(node, ast.Call): continue name = node.func.attr if isinstance(node.func, ast.Attribute) else getattr(node.func, "id", "") if name == "json_error" and node.args: yield path.relative_to(PACKAGE.parent), node def test_json_error_never_receives_a_message_as_its_status(): offenders = [ f"{path}:{node.lineno}" for path, node in _json_error_calls() if isinstance(node.args[0], ast.Constant) and isinstance(node.args[0].value, str) ] assert not offenders, ( "json_error(status_code, message) - a string in the status position builds a " f"JSONResponse with a non-int status and raises TypeError at request time: {offenders}" ) def test_json_error_never_receives_a_status_as_its_message(): offenders = [ f"{path}:{node.lineno}" for path, node in _json_error_calls() if len(node.args) > 1 and isinstance(node.args[1], ast.Constant) and isinstance(node.args[1].value, int) ] assert not offenders, ( "json_error(status_code, message) - an int in the message position means the " f"arguments were swapped: {offenders}" ) def test_every_json_error_status_is_a_real_http_error_code(): for path, node in _json_error_calls(): first = node.args[0] if isinstance(first, ast.Constant) and isinstance(first.value, int): assert 400 <= first.value <= 599, f"{path}:{node.lineno} status {first.value}"