poolcoach-analyzer / tests /conftest.py
masterdanh's picture
refactor(analyzer): translate identifiers and comments to English
876aff5
Raw History Blame Contribute Delete
2.39 kB
"""Shared test bootstrap.
The repository is not installed as a package, so `src/` and the repository
root have to be pushed onto `sys.path` BEFORE anything imports
`poolcoach_cv` or `app`. Doing it here rather than relying on `app/main.py`
(which also inserts src, but only once imported) keeps pass/fail independent
of pytest's collection order.
Principle: the tests check CONTRACTS (response shapes, transport behaviour,
front-end wiring), never physics. Real pooltool is heavy (~20s to import
plus the Numba JIT) and none of these gates need it, so a stub goes into
sys.modules before anything else is imported.
"""
from __future__ import annotations
import sys
import types
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
for _p in (ROOT / "src", ROOT):
if str(_p) not in sys.path:
sys.path.insert(0, str(_p))
import fakeredis # noqa: E402
import pytest # noqa: E402
def _install_pooltool_stub() -> None:
"""Stub `pooltool` and `pooltool.constants` as empty modules.
`poolcoach_cv.resim` and `poolcoach_sim.table` import pooltool LAZILY
inside their functions, so an empty stub is enough for every module to
import. The stub deliberately lacks `System`/`simulate`/`Table`: a test
that strays into the physics layer raises AttributeError immediately
instead of quietly running a 40 second simulation.
"""
if "pooltool" in sys.modules:
return
pt = types.ModuleType("pooltool")
constants = types.ModuleType("pooltool.constants")
constants.pocketed = "pocketed"
pt.constants = constants
sys.modules["pooltool"] = pt
sys.modules["pooltool.constants"] = constants
_install_pooltool_stub()
class FakeQueue:
"""A shared FakeServer plus two separate connections (API and worker).
The two connections behave like two real processes: the API uses the
module client installed by `jobqueue.setup(client=...)` and the fake
worker uses the other one.
"""
def __init__(self):
self.server = fakeredis.FakeServer()
self.api = fakeredis.FakeStrictRedis(server=self.server,
decode_responses=True)
self.worker = fakeredis.FakeStrictRedis(server=self.server,
decode_responses=True)
@pytest.fixture
def fake_queue() -> FakeQueue:
return FakeQueue()