diff --git a/tests/test_media_factory.py b/tests/test_media_factory.py new file mode 100644 index 0000000..b3965ec --- /dev/null +++ b/tests/test_media_factory.py @@ -0,0 +1,40 @@ +"""Tests für whisper_local.media Factory-Dispatch.""" + +import sys +from unittest.mock import patch + +import pytest + +from whisper_local.media import MediaController, create_media_controller +from whisper_local.media._noop import NoopController + + +def test_factory_returns_noop_when_disabled(): + controller = create_media_controller(enabled=False) + assert isinstance(controller, NoopController) + + +def test_factory_returns_noop_on_non_linux(): + with patch.object(sys, "platform", "win32"): + controller = create_media_controller(enabled=True) + assert isinstance(controller, NoopController) + + +@pytest.mark.skipif(sys.platform != "linux", reason="MPRIS is Linux-only") +def test_factory_returns_mpris_on_linux_when_enabled(): + from whisper_local.media._mpris import MprisController + + controller = create_media_controller(enabled=True) + assert isinstance(controller, MprisController) + + +@pytest.mark.asyncio +async def test_noop_controller_pause_is_noop(): + controller = NoopController() + await controller.pause() # Darf nicht werfen + await controller.resume() # Darf nicht werfen + + +def test_noop_controller_satisfies_protocol(): + controller = NoopController() + assert isinstance(controller, MediaController) diff --git a/whisper_local/media/__init__.py b/whisper_local/media/__init__.py new file mode 100644 index 0000000..90bf3d0 --- /dev/null +++ b/whisper_local/media/__init__.py @@ -0,0 +1,26 @@ +"""Media-Steuerung — plattformspezifische Backends hinter gemeinsamem Interface.""" + +import sys +from typing import Protocol, runtime_checkable + + +@runtime_checkable +class MediaController(Protocol): + async def pause(self) -> None: ... + async def resume(self) -> None: ... + + +def create_media_controller(enabled: bool) -> MediaController: + """Erstellt den plattformspezifischen Media-Controller. + + `enabled=False` → immer NoopController. Auf Nicht-Linux-Plattformen + wird aktuell ebenfalls der NoopController zurückgegeben. + """ + if not enabled: + from whisper_local.media._noop import NoopController + return NoopController() + if sys.platform == "linux": + from whisper_local.media._mpris import MprisController + return MprisController() + from whisper_local.media._noop import NoopController + return NoopController() diff --git a/whisper_local/media/_mpris.py b/whisper_local/media/_mpris.py new file mode 100644 index 0000000..c495444 --- /dev/null +++ b/whisper_local/media/_mpris.py @@ -0,0 +1,16 @@ +"""Linux-MPRIS-Implementierung. Vollständige Logik folgt in späteren Tasks.""" + +import logging + +logger = logging.getLogger(__name__) + + +class MprisController: + def __init__(self) -> None: + self._paused: list[str] = [] + + async def pause(self) -> None: + return None + + async def resume(self) -> None: + return None diff --git a/whisper_local/media/_noop.py b/whisper_local/media/_noop.py new file mode 100644 index 0000000..8f4b366 --- /dev/null +++ b/whisper_local/media/_noop.py @@ -0,0 +1,9 @@ +"""No-Op-Fallback für Plattformen ohne MPRIS oder wenn das Feature aus ist.""" + + +class NoopController: + async def pause(self) -> None: + return None + + async def resume(self) -> None: + return None