From b8af7c0723f3497726c467ef2fa7d0257ccea511 Mon Sep 17 00:00:00 2001
From: Andrew Sliwinski <andrewsliwinski@acm.org>
Date: Fri, 23 Dec 2016 14:09:35 -0500
Subject: [PATCH] Add minimal integration tests

---
 test/fixtures/project_demo.json | 373 +++++++++-----------------------
 test/integration/default.js     |  24 +-
 test/integration/demo.js        |  32 +++
 3 files changed, 150 insertions(+), 279 deletions(-)
 create mode 100644 test/integration/demo.js

diff --git a/test/fixtures/project_demo.json b/test/fixtures/project_demo.json
index b10376ec7..1cce6cc5b 100644
--- a/test/fixtures/project_demo.json
+++ b/test/fixtures/project_demo.json
@@ -1,110 +1,23 @@
 {
 	"objName": "Stage",
 	"variables": [{
-			"name": "x",
-			"value": "1",
-			"isPersistent": false
-		},
-		{
-			"name": "y",
-			"value": "1",
-			"isPersistent": false
-		},
-		{
-			"name": "z",
-			"value": "1",
-			"isPersistent": false
-		},
-		{
-			"name": "d",
-			"value": "1",
-			"isPersistent": false
-		},
-		{
-			"name": "a",
-			"value": 4,
+			"name": "foo",
+			"value": 119,
 			"isPersistent": false
 		}],
 	"lists": [{
-			"listName": "D# Minor Pentatonic",
-			"contents": ["78",
-				"75",
-				"73",
-				"75",
-				"70",
-				"78",
-				"73",
-				"75",
-				"75",
-				"78",
-				"75",
-				"73",
-				"75",
-				"70",
-				"75",
-				"78",
-				"73",
-				"75",
-				"78",
-				"75",
-				"73",
-				"75",
-				"70",
-				"73",
-				"68",
-				"70",
-				"66",
-				"68",
-				"63"],
+			"listName": "bar",
+			"contents": [116, 3, 279, 245, 203, 331, 9, 36, 152, 60],
 			"isPersistent": false,
 			"x": 5,
 			"y": 32,
-			"width": 125,
-			"height": 206,
+			"width": 102,
+			"height": 202,
 			"visible": true
 		}],
-	"scripts": [[52,
-			8,
-			[["whenIReceive", "start"],
-				["setVar:to:", "a", "1"],
-				["doRepeat",
-					["lineCountOfList:", "D# Minor Pentatonic"],
-					[["noteOn:duration:elapsed:from:", ["getLine:ofList:", ["readVariable", "a"], "D# Minor Pentatonic"], 0.5], ["changeVar:by:", "a", 1]]]]],
-		[53,
-			186,
-			[["whenIReceive", "start"],
-				["setVar:to:", "x", "1"],
-				["rest:elapsed:from:", 7.25],
-				["doRepeat",
-					["lineCountOfList:", "D# Minor Pentatonic"],
-					[["noteOn:duration:elapsed:from:", ["getLine:ofList:", ["readVariable", "x"], "D# Minor Pentatonic"], 0.25], ["changeVar:by:", "x", 1]]]]],
-		[48,
-			557,
-			[["whenIReceive", "start"],
-				["setVar:to:", "z", "1"],
-				["rest:elapsed:from:", 13],
-				["doRepeat",
-					["lineCountOfList:", "D# Minor Pentatonic"],
-					[["noteOn:duration:elapsed:from:", ["getLine:ofList:", ["readVariable", "z"], "D# Minor Pentatonic"], 0.0625], ["changeVar:by:", "z", 1]]]]],
-		[49,
-			368,
-			[["whenIReceive", "start"],
-				["setVar:to:", "y", "1"],
-				["rest:elapsed:from:", 11],
-				["doRepeat",
-					["lineCountOfList:", "D# Minor Pentatonic"],
-					[["noteOn:duration:elapsed:from:", ["getLine:ofList:", ["readVariable", "y"], "D# Minor Pentatonic"], 0.125], ["changeVar:by:", "y", 1]]]]],
-		[52,
-			745,
-			[["whenIReceive", "start"],
-				["setVar:to:", "d", "1"],
-				["rest:elapsed:from:", 13.5],
-				["doRepeat",
-					["lineCountOfList:", "D# Minor Pentatonic"],
-					[["noteOn:duration:elapsed:from:", ["getLine:ofList:", ["readVariable", "d"], "D# Minor Pentatonic"], 0.03125], ["changeVar:by:", "d", 1]]]]]],
 	"sounds": [{
 			"soundName": "pop",
-			"soundID": 0,
+			"soundID": 1,
 			"md5": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
 			"sampleCount": 258,
 			"rate": 11025,
@@ -112,11 +25,11 @@
 		}],
 	"costumes": [{
 			"costumeName": "backdrop1",
-			"baseLayerID": 4,
-			"baseLayerMD5": "b61b1077b0ea1931abee9dbbfa7903ff.png",
-			"bitmapResolution": 2,
-			"rotationCenterX": 480,
-			"rotationCenterY": 360
+			"baseLayerID": 5,
+			"baseLayerMD5": "739b5e2a2435f6e1ec2993791b423146.png",
+			"bitmapResolution": 1,
+			"rotationCenterX": 240,
+			"rotationCenterY": 180
 		}],
 	"currentCostumeIndex": 0,
 	"penLayerMD5": "5c81a336fab8be57adc039a8a2b33ca9.png",
@@ -124,124 +37,55 @@
 	"tempoBPM": 60,
 	"videoAlpha": 0.5,
 	"children": [{
-			"objName": "Indicator",
-			"scripts": [[247.85,
-					32.8,
-					[["procDef", "foo %n", ["bar"], [1], false],
-						["hide"],
-						["clearPenTrails"],
-						["penColor:", 5968094],
-						["say:", ["getParam", "bar", "r"]],
-						["stopScripts", "this script"]]],
-				[41, 36, [["whenGreenFlag"], ["call", "foo %n", 1]]]],
+			"objName": "Sprite1",
+			"scripts": [[30,
+					29,
+					[["whenGreenFlag"],
+						["doRepeat", 10, [["createCloneOf", "_myself_"]]],
+						["wait:elapsed:from:", 0.01],
+						["doWaitUntil", ["=", "1", ["randomFrom:to:", 1, 2]]],
+						["doForever", [["turnRight:", 15], ["changeGraphicEffect:by:", "color", 10]]]]],
+				[30,
+					275,
+					[["whenCloned"],
+						["append:toList:", ["randomFrom:to:", 0, 360], "bar"],
+						["heading:", ["getLine:ofList:", ["lineCountOfList:", "bar"], "bar"]],
+						["doForever",
+							[["forward:", ["readVariable", "foo"]],
+								["bounceOffEdge"],
+								["doIf", ["touching:", "_edge_"], [["changeGraphicEffect:by:", "color", 25]]]]]]],
+				[322,
+					23,
+					[["whenGreenFlag"], ["setVar:to:", "foo", 0], ["doForever", [["changeVar:by:", "foo", 1]]]]]],
 			"sounds": [{
-					"soundName": "pop",
+					"soundName": "meow",
 					"soundID": 0,
-					"md5": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
-					"sampleCount": 258,
-					"rate": 11025,
+					"md5": "83c36d806dc92327b9e7049a565c6bff.wav",
+					"sampleCount": 18688,
+					"rate": 22050,
 					"format": ""
 				}],
 			"costumes": [{
 					"costumeName": "costume1",
 					"baseLayerID": 1,
-					"baseLayerMD5": "d36f6603ec293d2c2198d3ea05109fe0.png",
-					"bitmapResolution": 2,
-					"rotationCenterX": 0,
-					"rotationCenterY": 0
-				}],
-			"currentCostumeIndex": 0,
-			"scratchX": 22,
-			"scratchY": -26,
-			"scale": 1,
-			"direction": 90,
-			"rotationStyle": "normal",
-			"isDraggable": false,
-			"indexInLibrary": 3,
-			"visible": false,
-			"spriteInfo": {
-			}
-		},
-		{
-			"target": "Stage",
-			"cmd": "timer",
-			"param": null,
-			"color": 2926050,
-			"label": "timer",
-			"mode": 1,
-			"sliderMin": 0,
-			"sliderMax": 100,
-			"isDiscrete": true,
-			"x": 5,
-			"y": 5,
-			"visible": false
-		},
-		{
-			"target": "Stage",
-			"cmd": "getVar:",
-			"param": "x",
-			"color": 15629590,
-			"label": "x",
-			"mode": 1,
-			"sliderMin": 0,
-			"sliderMax": 100,
-			"isDiscrete": true,
-			"x": 5,
-			"y": 268,
-			"visible": true
-		},
-		{
-			"target": "Stage",
-			"cmd": "getVar:",
-			"param": "y",
-			"color": 15629590,
-			"label": "y",
-			"mode": 1,
-			"sliderMin": 0,
-			"sliderMax": 100,
-			"isDiscrete": true,
-			"x": 5,
-			"y": 295,
-			"visible": true
-		},
-		{
-			"target": "Stage",
-			"cmd": "getVar:",
-			"param": "z",
-			"color": 15629590,
-			"label": "z",
-			"mode": 1,
-			"sliderMin": 0,
-			"sliderMax": 100,
-			"isDiscrete": true,
-			"x": 78,
-			"y": 268,
-			"visible": true
-		},
-		{
-			"objName": "Play",
-			"scripts": [[32, 33, [["whenClicked"], ["broadcast:", "start"]]]],
-			"sounds": [{
-					"soundName": "pop",
-					"soundID": 0,
-					"md5": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
-					"sampleCount": 258,
-					"rate": 11025,
-					"format": ""
-				}],
-			"costumes": [{
-					"costumeName": "costume1",
+					"baseLayerMD5": "f9a1c175dbe2e5dee472858dd30d16bb.svg",
+					"bitmapResolution": 1,
+					"rotationCenterX": 47,
+					"rotationCenterY": 55
+				},
+				{
+					"costumeName": "costume2",
 					"baseLayerID": 2,
-					"baseLayerMD5": "30f811366ae3a53e6447932cc7f0212d.png",
-					"bitmapResolution": 2,
-					"rotationCenterX": 68,
-					"rotationCenterY": 115
+					"baseLayerMD5": "6e8bd9ae68fdb02b7e1e3df656a75635.svg",
+					"bitmapResolution": 1,
+					"rotationCenterX": 47,
+					"rotationCenterY": 55
 				}],
 			"currentCostumeIndex": 0,
-			"scratchX": 2,
-			"scratchY": -48,
+			"scratchX": 0,
+			"scratchY": 0,
 			"scale": 1,
-			"direction": 90,
+			"direction": -30,
 			"rotationStyle": "normal",
 			"isDraggable": false,
 			"indexInLibrary": 1,
@@ -252,55 +96,43 @@
 		{
 			"target": "Stage",
 			"cmd": "getVar:",
-			"param": "d",
+			"param": "foo",
 			"color": 15629590,
-			"label": "d",
+			"label": "foo",
 			"mode": 1,
 			"sliderMin": 0,
 			"sliderMax": 100,
 			"isDiscrete": true,
 			"x": 5,
-			"y": 241,
+			"y": 5,
 			"visible": true
 		},
 		{
-			"target": "Stage",
-			"cmd": "getVar:",
-			"param": "a",
-			"color": 15629590,
-			"label": "a",
-			"mode": 1,
-			"sliderMin": 0,
-			"sliderMax": 100,
-			"isDiscrete": true,
-			"x": 78,
-			"y": 241,
-			"visible": true
-		},
-		{
-			"objName": "Stop",
-			"scripts": [[45, 104, [["whenClicked"], ["stopScripts", "all"]]]],
+			"objName": "Apple",
+			"scripts": [[52,
+					27,
+					[["whenGreenFlag"], ["doRepeat", 10, [["turnRight:", 15], ["broadcast:", "message1"]]]]]],
 			"sounds": [{
 					"soundName": "pop",
-					"soundID": 0,
+					"soundID": 1,
 					"md5": "83a9787d4cb6f3b7632b4ddfebf74367.wav",
 					"sampleCount": 258,
 					"rate": 11025,
 					"format": ""
 				}],
 			"costumes": [{
-					"costumeName": "costume1",
+					"costumeName": "apple",
 					"baseLayerID": 3,
-					"baseLayerMD5": "3de406f265b8d664406adf7c70762514.png",
-					"bitmapResolution": 2,
-					"rotationCenterX": 68,
-					"rotationCenterY": 70
+					"baseLayerMD5": "831ccd4741a7a56d85f6698a21f4ca69.svg",
+					"bitmapResolution": 1,
+					"rotationCenterX": 31,
+					"rotationCenterY": 31
 				}],
 			"currentCostumeIndex": 0,
-			"scratchX": 121,
-			"scratchY": -33,
+			"scratchX": 135,
+			"scratchY": 9,
 			"scale": 1,
-			"direction": 90,
+			"direction": 180,
 			"rotationStyle": "normal",
 			"isDraggable": false,
 			"indexInLibrary": 2,
@@ -309,51 +141,46 @@
 			}
 		},
 		{
-			"listName": "D# Minor Pentatonic",
-			"contents": ["78",
-				"75",
-				"73",
-				"75",
-				"70",
-				"78",
-				"73",
-				"75",
-				"75",
-				"78",
-				"75",
-				"73",
-				"75",
-				"70",
-				"75",
-				"78",
-				"73",
-				"75",
-				"78",
-				"75",
-				"73",
-				"75",
-				"70",
-				"73",
-				"68",
-				"70",
-				"66",
-				"68",
-				"63"],
+			"objName": "Bananas",
+			"scripts": [[53,
+					33,
+					[["whenIReceive", "message1"], ["doForever", [["turnRight:", ["readVariable", "foo"]]]]]]],
+			"costumes": [{
+					"costumeName": "bananas",
+					"baseLayerID": 4,
+					"baseLayerMD5": "40bb8a1afe88cec78254f6fcfee98242.svg",
+					"bitmapResolution": 1,
+					"rotationCenterX": 36,
+					"rotationCenterY": 37
+				}],
+			"currentCostumeIndex": 0,
+			"scratchX": -151,
+			"scratchY": 13,
+			"scale": 1,
+			"direction": -59,
+			"rotationStyle": "normal",
+			"isDraggable": false,
+			"indexInLibrary": 3,
+			"visible": true,
+			"spriteInfo": {
+			}
+		},
+		{
+			"listName": "bar",
+			"contents": [116, 3, 279, 245, 203, 331, 9, 36, 152, 60],
 			"isPersistent": false,
 			"x": 5,
 			"y": 32,
-			"width": 125,
-			"height": 206,
+			"width": 102,
+			"height": 202,
 			"visible": true
 		}],
 	"info": {
 		"spriteCount": 3,
-		"projectID": "118381369",
+		"flashVersion": "MAC 21,0,0,174",
+		"swfVersion": "v445.1",
 		"videoOn": false,
-		"hasCloudData": false,
-		"userAgent": "Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/53.0.2785.143 Safari\/537.36",
-		"scriptCount": 9,
-		"flashVersion": "MAC 23,0,0,185",
-		"swfVersion": "v450.1"
+		"userAgent": "Scratch 2.0 Offline Editor",
+		"scriptCount": 5
 	}
-}
+}
\ No newline at end of file
diff --git a/test/integration/default.js b/test/integration/default.js
index acbd0e9f4..92a05ac02 100644
--- a/test/integration/default.js
+++ b/test/integration/default.js
@@ -3,18 +3,30 @@ var VirtualMachine = require('../../src/index');
 
 var project = require('../fixtures/project_default.json');
 
-test('load default project & run', function (t) {
+test('default project', function (t) {
     var vm = new VirtualMachine();
+
+    // Evaluate playground data and exit
+    vm.on('playgroundData', function (e) {
+        var threads = JSON.parse(e.threads);
+        t.ok(threads.length == 0);
+        t.end();
+        process.nextTick(process.exit);
+    });
+
+    // Start VM, load project, and run
     t.doesNotThrow(function () {
         vm.start();
         vm.clear();
-        vm.setCompatibilityMode(true);
+        vm.setCompatibilityMode(false);
         vm.setTurboMode(false);
         vm.loadProject(JSON.stringify(project));
         vm.greenFlag();
-        vm.stopAll();
     });
-    t.
-    t.end();
-    process.nextTick(process.exit);
+
+    // After two seconds, get playground data and stop
+    setTimeout(function () {
+        vm.getPlaygroundData();
+        vm.stopAll();
+    }, 2000);
 });
diff --git a/test/integration/demo.js b/test/integration/demo.js
new file mode 100644
index 000000000..5ca3d9005
--- /dev/null
+++ b/test/integration/demo.js
@@ -0,0 +1,32 @@
+var test = require('tap').test;
+var VirtualMachine = require('../../src/index');
+
+var project = require('../fixtures/project_demo.json');
+
+test('demo project', function (t) {
+    var vm = new VirtualMachine();
+
+    // Evaluate playground data and exit
+    vm.on('playgroundData', function (e) {
+        var threads = JSON.parse(e.threads);
+        t.ok(threads.length > 0);
+        t.end();
+        process.nextTick(process.exit);
+    });
+
+    // Start VM, load project, and run
+    t.doesNotThrow(function () {
+        vm.start();
+        vm.clear();
+        vm.setCompatibilityMode(false);
+        vm.setTurboMode(false);
+        vm.loadProject(JSON.stringify(project));
+        vm.greenFlag();
+    });
+
+    // After two seconds, get playground data and stop
+    setTimeout(function () {
+        vm.getPlaygroundData();
+        vm.stopAll();
+    }, 2000);
+});