Skip to content

Commit 43cd1b5

Browse files
authored
Added code to block functionality for all blocks in the rhythm and flow palettes. (#4692)
1 parent 70f708b commit 43cd1b5

File tree

2 files changed

+634
-36
lines changed

2 files changed

+634
-36
lines changed

js/js-export/__tests__/ast2blocklist.test.js

Lines changed: 362 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,4 +716,365 @@ describe("AST2BlockList Class", () => {
716716
let blockList = AST2BlockList.toBlockList(trees);
717717
expect(blockList).toEqual(expectedBlockList);
718718
});
719-
});
719+
720+
// Test all Rhythm Blocks.
721+
test("should generate correct blockList for all rhythm blocks", () => {
722+
const code = `
723+
new Mouse(async mouse => {
724+
await mouse.playNote(1 / 4, async () => {
725+
await mouse.playPitch("sol", 4);
726+
return mouse.ENDFLOW;
727+
});
728+
await mouse.playNote(1 / 4, async () => {
729+
await mouse.playPitch("G", 4);
730+
return mouse.ENDFLOW;
731+
});
732+
await mouse.playNote(1 / 4, async () => {
733+
await mouse.playPitch("5", 4);
734+
return mouse.ENDFLOW;
735+
});
736+
await mouse.playNote(1 / 4, async () => {
737+
await mouse.playHertz(392);
738+
return mouse.ENDFLOW;
739+
});
740+
await mouse.playNote(1 / 4, async () => {
741+
await mouse.playRest();
742+
return mouse.ENDFLOW;
743+
});
744+
await mouse.dot(1, async () => {
745+
await mouse.playNote(1 / 4, async () => {
746+
await mouse.playPitch("sol", 4);
747+
return mouse.ENDFLOW;
748+
});
749+
return mouse.ENDFLOW;
750+
});
751+
await mouse.tie(async () => {
752+
await mouse.playNote(1 / 4, async () => {
753+
await mouse.playPitch("sol", 4);
754+
return mouse.ENDFLOW;
755+
});
756+
await mouse.playNote(1 / 4, async () => {
757+
await mouse.playPitch("sol", 4);
758+
return mouse.ENDFLOW;
759+
});
760+
return mouse.ENDFLOW;
761+
});
762+
await mouse.multiplyNoteValue(1 / 2, async () => {
763+
await mouse.playNote(1 / 4, async () => {
764+
await mouse.playPitch("sol", 4);
765+
return mouse.ENDFLOW;
766+
});
767+
return mouse.ENDFLOW;
768+
});
769+
await mouse.swing(1 / 24, 1 / 8, async () => {
770+
await mouse.playNote(1 / 4, async () => {
771+
await mouse.playPitch("sol", 4);
772+
return mouse.ENDFLOW;
773+
});
774+
await mouse.playNote(1 / 4, async () => {
775+
await mouse.playPitch("sol", 4);
776+
return mouse.ENDFLOW;
777+
});
778+
return mouse.ENDFLOW;
779+
});
780+
await mouse.playNoteMillis(1000 / (3 / 2), async () => {
781+
await mouse.playHertz(392);
782+
return mouse.ENDFLOW;
783+
});
784+
return mouse.ENDMOUSE;
785+
});
786+
MusicBlocks.run();`;
787+
788+
const expectedBlockList = [
789+
[0, "start", 200, 200, [null, 1, null]],
790+
[1, "newnote", 0, 0, [0, 2, 5, 9]],
791+
[2, "divide", 0, 0, [1, 3, 4]],
792+
[3, ["number", { "value": 1 }], 0, 0, [2]],
793+
[4, ["number", { "value": 4 }], 0, 0, [2]],
794+
[5, "vspace", 0, 0, [1, 6]],
795+
[6, "pitch", 0, 0, [5, 7, 8, null]],
796+
[7, ["solfege", { "value": "sol" }], 0, 0, [6]],
797+
[8, ["number", { "value": 4 }], 0, 0, [6]],
798+
[9, "newnote", 0, 0, [1, 10, 13, 17]],
799+
[10, "divide", 0, 0, [9, 11, 12]],
800+
[11, ["number", { "value": 1 }], 0, 0, [10]],
801+
[12, ["number", { "value": 4 }], 0, 0, [10]],
802+
[13, "vspace", 0, 0, [9, 14]],
803+
[14, "pitch", 0, 0, [13, 15, 16, null]],
804+
[15, ["notename", { "value": "G" }], 0, 0, [14]],
805+
[16, ["number", { "value": 4 }], 0, 0, [14]],
806+
[17, "newnote", 0, 0, [9, 18, 21, 25]],
807+
[18, "divide", 0, 0, [17, 19, 20]],
808+
[19, ["number", { "value": 1 }], 0, 0, [18]],
809+
[20, ["number", { "value": 4 }], 0, 0, [18]],
810+
[21, "vspace", 0, 0, [17, 22]],
811+
[22, "pitch", 0, 0, [21, 23, 24, null]],
812+
[23, ["solfege", { "value": "5" }], 0, 0, [22]],
813+
[24, ["number", { "value": 4 }], 0, 0, [22]],
814+
[25, "newnote", 0, 0, [17, 26, 29, 32]],
815+
[26, "divide", 0, 0, [25, 27, 28]],
816+
[27, ["number", { "value": 1 }], 0, 0, [26]],
817+
[28, ["number", { "value": 4 }], 0, 0, [26]],
818+
[29, "vspace", 0, 0, [25, 30]],
819+
[30, "hertz", 0, 0, [29, 31, null, null]],
820+
[31, ["number", { "value": 392 }], 0, 0, [30]],
821+
[32, "newnote", 0, 0, [25, 33, 36, 38]],
822+
[33, "divide", 0, 0, [32, 34, 35]],
823+
[34, ["number", { "value": 1 }], 0, 0, [33]],
824+
[35, ["number", { "value": 4 }], 0, 0, [33]],
825+
[36, "vspace", 0, 0, [32, 37]],
826+
[37, "rest2", 0, 0, [36, null]],
827+
[38, "rhythmicdot2", 0, 0, [32, 39, 40, 48]],
828+
[39, ["number", { "value": 1 }], 0, 0, [38]],
829+
[40, "newnote", 0, 0, [38, 41, 44, null]],
830+
[41, "divide", 0, 0, [40, 42, 43]],
831+
[42, ["number", { "value": 1 }], 0, 0, [41]],
832+
[43, ["number", { "value": 4 }], 0, 0, [41]],
833+
[44, "vspace", 0, 0, [40, 45]],
834+
[45, "pitch", 0, 0, [44, 46, 47, null]],
835+
[46, ["solfege", { "value": "sol" }], 0, 0, [45]],
836+
[47, ["number", { "value": 4 }], 0, 0, [45]],
837+
[48, "tie", 0, 0, [38, 49, 65]],
838+
[49, "newnote", 0, 0, [48, 50, 53, 57]],
839+
[50, "divide", 0, 0, [49, 51, 52]],
840+
[51, ["number", { "value": 1 }], 0, 0, [50]],
841+
[52, ["number", { "value": 4 }], 0, 0, [50]],
842+
[53, "vspace", 0, 0, [49, 54]],
843+
[54, "pitch", 0, 0, [53, 55, 56, null]],
844+
[55, ["solfege", { "value": "sol" }], 0, 0, [54]],
845+
[56, ["number", { "value": 4 }], 0, 0, [54]],
846+
[57, "newnote", 0, 0, [49, 58, 61, null]],
847+
[58, "divide", 0, 0, [57, 59, 60]],
848+
[59, ["number", { "value": 1 }], 0, 0, [58]],
849+
[60, ["number", { "value": 4 }], 0, 0, [58]],
850+
[61, "vspace", 0, 0, [57, 62]],
851+
[62, "pitch", 0, 0, [61, 63, 64, null]],
852+
[63, ["solfege", { "value": "sol" }], 0, 0, [62]],
853+
[64, ["number", { "value": 4 }], 0, 0, [62]],
854+
[65, "multiplybeatfactor", 0, 0, [48, 66, 69, 78]],
855+
[66, "divide", 0, 0, [65, 67, 68]],
856+
[67, ["number", { "value": 1 }], 0, 0, [66]],
857+
[68, ["number", { "value": 2 }], 0, 0, [66]],
858+
[69, "vspace", 0, 0, [65, 70]],
859+
[70, "newnote", 0, 0, [69, 71, 74, null]],
860+
[71, "divide", 0, 0, [70, 72, 73]],
861+
[72, ["number", { "value": 1 }], 0, 0, [71]],
862+
[73, ["number", { "value": 4 }], 0, 0, [71]],
863+
[74, "vspace", 0, 0, [70, 75]],
864+
[75, "pitch", 0, 0, [74, 76, 77, null]],
865+
[76, ["solfege", { "value": "sol" }], 0, 0, [75]],
866+
[77, ["number", { "value": 4 }], 0, 0, [75]],
867+
[78, "newswing2", 0, 0, [65, 79, 82, 85, 103]],
868+
[79, "divide", 0, 0, [78, 80, 81]],
869+
[80, ["number", { "value": 1 }], 0, 0, [79]],
870+
[81, ["number", { "value": 24 }], 0, 0, [79]],
871+
[82, "divide", 0, 0, [78, 83, 84]],
872+
[83, ["number", { "value": 1 }], 0, 0, [82]],
873+
[84, ["number", { "value": 8 }], 0, 0, [82]],
874+
[85, "vspace", 0, 0, [78, 86]],
875+
[86, "vspace", 0, 0, [85, 87]],
876+
[87, "newnote", 0, 0, [86, 88, 91, 95]],
877+
[88, "divide", 0, 0, [87, 89, 90]],
878+
[89, ["number", { "value": 1 }], 0, 0, [88]],
879+
[90, ["number", { "value": 4 }], 0, 0, [88]],
880+
[91, "vspace", 0, 0, [87, 92]],
881+
[92, "pitch", 0, 0, [91, 93, 94, null]],
882+
[93, ["solfege", { "value": "sol" }], 0, 0, [92]],
883+
[94, ["number", { "value": 4 }], 0, 0, [92]],
884+
[95, "newnote", 0, 0, [87, 96, 99, null]],
885+
[96, "divide", 0, 0, [95, 97, 98]],
886+
[97, ["number", { "value": 1 }], 0, 0, [96]],
887+
[98, ["number", { "value": 4 }], 0, 0, [96]],
888+
[99, "vspace", 0, 0, [95, 100]],
889+
[100, "pitch", 0, 0, [99, 101, 102, null]],
890+
[101, ["solfege", { "value": "sol" }], 0, 0, [100]],
891+
[102, ["number", { "value": 4 }], 0, 0, [100]],
892+
[103, "osctime", 0, 0, [78, 104, 109, null]],
893+
[104, "divide", 0, 0, [103, 105, 106]],
894+
[105, ["number", { "value": 1000 }], 0, 0, [104]],
895+
[106, "divide", 0, 0, [104, 107, 108]],
896+
[107, ["number", { "value": 3 }], 0, 0, [106]],
897+
[108, ["number", { "value": 2 }], 0, 0, [106]],
898+
[109, "vspace", 0, 0, [103, 110]],
899+
[110, "vspace", 0, 0, [109, 111]],
900+
[111, "hertz", 0, 0, [110, 112, null, null]],
901+
[112, ["number", { "value": 392 }], 0, 0, [111]]
902+
];
903+
904+
const AST = acorn.parse(code, { ecmaVersion: 2020 });
905+
let trees = AST2BlockList.toTrees(AST);
906+
let blockList = AST2BlockList.toBlockList(trees);
907+
expect(blockList).toEqual(expectedBlockList);
908+
});
909+
910+
// Test all Flow Blocks.
911+
test("should generate correct blockList for all flow blocks", () => {
912+
const code = `
913+
new Mouse(async mouse => {
914+
if (true) {
915+
await mouse.playNote(1 / 4, async () => {
916+
await mouse.playPitch("sol", 4);
917+
return mouse.ENDFLOW;
918+
});
919+
await mouse.playNote(1 / 4, async () => {
920+
await mouse.playPitch("sol", 4);
921+
return mouse.ENDFLOW;
922+
});
923+
await mouse.playNote(1 / 4, async () => {
924+
await mouse.playPitch("sol", 4);
925+
return mouse.ENDFLOW;
926+
});
927+
} else {
928+
await mouse.playNote(1 / 4, async () => {
929+
await mouse.playPitch("sol", 4);
930+
return mouse.ENDFLOW;
931+
});
932+
await mouse.playNote(1 / 6, async () => {
933+
await mouse.playPitch("sol", 4);
934+
return mouse.ENDFLOW;
935+
});
936+
}
937+
while (1000) {
938+
await mouse.playNote(1 / 4, async () => {
939+
await mouse.playPitch("sol", 4);
940+
return mouse.ENDFLOW;
941+
});
942+
break;
943+
}
944+
while (1000) {
945+
await mouse.playNote(1 / 4, async () => {
946+
await mouse.playPitch("sol", 4);
947+
return mouse.ENDFLOW;
948+
});
949+
}
950+
do {
951+
await mouse.playNote(1 / 4, async () => {
952+
await mouse.playPitch("sol", 4);
953+
return mouse.ENDFLOW;
954+
});
955+
} while (true);
956+
switch (1) {
957+
case 1:
958+
await mouse.playNote(1 / 4, async () => {
959+
await mouse.playPitch("sol", 4);
960+
return mouse.ENDFLOW;
961+
});
962+
break;
963+
break;
964+
break;
965+
default:
966+
await mouse.playNote(1 / 4, async () => {
967+
await mouse.playPitch("5", 4);
968+
return mouse.ENDFLOW;
969+
});
970+
}
971+
return mouse.ENDMOUSE;
972+
});
973+
MusicBlocks.run();`;
974+
975+
const expectedBlockList = [
976+
[0, "start", 200, 200, [null, 1, null]],
977+
[1, "ifthenelse", 0, 0, [0, 2, 3, 27, 43]],
978+
[2, ["boolean", { "value": true }], 0, 0, [1]],
979+
[3, "newnote", 0, 0, [1, 4, 7, 11]],
980+
[4, "divide", 0, 0, [3, 5, 6]],
981+
[5, ["number", { "value": 1 }], 0, 0, [4]],
982+
[6, ["number", { "value": 4 }], 0, 0, [4]],
983+
[7, "vspace", 0, 0, [3, 8]],
984+
[8, "pitch", 0, 0, [7, 9, 10, null]],
985+
[9, ["solfege", { "value": "sol" }], 0, 0, [8]],
986+
[10, ["number", { "value": 4 }], 0, 0, [8]],
987+
[11, "newnote", 0, 0, [3, 12, 15, 19]],
988+
[12, "divide", 0, 0, [11, 13, 14]],
989+
[13, ["number", { "value": 1 }], 0, 0, [12]],
990+
[14, ["number", { "value": 4 }], 0, 0, [12]],
991+
[15, "vspace", 0, 0, [11, 16]],
992+
[16, "pitch", 0, 0, [15, 17, 18, null]],
993+
[17, ["solfege", { "value": "sol" }], 0, 0, [16]],
994+
[18, ["number", { "value": 4 }], 0, 0, [16]],
995+
[19, "newnote", 0, 0, [11, 20, 23, null]],
996+
[20, "divide", 0, 0, [19, 21, 22]],
997+
[21, ["number", { "value": 1 }], 0, 0, [20]],
998+
[22, ["number", { "value": 4 }], 0, 0, [20]],
999+
[23, "vspace", 0, 0, [19, 24]],
1000+
[24, "pitch", 0, 0, [23, 25, 26, null]],
1001+
[25, ["solfege", { "value": "sol" }], 0, 0, [24]],
1002+
[26, ["number", { "value": 4 }], 0, 0, [24]],
1003+
[27, "newnote", 0, 0, [1, 28, 31, 35]],
1004+
[28, "divide", 0, 0, [27, 29, 30]],
1005+
[29, ["number", { "value": 1 }], 0, 0, [28]],
1006+
[30, ["number", { "value": 4 }], 0, 0, [28]],
1007+
[31, "vspace", 0, 0, [27, 32]],
1008+
[32, "pitch", 0, 0, [31, 33, 34, null]],
1009+
[33, ["solfege", { "value": "sol" }], 0, 0, [32]],
1010+
[34, ["number", { "value": 4 }], 0, 0, [32]],
1011+
[35, "newnote", 0, 0, [27, 36, 39, null]],
1012+
[36, "divide", 0, 0, [35, 37, 38]],
1013+
[37, ["number", { "value": 1 }], 0, 0, [36]],
1014+
[38, ["number", { "value": 6 }], 0, 0, [36]],
1015+
[39, "vspace", 0, 0, [35, 40]],
1016+
[40, "pitch", 0, 0, [39, 41, 42, null]],
1017+
[41, ["solfege", { "value": "sol" }], 0, 0, [40]],
1018+
[42, ["number", { "value": 4 }], 0, 0, [40]],
1019+
[43, "forever", 0, 0, [1, 44, 53]],
1020+
[44, "newnote", 0, 0, [43, 45, 48, 52]],
1021+
[45, "divide", 0, 0, [44, 46, 47]],
1022+
[46, ["number", { "value": 1 }], 0, 0, [45]],
1023+
[47, ["number", { "value": 4 }], 0, 0, [45]],
1024+
[48, "vspace", 0, 0, [44, 49]],
1025+
[49, "pitch", 0, 0, [48, 50, 51, null]],
1026+
[50, ["solfege", { "value": "sol" }], 0, 0, [49]],
1027+
[51, ["number", { "value": 4 }], 0, 0, [49]],
1028+
[52, "break", 0, 0, [44, null, null, null]],
1029+
[53, "forever", 0, 0, [43, 54, 62]],
1030+
[54, "newnote", 0, 0, [53, 55, 58, null]],
1031+
[55, "divide", 0, 0, [54, 56, 57]],
1032+
[56, ["number", { "value": 1 }], 0, 0, [55]],
1033+
[57, ["number", { "value": 4 }], 0, 0, [55]],
1034+
[58, "vspace", 0, 0, [54, 59]],
1035+
[59, "pitch", 0, 0, [58, 60, 61, null]],
1036+
[60, ["solfege", { "value": "sol" }], 0, 0, [59]],
1037+
[61, ["number", { "value": 4 }], 0, 0, [59]],
1038+
[62, "until", 0, 0, [53, 63, 64, 73]],
1039+
[63, ["boolean", { "value": true }], 0, 0, [62]],
1040+
[64, "vspace", 0, 0, [62, 65]],
1041+
[65, "newnote", 0, 0, [64, 66, 69, null]],
1042+
[66, "divide", 0, 0, [65, 67, 68]],
1043+
[67, ["number", { "value": 1 }], 0, 0, [66]],
1044+
[68, ["number", { "value": 4 }], 0, 0, [66]],
1045+
[69, "vspace", 0, 0, [65, 70]],
1046+
[70, "pitch", 0, 0, [69, 71, 72, null]],
1047+
[71, ["solfege", { "value": "sol" }], 0, 0, [70]],
1048+
[72, ["number", { "value": 4 }], 0, 0, [70]],
1049+
[73, "switch", 0, 0, [62, 74, 75, null]],
1050+
[74, ["number", { "value": 1 }], 0, 0, [73]],
1051+
[75, "case", 0, 0, [73, 76, 77, 88]],
1052+
[76, ["number", { "value": 1 }], 0, 0, [75]],
1053+
[77, "newnote", 0, 0, [75, 78, 81, 85]],
1054+
[78, "divide", 0, 0, [77, 79, 80]],
1055+
[79, ["number", { "value": 1 }], 0, 0, [78]],
1056+
[80, ["number", { "value": 4 }], 0, 0, [78]],
1057+
[81, "vspace", 0, 0, [77, 82]],
1058+
[82, "pitch", 0, 0, [81, 83, 84, null]],
1059+
[83, ["solfege", { "value": "sol" }], 0, 0, [82]],
1060+
[84, ["number", { "value": 4 }], 0, 0, [82]],
1061+
[85, "break", 0, 0, [77, 86, null, null]],
1062+
[86, "break", 0, 0, [85, 87, null, null]],
1063+
[87, "break", 0, 0, [86, null, null, null]],
1064+
[88, "defaultcase", 0, 0, [75, 89, null, null]],
1065+
[89, "newnote", 0, 0, [88, 90, 93, null]],
1066+
[90, "divide", 0, 0, [89, 91, 92]],
1067+
[91, ["number", { "value": 1 }], 0, 0, [90]],
1068+
[92, ["number", { "value": 4 }], 0, 0, [90]],
1069+
[93, "vspace", 0, 0, [89, 94]],
1070+
[94, "pitch", 0, 0, [93, 95, 96, null]],
1071+
[95, ["solfege", { "value": "5" }], 0, 0, [94]],
1072+
[96, ["number", { "value": 4 }], 0, 0, [94]]
1073+
];
1074+
1075+
const AST = acorn.parse(code, { ecmaVersion: 2020 });
1076+
let trees = AST2BlockList.toTrees(AST);
1077+
let blockList = AST2BlockList.toBlockList(trees);
1078+
expect(blockList).toEqual(expectedBlockList);
1079+
});
1080+
});

0 commit comments

Comments
 (0)