Skip to content

Commit 2135bfc

Browse files
authored
improved test coverage for drumactions.js (#4636)
1 parent 6ebd83b commit 2135bfc

File tree

1 file changed

+226
-52
lines changed

1 file changed

+226
-52
lines changed

js/turtleactions/__tests__/DrumActions.test.js

Lines changed: 226 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,16 @@ describe("setupDrumActions", () => {
3131
};
3232
global.DEFAULTDRUM = "defaultDrum";
3333
global.DRUMNAMES = { drum1: ["d1", "drum1"], drum2: ["d2", "drum2"] };
34-
global.NOISENAMES = { noise1: ["n1", "noise1"] };
34+
global.NOISENAMES = { noise1: ["n1", "noise1"], noise2: ["n2", "noise2"] };
3535
global.DEFAULTVOLUME = 100;
3636
global.last = jest.fn(array => array[array.length - 1]);
3737
global._ = jest.fn(msg => msg);
38+
global.MusicBlocks = {
39+
isRun: false
40+
};
41+
global.Mouse = {
42+
getMouseFromTurtle: jest.fn()
43+
};
3844
});
3945

4046
beforeEach(() => {
@@ -51,6 +57,7 @@ describe("setupDrumActions", () => {
5157
clearNoteParams: jest.fn(),
5258
inRhythmRuler: false,
5359
rhythmRuler: { Drums: [], Rulers: [] },
60+
_currentDrumBlock: null
5461
},
5562
errorMsg: jest.fn(),
5663
};
@@ -65,72 +72,239 @@ describe("setupDrumActions", () => {
6572
noteBeatValues: {},
6673
beatFactor: 1,
6774
pushedNote: false,
75+
pitchDrumTable: {}
6876
},
6977
};
7078

7179
activity.turtles.ithTurtle.mockReturnValue(targetTurtle);
80+
global.MusicBlocks.isRun = false;
81+
global.Mouse.getMouseFromTurtle.mockReturnValue(null);
7282
setupDrumActions(activity);
7383
});
7484

75-
it("should return the correct drum name", () => {
76-
const result = Singer.DrumActions.GetDrumname("d1");
77-
expect(result).toBe("drum1");
85+
describe("GetDrumname", () => {
86+
it("should return the correct drum name when given nickname", () => {
87+
const result = Singer.DrumActions.GetDrumname("d1");
88+
expect(result).toBe("drum1");
89+
});
90+
91+
it("should return the default drum for unknown drums", () => {
92+
const result = Singer.DrumActions.GetDrumname("unknown");
93+
expect(result).toBe(DEFAULTDRUM);
94+
});
7895

79-
const result2 = Singer.DrumActions.GetDrumname("unknown");
80-
expect(result2).toBe(DEFAULTDRUM);
81-
});
96+
it("should return http URLs directly", () => {
97+
const httpDrum = "https://example.com/drum.wav";
98+
const result = Singer.DrumActions.GetDrumname(httpDrum);
99+
expect(result).toBe(httpDrum);
100+
});
82101

83-
it("should play a standalone drum sound", () => {
84-
if (!targetTurtle.singer.noteDrums[1]) targetTurtle.singer.noteDrums[1] = [];
85-
Singer.DrumActions.playDrum("d1", 0, 1);
86-
expect(Singer.processNote).toHaveBeenCalledWith(
87-
activity,
88-
expect.any(Number),
89-
false,
90-
expect.anything(),
91-
0,
92-
expect.any(Function)
93-
);
94-
expect(activity.logo.clearNoteParams).toHaveBeenCalledWith(targetTurtle, 1, []);
95-
expect(targetTurtle.singer.inNoteBlock).toContain(1);
96-
expect(targetTurtle.singer.noteDrums[1]).toContain("drum1");
97-
expect(targetTurtle.singer.pushedNote).toBe(true);
102+
it("should handle direct drum names", () => {
103+
const result = Singer.DrumActions.GetDrumname("drum1");
104+
expect(result).toBe("drum1");
105+
});
98106
});
99-
100107

101-
it("should add a drum to an existing note block", () => {
102-
targetTurtle.singer.inNoteBlock.push(2);
103-
targetTurtle.singer.noteDrums[2] = [];
104-
Singer.DrumActions.playDrum("d1", 0, 1);
105-
expect(targetTurtle.singer.noteDrums[2]).toContain("drum1");
106-
});
108+
describe("playDrum", () => {
109+
it("should play a standalone drum sound", () => {
110+
if (!targetTurtle.singer.noteDrums[1]) targetTurtle.singer.noteDrums[1] = [];
111+
Singer.DrumActions.playDrum("d1", 0, 1);
112+
expect(Singer.processNote).toHaveBeenCalledWith(
113+
activity,
114+
expect.any(Number),
115+
false,
116+
expect.anything(),
117+
0,
118+
expect.any(Function)
119+
);
120+
expect(activity.logo.clearNoteParams).toHaveBeenCalledWith(targetTurtle, 1, []);
121+
expect(targetTurtle.singer.inNoteBlock).toContain(1);
122+
expect(targetTurtle.singer.noteDrums[1]).toContain("drum1");
123+
expect(targetTurtle.singer.pushedNote).toBe(true);
124+
});
125+
126+
it("should add a drum to an existing note block", () => {
127+
targetTurtle.singer.inNoteBlock.push(2);
128+
targetTurtle.singer.noteDrums[2] = [];
129+
Singer.DrumActions.playDrum("d1", 0, 1);
130+
expect(targetTurtle.singer.noteDrums[2]).toContain("drum1");
131+
});
107132

108-
it("should set the drum style and add a listener", () => {
109-
Singer.DrumActions.setDrum("d1", 0, 1);
110-
expect(targetTurtle.singer.drumStyle).toContain("drum1");
111-
expect(activity.logo.setDispatchBlock).toHaveBeenCalledWith(1, 0, "_setdrum_0");
112-
expect(activity.logo.setTurtleListener).toHaveBeenCalledWith(0, "_setdrum_0", expect.any(Function));
113-
});
133+
it("should use the drum style if one is set", () => {
134+
targetTurtle.singer.inNoteBlock.push(2);
135+
targetTurtle.singer.noteDrums[2] = [];
136+
targetTurtle.singer.drumStyle.push("drum2");
137+
138+
Singer.DrumActions.playDrum("d1", 0, 1);
139+
140+
expect(targetTurtle.singer.noteDrums[2]).toContain("drum2");
141+
expect(targetTurtle.singer.noteDrums[2]).not.toContain("drum1");
142+
});
114143

115-
it("should map pitch to drum", () => {
116-
Singer.DrumActions.mapPitchToDrum("d1", 0, 1);
117-
expect(targetTurtle.singer.drumStyle).toContain("drum1");
118-
expect(activity.logo.setDispatchBlock).toHaveBeenCalledWith(1, 0, "_mapdrum_0");
119-
expect(activity.logo.setTurtleListener).toHaveBeenCalledWith(0, "_mapdrum_0", expect.any(Function));
144+
it("should initialize synthVolume if not defined", () => {
145+
targetTurtle.singer.inNoteBlock.push(2);
146+
targetTurtle.singer.noteDrums[2] = [];
147+
targetTurtle.singer.synthVolume = {};
148+
149+
Singer.DrumActions.playDrum("d1", 0, 1);
150+
151+
expect(targetTurtle.singer.synthVolume["drum1"]).toEqual([DEFAULTVOLUME]);
152+
expect(targetTurtle.singer.crescendoInitialVolume["drum1"]).toEqual([DEFAULTVOLUME]);
153+
});
154+
155+
it("should not overwrite existing synthVolume and crescendoInitialVolume", () => {
156+
targetTurtle.singer.inNoteBlock.push(5);
157+
targetTurtle.singer.noteDrums[5] = [];
158+
targetTurtle.singer.synthVolume = { drum1: [30] };
159+
targetTurtle.singer.crescendoInitialVolume = { drum1: [40] };
160+
Singer.DrumActions.playDrum("d1", 0, 5);
161+
expect(targetTurtle.singer.synthVolume["drum1"]).toEqual([30]);
162+
expect(targetTurtle.singer.crescendoInitialVolume["drum1"]).toEqual([40]);
163+
});
164+
165+
it("should remove the block from inNoteBlock when the callback is invoked", () => {
166+
if (!targetTurtle.singer.noteDrums[2]) targetTurtle.singer.noteDrums[2] = [];
167+
Singer.DrumActions.playDrum("d1", 0, 2);
168+
expect(targetTurtle.singer.inNoteBlock).toContain(2);
169+
const callback = Singer.processNote.mock.calls[0][5];
170+
callback();
171+
expect(targetTurtle.singer.inNoteBlock).not.toContain(2);
172+
});
120173
});
121174

122-
it("should play noise in a note block", () => {
123-
targetTurtle.singer.inNoteBlock.push(2);
124-
targetTurtle.singer.noteDrums[2] = [];
125-
targetTurtle.singer.noteBeatValues[2] = [];
126-
Singer.DrumActions.playNoise("n1", 0, 1);
127-
expect(targetTurtle.singer.noteDrums[2]).toContain("noise1");
128-
expect(targetTurtle.singer.noteBeatValues[2]).toContain(1);
129-
expect(targetTurtle.singer.pushedNote).toBe(true);
175+
const actionConfigs = [
176+
['setDrum', '_setdrum_0', true],
177+
['mapPitchToDrum', '_mapdrum_0', false],
178+
];
179+
describe.each(actionConfigs)("%s", (actionName, prefix, resetPitchDrumTable) => {
180+
beforeEach(() => {
181+
targetTurtle.singer.drumStyle = [];
182+
targetTurtle.singer.pitchDrumTable = {};
183+
activity.logo.setDispatchBlock.mockClear();
184+
activity.logo.setTurtleListener.mockClear();
185+
global.MusicBlocks.isRun = false;
186+
global.Mouse.getMouseFromTurtle.mockReturnValue(null);
187+
});
188+
189+
it('sets drum style and listener', () => {
190+
Singer.DrumActions[actionName]("d1", 0, 1);
191+
expect(targetTurtle.singer.drumStyle).toContain('drum1');
192+
expect(activity.logo.setDispatchBlock).toHaveBeenCalledWith(1, 0, prefix);
193+
expect(activity.logo.setTurtleListener).toHaveBeenCalledWith(0, prefix, expect.any(Function));
194+
});
195+
196+
it('handles MusicBlocks.isRun case', () => {
197+
const mockMouse = { MB: { listeners: [] } };
198+
global.MusicBlocks.isRun = true;
199+
global.Mouse.getMouseFromTurtle.mockReturnValue(mockMouse);
200+
Singer.DrumActions[actionName]('d1', 0);
201+
expect(targetTurtle.singer.drumStyle).toContain('drum1');
202+
expect(mockMouse.MB.listeners).toContain(prefix);
203+
});
204+
205+
it('handles direct drum name input', () => {
206+
Singer.DrumActions[actionName]('drum2', 0, 1);
207+
expect(targetTurtle.singer.drumStyle).toContain('drum2');
208+
});
209+
210+
it('handles rhythm ruler', () => {
211+
activity.logo.inRhythmRuler = true;
212+
Singer.DrumActions[actionName]('d1', 0, 1);
213+
expect(activity.logo._currentDrumBlock).toBe(1);
214+
expect(activity.logo.rhythmRuler.Drums).toContain(1);
215+
expect(activity.logo.rhythmRuler.Rulers).toHaveLength(1);
216+
});
217+
218+
it('removes drumStyle on listener', () => {
219+
Singer.DrumActions[actionName]('d1', 0, 1);
220+
const listenerFn = activity.logo.setTurtleListener.mock.calls[0][2];
221+
listenerFn();
222+
expect(targetTurtle.singer.drumStyle).toHaveLength(0);
223+
if (resetPitchDrumTable) {
224+
expect(targetTurtle.singer.pitchDrumTable).toEqual({});
225+
}
226+
});
227+
228+
it('only adds listener when blk undefined and not running', () => {
229+
Singer.DrumActions[actionName]('d1', 0);
230+
expect(activity.logo.setDispatchBlock).not.toHaveBeenCalled();
231+
expect(global.Mouse.getMouseFromTurtle).not.toHaveBeenCalled();
232+
expect(activity.logo.setTurtleListener).toHaveBeenCalledWith(
233+
0,
234+
expect.any(String),
235+
expect.any(Function)
236+
);
237+
});
238+
239+
it('skips mouse listener when isRun and mouse null', () => {
240+
global.MusicBlocks.isRun = true;
241+
global.Mouse.getMouseFromTurtle.mockReturnValue(null);
242+
Singer.DrumActions[actionName]('d1', 0);
243+
expect(activity.logo.setDispatchBlock).not.toHaveBeenCalled();
244+
expect(global.Mouse.getMouseFromTurtle).toHaveBeenCalledWith(expect.any(Object));
245+
expect(activity.logo.setTurtleListener).toHaveBeenCalledWith(
246+
0,
247+
expect.any(String),
248+
expect.any(Function)
249+
);
250+
});
130251
});
131252

132-
it("should throw an error for standalone noise block", () => {
133-
Singer.DrumActions.playNoise("n1", 0, 1);
134-
expect(activity.errorMsg).toHaveBeenCalledWith("Noise Block: Did you mean to use a Note block?", 1);
253+
describe("playNoise", () => {
254+
it("should play noise in a note block", () => {
255+
targetTurtle.singer.inNoteBlock.push(2);
256+
targetTurtle.singer.noteDrums[2] = [];
257+
targetTurtle.singer.noteBeatValues[2] = [];
258+
Singer.DrumActions.playNoise("n1", 0, 1);
259+
expect(targetTurtle.singer.noteDrums[2]).toContain("noise1");
260+
expect(targetTurtle.singer.noteBeatValues[2]).toContain(1);
261+
expect(targetTurtle.singer.pushedNote).toBe(true);
262+
});
263+
264+
it("should throw an error for standalone noise block", () => {
265+
Singer.DrumActions.playNoise("n1", 0, 1);
266+
expect(activity.errorMsg).toHaveBeenCalledWith("Noise Block: Did you mean to use a Note block?", 1);
267+
});
268+
269+
it("should handle direct noise name input", () => {
270+
targetTurtle.singer.inNoteBlock.push(2);
271+
targetTurtle.singer.noteDrums[2] = [];
272+
targetTurtle.singer.noteBeatValues[2] = [];
273+
274+
Singer.DrumActions.playNoise("noise2", 0, 1);
275+
276+
expect(targetTurtle.singer.noteDrums[2]).toContain("noise2");
277+
});
278+
279+
it("should initialize synthVolume if not defined", () => {
280+
targetTurtle.singer.inNoteBlock.push(2);
281+
targetTurtle.singer.noteDrums[2] = [];
282+
targetTurtle.singer.noteBeatValues[2] = [];
283+
targetTurtle.singer.synthVolume = {};
284+
285+
Singer.DrumActions.playNoise("n1", 0, 1);
286+
287+
expect(targetTurtle.singer.synthVolume["noise1"]).toEqual([DEFAULTVOLUME]);
288+
expect(targetTurtle.singer.crescendoInitialVolume["noise1"]).toEqual([DEFAULTVOLUME]);
289+
});
290+
291+
it("should push unknown noise names directly", () => {
292+
targetTurtle.singer.inNoteBlock.push(3);
293+
targetTurtle.singer.noteDrums[3] = [];
294+
targetTurtle.singer.noteBeatValues[3] = [];
295+
Singer.DrumActions.playNoise("foo", 0, 3);
296+
expect(targetTurtle.singer.noteDrums[3]).toContain("foo");
297+
});
298+
299+
it("should not reinitialize synthVolume if already defined", () => {
300+
targetTurtle.singer.inNoteBlock.push(4);
301+
targetTurtle.singer.noteDrums[4] = [];
302+
targetTurtle.singer.noteBeatValues[4] = [];
303+
targetTurtle.singer.synthVolume = { noise1: [50] };
304+
targetTurtle.singer.crescendoInitialVolume = { noise1: [60] };
305+
Singer.DrumActions.playNoise("n1", 0, 4);
306+
expect(targetTurtle.singer.synthVolume["noise1"]).toEqual([50]);
307+
expect(targetTurtle.singer.crescendoInitialVolume["noise1"]).toEqual([60]);
308+
});
135309
});
136-
});
310+
});

0 commit comments

Comments
 (0)