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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
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
|