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
|
import pytest
from fixtures import mockPlayer, testSongs
from solo_tool.solo_tool import SoloTool
from solo_tool.midi_controller_actition import ActitionController
CHANNEL = 15
REWIND = 102
SET = 103
JUMP = 104
PLAY = 105
class MidiWrapperMock:
def __init__(self):
self.sentMessages = list()
def setCallback(self, callback):
self.callback = callback
def simulateInput(self, control, channel):
if self.callback is not None:
self.callback(control, channel)
def getLatestMessage(self):
return self.sentMessages[-1]
@pytest.fixture
def soloTool(mockPlayer, testSongs):
st = SoloTool(player=mockPlayer)
for song in testSongs:
st.addSong(song)
return st
@pytest.fixture
def midiWrapperMock(soloTool):
return MidiWrapperMock()
@pytest.fixture
def uut(soloTool, midiWrapperMock):
uut = ActitionController(midiWrapperMock)
uut.setSoloTool(soloTool)
return uut
def test_rewindMessage(uut, soloTool, mockPlayer, midiWrapperMock):
soloTool.song = 1
mockPlayer.position = 0.5
# Sending rewind goes back to the start of the song
midiWrapperMock.simulateInput(REWIND, CHANNEL)
assert mockPlayer.getPlaybackPosition() == 0.0
# Sending again does not change the song
assert soloTool.song == 1
midiWrapperMock.simulateInput(REWIND, CHANNEL)
assert soloTool.song == 1
assert mockPlayer.position == 0.0
def test_setMessage(uut, soloTool, mockPlayer, midiWrapperMock):
callbackValue = None
callbackCalled = False
def callback(keyPoint):
nonlocal callbackCalled, callbackValue
callbackValue = keyPoint
callbackCalled = True
soloTool.registerKeyPointSelectionCallback(callback)
# Sending set sets the current position as the key point
assert soloTool.keyPoint == 0.0
mockPlayer.position = 0.3
midiWrapperMock.simulateInput(SET, CHANNEL)
assert soloTool.keyPoint == 0.3
assert callbackCalled
assert callbackValue == 0.3
# Sending it again does nothing
callbackCalled = False
midiWrapperMock.simulateInput(SET, CHANNEL)
assert soloTool.keyPoint == 0.3
assert not callbackCalled
def test_jumpMessage(uut, soloTool, mockPlayer, midiWrapperMock):
soloTool.keyPoint = 0.5
mockPlayer.position = 0.0
# Sending jump sets the player position to the current key point
midiWrapperMock.simulateInput(JUMP, CHANNEL)
assert mockPlayer.position == 0.5
# Sending again does nothing
midiWrapperMock.simulateInput(JUMP, CHANNEL)
assert mockPlayer.position == 0.5
def test_playMessage(uut, soloTool, mockPlayer, midiWrapperMock):
callbackValue = None
callbackCalled = False
def callback(state):
nonlocal callbackCalled, callbackValue
callbackValue = state
callbackCalled = True
soloTool.registerPlayingStateCallback(callback)
# Sending play starts playing
assert not mockPlayer.isPlaying()
midiWrapperMock.simulateInput(PLAY, CHANNEL)
assert mockPlayer.isPlaying()
assert callbackCalled
assert callbackValue == True
# Sending again stops playing
callbackCalled = False
midiWrapperMock.simulateInput(PLAY, CHANNEL)
assert not mockPlayer.isPlaying()
assert callbackCalled
assert callbackValue == False
|