feat(media): Protocol, Factory und Noop-Controller
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||||
@@ -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()
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user