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
33 changes: 33 additions & 0 deletions js/js-export/__tests__/ast2blocklist.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1563,4 +1563,37 @@ describe("AST2BlockList Class", () => {
let blockList = AST2BlockList.toBlockList(AST, config);
expect(blockList).toEqual(expectedBlockList);
});

test("should generate heap blocks from JS", () => {
const code = `
new Mouse(async mouse => {
await mouse.print(mouse.HEAP);
await mouse.print(mouse.HEAPLENGTH);
await mouse.print(mouse.HEAPEMPTY);
await mouse.emptyHeap();
await mouse.reverseHeap();
await mouse.push(9);
await mouse.setHeapEntry(2, 5);
return mouse.ENDMOUSE;
});
MusicBlocks.run();`;

const AST = acorn.parse(code, { ecmaVersion: 2020 });
let blockList = AST2BlockList.toBlockList(AST, config);
const blockNames = blockList.map(block =>
Array.isArray(block[1]) ? block[1][0] : block[1]
);

expect(blockNames).toEqual(
expect.arrayContaining([
"heap",
"heapLength",
"heapEmpty",
"emptyHeap",
"reverseHeap",
"push",
"setHeapEntry"
])
);
});
});
43 changes: 43 additions & 0 deletions js/js-export/__tests__/export.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const globalActivity = {
logo: {
prepSynths: jest.fn(),
firstNoteTime: null,
turtleHeaps: {},
stage: {
removeEventListener: jest.fn()
}
Expand Down Expand Up @@ -138,6 +139,7 @@ describe("MusicBlocks Class", () => {
doWait: jest.fn(),
container: { x: 10, y: 20 }
});
globalActivity.turtles.getIndexOfTurtle.mockReturnValue(0);
mouse = new Mouse(jest.fn());
mouse.run = jest.fn();
musicBlocks = new MusicBlocks(mouse);
Expand Down Expand Up @@ -236,6 +238,47 @@ describe("MusicBlocks Class", () => {
expect(musicBlocks.GREY).toBe(75);
});

describe("Heap helpers", () => {
test("should get HEAP as JSON string", () => {
globalActivity.logo.turtleHeaps[musicBlocks.turIndex] = [1, 2, 3];
expect(musicBlocks.HEAP).toBe(JSON.stringify([1, 2, 3]));
});

test("should get HEAPLENGTH", () => {
globalActivity.logo.turtleHeaps[musicBlocks.turIndex] = [1, 2, 3, 4];
expect(musicBlocks.HEAPLENGTH).toBe(4);
});

test("should get HEAPEMPTY when heap is missing", () => {
delete globalActivity.logo.turtleHeaps[musicBlocks.turIndex];
expect(musicBlocks.HEAPEMPTY).toBe(true);
});

test("should emptyHeap", () => {
globalActivity.logo.turtleHeaps[musicBlocks.turIndex] = [1, 2];
musicBlocks.emptyHeap();
expect(globalActivity.logo.turtleHeaps[musicBlocks.turIndex]).toEqual([]);
});

test("should reverseHeap", () => {
globalActivity.logo.turtleHeaps[musicBlocks.turIndex] = [1, 2, 3];
musicBlocks.reverseHeap();
expect(globalActivity.logo.turtleHeaps[musicBlocks.turIndex]).toEqual([3, 2, 1]);
});

test("should setHeapEntry", () => {
globalActivity.logo.turtleHeaps[musicBlocks.turIndex] = [];
musicBlocks.setHeapEntry(2, 5);
expect(globalActivity.logo.turtleHeaps[musicBlocks.turIndex]).toEqual([0, 5]);
});

test("should push to heap", () => {
globalActivity.logo.turtleHeaps[musicBlocks.turIndex] = [1];
musicBlocks.push(2);
expect(globalActivity.logo.turtleHeaps[musicBlocks.turIndex]).toEqual([1, 2]);
});
});

test("should get NOTEVALUE", () => {
Singer.RhythmActions.getNoteValue.mockReturnValue(1);
expect(musicBlocks.NOTEVALUE).toBe(1);
Expand Down
24 changes: 24 additions & 0 deletions js/js-export/__tests__/interface.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ describe("JSInterface", () => {
expect(JSInterface.isGetter("mynotevalue")).toBe(true);
});

it("should return true for heap getters", () => {
expect(JSInterface.isGetter("heapLength")).toBe(true);
});

it("should return false for a block that is not a getter", () => {
expect(JSInterface.isGetter("pickup")).toBe(false);
});
Expand All @@ -56,6 +60,14 @@ describe("JSInterface", () => {
expect(JSInterface.isMethod("newnote")).toBe(true);
});

it("should return true for heap methods", () => {
expect(JSInterface.isMethod("emptyHeap")).toBe(true);
});

it("should return true for heap push method", () => {
expect(JSInterface.isMethod("push")).toBe(true);
});

it("should return false for a block that is not a method", () => {
expect(JSInterface.isMethod("pickup")).toBe(false);
});
Expand Down Expand Up @@ -86,6 +98,10 @@ describe("JSInterface", () => {
expect(JSInterface.getGetterName("mynotevalue")).toBe("NOTEVALUE");
});

it("should return the correct heap getter name when available", () => {
expect(JSInterface.getGetterName("heapLength")).toBe("HEAPLENGTH");
});

it("should return null when no getter exists for the given block", () => {
expect(JSInterface.getGetterName("pickup")).toBeNull();
});
Expand All @@ -96,6 +112,14 @@ describe("JSInterface", () => {
expect(JSInterface.getMethodName("newnote")).toBe("playNote");
});

it("should return the correct heap method name when available", () => {
expect(JSInterface.getMethodName("emptyHeap")).toBe("emptyHeap");
});

it("should return the correct heap push method name when available", () => {
expect(JSInterface.getMethodName("push")).toBe("push");
});

it("should return null when no method exists for the given block", () => {
expect(JSInterface.getMethodName("pickup")).toBeNull();
});
Expand Down
Loading
Loading