diff options
-rw-r--r-- | notifier.py | 15 | ||||
-rw-r--r-- | notifier_unittest.py | 32 | ||||
-rw-r--r-- | solo_tool.py | 17 | ||||
-rw-r--r-- | solo_tool_integrationtest.py | 37 |
4 files changed, 97 insertions, 4 deletions
diff --git a/notifier.py b/notifier.py new file mode 100644 index 0000000..1a68c56 --- /dev/null +++ b/notifier.py @@ -0,0 +1,15 @@ + +class Notifier: + PLAYING_STATE_EVENT = 0 + + def __init__(self): + self._callbacks = dict() + + def registerCallback(self, event, callback): + if event not in self._callbacks: + self._callbacks[event] = list() + self._callbacks[event].append(callback) + + def notify(self, event): + for callback in self._callbacks.get(event, list()): + callback() diff --git a/notifier_unittest.py b/notifier_unittest.py new file mode 100644 index 0000000..721a5fd --- /dev/null +++ b/notifier_unittest.py @@ -0,0 +1,32 @@ +import pytest + +from notifier import Notifier + +@pytest.fixture +def uut(): + return Notifier() + +def checkEvent(uut, event): + callbacks = 2 + calledFlags = [False] * 2 + + def createCallback(i): + def cb(): + nonlocal calledFlags + calledFlags[i] = True + return cb + + for i in range(0, callbacks): + uut.registerCallback(event, createCallback(i)) + + assert not any(calledFlags) + uut.notify(event) + assert all(calledFlags) + +def test_allEvents(uut): + checkEvent(uut, Notifier.PLAYING_STATE_EVENT) + +def test_eventWithoutRegisteredCallbacks(uut): + uut.notify(Notifier.PLAYING_STATE_EVENT) + # expect no crash + diff --git a/solo_tool.py b/solo_tool.py index 6581f5e..5e3a1fd 100644 --- a/solo_tool.py +++ b/solo_tool.py @@ -3,6 +3,7 @@ import os from playlist import Playlist from abcontroller import ABController from session_manager import SessionManager +from notifier import Notifier from player_vlc import Player class SoloTool: @@ -11,6 +12,7 @@ class SoloTool: self._playlist = Playlist(self._playlistCallback) self._abController = ABController(enabled=False, callback=self._abControllerCallback) self._sessionManager = SessionManager(self._playlist, self._abController) + self._notifier = Notifier() def _playlistCallback(self, path): self._player.setCurrentSong(path) @@ -78,13 +80,19 @@ class SoloTool: self._sessionManager.saveSession(f) def play(self): - self._player.play() + self._playerCommand(self._player.play) def pause(self): - self._player.pause() + self._playerCommand(self._player.pause) def stop(self): - self._player.stop() + self._playerCommand(self._player.stop) + + def _playerCommand(self, f): + playing = self.isPlaying() + f() + if playing != self.isPlaying(): + self._notifier.notify(Notifier.PLAYING_STATE_EVENT) def isPlaying(self): return self._player.isPlaying() @@ -101,3 +109,6 @@ class SoloTool: def setPlaybackVolume(self, volume): self._player.setPlaybackVolume(volume) + def registerPlayingStateCallback(self, callback): + self._notifier.registerCallback(Notifier.PLAYING_STATE_EVENT, callback) + diff --git a/solo_tool_integrationtest.py b/solo_tool_integrationtest.py index 6022454..117e539 100644 --- a/solo_tool_integrationtest.py +++ b/solo_tool_integrationtest.py @@ -311,7 +311,6 @@ def test_setTemporaryLimits(uut, mockPlayer): assert mockPlayer.position == abLimits[1][0] def test_jumpToA(uut, mockPlayer): - song = "test.flac" abLimits = (0.2, 0.4) initialPosition = 0.8 @@ -324,3 +323,39 @@ def test_jumpToA(uut, mockPlayer): uut.jumpToA() assert mockPlayer.position == abLimits[0] +def test_playingStateNotification(uut, mockPlayer): + song = "test.flac" + uut.addSong(song) + uut.setSong(0) + + called = False + def callback(): + nonlocal called + called = True + + uut.registerPlayingStateCallback(callback) + + assert mockPlayer.state == MockPlayer.STOPPED + assert not called + + uut.play() + assert called + called = False + uut.play() + assert not called + + uut.pause() + assert called + called = False + uut.pause() + assert not called + + uut.play() + assert called + called = False + + uut.stop() + assert called + called = False + uut.stop() + assert not called |