optimization-dev / backend /tests /test_contract.py
nhamid289's picture
Deploy optimisation from main (6727a1a)
c964813 verified
Raw History Blame Contribute Delete
2.31 kB
"""Replay each contract example in ../contract against a fresh Manager.
Each example lists calls in order, keyed by method name. A call has "args"
(omitted for methods that take none) and either "result" (the expected return
value as JSON; floats are compared to 6 significant figures) or "error" (a
UserError of "kind": "user", whose text contains "message" if given). This
mirrors what @elvis/pyodide's worker sends to the UI.
"""
import json
from pathlib import Path
import pytest
from manager import Manager
CONTRACT_DIR = Path(__file__).parent.parent / "contract"
EXAMPLES = sorted(CONTRACT_DIR.glob("*.json"))
def same(actual, expected) -> bool:
"""Equal JSON values, with floats compared approximately."""
if isinstance(expected, float) or isinstance(actual, float):
return isinstance(actual, (int, float)) and actual == pytest.approx(expected, rel=1e-6, abs=1e-12)
if isinstance(expected, dict):
return isinstance(actual, dict) and actual.keys() == expected.keys() and all(same(actual[k], expected[k]) for k in expected)
if isinstance(expected, list):
return isinstance(actual, list) and len(actual) == len(expected) and all(same(a, e) for a, e in zip(actual, expected))
return actual == expected
@pytest.mark.parametrize("path", EXAMPLES, ids=[p.stem for p in EXAMPLES])
def test_contract_example(path: Path) -> None:
example = json.loads(path.read_text())
manager = Manager()
for method, call in example["calls"].items():
fn = getattr(manager, method)
try:
data = fn(call["args"]) if "args" in call else fn()
except Exception as e:
# The worker treats only UserError as a user error; anything else is a bug
if type(e).__name__ != "UserError":
raise
assert "error" in call, f"{method} raised UserError: {e}"
assert call["error"]["kind"] == "user"
assert call["error"].get("message", "") in str(e)
continue
assert "error" not in call, f"{method} returned {data!r} instead of raising UserError"
# Results must be plain JSON values (no NumPy types) to reach the UI unchanged
actual = json.loads(json.dumps(data))
assert same(actual, call["result"]), f"{method} returned {actual!r}"