Files
tavolo/server/tests/helpers/asynctest.py
T
woggioni 5a73601ddf Split backend into tavolo-platform, tavolo-scopone and tavolo-app packages
Move the game-independent machinery (lobby, live-game store, websocket,
deadline scheduler, match history, leaderboards) into a new
tavolo-platform distribution behind a GameEngine contract, the scopone
scientifico rules plus a platform adapter into tavolo-scopone, and keep
only the composition root in tavolo-app. The three distributions share
the tavolo namespace (PEP 420, kaya-style monorepo).

Match history becomes fully generic: Match carries the engine's result
JSON and MatchPlayer points/details instead of scopone-shaped team
columns (migration 3 backfills existing rows). Lobby creation takes an
opaque per-game options object and websocket actions dispatch to the
session's engine.

Tests: platform suite runs against a DummyEngine toy game, scopone
keeps the rules tests plus new adapter tests, server/tests covers the
wired stack end to end (194 tests, was 143).
2026-09-19 07:28:58 +00:00

36 lines
1.2 KiB
Python

"""An ``async_test`` that also closes the app's Tortoise context.
``pwo.async_test`` runs every test in a fresh event loop (``asyncio.Runner``).
The app's :class:`~tavolo.platform.tortoise_mixin.TortoiseMixin` builds one
``TortoiseContext`` per loop, so without an explicit close each test orphans
an aiosqlite connection whose non-daemon worker thread keeps the interpreter
alive after the suite reports "OK".
"""
from __future__ import annotations
import asyncio
from functools import wraps
from typing import Any, Callable, Coroutine
from tavolo.app import scheduler, tortoise_mixin
def async_test(coro: Callable[..., Coroutine[Any, Any, None]]) -> Callable[..., None]:
"""Like ``pwo.async_test``, but close the Tortoise context and stop the
deadline consumer afterwards."""
@wraps(coro)
def wrapper(*args: Any, **kwargs: Any) -> None:
async def run() -> None:
loop = asyncio.get_running_loop()
try:
await coro(*args, **kwargs)
finally:
scheduler.stop_consumer(loop)
await tortoise_mixin.aclose()
with asyncio.Runner() as runner:
runner.run(run())
return wrapper