Skip to content

Commit bf3691b

Browse files
committed
resolve
1 parent 08ad80b commit bf3691b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+310987
-296757
lines changed

css/activities.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,19 @@
1616
outline: none;
1717
}
1818

19+
body:not(.dark) #helpfulSearch,
20+
body:not(.dark) .ui-autocomplete {
21+
background-color: #fff !important;
22+
color: #000 !important;
23+
}
1924

25+
body:not(.dark) .ui-autocomplete li:hover {
26+
background-color: #ddd !important;
27+
}
28+
29+
body:not(.dark) #helpfulSearchDiv {
30+
background-color: #f9f9f9 !important;
31+
}
2032

2133
.modal {
2234
display: none;
@@ -622,6 +634,8 @@ table {
622634

623635
#canvas {
624636
overflow-y: visible;
637+
background-color: #FFFFFF;
638+
width: 100%;
625639
}
626640

627641
#statusDiv {

css/themes.css

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
1+
/* Theme DropDown Styling */
2+
3+
#themedropdown{
4+
background-color: transparent;
5+
box-shadow: none;
6+
display: flex;
7+
transform: translateX(-25%) !important;
8+
}
9+
10+
#themedropdown a{
11+
color: #2196F3;
12+
transition: all 0.3s ease;
13+
}
14+
#themedropdown a:hover{
15+
color: #1E88E5;
16+
background-color: transparent;
17+
transition: all 0.3s ease;
18+
}
19+
20+
121
/* Dark Mode */
222

323
.dark .blue {
424
background-color: #022363 !important;
525
}
626

27+
.dark #canvas {
28+
background-color: #1c1c1c;
29+
}
30+
731
.dark .blue.darken-1 {
832
background-color: #01143b !important;
933
}
@@ -39,19 +63,6 @@
3963
color: white !important;
4064
}
4165

42-
.dark .dropdown-content li > a {
43-
background-color: #1c1c1c;
44-
color: #3fe0d1;
45-
}
46-
47-
.dark .dropdown-content li > a:hover {
48-
color: #252525;
49-
}
50-
51-
.dark .dropdown-content {
52-
background-color: #1c1c1c;
53-
}
54-
5566
.dark .language-link {
5667
color: #fff;
5768
}
@@ -68,21 +79,31 @@
6879
.dark #search,
6980
#helpfulSearch,
7081
.ui-autocomplete {
71-
background-color: #1c1c1c;
72-
color: #fff;
82+
background-color: #1c1c1c !important;
83+
color: #fff !important;
7384
}
7485

7586
.dark .ui-autocomplete li:hover {
76-
background-color: #225a91;
87+
background-color: #225a91 !important;
7788
}
7889

7990
.dark #helpfulSearchDiv {
80-
background-color: transparent;
91+
background-color: transparent !important;
8192
}
8293

8394
.dark #crossButton {
8495
color: #fff;
8596
}
8697

98+
.dark #chooseKeyDiv {
99+
background: #333;
100+
}
101+
102+
.dark #movable {
103+
background: #333;
104+
color: white;
105+
}
106+
107+
87108

88109
/* Your Custom Theme can go here if you don't want to modify the existing dark mode */

index.html

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,6 @@
311311
id="canvas"
312312
width="100%"
313313
height="100%"
314-
style="background-color:#FFFFFF; width:100%"
315314
>
316315
</canvas>
317316

@@ -781,7 +780,7 @@
781780
class="tooltipped dropdown-trigger"
782781
data-position="left"
783782
data-activates="themedropdown"
784-
><i class="material-icons md-48">brightness_4</i></a
783+
><i class="material-icons md-48">brightness_7</i></a
785784
>
786785
</li>
787786
<li>
@@ -922,9 +921,9 @@
922921
<li><a id="ur"></a></li>
923922
</ul>
924923

925-
<ul id="themedropdown" class="dropdown-content">
926-
<li><a id="light"></a></li>
927-
<li><a id="dark"></a></li>
924+
<ul style="display: none;" id="themedropdown" class="dropdown-content">
925+
<a id="light" class="tooltipped" data-tooltip="Light Mode"><i class='material-icons'>brightness_7</i></a>
926+
<a id="dark" class="tooltipped" data-tooltip="Dark Mode"><i class='material-icons'>brightness_4</i></a>
928927
</ul>
929928

930929
<div id="modal-container" style="display: none;z-index: 999;">

js/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ used with the `Add-1` and `Add to` blocks.
193193

194194
```
195195
setter(logo, value, turtle, blk) {
196-
logo.turtles.turtleList[turtle].painter.doSetHeading(value);
196+
logo.turtles.getTurtle(turtle).painter.doSetHeading(value);
197197
}
198198
```
199199

@@ -370,7 +370,7 @@ class StartDrumBlock extends StartBlock {
370370
if (logo.inStatusMatrix && logo.blocks.blockList[logo.blocks.blockList[blk].connections[0]].name === 'print') {
371371
logo.statusFields.push([blk, 'x']);
372372
} else {
373-
return logo.turtles.screenX2turtleX(logo.turtles.turtleList[turtle].container.x);
373+
return logo.turtles.screenX2turtleX(logo.turtles.getTurtle(turtle).container.x);
374374
}
375375
}
376376
}

js/SaveInterface.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -528,10 +528,10 @@ class SaveInterface {
528528
activity.logo.runningAbc = true;
529529
activity.logo.notationOutput = ABCHEADER;
530530
activity.logo.notationNotes = {};
531-
for (let t = 0; t < activity.turtles.turtleList.length; t++) {
531+
for (let t = 0; t < activity.turtles.getTurtleCount(); t++) {
532532
activity.logo.notation.notationStaging[t] = [];
533533
activity.logo.notation.notationDrumStaging[t] = [];
534-
activity.turtles.turtleList[t].painter.doClear(true, true, true);
534+
activity.turtles.getTurtle(t).painter.doClear(true, true, true);
535535
}
536536
activity.logo.runLogoCommands();
537537
}
@@ -687,10 +687,10 @@ class SaveInterface {
687687
}
688688
this.activity.logo.notationOutput = lyheader;
689689
this.activity.logo.notationNotes = {};
690-
for (let t = 0; t < this.activity.turtles.turtleList.length; t++) {
690+
for (let t = 0; t < this.activity.turtles.getTurtleCount(); t++) {
691691
this.activity.logo.notation.notationStaging[t] = [];
692692
this.activity.logo.notation.notationDrumStaging[t] = [];
693-
this.activity.turtles.turtleList[t].painter.doClear(true, true, true);
693+
this.activity.turtles.getTurtle(t).painter.doClear(true, true, true);
694694
}
695695
document.body.style.cursor = "wait";
696696
this.activity.logo.runLogoCommands();
@@ -800,10 +800,10 @@ class SaveInterface {
800800
// eslint-disable-next-line no-unused-vars
801801
saveMxml(filename) {
802802
this.activity.logo.runningMxml = true;
803-
for (let t = 0; t < this.activity.turtles.turtleList.length; t++) {
803+
for (let t = 0; t < this.activity.turtles.getTurtleCount(); t++) {
804804
this.activity.logo.notation.notationStaging[t] = [];
805805
this.activity.logo.notation.notationDrumStaging[t] = [];
806-
this.activity.turtles.turtleList[t].painter.doClear(true, true, true);
806+
this.activity.turtles.getTurtle(t).painter.doClear(true, true, true);
807807
}
808808

809809
this.activity.logo.runLogoCommands();

js/__tests__/abc.test.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Mock global constants
2+
global.NOTATIONNOTE = 0;
3+
global.NOTATIONDURATION = 1;
4+
global.NOTATIONDOTCOUNT = 2;
5+
global.NOTATIONTUPLETVALUE = 3;
6+
global.NOTATIONROUNDDOWN = 4;
7+
global.NOTATIONINSIDECHORD = 5; // deprecated
8+
global.NOTATIONSTACCATO = 6;
9+
10+
global.frequencyToPitch = jest.fn((freq) => ["G♯", "4"]);
11+
global.toFraction = jest.fn((num) => [1, 1]);
12+
13+
const { getABCHeader, processABCNotes, saveAbcOutput, ACCIDENTAL_MAP, OCTAVE_NOTATION_MAP } = require('../abc');
14+
15+
describe('getABCHeader', () => {
16+
it('should return the correct ABC header', () => {
17+
const expectedHeader = "X:1\nT:Music Blocks composition\nC:Mr. Mouse\nL:1/16\nM:C\n";
18+
expect(getABCHeader()).toBe(expectedHeader);
19+
});
20+
});
21+
22+
describe('processABCNotes', () => {
23+
let logo;
24+
25+
beforeEach(() => {
26+
logo = {
27+
notationNotes: { "0": "" },
28+
notation: {
29+
notationStaging: {
30+
"0": [
31+
[["G♯4"], 4, 0, null, null, -1, false],
32+
[["F4"], 4, 0, null, null, -1, false],
33+
[["G♯4"], 2, 0, null, null, -1, false],
34+
],
35+
},
36+
},
37+
};
38+
});
39+
40+
it('should process notes and update notationNotes correctly', () => {
41+
processABCNotes(logo, "0");
42+
expect(logo.notationNotes["0"]).toBe("G^4 G^4 F4 F4 G^2 G^8 ");
43+
});
44+
});
45+
46+
describe('saveAbcOutput', () => {
47+
let activity;
48+
49+
beforeEach(() => {
50+
activity = {
51+
logo: {
52+
notationOutput: "",
53+
notationNotes: { "0": "" },
54+
notation: {
55+
notationStaging: {
56+
"0": [
57+
[["G♯4"], 4, 0, null, null, -1, false],
58+
[["F4"], 4, 0, null, null, -1, false],
59+
[["G♯4"], 2, 0, null, null, -1, false],
60+
],
61+
},
62+
},
63+
},
64+
turtles: {
65+
ithTurtle: (t) => ({
66+
singer: {
67+
keySignature: "C major",
68+
},
69+
}),
70+
},
71+
};
72+
});
73+
74+
it('should generate the correct ABC notation output', () => {
75+
const expectedOutput ="X:1\n"+
76+
"T:Music Blocks composition\n"+
77+
"C:Mr. Mouse\n"+
78+
"L:1/16\n"+
79+
"M:C\n"+
80+
"K:CMAJOR\n"+
81+
"G^4 G^4 F4 F4 G^2 G^8 \n";
82+
83+
const result = saveAbcOutput(activity);
84+
expect(result).toBe(expectedOutput);
85+
});
86+
});
87+
88+
describe('processABCNotes - Tuplet Handling', () => {
89+
it('should process tuplets correctly', () => {
90+
const logo = {
91+
notationNotes: { "0": "" },
92+
notation: {
93+
notationStaging: {
94+
"0": [
95+
[["G♯4"], 4, 0, 3, 2, -1, false], // Tuplet
96+
[["F4"], 4, 0, 3, 2, -1, false], // Tuplet
97+
[["G♯4"], 4, 0, 3, 2, -1, false], // Tuplet
98+
],
99+
},
100+
},
101+
};
102+
103+
processABCNotes(logo, "0");
104+
expect(logo.notationNotes["0"]).toBe("(1:1G^ 2G^ 2G^ 2 ");
105+
});
106+
});
107+
108+
describe("OCTAVE_NOTATION_MAP", () => {
109+
it("should correctly map octaves to ABC notation", () => {
110+
expect(OCTAVE_NOTATION_MAP[10]).toBe("'''''");
111+
expect(OCTAVE_NOTATION_MAP[2]).toBe(",,");
112+
expect(OCTAVE_NOTATION_MAP[1]).toBe(",,,");
113+
expect(OCTAVE_NOTATION_MAP[0]).toBeUndefined();
114+
});
115+
});
116+
117+
describe("ACCIDENTAL_MAP", () => {
118+
test("should correctly map accidentals to ABC notation", () => {
119+
expect(ACCIDENTAL_MAP["♯"]).toBe("^");
120+
expect(ACCIDENTAL_MAP["♭"]).toBe("_");
121+
});
122+
123+
test("should return undefined for unmapped accidentals", () => {
124+
expect(ACCIDENTAL_MAP["♮"]).toBeUndefined();
125+
});
126+
});

js/__tests__/artwork.test.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
global._THIS_IS_TURTLE_BLOCKS_ = true;
2+
const { showMaterialHighlight, hideButtonHighlight, hidePaletteNameDisplay, COLLAPSEBUTTONXOFF, STANDARDBLOCKHEIGHT, FILLCOLORS, TURTLESVG } = require('../artwork');
3+
4+
global.createjs = {
5+
Shape: jest.fn(() => ({
6+
graphics: { f: jest.fn().mockReturnThis(), drawCircle: jest.fn().mockReturnThis() },
7+
alpha: 0,
8+
x: 0,
9+
y: 0
10+
})),
11+
Tween: {
12+
get: jest.fn(() => ({
13+
to: jest.fn().mockReturnThis()
14+
}))
15+
},
16+
Ease: { circInOut: jest.fn() }
17+
};
18+
19+
describe('artwork.js Test Suite', () => {
20+
let mockStage;
21+
22+
beforeEach(() => {
23+
mockStage = {
24+
addChild: jest.fn(),
25+
removeChild: jest.fn()
26+
};
27+
});
28+
29+
test('showMaterialHighlight creates highlight and active shapes', () => {
30+
const event = { rawX: 100, rawY: 100 };
31+
const scale = 1;
32+
const result = showMaterialHighlight(50, 50, 10, event, scale, mockStage);
33+
expect(result).toHaveProperty('highlight');
34+
expect(result).toHaveProperty('active');
35+
expect(mockStage.addChild).toHaveBeenCalledWith(result.highlight, result.active);
36+
});
37+
38+
test('hideButtonHighlight removes highlight properly', () => {
39+
jest.useFakeTimers();
40+
const circles = { highlight: {}, active: {} };
41+
hideButtonHighlight(circles, mockStage);
42+
jest.runAllTimers();
43+
expect(mockStage.removeChild).toBeCalledWith(circles.active, circles.highlight);
44+
jest.useRealTimers();
45+
});
46+
47+
test('hidePaletteNameDisplay removes palette text after delay', () => {
48+
jest.useFakeTimers();
49+
const paletteText = {};
50+
hidePaletteNameDisplay(paletteText, mockStage);
51+
jest.runAllTimers();
52+
expect(mockStage.removeChild).toBeCalledWith(paletteText);
53+
jest.useRealTimers();
54+
});
55+
56+
test('Constants are correctly defined', () => {
57+
expect(typeof COLLAPSEBUTTONXOFF).toBe('number');
58+
expect(typeof STANDARDBLOCKHEIGHT).toBe('number');
59+
expect(Array.isArray(FILLCOLORS)).toBe(true);
60+
expect(typeof TURTLESVG).toBe('string');
61+
});
62+
});

0 commit comments

Comments
 (0)