Skip to content

Commit 82f7d6d

Browse files
committed
dk
1 parent c9cc194 commit 82f7d6d

File tree

3 files changed

+649
-157
lines changed

3 files changed

+649
-157
lines changed

js/base64Utils.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ function base64Decode(str) {
2828
}
2929

3030
export default { base64Encode, base64Decode };
31+
//module.exports = { base64Encode, base64Decode };
Lines changed: 383 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,383 @@
1+
/* eslint-disable no-trailing-spaces */
2+
/* eslint-disable indent */
3+
/* eslint-disable quotes */
4+
/* eslint-disable no-undef */
5+
// Mock global window for btoa function
6+
global._ = jest.fn((str) => str);
7+
global.window = {
8+
btoa: jest.fn((str) => Buffer.from(str, "utf8").toString("base64"))
9+
};
10+
11+
const {
12+
setOctaveRatio,
13+
getOctaveRatio,
14+
TEMPERAMENT,
15+
TEMPERAMENTS,
16+
INITIALTEMPERAMENTS,
17+
PreDefinedTemperaments,
18+
getTemperamentsList,
19+
getTemperament,
20+
getTemperamentKeys,
21+
addTemperamentToList,
22+
addTemperamentToDictionary,
23+
updateTemperaments,
24+
deleteTemperamentFromList,
25+
DEFAULTINVERT,
26+
DEFAULTMODE,
27+
customMode,
28+
getInvertMode,
29+
getIntervalNumber,
30+
getIntervalDirection,
31+
getIntervalRatio,
32+
getModeNumbers,
33+
getDrumIndex,
34+
getDrumName,
35+
getDrumSymbol,
36+
getFilterTypes
37+
} = require("../musicutils");
38+
39+
40+
describe("musicutils", () => {
41+
it("should set and get Octave Ratio", () => {
42+
setOctaveRatio(4);
43+
const octaveR = getOctaveRatio();
44+
expect(octaveR).toBe(4);
45+
});
46+
});
47+
48+
describe("Temperament Functions", () => {
49+
test("getTemperamentsList should return the list of temperaments", () => {
50+
expect(getTemperamentsList()).toEqual([
51+
[_("Equal (12EDO)"), "equal", "equal"],
52+
[_("Equal (5EDO)"), "equal5", "equal5"],
53+
[_("Equal (7EDO)"), "equal7", "equal7"],
54+
[_("Equal (19EDO)"), "equal19", "equal19"],
55+
[_("Equal (31EDO)"), "equal31", "equal31"],
56+
[_("5-limit Just Intonation"), "just intonation", "just intonation"],
57+
[_("Pythagorean (3-limit JI)"), "Pythagorean", "Pythagorean"],
58+
[_("Meantone") + " (1/3)", "1/3 comma meantone", "meantone (1/3)"],
59+
[_("Meantone") + " (1/4)", "1/4 comma meantone", "meantone (1/4)"],
60+
[_("Custom"), "custom", "custom"]
61+
]);
62+
});
63+
64+
describe("getTemperament", () => {
65+
it("should return the correct temperament for a valid key", () => {
66+
const equalTemperament = getTemperament("equal");
67+
expect(equalTemperament).toHaveProperty("perfect 1");
68+
expect(equalTemperament).toHaveProperty("minor 2");
69+
expect(equalTemperament).toHaveProperty("pitchNumber", 12);
70+
});
71+
72+
it('should return the correct temperament for equal5 key', () => {
73+
const equal5Temperament = getTemperament("equal5");
74+
expect(equal5Temperament).toHaveProperty("perfect 1");
75+
expect(equal5Temperament).toHaveProperty("minor 2");
76+
expect(equal5Temperament).toHaveProperty("pitchNumber", 5);
77+
});
78+
79+
it("should return undefined for an invalid key", () => {
80+
const invalidTemperament = getTemperament("invalid");
81+
expect(invalidTemperament).toBeUndefined();
82+
});
83+
});
84+
85+
describe("getTemperamentKeys", () => {
86+
it("should return an array with the correct length", () => {
87+
const keys = getTemperamentKeys();
88+
expect(keys.length).toBe(10);
89+
});
90+
91+
it('should return an array containing all keys', () => {
92+
const keys = getTemperamentKeys();
93+
expect(keys).toEqual(
94+
expect.arrayContaining([
95+
"equal",
96+
"equal5",
97+
"equal7",
98+
"equal19",
99+
"equal31",
100+
"just intonation",
101+
"Pythagorean",
102+
"1/3 comma meantone",
103+
"1/4 comma meantone",
104+
"custom"
105+
])
106+
);
107+
});
108+
});
109+
110+
describe("Temperament Management", () => {
111+
beforeEach(() => {
112+
// Reset global variables before each test
113+
global.TEMPERAMENTS = [...INITIALTEMPERAMENTS];
114+
global.TEMPERAMENT = {
115+
equal: {
116+
pitchNumber: 12,
117+
interval: ["perfect 1", "minor 2", "major 2"]
118+
}
119+
};
120+
});
121+
122+
test("addTemperamentToList should add a new temperament if not predefined", () => {
123+
const newEntry = "customTemperament";
124+
addTemperamentToList(newEntry);
125+
expect(TEMPERAMENTS).toContain(newEntry);
126+
});
127+
128+
test("addTemperamentToList should not add a predefined temperament", () => {
129+
const predefinedEntry = "equal";
130+
addTemperamentToList(predefinedEntry);
131+
expect(TEMPERAMENTS).not.toContain(predefinedEntry);
132+
});
133+
134+
test("deleteTemperamentFromList should remove a temperament from the dictionary", () => {
135+
const oldEntry = "equal";
136+
deleteTemperamentFromList(oldEntry);
137+
expect(TEMPERAMENT[oldEntry]).toBeUndefined();
138+
});
139+
140+
test("addTemperamentToDictionary should add a new temperament to the dictionary", () => {
141+
const entryName = "newTemperament";
142+
const entryValue = {
143+
pitchNumber: 7,
144+
interval: ["perfect 1", "minor 3", "major 3"]
145+
};
146+
addTemperamentToDictionary(entryName, entryValue);
147+
expect(TEMPERAMENT[entryName]).toEqual(entryValue);
148+
});
149+
150+
test("updateTemperaments should update TEMPERAMENTS with new entries", () => {
151+
const newEntry = "customTemperament";
152+
TEMPERAMENT[newEntry] = {
153+
pitchNumber: 8,
154+
interval: ["perfect 1", "minor 3"]
155+
};
156+
updateTemperaments();
157+
expect(TEMPERAMENTS.some(([_, name]) => name === newEntry)).toBe(true);
158+
});
159+
160+
test("updateTemperaments should not duplicate predefined temperaments", () => {
161+
updateTemperaments();
162+
const predefinedEntries = TEMPERAMENTS.filter(([_, name]) => name in PreDefinedTemperaments);
163+
expect(predefinedEntries.length).toBe(Object.keys(PreDefinedTemperaments).length);
164+
});
165+
});
166+
});
167+
168+
describe("Constants", () => {
169+
test("should have correct default values", () => {
170+
expect(DEFAULTINVERT).toBe("even");
171+
expect(DEFAULTMODE).toBe("major");
172+
});
173+
});
174+
175+
describe("customMode", () => {
176+
test("should return custom mode from MUSICALMODES", () => {
177+
expect(customMode).toEqual([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]);
178+
});
179+
});
180+
181+
describe("getInvertMode", () => {
182+
test("should return the correct invert mode name", () => {
183+
expect(getInvertMode("even")).toBe("even");
184+
expect(getInvertMode("scalar")).toBe("scalar");
185+
expect(getInvertMode("nonexistent")).toBe("nonexistent");
186+
});
187+
});
188+
189+
describe("getIntervalNumber", () => {
190+
test("should return the number of semi-tones for a given interval", () => {
191+
expect(getIntervalNumber("perfect 5")).toBe(7);
192+
expect(getIntervalNumber("major 3")).toBe(4);
193+
});
194+
});
195+
196+
describe("getIntervalDirection", () => {
197+
test("should return the direction of the interval", () => {
198+
expect(getIntervalDirection("diminished 6")).toBe(-1);
199+
expect(getIntervalDirection("minor 3")).toBe(-1);
200+
});
201+
});
202+
203+
describe("getIntervalRatio", () => {
204+
test("should return the ratio for a given interval", () => {
205+
expect(getIntervalRatio("perfect 5")).toBe(1.5);
206+
expect(getIntervalRatio("major 3")).toBe(1.25);
207+
});
208+
});
209+
210+
//
211+
212+
describe("getModeNumbers", () => {
213+
test("should return the correct mode numbers for a valid mode", () => {
214+
expect(getModeNumbers("chromatic")).toBe("0 1 2 3 4 5 6 7 8 9 10 11");
215+
expect(getModeNumbers("major")).toBe("0 2 4 5 7 9 11");
216+
expect(getModeNumbers("minor")).toBe("0 2 3 5 7 8 10");
217+
});
218+
219+
test("should return an empty string for an invalid mode", () => {
220+
expect(getModeNumbers("invalidMode")).toBe("");
221+
});
222+
223+
test("should handle custom mode correctly", () => {
224+
expect(getModeNumbers("custom")).toBe("0 1 2 3 4 5 6 7 8 9 10 11");
225+
});
226+
});
227+
228+
//
229+
230+
jest.mock('../musicutils', () => {
231+
const actualModule = jest.requireActual('../musicutils');
232+
return {
233+
...actualModule,
234+
getDrumIndex: jest.fn(),
235+
getDrumName: jest.fn(),
236+
getDrumSymbol: jest.fn()
237+
};
238+
});
239+
240+
describe('getDrum', () => {
241+
let DRUMNAMES, DEFAULTDRUM;
242+
243+
beforeEach(() => {
244+
DRUMNAMES = [
245+
["snare drum", "snare drum", "images/snaredrum.svg", "sn", "drum"],
246+
["kick drum", "kick drum", "images/kick.svg", "hh", "drum"],
247+
["tom tom", "tom tom", "images/tom.svg", "tomml", "drum"],
248+
["floor tom", "floor tom", "images/floortom.svg", "tomfl", "drum"],
249+
["bass drum", "bass drum", "images/kick.svg", "tomfl", "drum"],
250+
["hi hat", "hi hat", "images/hihat.svg", "hh", "bell"]
251+
];
252+
DEFAULTDRUM = "kick drum";
253+
254+
// Mock for getDrumIndex
255+
require('../musicutils').getDrumIndex.mockImplementation((name) => {
256+
if (name.slice(0, 4) === "http") return null;
257+
if (name === "") return DRUMNAMES.findIndex(drum => drum[0] === DEFAULTDRUM);
258+
259+
const index = DRUMNAMES.findIndex(
260+
(drum) => drum[0].toLowerCase() === name.toLowerCase()
261+
);
262+
return index >= 0 ? index : -1;
263+
});
264+
265+
// Mock for getDrumName
266+
require('../musicutils').getDrumName.mockImplementation((name) => {
267+
if (name === "") name = DEFAULTDRUM;
268+
if (name.slice(0, 4) === "http") return null;
269+
270+
for (let drum = 0; drum < DRUMNAMES.length; drum++) {
271+
if (DRUMNAMES[drum][0].toLowerCase() === name.toLowerCase()) {
272+
return DRUMNAMES[drum][0];
273+
} else if (DRUMNAMES[drum][1].toLowerCase() === name.toLowerCase()) {
274+
return DRUMNAMES[drum][1];
275+
}
276+
}
277+
278+
return null;
279+
});
280+
281+
require('../musicutils').getDrumSymbol.mockImplementation((name) => {
282+
if (name === "") return "hh";
283+
284+
for (let drum = 0; drum < DRUMNAMES.length; drum++) {
285+
if (DRUMNAMES[drum][0].toLowerCase() === name.toLowerCase()) {
286+
return DRUMNAMES[drum][3];
287+
} else if (DRUMNAMES[drum][1].toLowerCase() === name.toLowerCase()) {
288+
return "hh";
289+
}
290+
}
291+
292+
return "hh";
293+
});
294+
});
295+
296+
describe('getDrumIndex', () => {
297+
it('should return the index of a valid drum name', () => {
298+
expect(getDrumIndex('snare drum')).toBe(0);
299+
expect(getDrumIndex('kick drum')).toBe(1);
300+
expect(getDrumIndex('floor tom')).toBe(3);
301+
});
302+
303+
it('should return -1 for an invalid drum name', () => {
304+
expect(getDrumIndex('invalid drum')).toBe(-1);
305+
});
306+
307+
it('should return the index of the DEFAULTDRUM for empty input', () => {
308+
expect(getDrumIndex('')).toBe(1);
309+
});
310+
311+
it('should ignore case sensitivity when matching drum names', () => {
312+
expect(getDrumIndex('SNARE DRUM')).toBe(0);
313+
});
314+
315+
it('should return null for names starting with "http"', () => {
316+
expect(getDrumIndex('http')).toBe(null);
317+
});
318+
});
319+
320+
describe('getDrumName', () => {
321+
it('should return the name of a valid drum', () => {
322+
expect(getDrumName('snare drum')).toBe('snare drum');
323+
expect(getDrumName('kick drum')).toBe('kick drum');
324+
});
325+
326+
it('should return the DEFAULTDRUM name for empty input', () => {
327+
expect(getDrumName('')).toBe('kick drum');
328+
});
329+
330+
it('should return null for names starting with "http"', () => {
331+
expect(getDrumName('http')).toBe(null);
332+
});
333+
334+
it('should ignore case sensitivity when matching drum names', () => {
335+
expect(getDrumName('SNARE DRUM')).toBe('snare drum');
336+
expect(getDrumName('KICK DRUM')).toBe('kick drum');
337+
});
338+
339+
it('should return null for an invalid drum name', () => {
340+
expect(getDrumName('invalid drum')).toBe(null);
341+
});
342+
343+
it('should match the second element of DRUMNAMES if provided', () => {
344+
expect(getDrumName('kick drum')).toBe('kick drum');
345+
});
346+
});
347+
348+
describe('getDrumSymbol', () => {
349+
it('should return the correct symbol for a valid drum name', () => {
350+
expect(getDrumSymbol('snare drum')).toBe('sn');
351+
expect(getDrumSymbol('kick drum')).toBe('hh');
352+
expect(getDrumSymbol('floor tom')).toBe('tomfl');
353+
});
354+
355+
it('should return "hh" for an empty name', () => {
356+
expect(getDrumSymbol('')).toBe('hh');
357+
});
358+
359+
it('should return "hh" for an invalid drum name', () => {
360+
expect(getDrumSymbol('invalid drum')).toBe('hh');
361+
});
362+
363+
it('should return "hh" for a name matching the second element of DRUMNAMES', () => {
364+
expect(getDrumSymbol('snare drum')).toBe('sn');
365+
expect(getDrumSymbol('kick drum')).toBe('hh'); // As per logic
366+
});
367+
368+
it('should ignore case sensitivity when matching drum names', () => {
369+
expect(getDrumSymbol('SNARE DRUM')).toBe('sn');
370+
expect(getDrumSymbol('KICK DRUM')).toBe('hh');
371+
});
372+
});
373+
});
374+
375+
describe('getFilterTypes',() => {
376+
it('should return default filter type', () => {
377+
expect(getFilterTypes('')).toBe('highpass'); //DEFAULTFILTERTYPES
378+
});
379+
it('should return correct filter types', () => {
380+
expect(getFilterTypes('highpass')).toBe('highpass');
381+
expect(getFilterTypes('notch')).toBe('notch');
382+
});
383+
});

0 commit comments

Comments
 (0)