Skip to content

Commit 5a34c5b

Browse files
authored
Merge pull request #5589 from varruunnn/generatetest
Test: Boost generate.js coverage to ~100% with complex stack scenarios
2 parents db464a7 + 2cfc5a9 commit 5a34c5b

File tree

1 file changed

+176
-0
lines changed

1 file changed

+176
-0
lines changed

js/js-export/__tests__/generate.test.js

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ const astring = {
4444
global.ASTUtils = ASTUtils;
4545
global.astring = astring;
4646

47+
global.JSInterface = {
48+
isGetter: jest.fn(name => name === "myGetter")
49+
};
50+
4751
describe("JSGenerate Class", () => {
4852
beforeEach(() => {
4953
jest.clearAllMocks();
@@ -169,4 +173,176 @@ describe("JSGenerate Class", () => {
169173
);
170174
expect(console.log).toHaveBeenCalledWith("generated code");
171175
});
176+
test("should generate stack trees with various block types and arguments", () => {
177+
globalActivity.blocks.stackList = [1, 20];
178+
const booleanGrandParent = { constructor: { name: "BooleanBlock" } };
179+
const booleanParent = Object.create(booleanGrandParent);
180+
const booleanProtoblock = Object.create(booleanParent);
181+
booleanProtoblock.style = "value";
182+
const standardGrandParent = { constructor: { name: "StandardBlock" } };
183+
const standardParent = Object.create(standardGrandParent);
184+
const standardProtoblock = Object.create(standardParent);
185+
standardProtoblock.style = "value";
186+
187+
globalActivity.blocks.blockList = {
188+
1: {
189+
name: "start",
190+
trash: false,
191+
connections: [null, 2, null],
192+
protoblock: { style: "hat" }
193+
},
194+
2: {
195+
name: "storein2",
196+
privateData: "myVar",
197+
connections: [1, 4, 3],
198+
protoblock: { style: "command", args: 1 }
199+
},
200+
4: {
201+
name: "hspace",
202+
connections: [2, 5],
203+
protoblock: { style: "spacer" }
204+
},
205+
5: {
206+
name: "value",
207+
value: 42,
208+
connections: [4],
209+
protoblock: standardProtoblock
210+
},
211+
3: {
212+
name: "if",
213+
connections: [2, 6, 7, 10, 13],
214+
protoblock: { style: "doubleclamp", args: 3 }
215+
},
216+
6: {
217+
name: "boolean",
218+
value: "true",
219+
connections: [3],
220+
protoblock: booleanProtoblock
221+
},
222+
7: {
223+
name: "nameddo",
224+
privateData: "myProc",
225+
connections: [3, 8],
226+
protoblock: { style: "command" }
227+
},
228+
8: { name: "hidden", connections: [7, 9], protoblock: { style: "command" } },
229+
9: { name: "command", connections: [8, null], protoblock: { style: "command" } },
230+
231+
10: {
232+
name: "repeat",
233+
connections: [3, 11, 12, null],
234+
protoblock: { style: "clamp", args: 2 }
235+
},
236+
11: {
237+
name: "namedbox",
238+
privateData: "box1",
239+
connections: [10],
240+
protoblock: standardProtoblock
241+
},
242+
12: { name: "command", connections: [10, null], protoblock: { style: "command" } },
243+
13: { name: "command", connections: [3, null], protoblock: { style: "command" } },
244+
20: {
245+
name: "action",
246+
trash: false,
247+
connections: [null, 21, 22, null],
248+
protoblock: { style: "hat" }
249+
},
250+
21: {
251+
name: "value",
252+
value: "myAction",
253+
connections: [20],
254+
protoblock: standardProtoblock
255+
},
256+
22: {
257+
name: "myGetter",
258+
connections: [20, null],
259+
protoblock: { style: "value" }
260+
}
261+
};
262+
263+
JSGenerate.generateStacksTree();
264+
265+
expect(JSGenerate.startTrees.length).toBe(1);
266+
expect(JSGenerate.actionTrees.length).toBe(1);
267+
expect(JSGenerate.actionNames).toContain("myAction");
268+
269+
const tree = JSGenerate.startTrees[0];
270+
expect(tree[0][0]).toBe("storein2_myVar");
271+
expect(tree[0][1][0]).toBe(42);
272+
expect(tree[1][0]).toBe("if");
273+
expect(tree[1][1][0]).toBe("bool_true");
274+
expect(tree[1][2][0][0]).toBe("nameddo_myProc");
275+
expect(tree[1][3][0][1][0]).toBe("box_box1");
276+
});
277+
278+
test("should warn when clamp block flows left", () => {
279+
globalActivity.blocks.stackList = [1];
280+
globalActivity.blocks.blockList = {
281+
1: {
282+
name: "start",
283+
trash: false,
284+
connections: [null, 2, null],
285+
protoblock: { style: "hat" }
286+
},
287+
2: {
288+
name: "command",
289+
connections: [1, 3, null],
290+
protoblock: { style: "command", args: 1 }
291+
},
292+
3: {
293+
name: "badClamp",
294+
connections: [2],
295+
protoblock: {
296+
style: "clamp",
297+
_style: { flows: { left: true } }
298+
}
299+
}
300+
};
301+
302+
const warnSpy = jest.spyOn(console, "warn").mockImplementation();
303+
JSGenerate.generateStacksTree();
304+
expect(warnSpy).toHaveBeenCalledWith('CANNOT PROCESS "badClamp" BLOCK');
305+
warnSpy.mockRestore();
306+
});
307+
test("should print complex stack trees with nested args and flows", () => {
308+
JSGenerate.startTrees = [
309+
[
310+
["block1", ["arg1", "subArg"], null],
311+
["block2", null, [["flow1Block", null, null]], [["flow2Block", null, null]]]
312+
]
313+
];
314+
JSGenerate.actionTrees = [[["actionBlock", null, null]]];
315+
316+
JSGenerate.printStacksTree();
317+
expect(console.log).toHaveBeenCalledWith(
318+
expect.stringContaining("(arg1, subArg)"),
319+
"background: mediumslateblue",
320+
"background; none",
321+
"color: dodgerblue"
322+
);
323+
expect(console.log).toHaveBeenCalledWith(
324+
expect.stringContaining("** NEXTFLOW **"),
325+
"color: green"
326+
);
327+
expect(console.log).toHaveBeenCalledWith(
328+
expect.stringContaining("ACTION"),
329+
"background: green; color: white; font-weight: bold"
330+
);
331+
});
332+
test("should handle astring generation errors", () => {
333+
JSGenerate.AST = { type: "Program", body: [] };
334+
astring.generate
335+
.mockImplementationOnce(() => {
336+
throw new Error("Code Gen Error");
337+
})
338+
.mockImplementationOnce(() => "fallback code");
339+
340+
JSGenerate.generateCode();
341+
342+
expect(JSGenerate.generateFailed).toBe(true);
343+
expect(console.error).toHaveBeenCalledWith(
344+
"CANNOT GENERATE CODE\nError: INVALID ABSTRACT SYNTAX TREE"
345+
);
346+
expect(JSGenerate.code).toBe("fallback code");
347+
});
172348
});

0 commit comments

Comments
 (0)