mirror of
https://github.com/scratchfoundation/scratch-parser.git
synced 2025-07-27 14:40:01 -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)
|
return JSZip.loadAsync(input)
|
||||||
.then(function (zip) {
|
.then(function (zip) {
|
||||||
return zip.file(isSprite ? 'sprite.json' : 'project.json').async('string')
|
// look for json in the list of files, or in a subdirectory
|
||||||
.then(function (project) {
|
// assumes there is only one sprite or project json in the zipfile
|
||||||
return callback(null, [project, zip]);
|
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) {
|
.catch(function (err) {
|
||||||
return callback(msg + JSON.stringify(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')),
|
sb: fs.readFileSync(path.resolve(__dirname, './data/_example.sb')),
|
||||||
sb2: fs.readFileSync(path.resolve(__dirname, './data/_example.sb2')),
|
sb2: fs.readFileSync(path.resolve(__dirname, './data/_example.sb2')),
|
||||||
json: fs.readFileSync(path.resolve(__dirname, './data/_example.json')),
|
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: {
|
sprites: {
|
||||||
default_cat_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_default_cat.sprite2')),
|
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')),
|
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: fs.readFileSync(path.resolve(__dirname, './data/_example_sprite.sprite2')),
|
||||||
example_sprite2_json: fs.readFileSync(path.resolve(__dirname, './data/_example_sprite.sprite2json')),
|
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: {
|
sb3_comments: {
|
||||||
comments: fs.readFileSync(path.resolve(__dirname, './data/_comments.sb3')),
|
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();
|
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) {
|
test('default cat sprite2 json', function (t) {
|
||||||
parser(data.sprites.default_cat_sprite2_json, true, function (err, result) {
|
parser(data.sprites.default_cat_sprite2_json, true, function (err, result) {
|
||||||
t.equal(err, null);
|
t.equal(err, null);
|
||||||
|
|
|
@ -11,7 +11,8 @@ var fixtures = {
|
||||||
zipFakeProjectJSON:
|
zipFakeProjectJSON:
|
||||||
path.resolve(__dirname, '../fixtures/data/_zipFakeProjectJson.zip'),
|
path.resolve(__dirname, '../fixtures/data/_zipFakeProjectJson.zip'),
|
||||||
zipNoProjectJSON:
|
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) {
|
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) {
|
test('zip without project json', function (t) {
|
||||||
var buffer = new Buffer(fixtures.zipNoProjectJSON);
|
var buffer = new Buffer(fixtures.zipNoProjectJSON);
|
||||||
unzip(buffer, false, false, function (err, res) {
|
unzip(buffer, false, false, function (err, res) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue