1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
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
|