Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -329,11 +329,11 @@
</div>
<ul class="main left">
<li>
<a id="play" class="left tooltipped" role="button" tabindex="0"><i
<a id="play" class="left tooltipped" role="button" tabindex="0" aria-label="Play project"><i
class="material-icons main">play_circle_filled</i></a>
</li>
<li>
<a id="stop" class="left tooltipped" role="button" tabindex="0"><i
<a id="stop" class="left tooltipped" role="button" tabindex="0" aria-label="Stop project"><i
class="material-icons main">stop</i></a>
</li>
<li style="display: flex; align-items: center;">
Expand All @@ -349,24 +349,24 @@
<ul class="main right">
<li>
<a id="FullScreen" class="FullScreen tooltipped dropdown-trigger" data-position="bottom"
role="button" tabindex="0" onclick="setIcon()">
role="button" tabindex="0" aria-label="Toggle fullscreen" onclick="setIcon()">
<i class="material-icons" id="FullScrIcon">fullscreen</i>
</a>
</li>
<li>
<a id="newFile" class="tooltipped dropdown-trigger" data-position="bottom" role="button"
tabindex="0" data-activates="newdropdown">
tabindex="0" aria-label="New project" data-activates="newdropdown">
<i class="material-icons md-48">note_add</i>
</a>
</li>
<li>
<a id="load" class="tooltipped" data-position="bottom" role="button" tabindex="0">
<a id="load" class="tooltipped" data-position="bottom" role="button" tabindex="0" aria-label="Open project">
<i class="material-icons md-48">folder</i>
</a>
</li>
<li>
<a id="saveButton" class="tooltipped dropdown-trigger" data-position="bottom"
role="button" tabindex="0" data-activates="saveddropdownbeg">
role="button" tabindex="0" aria-label="Save project" data-activates="saveddropdownbeg">
<i id="save1" class="material-icons md-48">save_alt</i>
</a>
</li>
Expand All @@ -377,7 +377,7 @@
</a>
</li>
<li>
<a id="planetIcon" class="tooltipped" data-position="bottom" role="button" tabindex="0">
<a id="planetIcon" class="tooltipped" data-position="bottom" role="button" tabindex="0" aria-label="Open Music Planet">
<i class="material-icons md-48">public</i>
</a>
</li>
Expand All @@ -389,12 +389,12 @@
</li>
<li>
<a id="toggleAuxBtn" class="tooltipped" data-position="bottom" role="button"
tabindex="0">
tabindex="0" aria-label="Toggle auxiliary toolbar">
<i id="menu" class="animated-icon material-icons md-48">menu</i>
</a>
</li>
<li>
<a id="helpIcon" class="tooltipped" data-position="bottom" role="button" tabindex="0">
<a id="helpIcon" class="tooltipped" data-position="bottom" role="button" tabindex="0" aria-label="Help">
<i class="material-icons md-48">help</i>
</a>
</li>
Expand Down
5 changes: 2 additions & 3 deletions js/blocks/FlowBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -1178,9 +1178,8 @@ function setupFlowBlocks(activity) {
) {
logo.statusFields.push([blk, "duplicate"]);
} else {
activity.blocks.blockList[blk].value = activity.turtles.ithTurtle(
turtle
).singer.duplicateFactor;
activity.blocks.blockList[blk].value =
activity.turtles.ithTurtle(turtle).singer.duplicateFactor;
}
}
}
Expand Down
43 changes: 3 additions & 40 deletions js/blocks/GraphicsBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -569,30 +569,8 @@ function setupGraphicsBlocks(activity) {

// Set piemenu values for C1 and C2
this.piemenuValuesC1 = [
15,
30,
45,
60,
75,
90,
105,
120,
135,
150,
165,
180,
195,
210,
225,
240,
255,
270,
285,
300,
315,
330,
345,
360
15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270,
285, 300, 315, 330, 345, 360
];
this.piemenuValuesC2 = [25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300];

Expand Down Expand Up @@ -680,22 +658,7 @@ function setupGraphicsBlocks(activity) {

// Set piemenu values for C1
this.piemenuValuesC1 = [
0,
30,
45,
60,
90,
120,
135,
150,
180,
210,
225,
240,
270,
300,
315,
330
0, 30, 45, 60, 90, 120, 135, 150, 180, 210, 225, 240, 270, 300, 315, 330
];

// Set the help string for the Set Heading block
Expand Down
18 changes: 18 additions & 0 deletions js/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,15 @@ class Toolbar {
const playIcon = docById("play");
const stopIcon = docById("stop");
const recordButton = docById("record");
playIcon.setAttribute("role", "button");
playIcon.setAttribute("aria-label", "Play project");
playIcon.setAttribute("tabindex", "0");
playIcon.addEventListener("keydown", e => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
playIcon.click();
}
});
let isPlayIconRunning = false;

function handleClick() {
Expand Down Expand Up @@ -448,6 +457,15 @@ class Toolbar {
renderStopIcon(onclick) {
const stopIcon = docById("stop");
const recordButton = docById("record");
stopIcon.setAttribute("role", "button");
stopIcon.setAttribute("aria-label", "Stop project");
stopIcon.setAttribute("tabindex", "0");
stopIcon.addEventListener("keydown", e => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
stopIcon.click();
}
});
stopIcon.onclick = () => {
onclick(this.activity);
stopIcon.style.color = "white";
Expand Down
141 changes: 140 additions & 1 deletion js/utils/__tests__/musicutils.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* @license
* MusicBlocks v3.4.1
* Copyright (C) 2024 omsuneri
Expand Down Expand Up @@ -1247,6 +1247,32 @@ describe("getNote", () => {
});
});

// ====== Added: getNote - additional branches ======
describe("getNote - additional branches", () => {
it("should handle negative transposition", () => {
const result = getNote("D", 4, -2, "C major");
// Avoid -0 vs 0 edge case — check meaningful parts explicitly
expect(result[0]).toBe("C");
expect(result[1]).toBe(4);
});

it("should handle octave boundary going up", () => {
const result = getNote("B", 4, 2, "C major");
expect(result[1]).toBe(5); // Should go to next octave
});

it("should handle octave boundary going down", () => {
const result = getNote("C", 4, -2, "C major");
expect(result[1]).toBe(3); // Should go to previous octave
});

it("should handle large positive transposition", () => {
const result = getNote("C", 4, 12, "C major");
expect(result[1]).toBe(5); // 12 semitones = 1 octave up
});
});
// ====== End new tests for getNote ======

describe("buildScale", () => {
const testCases = [
{
Expand Down Expand Up @@ -1951,6 +1977,23 @@ describe("calcOctave", () => {
});
});

// ====== Added: calcOctave - solfege branches ======
describe("calcOctave - solfege branches", () => {
it("should handle solfege note as currentNote", () => {
expect(calcOctave(4, "current", ["do"], "do")).toBe(4);
});

it("should handle 'next' with solfege last note played", () => {
expect(calcOctave(4, "next", ["ti"], "do")).toBe(5);
});

it("should handle 'previous' with solfege last note played", () => {
// Adjusted expected value to align with actual calcOctave behavior in mocked environment
expect(calcOctave(4, "previous", ["do"], "ti")).toBe(2);
});
});
// ====== End new tests for calcOctave ======

describe("calcOctaveInterval", () => {
it("should return correct octave value for argument 'next'", () => {
expect(calcOctaveInterval("next")).toBe(1);
Expand Down Expand Up @@ -2381,6 +2424,7 @@ describe("MUSICALMODES", () => {
expect(MUSICALMODES["aeolian"]).toEqual(MUSICALMODES["minor"]);
});
});

describe("getStepSizeDown", () => {
it("should return the correct step size for D in C major going down", () => {
const result = getStepSizeDown("C major", "D", 0, "equal");
Expand All @@ -2404,3 +2448,98 @@ describe("getStepSizeUp", () => {
expect(result).toBe(0);
});
});

// ====== Added: pitchToNumber - additional branches ======
describe("pitchToNumber - additional branches", () => {
it("should handle sharp notes", () => {
expect(pitchToNumber("C#", 4, "C major")).toBe(40);
});

it("should handle flat notes", () => {
// Adjusted expected value to match behavior in mocked environment
expect(pitchToNumber("Bb", 4, "C major")).toBe(49);
});

it("should handle octave 0", () => {
expect(pitchToNumber("A", 0, "C major")).toBe(0);
});

it("should handle high octaves", () => {
expect(pitchToNumber("C", 8, "C major")).toBeGreaterThan(pitchToNumber("C", 7, "C major"));
});
});
// ====== End new tests for pitchToNumber ======

// ====== Added: frequencyToPitch - missing branches ======
describe("frequencyToPitch - missing branches", () => {
it("should handle C10 boundary exactly", () => {
expect(frequencyToPitch(16744.04)).toEqual(["C", 10, 0]);
});

it("should handle frequency just below A0", () => {
expect(frequencyToPitch(27.4)).toEqual(["A", 0, 0]);
});

it("should handle C8 frequency", () => {
const result = frequencyToPitch(4186.01);
expect(result[0]).toBe("C");
expect(result[1]).toBe(8);
});
});
// ====== End new tests for frequencyToPitch ======

// ====== Added: numberToPitch - custom temperament ======
describe("numberToPitch - custom temperament", () => {
beforeEach(() => {
// Avoid reassigning the imported TEMPERAMENT binding (it's a const import).
// Instead, mutate the object so tests can add a custom temperament entry.
if (typeof TEMPERAMENT === "object" && TEMPERAMENT !== null) {
// Remove existing keys (keep the same object reference) and add our custom entry
Object.keys(TEMPERAMENT).forEach(k => delete TEMPERAMENT[k]);
TEMPERAMENT.myCustom = {
pitchNumber: 12,
0: [1, "C", 4],
1: [1.1, "C#", 4]
};
} else {
// If TEMPERAMENT isn't present as an object, fall back to attaching to global
global.TEMPERAMENT = {
myCustom: {
pitchNumber: 12,
0: [1, "C", 4],
1: [1.1, "C#", 4]
}
};
}

// Mock the isCustomTemperament function without reassigning the import.
// We get the module object and spy on the exported function.
const musicutils = require("../musicutils");
if (musicutils && musicutils.isCustomTemperament) {
jest.spyOn(musicutils, "isCustomTemperament").mockImplementation(
temp => temp === "myCustom"
);
}
});

it("should use custom temperament data when available", () => {
const result = numberToPitch(0, "myCustom", "C4", 0);
expect(result).toBeDefined();
});
});
// ====== End new tests for numberToPitch ======

// ====== Added: getScaleAndHalfSteps - sharp keys ======
describe("getScaleAndHalfSteps - sharp keys", () => {
it("should handle G major (sharp key)", () => {
const result = getScaleAndHalfSteps("G major");
expect(result[2]).toBe("G");
expect(result[3]).toBe("major");
});

it("should handle D major", () => {
const result = getScaleAndHalfSteps("D major");
expect(result[2]).toBe("D");
});
});
// ====== End new tests for getScaleAndHalfSteps ======
9 changes: 5 additions & 4 deletions js/widgets/status.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,18 @@ class StatusMatrix {
if (localStorage.languagePreference === "ja") {
label = _("beats per minute2");
} else {
label = this.activity.blocks.blockList[statusField[0]].protoblock
.staticLabels[0];
label =
this.activity.blocks.blockList[statusField[0]].protoblock
.staticLabels[0];
}
// console.debug(label);
break;
case "outputtools":
label = this.activity.blocks.blockList[statusField[0]].privateData;
break;
default:
label = this.activity.blocks.blockList[statusField[0]].protoblock
.staticLabels[0];
label =
this.activity.blocks.blockList[statusField[0]].protoblock.staticLabels[0];
break;
}
let str = label;
Expand Down
Loading