Add comments for deserialization and add tests

This commit is contained in:
Corey Frang 2018-08-20 13:25:24 -04:00
parent 896e62d2c4
commit ae219e361a
2 changed files with 52 additions and 6 deletions

View file

@ -18,6 +18,8 @@ const {loadCostume} = require('../import/load-costume.js');
const {loadSound} = require('../import/load-sound.js');
const {deserializeCostume, deserializeSound} = require('./deserialize-assets.js');
const hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* @typedef {object} ImportedProject
* @property {Array.<Target>} targets - the imported Scratch 3.0 target objects.
@ -99,7 +101,7 @@ const primitiveOpcodeInfoMap = {
const serializePrimitiveBlock = function (block) {
// Returns an array represeting a primitive block or null if not one of
// the primitive types above
if (primitiveOpcodeInfoMap.hasOwnProperty(block.opcode)) {
if (hasOwnProperty.call(primitiveOpcodeInfoMap, block.opcode)) {
const primitiveInfo = primitiveOpcodeInfoMap[block.opcode];
const primitiveConstant = primitiveInfo[0];
const fieldName = primitiveInfo[1];
@ -132,7 +134,7 @@ const serializePrimitiveBlock = function (block) {
const serializeInputs = function (inputs) {
const obj = Object.create(null);
for (const inputName in inputs) {
if (!inputs.hasOwnProperty(inputName)) continue;
if (!hasOwnProperty.call(inputs, inputName)) continue;
// if block and shadow refer to the same block, only serialize one
if (inputs[inputName].block === inputs[inputName].shadow) {
// has block and shadow, and they are the same
@ -166,7 +168,7 @@ const serializeInputs = function (inputs) {
const serializeFields = function (fields) {
const obj = Object.create(null);
for (const fieldName in fields) {
if (!fields.hasOwnProperty(fieldName)) continue;
if (!hasOwnProperty.call(fields, fieldName)) continue;
obj[fieldName] = [fields[fieldName].value];
if (fields[fieldName].hasOwnProperty('id')) {
obj[fieldName].push(fields[fieldName].id);
@ -688,8 +690,9 @@ const deserializeInputs = function (inputs, parentId, blocks) {
// because we call prototype functions later in the vm
const obj = {};
for (const inputName in inputs) {
if (!inputs.hasOwnProperty(inputName)) continue;
if (!hasOwnProperty.call(inputs, inputName)) continue;
const inputDescArr = inputs[inputName];
// If this block has already been deserialized (it's not an array) skip it
if (!Array.isArray(inputDescArr)) continue;
let block = null;
let shadow = null;
@ -722,8 +725,9 @@ const deserializeFields = function (fields) {
// because we call prototype functions later in the vm
const obj = {};
for (const fieldName in fields) {
if (!fields.hasOwnProperty(fieldName)) continue;
if (!hasOwnProperty.call(fields, fieldName)) continue;
const fieldDescArr = fields[fieldName];
// If this block has already been deserialized (it's not an array) skip it
if (!Array.isArray(fieldDescArr)) continue;
obj[fieldName] = {
name: fieldName,
@ -745,13 +749,16 @@ const deserializeFields = function (fields) {
/**
* Covnert serialized INPUT and FIELD primitives back to hydrated block templates.
* Should be able to deserialize a format that has already been deserialized. The only
* "east" path to adding new targets/code requires going through deserialize, so it should
* work with pre-parsed deserialized blocks.
*
* @param {object} blocks Serialized SB3 "blocks" property of a target. Will be mutated.
* @return {object} input is modified and returned
*/
const deserializeBlocks = function (blocks) {
for (const blockId in blocks) {
if (!blocks.hasOwnProperty(blockId)) {
if (!Object.prototype.hasOwnProperty.call(blocks, blockId)) {
continue;
}
const block = blocks[blockId];

View file

@ -182,3 +182,42 @@ test('serialize sb3 preserves sprite layer order', t => {
t.end();
});
});
test('serializeBlocks', t => {
const vm = new VirtualMachine();
vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
.then(() => {
const blocks = vm.runtime.targets[1].blocks._blocks;
const result = sb3.serializeBlocks(blocks);
// @todo Analyze
t.type(result[0], 'object');
t.ok(Object.keys(result[0]).length < Object.keys(blocks).length, 'less blocks in serialized format');
t.ok(Array.isArray(result[1]));
t.end();
});
});
test('deserializeBlocks', t => {
const vm = new VirtualMachine();
vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
.then(() => {
const blocks = vm.runtime.targets[1].blocks._blocks;
const serialized = sb3.serializeBlocks(blocks)[0];
const deserialized = sb3.deserializeBlocks(serialized);
t.equal(Object.keys(deserialized).length, Object.keys(blocks).length, 'same number of blocks');
t.end();
});
});
test('deserializeBlocks on already deserialized input', t => {
const vm = new VirtualMachine();
vm.loadProject(readFileToBuffer(commentsSB3ProjectPath))
.then(() => {
const blocks = vm.runtime.targets[1].blocks._blocks;
const serialized = sb3.serializeBlocks(blocks)[0];
const deserialized = sb3.deserializeBlocks(serialized);
const deserializedAgain = sb3.deserializeBlocks(deserialized);
t.deepEqual(deserialized, deserializedAgain, 'no change from second pass of deserialize');
t.end();
});
});