mirror of
https://github.com/scratchfoundation/scratch-parser.git
synced 2025-07-25 13:38:47 -04:00
fix(unzip): handle sb2 files zipped with a folder
Uses a pattern to find the sprite or project json in a zipped folder or flat list of files. Added tests for * loading a sprite or project with a nested folder * loading a file without a json Fixes #42
This commit is contained in:
parent
18579217e8
commit
750e866444
8 changed files with 55 additions and 7 deletions
lib
test
fixtures
integration
unit
16
lib/unzip.js
16
lib/unzip.js
|
@ -23,10 +23,18 @@ module.exports = function (input, isGZip, isSprite, callback) {
|
|||
}
|
||||
return JSZip.loadAsync(input)
|
||||
.then(function (zip) {
|
||||
return zip.file(isSprite ? 'sprite.json' : 'project.json').async('string')
|
||||
.then(function (project) {
|
||||
return callback(null, [project, zip]);
|
||||
});
|
||||
// look for json in the list of files, or in a subdirectory
|
||||
// assumes there is only one sprite or project json in the zipfile
|
||||
const file = isSprite ?
|
||||
zip.file(/^([^/]*\/)?sprite\.json$/)[0] :
|
||||
zip.file(/^([^/]*\/)?project\.json$/)[0];
|
||||
if (file) {
|
||||
return file.async('string')
|
||||
.then(function (project) {
|
||||
return callback(null, [project, zip]);
|
||||
});
|
||||
}
|
||||
return callback(msg + 'missing project or sprite json');
|
||||
})
|
||||
.catch(function (err) {
|
||||
return callback(msg + JSON.stringify(err));
|
||||
|
|
6
test/fixtures/data.js
vendored
6
test/fixtures/data.js
vendored
|
@ -33,14 +33,16 @@ module.exports = {
|
|||
sb: fs.readFileSync(path.resolve(__dirname, './data/_example.sb')),
|
||||
sb2: fs.readFileSync(path.resolve(__dirname, './data/_example.sb2')),
|
||||
json: fs.readFileSync(path.resolve(__dirname, './data/_example.json')),
|
||||
gzipJson: fs.readFileSync(path.resolve(__dirname, './data/_example.json.gz'))
|
||||
gzipJson: fs.readFileSync(path.resolve(__dirname, './data/_example.json.gz')),
|
||||
invalidEmpty: fs.readFileSync(path.resolve(__dirname, './data/invalid/_invalidEmpty.sb2'))
|
||||
},
|
||||
sprites: {
|
||||
default_cat_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_default_cat.sprite2')),
|
||||
default_cat_sprite2_json: fs.readFileSync(path.resolve(__dirname, './data/_default_cat.sprite2json')),
|
||||
example_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_example_sprite.sprite2')),
|
||||
example_sprite2_json: fs.readFileSync(path.resolve(__dirname, './data/_example_sprite.sprite2json')),
|
||||
bananas_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas.sprite2'))
|
||||
bananas_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas.sprite2')),
|
||||
bananas_nested_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas_nested.sprite2'))
|
||||
},
|
||||
sb3_comments: {
|
||||
comments: fs.readFileSync(path.resolve(__dirname, './data/_comments.sb3')),
|
||||
|
|
BIN
test/fixtures/data/_bananas_nested.sprite2
vendored
Normal file
BIN
test/fixtures/data/_bananas_nested.sprite2
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/data/_nestedFolder.sb2
vendored
Normal file
BIN
test/fixtures/data/_nestedFolder.sb2
vendored
Normal file
Binary file not shown.
BIN
test/fixtures/data/invalid/_invalidEmpty.sb2
vendored
Normal file
BIN
test/fixtures/data/invalid/_invalidEmpty.sb2
vendored
Normal file
Binary file not shown.
|
@ -62,3 +62,13 @@ test('gzipped json', function (t) {
|
|||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('invalid empty project archive', function (t) {
|
||||
var msg = 'Failed to unzip and extract project.json, with error: ';
|
||||
parser(data.example.invalidEmpty, false, function (err, result) {
|
||||
t.type(err, 'string');
|
||||
t.equal(err.startsWith(msg), true);
|
||||
t.type(result, 'undefined');
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -42,6 +42,19 @@ test('banana sprite2, no sounds', function (t) {
|
|||
});
|
||||
});
|
||||
|
||||
test('nested banana sprite2', function (t) {
|
||||
parser(data.sprites.bananas_nested_sprite2, true, 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, 2);
|
||||
t.equal(possibleZip instanceof JSZip, true);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('default cat sprite2 json', function (t) {
|
||||
parser(data.sprites.default_cat_sprite2_json, true, function (err, result) {
|
||||
t.equal(err, null);
|
||||
|
|
|
@ -11,7 +11,8 @@ var fixtures = {
|
|||
zipFakeProjectJSON:
|
||||
path.resolve(__dirname, '../fixtures/data/_zipFakeProjectJson.zip'),
|
||||
zipNoProjectJSON:
|
||||
path.resolve(__dirname, '../fixtures/data/_zipNoProjectJson.zip')
|
||||
path.resolve(__dirname, '../fixtures/data/_zipNoProjectJson.zip'),
|
||||
sb2Nested: path.resolve(__dirname, '../fixtures/data/_nestedFolder.sb2')
|
||||
};
|
||||
|
||||
for (var i in fixtures) {
|
||||
|
@ -63,6 +64,20 @@ test('gzipped JSON', function (t) {
|
|||
});
|
||||
});
|
||||
|
||||
test('sb2 with nested folder', function (t) {
|
||||
var buffer = new Buffer(fixtures.sb2Nested);
|
||||
unzip(buffer, false, false, function (err, res) {
|
||||
t.equal(err, null);
|
||||
t.equal(Array.isArray(res), true);
|
||||
t.type(res[0], 'string');
|
||||
t.doesNotThrow(function () {
|
||||
JSON.parse(res[0]);
|
||||
});
|
||||
t.equal(res[1] instanceof JSZip, true);
|
||||
t.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('zip without project json', function (t) {
|
||||
var buffer = new Buffer(fixtures.zipNoProjectJSON);
|
||||
unzip(buffer, false, false, function (err, res) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue