Test code refactor #63

Use mocha for feature-specific unit tests

Add test coverage report via istanbul
This commit is contained in:
Lovell Fuller
2014-10-20 15:32:56 +01:00
parent f4cb577cb4
commit ca561daedf
37 changed files with 1341 additions and 1223 deletions

49
test/unit/alpha.js Executable file
View File

@@ -0,0 +1,49 @@
'use strict';
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Alpha transparency', function() {
it('Flatten to black', function(done) {
sharp(fixtures.inputPngWithTransparency)
.flatten()
.resize(400, 300)
.toFile(fixtures.path('output.flatten-black.jpg'), done);
});
it('Flatten to RGB orange', function(done) {
sharp(fixtures.inputPngWithTransparency)
.flatten()
.background({r: 255, g: 102, b: 0})
.resize(400, 300)
.toFile(fixtures.path('output.flatten-rgb-orange.jpg'), done);
});
it('Flatten to CSS/hex orange', function(done) {
sharp(fixtures.inputPngWithTransparency)
.flatten()
.background('#ff6600')
.resize(400, 300)
.toFile(fixtures.path('output.flatten-hex-orange.jpg'), done);
});
it('Ignored for JPEG', function(done) {
sharp(fixtures.inputJpg)
.background('#ff0000')
.flatten()
.resize(500, 400)
.toBuffer(function(err, data) {
if (err) throw err;
sharp(data).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('jpeg', metadata.format);
assert.strictEqual(3, metadata.channels);
done();
});
});
});
});

62
test/unit/colourspace.js Executable file
View File

@@ -0,0 +1,62 @@
'use strict';
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Colour space conversion', function() {
it('To greyscale', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.greyscale()
.toFile(fixtures.path('output.greyscale-gamma-0.0.jpg'), done);
});
it('To greyscale with gamma correction', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.gamma()
.greyscale()
.toFile(fixtures.path('output.greyscale-gamma-2.2.jpg'), done);
});
it('From 1-bit TIFF to sRGB WebP [slow]', function(done) {
sharp(fixtures.inputTiff)
.webp()
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('webp', info.format);
done();
});
});
it('From CMYK to sRGB', function(done) {
sharp(fixtures.inputJpgWithCmykProfile)
.resize(320)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
done();
});
});
it('From CMYK to sRGB with white background, not yellow', function(done) {
sharp(fixtures.inputJpgWithCmykProfile)
.resize(320, 240)
.background('white')
.embed()
.toFile(fixtures.path('output.cmyk2srgb.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
});

82
test/unit/crop.js Executable file
View File

@@ -0,0 +1,82 @@
'use strict';
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Crop gravities', function() {
it('North', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 80)
.crop(sharp.gravity.north)
.toFile(fixtures.path('output.gravity-north.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
done();
});
});
it('East', function(done) {
sharp(fixtures.inputJpg)
.resize(80, 320)
.crop(sharp.gravity.east)
.toFile(fixtures.path('output.gravity-east.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(80, info.width);
assert.strictEqual(320, info.height);
done();
});
});
it('South', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 80)
.crop(sharp.gravity.south)
.toFile(fixtures.path('output.gravity-south.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
done();
});
});
it('West', function(done) {
sharp(fixtures.inputJpg)
.resize(80, 320)
.crop(sharp.gravity.west)
.toFile(fixtures.path('output.gravity-west.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(80, info.width);
assert.strictEqual(320, info.height);
done();
});
});
it('Center', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 80)
.crop(sharp.gravity.center)
.toFile(fixtures.path('output.gravity-center.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
done();
});
});
it('Centre', function(done) {
sharp(fixtures.inputJpg)
.resize(80, 320)
.crop(sharp.gravity.centre)
.toFile(fixtures.path('output.gravity-centre.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(80, info.width);
assert.strictEqual(320, info.height);
done();
});
});
});

49
test/unit/embed.js Executable file
View File

@@ -0,0 +1,49 @@
'use strict';
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Embed', function() {
it('JPEG within PNG, no alpha channel', function(done) {
sharp(fixtures.inputJpg)
.embed()
.resize(320, 240)
.png()
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('png', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
sharp(data).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual(3, metadata.channels);
done();
});
});
});
it('JPEG within WebP, to include alpha channel', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.background({r: 0, g: 0, b: 0, a: 0})
.embed()
.webp()
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('webp', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
sharp(data).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual(4, metadata.channels);
done();
});
});
});
});

93
test/unit/extract.js Executable file
View File

@@ -0,0 +1,93 @@
'use strict';
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Partial image extraction', function() {
it('JPEG', function(done) {
sharp(fixtures.inputJpg)
.extract(2, 2, 20, 20)
.toFile(fixtures.path('output.extract.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(20, info.width);
assert.strictEqual(20, info.height);
done();
});
});
it('PNG', function(done) {
sharp(fixtures.inputPng)
.extract(300, 200, 400, 200)
.toFile(fixtures.path('output.extract.png'), function(err, info) {
if (err) throw err;
assert.strictEqual(400, info.width);
assert.strictEqual(200, info.height);
done();
});
});
it('WebP', function(done) {
sharp(fixtures.inputWebP)
.extract(50, 100, 125, 200)
.toFile(fixtures.path('output.extract.webp'), function(err, info) {
if (err) throw err;
assert.strictEqual(125, info.width);
assert.strictEqual(200, info.height);
done();
});
});
it('TIFF', function(done) {
sharp(fixtures.inputTiff)
.extract(63, 34, 341, 529)
.toFile(fixtures.path('output.extract.tiff'), function(err, info) {
if (err) throw err;
assert.strictEqual(341, info.width);
assert.strictEqual(529, info.height);
done();
});
});
it('Before resize', function(done) {
sharp(fixtures.inputJpg)
.extract(10, 10, 10, 500, 500)
.resize(100, 100)
.toFile(fixtures.path('output.extract.resize.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(100, info.width);
assert.strictEqual(100, info.height);
done();
});
});
it('After resize and crop', function(done) {
sharp(fixtures.inputJpg)
.resize(500, 500)
.crop(sharp.gravity.north)
.extract(10, 10, 100, 100)
.toFile(fixtures.path('output.resize.crop.extract.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(100, info.width);
assert.strictEqual(100, info.height);
done();
});
});
it('Before and after resize and crop', function(done) {
sharp(fixtures.inputJpg)
.extract(0, 0, 700, 700)
.resize(500, 500)
.crop(sharp.gravity.north)
.extract(10, 10, 100, 100)
.toFile(fixtures.path('output.extract.resize.crop.extract.jpg'), function(err, info) {
if (err) throw err;
assert.strictEqual(100, info.width);
assert.strictEqual(100, info.height);
done();
});
});
});

26
test/unit/gamma.js Executable file
View File

@@ -0,0 +1,26 @@
'use strict';
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Gamma correction', function() {
it('value of 0.0 (disabled)', function(done) {
sharp(fixtures.inputJpgWithGammaHoliness)
.resize(129, 111)
.toFile(fixtures.path('output.gamma-0.0.jpg'), done);
});
it('value of 2.2 (default)', function(done) {
sharp(fixtures.inputJpgWithGammaHoliness)
.resize(129, 111)
.gamma()
.toFile(fixtures.path('output.gamma-2.2.jpg'), done);
});
it('value of 3.0', function(done) {
sharp(fixtures.inputJpgWithGammaHoliness)
.resize(129, 111)
.gamma(3)
.toFile(fixtures.path('output.gamma-3.0.jpg'), done);
});
});

94
test/unit/interpolation.js Executable file
View File

@@ -0,0 +1,94 @@
'use strict';
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Interpolation', function() {
it('nearest neighbour', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.interpolateWith(sharp.interpolator.nearest)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
it('bilinear', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.interpolateWith(sharp.interpolator.bilinear)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
it('bicubic', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.interpolateWith(sharp.interpolator.bicubic)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
it('nohalo', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.interpolateWith(sharp.interpolator.nohalo)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
it('locally bounded bicubic (LBB)', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.interpolateWith(sharp.interpolator.locallyBoundedBicubic)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
it('vertex split quadratic basis spline (VSQBS)', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.interpolateWith(sharp.interpolator.vertexSplitQuadraticBasisSpline)
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
});

253
test/unit/io.js Executable file
View File

@@ -0,0 +1,253 @@
'use strict';
var fs = require('fs');
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Input/output', function() {
it('Read from File and write to Stream', function(done) {
var writable = fs.createWriteStream(fixtures.outputJpg);
writable.on('finish', function() {
sharp(fixtures.outputJpg).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
fs.unlinkSync(fixtures.outputJpg);
done();
});
});
sharp(fixtures.inputJpg).resize(320, 240).pipe(writable);
});
it('Read from Buffer and write to Stream', function(done) {
var inputJpgBuffer = fs.readFileSync(fixtures.inputJpg);
var writable = fs.createWriteStream(fixtures.outputJpg);
writable.on('finish', function() {
sharp(fixtures.outputJpg).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
fs.unlinkSync(fixtures.outputJpg);
done();
});
});
sharp(inputJpgBuffer).resize(320, 240).pipe(writable);
});
it('Read from Stream and write to File', function(done) {
var readable = fs.createReadStream(fixtures.inputJpg);
var pipeline = sharp().resize(320, 240).toFile(fixtures.outputJpg, function(err, info) {
if (err) throw err;
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
fs.unlinkSync(fixtures.outputJpg);
done();
});
readable.pipe(pipeline);
});
it('Read from Stream and write to Buffer', function(done) {
var readable = fs.createReadStream(fixtures.inputJpg);
var pipeline = sharp().resize(320, 240).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
readable.pipe(pipeline);
});
it('Read from Stream and write to Stream', function(done) {
var readable = fs.createReadStream(fixtures.inputJpg);
var writable = fs.createWriteStream(fixtures.outputJpg);
writable.on('finish', function() {
sharp(fixtures.outputJpg).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
fs.unlinkSync(fixtures.outputJpg);
done();
});
});
var pipeline = sharp().resize(320, 240);
readable.pipe(pipeline).pipe(writable);
});
it('Handle Stream to Stream error ', function(done) {
var pipeline = sharp().resize(320, 240);
var anErrorWasEmitted = false;
pipeline.on('error', function(err) {
anErrorWasEmitted = !!err;
}).on('end', function() {
assert(anErrorWasEmitted);
fs.unlinkSync(fixtures.outputJpg);
done();
});
var readableButNotAnImage = fs.createReadStream(__filename);
var writable = fs.createWriteStream(fixtures.outputJpg);
readableButNotAnImage.pipe(pipeline).pipe(writable);
});
it('Handle File to Stream error', function(done) {
var readableButNotAnImage = sharp(__filename).resize(320, 240);
var anErrorWasEmitted = false;
readableButNotAnImage.on('error', function(err) {
anErrorWasEmitted = !!err;
}).on('end', function() {
assert(anErrorWasEmitted);
fs.unlinkSync(fixtures.outputJpg);
done();
});
var writable = fs.createWriteStream(fixtures.outputJpg);
readableButNotAnImage.pipe(writable);
});
it('Fail when output File is input File', function(done) {
sharp(fixtures.inputJpg).toFile(fixtures.inputJpg, function(err) {
assert(!!err);
done();
});
});
it('Fail when input is empty Buffer', function(done) {
var fail = false;
try {
sharp(new Buffer(0));
fail = true;
} catch (e) {}
assert(!fail);
done();
});
it('Promises/A+', function(done) {
sharp(fixtures.inputJpg).resize(320, 240).toBuffer().then(function(data) {
sharp(data).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
}).catch(function(err) {
throw err;
});
});
it('JPEG quality', function(done) {
sharp(fixtures.inputJpg).resize(320, 240).quality(70).toBuffer(function(err, buffer70) {
if (err) throw err;
sharp(fixtures.inputJpg).resize(320, 240).toBuffer(function(err, buffer80) {
if (err) throw err;
sharp(fixtures.inputJpg).resize(320, 240).quality(90).toBuffer(function(err, buffer90) {
if (err) throw err;
assert(buffer70.length < buffer80.length);
assert(buffer80.length < buffer90.length);
done();
});
});
});
});
describe('Output filename without extension uses input format', function() {
it('JPEG', function(done) {
sharp(fixtures.inputJpg).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
if (err) throw err;
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
fs.unlinkSync(fixtures.outputZoinks);
done();
});
});
it('PNG', function(done) {
sharp(fixtures.inputPng).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
if (err) throw err;
assert.strictEqual('png', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
fs.unlinkSync(fixtures.outputZoinks);
done();
});
});
it('Transparent PNG', function(done) {
sharp(fixtures.inputPngWithTransparency).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
if (err) throw err;
assert.strictEqual('png', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
done();
});
});
it('WebP', function(done) {
sharp(fixtures.inputWebP).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
if (err) throw err;
assert.strictEqual('webp', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
fs.unlinkSync(fixtures.outputZoinks);
done();
});
});
it('TIFF', function(done) {
sharp(fixtures.inputTiff).resize(320, 80).toFile(fixtures.outputZoinks, function(err, info) {
if (err) throw err;
assert.strictEqual('tiff', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(80, info.height);
fs.unlinkSync(fixtures.outputZoinks);
done();
});
});
it('Fail with GIF', function(done) {
sharp(fixtures.inputGif).resize(320, 80).toFile(fixtures.outputZoinks, function(err) {
assert(!!err);
done();
});
});
});
describe('PNG compression level', function() {
it('valid', function(done) {
var isValid = false;
try {
sharp().compressionLevel(0);
isValid = true;
} catch (e) {}
assert(isValid);
done();
});
it('invalid', function(done) {
var isValid = false;
try {
sharp().compressionLevel(-1);
isValid = true;
} catch (e) {}
assert(!isValid);
done();
});
});
});

1
test/unit/jshint.js Executable file
View File

@@ -0,0 +1 @@
require('mocha-jshint')();

171
test/unit/metadata.js Executable file
View File

@@ -0,0 +1,171 @@
'use strict';
var fs = require('fs');
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Image metadata', function() {
it('JPEG', function(done) {
sharp(fixtures.inputJpg).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('jpeg', metadata.format);
assert.strictEqual(2725, metadata.width);
assert.strictEqual(2225, metadata.height);
assert.strictEqual('srgb', metadata.space);
assert.strictEqual(3, metadata.channels);
assert.strictEqual('undefined', typeof metadata.orientation);
done();
});
});
it('JPEG with EXIF', function(done) {
sharp(fixtures.inputJpgWithExif).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('jpeg', metadata.format);
assert.strictEqual(450, metadata.width);
assert.strictEqual(600, metadata.height);
assert.strictEqual('srgb', metadata.space);
assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasAlpha);
assert.strictEqual(8, metadata.orientation);
done();
});
});
it('TIFF', function(done) {
sharp(fixtures.inputTiff).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('tiff', metadata.format);
assert.strictEqual(2464, metadata.width);
assert.strictEqual(3248, metadata.height);
assert.strictEqual('b-w', metadata.space);
assert.strictEqual(1, metadata.channels);
assert.strictEqual(false, metadata.hasAlpha);
done();
});
});
it('PNG', function(done) {
sharp(fixtures.inputPng).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('png', metadata.format);
assert.strictEqual(2809, metadata.width);
assert.strictEqual(2074, metadata.height);
assert.strictEqual('b-w', metadata.space);
assert.strictEqual(1, metadata.channels);
assert.strictEqual(false, metadata.hasAlpha);
done();
});
});
it('Transparent PNG', function(done) {
sharp(fixtures.inputPngWithTransparency).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('png', metadata.format);
assert.strictEqual(2048, metadata.width);
assert.strictEqual(1536, metadata.height);
assert.strictEqual('srgb', metadata.space);
assert.strictEqual(4, metadata.channels);
assert.strictEqual(true, metadata.hasAlpha);
done();
});
});
it('WebP', function(done) {
sharp(fixtures.inputWebP).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('webp', metadata.format);
assert.strictEqual(1024, metadata.width);
assert.strictEqual(772, metadata.height);
assert.strictEqual('srgb', metadata.space);
assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasAlpha);
done();
});
});
it('GIF via libmagick', function(done) {
sharp(fixtures.inputGif).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('magick', metadata.format);
assert.strictEqual(800, metadata.width);
assert.strictEqual(533, metadata.height);
assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasAlpha);
done();
});
});
it('Promise', function(done) {
sharp(fixtures.inputJpg).metadata().then(function(metadata) {
assert.strictEqual('jpeg', metadata.format);
assert.strictEqual(2725, metadata.width);
assert.strictEqual(2225, metadata.height);
assert.strictEqual('srgb', metadata.space);
assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasAlpha);
done();
});
});
it('Stream', function(done) {
var readable = fs.createReadStream(fixtures.inputJpg);
var pipeline = sharp().metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('jpeg', metadata.format);
assert.strictEqual(2725, metadata.width);
assert.strictEqual(2225, metadata.height);
assert.strictEqual('srgb', metadata.space);
assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasAlpha);
done();
});
readable.pipe(pipeline);
});
it('Resize to half width using metadata', function(done) {
var image = sharp(fixtures.inputJpg);
image.metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('jpeg', metadata.format);
assert.strictEqual(2725, metadata.width);
assert.strictEqual(2225, metadata.height);
assert.strictEqual('srgb', metadata.space);
assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasAlpha);
image.resize(metadata.width / 2).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual(1362, info.width);
assert.strictEqual(1112, info.height);
done();
});
});
});
it('Keep EXIF metadata after a resize', function(done) {
sharp(fixtures.inputJpgWithExif).resize(320, 240).withMetadata().toBuffer(function(err, buffer) {
if (err) throw err;
sharp(buffer).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual(8, metadata.orientation);
done();
});
});
});
it('Remove EXIF metadata after a resize', function(done) {
sharp(fixtures.inputJpgWithExif).resize(320, 240).withMetadata(false).toBuffer(function(err, buffer) {
if (err) throw err;
sharp(buffer).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('undefined', typeof metadata.orientation);
done();
});
});
});
});

142
test/unit/resize.js Executable file
View File

@@ -0,0 +1,142 @@
'use strict';
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Resize dimensions', function() {
it('Exact crop', function(done) {
sharp(fixtures.inputJpg).resize(320, 240).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
it('Fixed width', function(done) {
sharp(fixtures.inputJpg).resize(320).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(261, info.height);
done();
});
});
it('Fixed height', function(done) {
sharp(fixtures.inputJpg).resize(null, 320).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(391, info.width);
assert.strictEqual(320, info.height);
done();
});
});
it('Identity transform', function(done) {
sharp(fixtures.inputJpg).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(2725, info.width);
assert.strictEqual(2225, info.height);
done();
});
});
it('Upscale', function(done) {
sharp(fixtures.inputJpg).resize(3000).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(3000, info.width);
assert.strictEqual(2449, info.height);
done();
});
});
it('TIFF embed known to cause rounding errors', function(done) {
sharp(fixtures.inputTiff).resize(240, 320).embed().jpeg().toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(240, info.width);
assert.strictEqual(320, info.height);
done();
});
});
it('TIFF known to cause rounding errors', function(done) {
sharp(fixtures.inputTiff).resize(240, 320).jpeg().toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(240, info.width);
assert.strictEqual(320, info.height);
done();
});
});
it('Max width or height considering ratio (landscape)', function(done) {
sharp(fixtures.inputJpg).resize(320, 320).max().toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(261, info.height);
done();
});
});
it('Max width or height considering ratio (portrait)', function(done) {
sharp(fixtures.inputTiff).resize(320, 320).max().jpeg().toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(243, info.width);
assert.strictEqual(320, info.height);
done();
});
});
it('Provide only one dimension with max, should default to crop', function(done) {
sharp(fixtures.inputJpg).resize(320).max().toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(261, info.height);
done();
});
});
it('Do not enlarge if input width is already less than output width', function(done) {
sharp(fixtures.inputJpg).resize(2800).withoutEnlargement().toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(2725, info.width);
assert.strictEqual(2225, info.height);
done();
});
});
it('Do not enlarge if input height is already less than output height', function(done) {
sharp(fixtures.inputJpg).resize(null, 2300).withoutEnlargement().toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(2725, info.width);
assert.strictEqual(2225, info.height);
done();
});
});
});

64
test/unit/rotate.js Executable file
View File

@@ -0,0 +1,64 @@
'use strict';
var assert = require('assert');
var sharp = require('../../index');
var fixtures = require('../fixtures');
describe('Rotation', function() {
it('Rotate by 90 degrees, respecting output input size', function(done) {
sharp(fixtures.inputJpg).rotate(90).resize(320, 240).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
it('Input image has Orientation EXIF tag but do not rotate output', function(done) {
sharp(fixtures.inputJpgWithExif).resize(320).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(426, info.height);
done();
});
});
it('Input image has Orientation EXIF tag value of 8 (270 degrees), auto-rotate', function(done) {
sharp(fixtures.inputJpgWithExif).rotate().resize(320).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
done();
});
});
it('Attempt to auto-rotate using image that has no EXIF', function(done) {
sharp(fixtures.inputJpg).rotate().resize(320).toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('jpeg', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(261, info.height);
done();
});
});
it('Rotate to an invalid angle, should fail', function(done) {
var fail = false;
try {
sharp(fixtures.inputJpg).rotate(1);
fail = true;
} catch (e) {}
assert(!fail);
done();
});
});

38
test/unit/util.js Executable file
View File

@@ -0,0 +1,38 @@
'use strict';
var assert = require('assert');
var sharp = require('../../index');
var defaultConcurrency = sharp.concurrency();
describe('Utilities', function() {
describe('Cache', function() {
it('Can be disabled', function() {
sharp.cache(0);
});
it('Can be set to a maximum of 50MB and 500 items', function() {
sharp.cache(50, 500);
});
});
describe('Concurrency', function() {
it('Can be set to use 16 threads', function() {
sharp.concurrency(16);
assert.strictEqual(16, sharp.concurrency());
});
it('Can be reset to default', function() {
sharp.concurrency(0);
assert.strictEqual(defaultConcurrency, sharp.concurrency());
});
});
describe('Counters', function() {
it('Have zero value at rest', function() {
var counters = sharp.counters();
assert.strictEqual(0, counters.queue);
assert.strictEqual(0, counters.process);
});
});
});