aboutsummaryrefslogtreecommitdiffstats
path: root/solo-tool-project/src
diff options
context:
space:
mode:
Diffstat (limited to 'solo-tool-project/src')
-rw-r--r--solo-tool-project/src/solo_tool/notifier.py5
-rw-r--r--solo-tool-project/src/solo_tool/solo_tool.py16
-rw-r--r--solo-tool-project/src/solo_tool/solo_tool_songs_integrationtest.py112
3 files changed, 14 insertions, 119 deletions
diff --git a/solo-tool-project/src/solo_tool/notifier.py b/solo-tool-project/src/solo_tool/notifier.py
index dadf85c..ac1c736 100644
--- a/solo-tool-project/src/solo_tool/notifier.py
+++ b/solo-tool-project/src/solo_tool/notifier.py
@@ -3,8 +3,9 @@ class Notifier:
PLAYBACK_VOLUME_EVENT = 1
PLAYBACK_RATE_EVENT = 2
CURRENT_SONG_EVENT = 3
- CURRENT_KEY_POINT_EVENT = 3
- KEY_POINTS_EVENT = 4
+ SONG_LIST_EVENT = 4
+ CURRENT_KEY_POINT_EVENT = 5
+ KEY_POINTS_EVENT = 6
def __init__(self, player):
self._callbacks = dict()
diff --git a/solo-tool-project/src/solo_tool/solo_tool.py b/solo-tool-project/src/solo_tool/solo_tool.py
index f5b05c0..bc20013 100644
--- a/solo-tool-project/src/solo_tool/solo_tool.py
+++ b/solo-tool-project/src/solo_tool/solo_tool.py
@@ -4,8 +4,8 @@ from .notifier import Notifier
from .player_vlc import Player
class SoloTool:
- def __init__(self, playerOverride=None):
- self._player = Player() if playerOverride is None else playerOverride
+ def __init__(self, player=None):
+ self._player = Player() if player is None else player
self._notifier = Notifier(self._player)
self._songs = []
self._song = None
@@ -31,8 +31,11 @@ class SoloTool:
def addSong(self, path: str) -> None:
if not os.path.isfile(path):
raise FileNotFoundError(path)
+ if path in self._songs:
+ return
self._songs.append(path)
self._keyPoints.append([])
+ self._notifier.notify(Notifier.SONG_LIST_EVENT, self.songs)
if self.song is None:
self.song = 0
@@ -116,6 +119,12 @@ class SoloTool:
if new is not None and new != self._player.getPlaybackPosition():
self._player.setPlaybackPosition(min(max(0.0, new), 1.0))
+ def registerSongSelectionCallback(self, callback):
+ self._notifier.registerCallback(Notifier.CURRENT_SONG_EVENT, callback)
+
+ def registerSongListCallback(self, callback):
+ self._notifier.registerCallback(Notifier.SONG_LIST_EVENT, callback)
+
def registerPlayingStateCallback(self, callback):
self._notifier.registerCallback(Notifier.PLAYING_STATE_EVENT, callback)
@@ -125,9 +134,6 @@ class SoloTool:
def registerRateCallback(self, callback):
self._notifier.registerCallback(Notifier.PLAYBACK_RATE_EVENT, callback)
- def registerCurrentSongCallback(self, callback):
- self._notifier.registerCallback(Notifier.CURRENT_SONG_EVENT, callback)
-
def registerCurrentKeyPointCallback(self, callback):
self._notifier.registerCallback(Notifier.CURRENT_KEY_POINT_EVENT, callback)
diff --git a/solo-tool-project/src/solo_tool/solo_tool_songs_integrationtest.py b/solo-tool-project/src/solo_tool/solo_tool_songs_integrationtest.py
deleted file mode 100644
index 0023d81..0000000
--- a/solo-tool-project/src/solo_tool/solo_tool_songs_integrationtest.py
+++ /dev/null
@@ -1,112 +0,0 @@
-import pathlib
-import shutil
-import pytest
-
-from solo_tool.solo_tool import SoloTool
-from player_mock import Player as MockPlayer
-
-@pytest.fixture
-def mockPlayer():
- return MockPlayer()
-
-@pytest.fixture
-def uut(mockPlayer):
- return SoloTool(player=mockPlayer)
-
-@pytest.fixture
-def testSongs():
- return [
- "test.flac",
- "test.mp3"
- ]
-
-def test_songSelectionFlow(uut, mockPlayer, testSongs):
- # Initially, song list is empty and no song is selected
- assert uut.song is None
- assert mockPlayer.currentSong == None
- assert uut.songs == []
-
- # When the first song is added, it is selected automatically
- uut.addSong(testSongs[0])
- assert uut.song == 0
- assert mockPlayer.currentSong == testSongs[0]
- assert uut.songs == testSongs[0:1]
-
- # Subsequently added songs are not selected automatically
- # Song list order is addition order
- for i, song in enumerate(testSongs[1:]):
- uut.addSong(testSongs[1])
- assert uut.song == 0
- assert mockPlayer.currentSong == testSongs[0]
- assert uut.songs == testSongs[0:i + 2]
-
- # Songs are selected by index
- for i, s in enumerate(uut.songs):
- uut.song = i
- assert uut.song == i
- assert mockPlayer.currentSong == uut.songs[i]
-
-def test_songSelectionSanitization(uut, mockPlayer, testSongs):
- for song in testSongs:
- uut.addSong(song)
-
- # Modifying the song list directly has no effect
- uut.songs.append("something")
- assert uut.songs == testSongs
- assert mockPlayer.currentSong == testSongs[0]
-
- # The current song cannot be de-selected
- uut.song = None
- assert uut.song == 0
- assert mockPlayer.currentSong == testSongs[0]
-
- # Non-existent songs cannot be selected
- uut.song = -1
- assert uut.song == 0
- assert mockPlayer.currentSong == testSongs[0]
-
- uut.song = len(testSongs)
- assert uut.song == 0
- assert mockPlayer.currentSong == testSongs[0]
-
-def test_addInexistentSong(uut, mockPlayer):
- # Songs must exist in the filesystem
- song = "not/a/real/file"
-
- with pytest.raises(FileNotFoundError):
- uut.addSong(song)
-
- assert uut.songs == []
- assert uut.song is None
-
-def test_songSelectionNotification(uut, testSongs):
- called = False
- receivedValue = None
- def callback(value):
- nonlocal called, receivedValue
- called = True
- receivedValue = value
-
- uut.registerSongSelectionCallback(callback)
- assert not called
-
- # Adding the first song triggers because the song is automatically selected
- uut.addSong(songs[0])
- assert called
- assert receivedValue == 0
- called = False
-
- # Adding more songs does not trigger since the selection doesn't change
- for song in testSongs:
- uut.addSong(song)
- assert not called
-
- # Selecting another song triggers
- uut.song = 1
- assert called
- assert receivedValue == 1
- called = False
-
- # Selecting the currently selected song does not trigger
- uut.song = 1
- assert not called