Skip to content

Commit 750e866

Browse files
committed
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
1 parent 1857921 commit 750e866

File tree

8 files changed

+55
-7
lines changed

8 files changed

+55
-7
lines changed

lib/unzip.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,18 @@ module.exports = function (input, isGZip, isSprite, callback) {
2323
}
2424
return JSZip.loadAsync(input)
2525
.then(function (zip) {
26-
return zip.file(isSprite ? 'sprite.json' : 'project.json').async('string')
27-
.then(function (project) {
28-
return callback(null, [project, zip]);
29-
});
26+
// look for json in the list of files, or in a subdirectory
27+
// assumes there is only one sprite or project json in the zipfile
28+
const file = isSprite ?
29+
zip.file(/^([^/]*\/)?sprite\.json$/)[0] :
30+
zip.file(/^([^/]*\/)?project\.json$/)[0];
31+
if (file) {
32+
return file.async('string')
33+
.then(function (project) {
34+
return callback(null, [project, zip]);
35+
});
36+
}
37+
return callback(msg + 'missing project or sprite json');
3038
})
3139
.catch(function (err) {
3240
return callback(msg + JSON.stringify(err));

test/fixtures/data.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,16 @@ module.exports = {
3333
sb: fs.readFileSync(path.resolve(__dirname, './data/_example.sb')),
3434
sb2: fs.readFileSync(path.resolve(__dirname, './data/_example.sb2')),
3535
json: fs.readFileSync(path.resolve(__dirname, './data/_example.json')),
36-
gzipJson: fs.readFileSync(path.resolve(__dirname, './data/_example.json.gz'))
36+
gzipJson: fs.readFileSync(path.resolve(__dirname, './data/_example.json.gz')),
37+
invalidEmpty: fs.readFileSync(path.resolve(__dirname, './data/invalid/_invalidEmpty.sb2'))
3738
},
3839
sprites: {
3940
default_cat_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_default_cat.sprite2')),
4041
default_cat_sprite2_json: fs.readFileSync(path.resolve(__dirname, './data/_default_cat.sprite2json')),
4142
example_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_example_sprite.sprite2')),
4243
example_sprite2_json: fs.readFileSync(path.resolve(__dirname, './data/_example_sprite.sprite2json')),
43-
bananas_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas.sprite2'))
44+
bananas_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas.sprite2')),
45+
bananas_nested_sprite2: fs.readFileSync(path.resolve(__dirname, './data/_bananas_nested.sprite2'))
4446
},
4547
sb3_comments: {
4648
comments: fs.readFileSync(path.resolve(__dirname, './data/_comments.sb3')),
2.72 KB
Binary file not shown.
42.6 KB
Binary file not shown.
42 KB
Binary file not shown.

test/integration/example.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,13 @@ test('gzipped json', function (t) {
6262
t.end();
6363
});
6464
});
65+
66+
test('invalid empty project archive', function (t) {
67+
var msg = 'Failed to unzip and extract project.json, with error: ';
68+
parser(data.example.invalidEmpty, false, function (err, result) {
69+
t.type(err, 'string');
70+
t.equal(err.startsWith(msg), true);
71+
t.type(result, 'undefined');
72+
t.end();
73+
});
74+
});

test/integration/sprites.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ test('banana sprite2, no sounds', function (t) {
4242
});
4343
});
4444

45+
test('nested banana sprite2', function (t) {
46+
parser(data.sprites.bananas_nested_sprite2, true, function (err, result) {
47+
t.equal(err, null);
48+
t.equal(Array.isArray(result), true);
49+
var res = result[0];
50+
var possibleZip = result[1];
51+
t.type(res, 'object');
52+
t.equal(res.projectVersion, 2);
53+
t.equal(possibleZip instanceof JSZip, true);
54+
t.end();
55+
});
56+
});
57+
4558
test('default cat sprite2 json', function (t) {
4659
parser(data.sprites.default_cat_sprite2_json, true, function (err, result) {
4760
t.equal(err, null);

test/unit/unzip.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ var fixtures = {
1111
zipFakeProjectJSON:
1212
path.resolve(__dirname, '../fixtures/data/_zipFakeProjectJson.zip'),
1313
zipNoProjectJSON:
14-
path.resolve(__dirname, '../fixtures/data/_zipNoProjectJson.zip')
14+
path.resolve(__dirname, '../fixtures/data/_zipNoProjectJson.zip'),
15+
sb2Nested: path.resolve(__dirname, '../fixtures/data/_nestedFolder.sb2')
1516
};
1617

1718
for (var i in fixtures) {
@@ -63,6 +64,20 @@ test('gzipped JSON', function (t) {
6364
});
6465
});
6566

67+
test('sb2 with nested folder', function (t) {
68+
var buffer = new Buffer(fixtures.sb2Nested);
69+
unzip(buffer, false, false, function (err, res) {
70+
t.equal(err, null);
71+
t.equal(Array.isArray(res), true);
72+
t.type(res[0], 'string');
73+
t.doesNotThrow(function () {
74+
JSON.parse(res[0]);
75+
});
76+
t.equal(res[1] instanceof JSZip, true);
77+
t.end();
78+
});
79+
});
80+
6681
test('zip without project json', function (t) {
6782
var buffer = new Buffer(fixtures.zipNoProjectJSON);
6883
unzip(buffer, false, false, function (err, res) {

0 commit comments

Comments
 (0)