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_songSelectionEdgeCases(uut, mockPlayer, testSongs): # When no songs are available, selecting has no effect uut.song = 0 assert uut.song == None assert mockPlayer.currentSong == None for song in testSongs: uut.addSong(song) # 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_songAdditionEdgeCases(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] # Same song cannot be added twice uut.addSong(testSongs[0]) assert uut.song == 0 assert mockPlayer.currentSong == testSongs[0] assert uut.songs == testSongs # Songs must exist in the filesystem with pytest.raises(FileNotFoundError): uut.addSong("/not/a/real/file") assert uut.song == 0 assert mockPlayer.currentSong == testSongs[0] assert uut.songs == testSongs def test_songSelectionNotification(uut, testSongs): selectionCalled = False selectionValue = None def selectionCallback(value): nonlocal selectionCalled, selectionValue selectionCalled = True selectionValue = value uut.registerSongSelectionCallback(selectionCallback) assert not selectionCalled # Adding the first song triggers because the song is automatically selected uut.addSong(testSongs[0]) assert selectionCalled assert selectionValue == 0 selectionCalled = False # Adding more songs does not trigger for i, song in enumerate(testSongs[1:]): uut.addSong(song) assert not selectionCalled # Selecting another song triggers uut.song = 1 assert selectionCalled assert selectionValue == 1 selectionCalled = False # Selecting the currently selected song does not trigger uut.song = 1 assert not selectionCalled def test_songListNotification(uut, testSongs): listCalled = False listValue = None def listCallback(value): nonlocal listCalled, listValue listCalled = True listValue = value uut.registerSongListCallback(listCallback) assert not listCalled # Adding the first song triggers uut.addSong(testSongs[0]) assert listCalled assert listValue == testSongs[0:1] listCalled = False # Adding more songs triggers for i, song in enumerate(testSongs[1:]): uut.addSong(song) assert listCalled assert listValue == testSongs[0:i + 2] listCalled = False # Modifying the list in place does not trigger uut.songs.append("something") assert not listCalled # Adding an existing song does not trigger uut.addSong(testSongs[0]) assert not listCalled