Skip to content

Commit 7bd248d

Browse files
ssz2605Walter Bender
andauthored
Added unit tests for GraphicsBlocks.js (#4927)
* Added unit tests for GraphicsBlocks * prettier * prettier * chore: format GraphicsBlocks files with Prettier --------- Co-authored-by: Walter Bender <walter@sorceo.com>
1 parent 12e8e01 commit 7bd248d

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed

js/blocks/GraphicsBlocks.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,3 +1287,6 @@ function setupGraphicsBlocks(activity) {
12871287
new BackBlock().setup(activity);
12881288
new ForwardBlock().setup(activity);
12891289
}
1290+
if (typeof module !== "undefined" && module.exports) {
1291+
module.exports = { setupGraphicsBlocks };
1292+
}
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/**
2+
* MusicBlocks v3.6.2
3+
*
4+
* @author Shreya Saxena
5+
*
6+
* @copyright 2025 Shreya Saxena
7+
*
8+
* @license
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
*/
22+
23+
global._ = jest.fn(s => s);
24+
global.last = arr => arr[arr.length - 1];
25+
global.NANERRORMSG = "NaN error";
26+
global.NOINPUTERRORMSG = "No input error";
27+
global._THIS_IS_MUSIC_BLOCKS_ = false;
28+
global.toFixed2 = jest.fn(n => n);
29+
30+
/* Base block mocks */
31+
global.ValueBlock = class {
32+
constructor(name) {
33+
this.name = name;
34+
}
35+
setPalette = jest.fn();
36+
setHelpString = jest.fn();
37+
formBlock = jest.fn();
38+
beginnerBlock = jest.fn();
39+
40+
setup(activity) {
41+
activity.blocks[this.name] = this.constructor;
42+
}
43+
};
44+
45+
global.FlowBlock = class extends global.ValueBlock {};
46+
global.FlowClampBlock = class extends global.FlowBlock {
47+
makeMacro = jest.fn();
48+
};
49+
50+
const { setupGraphicsBlocks } = require("../GraphicsBlocks");
51+
52+
describe("GraphicsBlocks", () => {
53+
let activity, logo, turtle, turtleObj;
54+
55+
beforeEach(() => {
56+
turtle = 0;
57+
58+
turtleObj = {
59+
singer: {
60+
inNoteBlock: [],
61+
suppressOutput: false,
62+
embeddedGraphics: [[]]
63+
},
64+
painter: {
65+
doSetHeading: jest.fn(),
66+
doSetXY: jest.fn(),
67+
doScrollXY: jest.fn(),
68+
doClear: jest.fn(),
69+
doBezier: jest.fn(),
70+
doArc: jest.fn(),
71+
doForward: jest.fn(),
72+
doRight: jest.fn(),
73+
penState: true,
74+
wrap: false
75+
},
76+
x: 0,
77+
y: 0,
78+
orientation: 45,
79+
container: { x: 10, y: 20 }
80+
};
81+
82+
activity = {
83+
blocks: {},
84+
errorMsg: jest.fn(),
85+
turtles: {
86+
companionTurtle: jest.fn(() => 0),
87+
ithTurtle: jest.fn(() => turtleObj),
88+
getTurtle: jest.fn(() => turtleObj),
89+
screenX2turtleX: jest.fn(x => x),
90+
screenY2turtleY: jest.fn(y => y)
91+
}
92+
};
93+
94+
logo = {
95+
inMatrix: false,
96+
inStatusMatrix: false,
97+
statusFields: [],
98+
phraseMaker: {
99+
addRowBlock: jest.fn(),
100+
rowLabels: [],
101+
rowArgs: []
102+
},
103+
pitchBlocks: [],
104+
setDispatchBlock: jest.fn(),
105+
setTurtleListener: jest.fn()
106+
};
107+
108+
setupGraphicsBlocks(activity);
109+
});
110+
111+
test("setupGraphicsBlocks initializes without crashing", () => {
112+
expect(typeof setupGraphicsBlocks).toBe("function");
113+
expect(activity.blocks).toBeDefined();
114+
});
115+
116+
test("HeadingBlock: arg returns turtle orientation", () => {
117+
const Heading = activity.blocks.heading;
118+
const block = new Heading();
119+
120+
const value = block.arg(logo, turtle, 0);
121+
expect(value).toBe(45);
122+
});
123+
124+
test("XBlock: arg returns turtle X position", () => {
125+
const X = activity.blocks.x;
126+
const block = new X();
127+
128+
const value = block.arg(logo, turtle, 0);
129+
expect(value).toBe(10);
130+
});
131+
132+
test("YBlock: arg returns turtle Y position", () => {
133+
const Y = activity.blocks.y;
134+
const block = new Y();
135+
136+
const value = block.arg(logo, turtle, 0);
137+
expect(value).toBe(20);
138+
});
139+
140+
test("ForwardBlock: flow moves turtle forward", () => {
141+
const Forward = activity.blocks.forward;
142+
const block = new Forward();
143+
144+
block.flow([100], logo, turtle, 1);
145+
expect(turtleObj.painter.doForward).toHaveBeenCalledWith(100);
146+
});
147+
148+
test("RightBlock: flow turns turtle right", () => {
149+
const Right = activity.blocks.right;
150+
const block = new Right();
151+
152+
block.flow([90], logo, turtle, 1);
153+
expect(turtleObj.painter.doRight).toHaveBeenCalledWith(90);
154+
});
155+
156+
test("BackBlock: flow moves turtle backward", () => {
157+
const Back = activity.blocks.back;
158+
const block = new Back();
159+
160+
block.flow([50], logo, turtle, 1);
161+
expect(turtleObj.painter.doForward).toHaveBeenCalledWith(-50);
162+
});
163+
164+
test("SetXYBlock: flow sets turtle position", () => {
165+
const SetXY = activity.blocks.setxy;
166+
const block = new SetXY();
167+
168+
block.flow([30, 40], logo, turtle, 1);
169+
expect(turtleObj.painter.doSetXY).toHaveBeenCalledWith(30, 40);
170+
});
171+
172+
test("ScrollXYBlock: flow scrolls canvas", () => {
173+
const ScrollXY = activity.blocks.scrollxy;
174+
const block = new ScrollXY();
175+
176+
block.flow([10, 20], logo, turtle, 1);
177+
expect(turtleObj.painter.doScrollXY).toHaveBeenCalledWith(10, 20);
178+
});
179+
180+
test("ClearBlock: flow clears turtle drawing", () => {
181+
const Clear = activity.blocks.clear;
182+
const block = new Clear();
183+
184+
block.flow([], logo, turtle, 1);
185+
expect(turtleObj.painter.doClear).toHaveBeenCalled();
186+
});
187+
188+
test("ArcBlock: flow draws arc", () => {
189+
const Arc = activity.blocks.arc;
190+
const block = new Arc();
191+
192+
block.flow([90, 100], logo, turtle, 1);
193+
expect(turtleObj.painter.doArc).toHaveBeenCalledWith(90, 100);
194+
});
195+
});

0 commit comments

Comments
 (0)