diff --git a/lib/sb3_definitions.json b/lib/sb3_definitions.json index 008e9c5a..1f5f9a0d 100644 --- a/lib/sb3_definitions.json +++ b/lib/sb3_definitions.json @@ -220,6 +220,9 @@ "opcode": { "type": "string" }, + "comment": { + "type": "string" + }, "inputs": { "type": "object", "additionalProperties": { @@ -281,6 +284,24 @@ "opcode" ] }, + "comment": { + "type": "object", + "properties": { + "blockId": {"$ref": "#/definitions/optionalString"}, + "text": { + "type": "string", + "maxLength": 8000 + }, + "minimized": {"type": "boolean"}, + "x": {"type": "number"}, + "y": {"type": "number"}, + "width": {"type": "number"}, + "height": {"type": "number"} + }, + "required": [ + "text" + ] + }, "stage": { "type": "object", "description": "Description of property (and/or property/value pairs) that are unique to the stage.", @@ -378,6 +399,10 @@ "type": "object", "additionalProperties": {"$ref":"#/definitions/broadcast_message"} }, + "comments": { + "type": "object", + "additionalProperties": {"$ref": "#/definitions/comment"} + }, "costumes": { "type": "array", "items": {"$ref":"#/definitions/costume"}, diff --git a/test/fixtures/data.js b/test/fixtures/data.js index 05095483..81b2f08d 100644 --- a/test/fixtures/data.js +++ b/test/fixtures/data.js @@ -5,6 +5,7 @@ var path = require('path'); // Build file listings var sb = glob.sync(path.resolve(__dirname, './data/*.sb')); var sb2 = glob.sync(path.resolve(__dirname, './data/*.sb2')); +var sb3 = glob.sync(path.resolve(__dirname, './data/*.sb3')); var sprite2 = glob.sync(path.resolve(__dirname, './data/*.sprite2')); // Sprite2 and Sprite3 jsons have modified file extensions // so that they don't get caught here but can still be used by the @@ -15,9 +16,10 @@ var gzipJson = glob.sync(path.resolve(__dirname, './data/*.json.gz')); // Read files and convert to buffers for (var a in sb) sb[a] = fs.readFileSync(sb[a]); for (var b in sb2) sb2[b] = fs.readFileSync(sb2[b]); -for (var c in json) json[c] = fs.readFileSync(json[c]); -for (var d in gzipJson) gzipJson[d] = fs.readFileSync(gzipJson[d]); -for (var e in sprite2) sprite2[e] = fs.readFileSync(sprite2[e]); +for (var c in sb3) sb3[c] = fs.readFileSync(sb3[c]); +for (var d in json) json[d] = fs.readFileSync(json[d]); +for (var e in gzipJson) gzipJson[e] = fs.readFileSync(gzipJson[e]); +for (var f in sprite2) sprite2[f] = fs.readFileSync(sprite2[f]); // Return listings module.exports = { @@ -40,8 +42,13 @@ module.exports = { example_sprite2_json: fs.readFileSync(path.resolve(__dirname, './data/_example_sprite.sprite2json')), bananas_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas.sprite2')) }, + sb3_comments: { + comments: fs.readFileSync(path.resolve(__dirname, './data/_comments.sb3')), + invalid_comments: fs.readFileSync(path.resolve(__dirname, './data/_invalid_comments.sb3')) + }, sb: sb, sb2: sb2, + sb3: sb3, json: json, gzipJson: gzipJson, sprite2: sprite2 diff --git a/test/fixtures/data/_comments.sb3 b/test/fixtures/data/_comments.sb3 new file mode 100644 index 00000000..ce937c45 Binary files /dev/null and b/test/fixtures/data/_comments.sb3 differ diff --git a/test/fixtures/data/_invalid_comments.sb3 b/test/fixtures/data/_invalid_comments.sb3 new file mode 100644 index 00000000..39d9714c Binary files /dev/null and b/test/fixtures/data/_invalid_comments.sb3 differ diff --git a/test/integration/comments_sb3.js b/test/integration/comments_sb3.js new file mode 100644 index 00000000..57bacff6 --- /dev/null +++ b/test/integration/comments_sb3.js @@ -0,0 +1,44 @@ +var test = require('tap').test; +var JSZip = require('jszip'); +var data = require('../fixtures/data'); +var parser = require('../../index'); + +test('comments sb3', function (t) { + parser(data.sb3_comments.comments, false, function (err, result) { + t.equal(err, null); + t.equal(Array.isArray(result), true); + var res = result[0]; + var possibleZip = result[1]; + t.type(res, 'object'); + t.equal(res.projectVersion, 3); + t.equal(possibleZip instanceof JSZip, true); + + t.type(res.targets[0].comments, 'object'); + t.equal(Object.values(res.targets[0].comments).length, 1); + + t.type(res.targets[1].comments, 'object'); + t.equal(Object.values(res.targets[1].comments).length, 6); + + t.end(); + }); +}); + +test('invalid comments sb3', function (t) { + parser(data.sb3_comments.invalid_comments, false, function (err, result) { + t.type(err, 'object'); + t.type(err.validationError, 'string'); + + var sb3Errors = err.sb3Errors; + t.type(sb3Errors, 'object'); + t.type(sb3Errors[0].keyword, 'string'); + t.type(sb3Errors[0].dataPath, 'string'); + t.match(sb3Errors[0].dataPath, /^\.targets\[1\]\.comments\[.*\]\.width$/); + t.type(sb3Errors[0].schemaPath, 'string'); + t.type(sb3Errors[0].message, 'string'); + t.equal(sb3Errors[0].message, 'should be number'); + t.type(sb3Errors[0].params, 'object'); + t.type(result, 'undefined'); + + t.end(); + }); +});