Skip to content

Commit

Permalink
Support buffer input and output
Browse files Browse the repository at this point in the history
  • Loading branch information
selaux committed Mar 5, 2017
1 parent a5bc8c4 commit c8c702f
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 11 deletions.
20 changes: 14 additions & 6 deletions lib/nsg.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ var Promise = require('bluebird'),
}
};

function readAllSources(src) {
var stringSources = R.filter(R.is(String))(src),
otherSources = R.difference(src, stringSources);

return Promise.map(stringSources, R.unary(glob))
.then(R.flatten)
.then(R.uniq)
.map(function (path) {
return readFile(path).then(R.assoc('data', R.__, { path: path }));
})
.then(R.union(otherSources));
}

function generateSprite(userOptions, callback) {
var options = R.pipe(
R.merge(defaultOptions),
Expand All @@ -59,12 +72,7 @@ function generateSprite(userOptions, callback) {
readImage = R.propOr(null, 'readImage', compositor),
renderSprite = R.propOr(null, 'render', compositor);

return Promise.map(options.src, R.unary(glob))
.then(R.flatten)
.then(R.uniq)
.map(function (path) {
return readFile(path).then(R.assoc('data', R.__, { path: path }));
})
return readAllSources(options.src)
.map(readImage, { concurrency: MAX_PARALLEL_FILE_READS })
.then(R.partialRight(generateLayout, [ options.layoutOptions ]))
.tap(function createTargetDirectories() {
Expand Down
109 changes: 104 additions & 5 deletions test/specs/nsg.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ var fs = require('fs'),
require('sinon-as-promised');

describe('NSG', function () {
var defaultFilename = __filename,
var defaultFilename = 'test',
defaultFileContent = {
path: defaultFilename,
data: fs.readFileSync(defaultFilename)
data: 'test'
};
function mergeDefaultOptions(options) {
return R.merge({
src: [ defaultFilename ],
src: [ defaultFileContent ],
compositor: { readImage: sinon.stub().resolves({}), render: sinon.stub().resolves() },
layout: sinon.stub().resolves([]),
stylesheet: sinon.stub().resolves()
Expand Down Expand Up @@ -82,7 +82,7 @@ describe('NSG', function () {
this.stub(providedLayouts, 'vertical').resolves({ width: 0, height: 0, images: [] });
this.stub(providedStylesheets, 'stylus').resolves();

nsg({ src: [ defaultFilename ] }).then(function () {
nsg({ src: [ defaultFileContent ] }).then(function () {
expect(providedCompositors.canvas.readImage).to.have.been.calledOnce;
expect(providedCompositors.canvas.render).to.have.been.calledOnce;
expect(providedLayouts.vertical).to.have.been.calledOnce;
Expand Down Expand Up @@ -166,7 +166,7 @@ describe('NSG', function () {
this.stub(providedStylesheets, 'css').resolves();

nsg({
src: [ defaultFilename ],
src: [ defaultFileContent ],
compositor: 'gm',
layout: 'horizontal',
stylesheet: 'css'
Expand All @@ -187,6 +187,105 @@ describe('NSG', function () {
expect(stylesheet).to.equal('test template');
}).nodeify(done);
}));

it('should pass all directly passed in data to compositor', function () {
var options = mergeDefaultOptions({
src: [{path: 'somefile.png', data: 'somdata'}, {path: 'otherfile.png', data: 'otherdata'}]
});

return nsg(options).then(function () {
expect(options.compositor.readImage).to.have.been.calledTwice;
expect(options.compositor.readImage).to.have.been.calledWith(options.src[0]);
expect(options.compositor.readImage).to.have.been.calledWith(options.src[1]);
});
});

it('should pass all directly passed in source data to compositor', function () {
var options = mergeDefaultOptions({
src: [ { path: 'somefile.png', data: 'somdata' }, { path: 'otherfile.png', data: 'otherdata' } ]
});

return nsg(options).then(function () {
expect(options.compositor.readImage).to.have.been.calledTwice;
expect(options.compositor.readImage).to.have.been.calledWith(options.src[0]);
expect(options.compositor.readImage).to.have.been.calledWith(options.src[1]);
});
});

it('should glob for passed in source strings', function () {
var options = mergeDefaultOptions({
src: [ 'glob1', 'glob2' ]
}),
stubs = { glob: sinon.stub(), fs: { readFile: sinon.stub() } },
nsgProxy = proxyquire('../../lib/nsg', stubs);

stubs.glob.withArgs('glob1').yieldsAsync(null, [ 'path11', 'path12' ]);
stubs.glob.withArgs('glob2').yieldsAsync(null, [ 'path2' ]);
stubs.fs.readFile.withArgs('path11').yieldsAsync(null, 'data11');
stubs.fs.readFile.withArgs('path12').yieldsAsync(null, 'data12');
stubs.fs.readFile.withArgs('path2').yieldsAsync(null, 'data2');

return nsgProxy(options).then(function () {
expect(options.compositor.readImage).to.have.been.calledThrice;
expect(options.compositor.readImage).to.have.been.calledWith({ path: 'path11', data: 'data11' });
expect(options.compositor.readImage).to.have.been.calledWith({ path: 'path12', data: 'data12' });
expect(options.compositor.readImage).to.have.been.calledWith({ path: 'path2', data: 'data2' });
});
});

it('should support mixed string and buffer sources', function () {
var options = mergeDefaultOptions({
src: [ 'glob1', { path: 'foobar.jpg', data: 'fob' } ]
}),
stubs = { glob: sinon.stub(), fs: { readFile: sinon.stub() } },
nsgProxy = proxyquire('../../lib/nsg', stubs);

stubs.glob.withArgs('glob1').yieldsAsync(null, [ 'path11', 'path12' ]);
stubs.fs.readFile.withArgs('path11').yieldsAsync(null, 'data11');
stubs.fs.readFile.withArgs('path12').yieldsAsync(null, 'data12');

return nsgProxy(options).then(function () {
expect(options.compositor.readImage).to.have.been.calledThrice;
expect(options.compositor.readImage).to.have.been.calledWith({ path: 'path11', data: 'data11' });
expect(options.compositor.readImage).to.have.been.calledWith({ path: 'path12', data: 'data12' });
expect(options.compositor.readImage).to.have.been.calledWith({ path: 'foobar.jpg', data: 'fob' });
});
});

it('should go through the pipeline correctly', function () {
var sources = [
{ path: 'test', data: '1' },
{ path: 'test2', data: '2' }
],
readResults = [
{ path: 'test', data: '1', width: 10, height: 30 },
{ path: 'test2', data: '2', width: 10, height: 30 }
],
layoutResult = {
width: 20,
height: 30,
images: [
{ path: 'test', data: '1', width: 10, height: 30 },
{ path: 'test2', data: '2', width: 10, height: 30 }
]
},
stylesheetResult = 'my stylesheet',
renderResult = new Buffer('render result'),
options = mergeDefaultOptions({
src: sources
});

options.compositor.readImage.withArgs(sources[0]).resolves(readResults[0]);
options.compositor.readImage.withArgs(sources[1]).resolves(readResults[1]);
options.layout.withArgs(readResults).resolves(layoutResult);
options.stylesheet.withArgs(layoutResult).resolves(stylesheetResult);
options.compositor.render.withArgs(layoutResult).resolves(renderResult);

return nsg(options).spread(function (stylesheet, sprite) {
expect(stylesheet).to.equal(stylesheetResult);
expect(sprite).to.equal(renderResult);
});
});
});

describe('NSG functional tests', function () {
Expand Down

0 comments on commit c8c702f

Please sign in to comment.