Merge pull request #1993 from chrisgarrity/handle-nested-sb2

handle sb2 files zipped in a folder
This commit is contained in:
chrisgarrity 2019-02-12 16:41:27 +01:00 committed by GitHub
commit 77fd88302f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 2654 additions and 2607 deletions

5185
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -43,7 +43,7 @@
"jszip": "^3.1.5", "jszip": "^3.1.5",
"minilog": "3.1.0", "minilog": "3.1.0",
"nets": "3.2.0", "nets": "3.2.0",
"scratch-parser": "4.3.3", "scratch-parser": "4.3.4",
"scratch-sb1-converter": "0.2.6", "scratch-sb1-converter": "0.2.6",
"scratch-translate-extension-languages": "0.0.20181205140428", "scratch-translate-extension-languages": "0.0.20181205140428",
"socket.io-client": "2.0.4", "socket.io-client": "2.0.4",

View file

@ -26,7 +26,13 @@ const deserializeSound = function (sound, runtime, zip, assetFileName) {
return Promise.resolve(null); return Promise.resolve(null);
} }
const soundFile = zip.file(fileName); let soundFile = zip.file(fileName);
if (!soundFile) {
// look for assetfile in a flat list of files, or in a folder
const fileMatch = new RegExp(`^([^/]*/)?${fileName}$`);
soundFile = zip.file(fileMatch)[0]; // use first matching file
}
if (!soundFile) { if (!soundFile) {
log.error(`Could not find sound file associated with the ${sound.name} sound.`); log.error(`Could not find sound file associated with the ${sound.name} sound.`);
return Promise.resolve(null); return Promise.resolve(null);
@ -100,7 +106,13 @@ const deserializeCostume = function (costume, runtime, zip, assetFileName, textL
return Promise.resolve(null); return Promise.resolve(null);
} }
const costumeFile = zip.file(fileName); let costumeFile = zip.file(fileName);
if (!costumeFile) {
// look for assetfile in a flat list of files, or in a folder
const fileMatch = new RegExp(`^([^/]*/)?${fileName}$`);
costumeFile = zip.file(fileMatch)[0]; // use the first matched file
}
if (!costumeFile) { if (!costumeFile) {
log.error(`Could not find costume file associated with the ${costume.name} costume.`); log.error(`Could not find costume file associated with the ${costume.name} costume.`);
return Promise.resolve(null); return Promise.resolve(null);

BIN
test/fixtures/default_nested.sb2 vendored Normal file

Binary file not shown.

View file

@ -7,6 +7,10 @@ module.exports = {
}, },
extractProjectJson: function (path) { extractProjectJson: function (path) {
const zip = new AdmZip(path); const zip = new AdmZip(path);
return JSON.parse(zip.readAsText('project.json', 'utf8')); const projectEntry = zip.getEntries().filter(item => item.entryName.match(/project\.json/))[0];
if (projectEntry) {
return JSON.parse(zip.readAsText(projectEntry.entryName, 'utf8'));
}
return null;
} }
}; };

View file

@ -0,0 +1,52 @@
const path = require('path');
const test = require('tap').test;
const makeTestStorage = require('../fixtures/make-test-storage');
const extractProjectJson = require('../fixtures/readProjectFile').extractProjectJson;
const renderedTarget = require('../../src/sprites/rendered-target');
const runtime = require('../../src/engine/runtime');
const sb2 = require('../../src/serialization/sb2');
test('spec', t => {
t.type(sb2.deserialize, 'function');
t.end();
});
test('nested default/*', t => {
// Get SB2 JSON (string)
const uri = path.resolve(__dirname, '../fixtures/default_nested.sb2');
const json = extractProjectJson(uri, 'default');
// Create runtime instance & load SB2 into it
const rt = new runtime();
rt.attachStorage(makeTestStorage());
sb2.deserialize(json, rt).then(({targets}) => {
// Test
t.type(json, 'object');
t.type(rt, 'object');
t.type(targets, 'object');
t.ok(targets[0] instanceof renderedTarget);
t.type(targets[0].id, 'string');
t.type(targets[0].blocks, 'object');
t.type(targets[0].variables, 'object');
t.type(targets[0].comments, 'object');
t.equal(targets[0].isOriginal, true);
t.equal(targets[0].currentCostume, 0);
t.equal(targets[0].isOriginal, true);
t.equal(targets[0].isStage, true);
t.ok(targets[1] instanceof renderedTarget);
t.type(targets[1].id, 'string');
t.type(targets[1].blocks, 'object');
t.type(targets[1].variables, 'object');
t.type(targets[1].comments, 'object');
t.equal(targets[1].isOriginal, true);
t.equal(targets[1].currentCostume, 0);
t.equal(targets[1].isOriginal, true);
t.equal(targets[1].isStage, false);
t.end();
});
});