Skip to content

Commit b4c9f29

Browse files
authored
Merge pull request #5204 from varruunnn/lilypondTest
Boost lilypond.js coverage
2 parents d80a379 + a9655db commit b4c9f29

File tree

1 file changed

+208
-1
lines changed

1 file changed

+208
-1
lines changed

js/__tests__/lilypond.test.js

Lines changed: 208 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,15 @@ describe("processLilypondNotes", () => {
226226
processLilypondNotes(lilypond, logo, turtle);
227227
expect(logo.notationNotes[turtle]).toContain("\\staccato ");
228228
});
229-
229+
test("should process custom key modes (freygish) correctly", () => {
230+
getScaleAndHalfSteps.mockReturnValueOnce([
231+
["C", "D", "E", "F", "G", "A", "B"],
232+
["", "♭", "", "", "", "♭", ""]
233+
]);
234+
logo.notation.notationStaging[turtle] = ["key", "C", "myCustomMode"];
235+
processLilypondNotes(lilypond, logo, turtle);
236+
expect(logo.notationNotes[turtle]).toContain("\\myCustomMode");
237+
});
230238
test("should insert newline after 8 notes", () => {
231239
const notesArray = [];
232240
for (let i = 0; i < 9; i++) {
@@ -242,6 +250,107 @@ describe("processLilypondNotes", () => {
242250
processLilypondNotes(lilypond, logo, turtle);
243251
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
244252
});
253+
test("should handle tuplet with non-integer fraction", () => {
254+
toFraction.mockReturnValueOnce([3.5, 2]).mockReturnValueOnce([7, 4]);
255+
256+
logo.notation.notationStaging[turtle] = [[["G4"], 4, 0, [3, 2], 0, -1, false]];
257+
processLilypondNotes(lilypond, logo, turtle);
258+
expect(logo.notationNotes[turtle]).toContain("\\tuplet 7/4");
259+
});
260+
test("should process chord with multiple notes correctly", () => {
261+
logo.notation.notationStaging[turtle] = [[["G4", "B4", "D5"], 4, 0, null, 0, -1, false]];
262+
processLilypondNotes(lilypond, logo, turtle);
263+
expect(logo.notationNotes[turtle]).toContain("<");
264+
expect(logo.notationNotes[turtle]).toContain(">");
265+
expect(logo.notationNotes[turtle]).toContain("g'");
266+
expect(logo.notationNotes[turtle]).toContain("b'");
267+
});
268+
test("should handle tuplet with notes of varying durations", () => {
269+
logo.notation.notationStaging[turtle] = [
270+
[["G4"], 8, 4, [3, 2], 0, -1, false],
271+
[["A4"], 4, 2, [3, 2], 0, -1, false],
272+
[["B4"], 8, 4, [3, 2], 0, -1, false]
273+
];
274+
processLilypondNotes(lilypond, logo, turtle);
275+
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
276+
});
277+
278+
test("should handle tuplet with varying tuplet factors", () => {
279+
logo.notation.notationStaging[turtle] = [
280+
[["G4"], 4, 2, [3, 4], 0, -1, false],
281+
[["A4"], 4, 2, [3, 2], 0, -1, false]
282+
];
283+
processLilypondNotes(lilypond, logo, turtle);
284+
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
285+
});
286+
287+
test("should handle tie command within tuplet", () => {
288+
logo.notation.notationStaging[turtle] = [
289+
[["G4"], 4, 2, [3, 2], 0, -1, false],
290+
"tie",
291+
[["A4"], 4, 2, [3, 2], 0, -1, false]
292+
];
293+
processLilypondNotes(lilypond, logo, turtle);
294+
expect(logo.notationNotes[turtle]).toContain("~");
295+
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
296+
});
297+
298+
test("should break tuplet when reaching POW2 duration (0.5)", () => {
299+
logo.notation.notationStaging[turtle] = [
300+
[["G4"], 4, 2, [3, 2], 0, -1, false],
301+
[["A4"], 4, 2, [3, 2], 0, -1, false],
302+
[["B4"], 4, 2, [3, 2], 0, -1, false],
303+
[["C4"], 4, 0, null, 0, -1, false]
304+
];
305+
processLilypondNotes(lilypond, logo, turtle);
306+
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
307+
});
308+
test("should handle null tuplet value interrupting tuplet", () => {
309+
logo.notation.notationStaging[turtle] = [
310+
[["G4"], 4, 2, [3, 2], 0, -1, false],
311+
[["A4"], 4, 0, null, 0, -1, false],
312+
[["B4"], 4, 2, [3, 2], 0, -1, false]
313+
];
314+
processLilypondNotes(lilypond, logo, turtle);
315+
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
316+
});
317+
test("should break tuplet when tuplet factor changes", () => {
318+
logo.notation.notationStaging[turtle] = [
319+
[["G4"], 4, 2, [3, 2], 0, -1, false],
320+
[["A4"], 4, 2, [5, 2], 0, -1, false]
321+
];
322+
processLilypondNotes(lilypond, logo, turtle);
323+
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
324+
});
325+
test("should handle tuplet with mixed NOTATIONROUNDDOWN values (greater)", () => {
326+
logo.notation.notationStaging[turtle] = [
327+
[["G4"], 4, 2, [3, 2], 0, -1, false],
328+
[["A4"], 8, 4, [3, 2], 0, -1, false],
329+
[["B4"], 4, 2, [3, 2], 0, -1, false]
330+
];
331+
processLilypondNotes(lilypond, logo, turtle);
332+
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
333+
});
334+
335+
test("should handle tuplet with mixed NOTATIONROUNDDOWN values (less)", () => {
336+
logo.notation.notationStaging[turtle] = [
337+
[["G4"], 4, 4, [3, 2], 0, -1, false],
338+
[["A4"], 8, 2, [3, 2], 0, -1, false],
339+
[["B4"], 4, 4, [3, 2], 0, -1, false]
340+
];
341+
processLilypondNotes(lilypond, logo, turtle);
342+
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
343+
});
344+
345+
test("should handle tuplet with equal NOTATIONROUNDDOWN values", () => {
346+
logo.notation.notationStaging[turtle] = [
347+
[["G4"], 4, 2, [3, 2], 0, -1, false],
348+
[["A4"], 4, 2, [3, 2], 0, -1, false],
349+
[["B4"], 4, 2, [3, 2], 0, -1, false]
350+
];
351+
processLilypondNotes(lilypond, logo, turtle);
352+
expect(logo.notationNotes[turtle]).toContain("\\tuplet");
353+
});
245354
});
246355

247356
describe("saveLilypondOutput", () => {
@@ -435,4 +544,102 @@ describe("saveLilypondOutput", () => {
435544
const result = saveLilypondOutput(activity);
436545
expect(result).toContain("% MIDI Output");
437546
});
547+
test("should handle instrument short name collisions (no spaces)", () => {
548+
activity.turtles.turtleList = {
549+
"0": { name: "Trumpet" },
550+
"1": { name: "Trombone" },
551+
"2": { name: "Tuba" }
552+
};
553+
activity.logo.notation.notationStaging = {
554+
"0": ["note"],
555+
"1": ["note"],
556+
"2": ["note"]
557+
};
558+
frequencyToPitch.mockReturnValue(["C", 4]);
559+
560+
const result = saveLilypondOutput(activity);
561+
expect(result).toContain('shortInstrumentName = "Tr"');
562+
expect(result).toContain('instrumentName = "Trombone"');
563+
});
564+
565+
test("should handle instrument short name collisions (with spaces)", () => {
566+
activity.turtles.turtleList = {
567+
"0": { name: "Violin One" },
568+
"1": { name: "Violin Two" }
569+
};
570+
activity.logo.notation.notationStaging = { "0": ["note"], "1": ["note"] };
571+
const result = saveLilypondOutput(activity);
572+
expect(result).toContain('shortInstrumentName = "Vi"');
573+
expect(result).toContain('shortInstrumentName = "Vio"');
574+
});
575+
test("should map special turtle names (start, numeric) to Rodent names", () => {
576+
activity.turtles.turtleList = {
577+
"0": { name: "start" },
578+
"1": { name: "start drum" },
579+
"2": { name: "2" }
580+
};
581+
582+
activity.logo.notation.notationStaging = {
583+
"0": ["note"],
584+
"1": ["note"],
585+
"2": ["note"]
586+
};
587+
588+
const result = saveLilypondOutput(activity);
589+
expect(result).toContain('instrumentName = "mouse"');
590+
expect(result).toContain('instrumentName = "mole"');
591+
});
592+
test("should select bass_8 clef for very low notes", () => {
593+
frequencyToPitch.mockReturnValue(["C", 1]);
594+
595+
activity.logo.notation.notationStaging = {
596+
"0": [[["C1"], 4, 0, null, 0, -1, false]]
597+
};
598+
const result = saveLilypondOutput(activity);
599+
expect(result).toContain('\\clef "bass_8"');
600+
});
601+
test("should select bass clef for mid-low notes", () => {
602+
frequencyToPitch.mockReturnValue(["C", 3]);
603+
activity.logo.notation.notationStaging = {
604+
"0": [[["C3"], 4, 0, null, 0, -1, false]]
605+
};
606+
607+
const result = saveLilypondOutput(activity);
608+
expect(result).toContain('\\clef "bass"');
609+
});
610+
611+
test("should handle rest notes in octave calculation", () => {
612+
activity.logo.notation.notationStaging = {
613+
"0": [[["R"], 4, 0, null, 0, -1, false]]
614+
};
615+
const result = saveLilypondOutput(activity);
616+
expect(result).toBeDefined();
617+
});
618+
619+
test("should handle numeric frequency in octave calculation", () => {
620+
frequencyToPitch.mockReturnValue(["A", 4]);
621+
activity.logo.notation.notationStaging = {
622+
"0": [[[440], 4, 0, null, 0, -1, false]]
623+
};
624+
const result = saveLilypondOutput(activity);
625+
expect(result).toBeDefined();
626+
expect(frequencyToPitch).toHaveBeenCalledWith(440);
627+
});
628+
test("should handle short name collision for names without spaces (longer loop)", () => {
629+
activity.turtles.turtleList = {
630+
"0": { name: "Trumpet" },
631+
"1": { name: "Trombone" },
632+
"2": { name: "Triangle" }
633+
};
634+
activity.logo.notation.notationStaging = {
635+
"0": ["note"],
636+
"1": ["note"],
637+
"2": ["note"]
638+
};
639+
const result = saveLilypondOutput(activity);
640+
641+
expect(result).toContain('shortInstrumentName = "Tr"');
642+
expect(result).toContain('shortInstrumentName = "Tro"');
643+
expect(result).toContain('shortInstrumentName = "Tri"');
644+
});
438645
});

0 commit comments

Comments
 (0)