abstracting tests to exist in a separate file, let them be required and run as a library

This commit is contained in:
Kiril Vatev 2023-11-28 02:27:56 -05:00
parent ad3f4cae6c
commit 2a3d82d7e4
3 changed files with 156 additions and 147 deletions

View File

@ -5,7 +5,7 @@
"main": "index.js",
"scripts": {
"pretest": "node scripts/images.js",
"test": "mocha --timeout 40000 --slow 0 \"test/**/*.js\""
"test": "mocha --timeout 40000 --slow 0 \"test/**/*.test.js\""
},
"repository": {
"type": "git",

View File

@ -1,148 +1,9 @@
/* eslint-env mocha */
const { promisify } = require('util');
const fs = require('fs');
const path = require('path');
const runTests = require('./run-tests.js');
const root = require('rootrequire');
const { fromBuffer: filetype } = require('file-type');
const { expect } = require('chai');
const toUint8 = require('buffer-to-uint8array');
const pixelmatch = require('pixelmatch');
const { PNG } = require('pngjs');
const jpegJs = require('jpeg-js');
const convert = require('../');
const readFile = promisify(fs.readFile);
describe('heic-convert', () => {
it('exports a function', () => {
expect(convert).to.be.a('function');
});
const decode = {
'image/png': buffer => PNG.sync.read(buffer),
'image/jpeg': buffer => jpegJs.decode(buffer)
};
const readControl = async name => {
const buffer = await readFile(path.resolve(root, `temp/${name}`));
return decode['image/png'](buffer);
};
const compare = (expected, actual, width, height, errString = 'actual image did not match control image') => {
const result = pixelmatch(toUint8(Buffer.from(expected)), toUint8(Buffer.from(actual)), null, width, height, {
threshold: 0.1
});
// allow 5% of pixels to be different
expect(result).to.be.below(width * height * 0.05, errString);
};
const assertImage = async (buffer, mime, control) => {
const type = await filetype(buffer);
expect(type.mime).to.equal(mime);
const actual = decode[mime](buffer);
expect(actual.width).to.equal(control.width);
expect(actual.height).to.equal(control.height);
compare(control.data, actual.data, control.width, control.height);
};
it('converts known image to jpeg', async () => {
const control = await readControl('0002-control.png');
const buffer = await readFile(path.resolve(root, 'temp', '0002.heic'));
// quality of 92%
const output92 = await convert({ buffer, format: 'JPEG' });
await assertImage(output92, 'image/jpeg', control);
// quality of 100%
const output100 = await convert({ buffer, format: 'JPEG', quality: 1 });
await assertImage(output100, 'image/jpeg', control);
expect(output92).to.not.deep.equal(output100);
expect(output92.length).to.be.below(output100.length);
});
it('converts known image to png', async () => {
const control = await readControl('0002-control.png');
const buffer = await readFile(path.resolve(root, 'temp', '0002.heic'));
const output = await convert({ buffer, format: 'PNG' });
await assertImage(output, 'image/png', control);
});
it('converts multiple images inside a single file to jpeg', async () => {
const controls = await Promise.all([
readControl('0003-0-control.png'),
readControl('0003-1-control.png'),
]);
const buffer = await readFile(path.resolve(root, 'temp', '0003.heic'));
const images = await convert.all({ buffer, format: 'JPEG' });
expect(images).to.have.lengthOf(3);
for (let { i, control } of [
{ i: 0, control: controls[0] },
{ i: 1, control: controls[1] },
{ i: 2, control: controls[1] },
]) {
expect(images[i]).to.have.a.property('convert').and.to.be.a('function');
await assertImage(await images[i].convert(), 'image/jpeg', control);
}
});
it('converts multiple images inside a single file to png', async () => {
const controls = await Promise.all([
readControl('0003-0-control.png'),
readControl('0003-1-control.png'),
]);
const buffer = await readFile(path.resolve(root, 'temp', '0003.heic'));
const images = await convert.all({ buffer, format: 'PNG' });
expect(images).to.have.lengthOf(3);
for (let { i, control } of [
{ i: 0, control: controls[0] },
{ i: 1, control: controls[1] },
{ i: 2, control: controls[1] },
]) {
expect(images[i]).to.have.a.property('convert').and.to.be.a('function');
await assertImage(await images[i].convert(), 'image/png', control);
}
});
[
{ when: 'converting only the main image', method: convert },
{ when: 'converting all images', method: convert.all }
].forEach(({ when, method }) => {
it(`errors for an unknown output format when ${when}`, async () => {
const buffer = Buffer.from(Math.random().toString() + Math.random().toString());
let error;
await method({ buffer, format: 'PINEAPPLES' }).catch(err => {
error = err;
});
expect(error).to.be.instanceof(Error)
.and.to.have.property('message', 'output format needs to be one of [JPEG,PNG]');
});
it(`errors if data other than a HEIC image is passed in when ${when}`, async () => {
const buffer = Buffer.from(Math.random().toString() + Math.random().toString());
let error;
await method({ buffer, format: 'JPEG' }).catch(err => {
error = err;
});
expect(error).to.be.instanceof(TypeError)
.and.to.have.property('message', 'input buffer is not a HEIC image');
});
});
describe('heic-convert (default wasm)', () => {
runTests(require('..'));
});
describe('heic-convert (legacy js)', () => {
runTests(require('../legacy'));
});

148
test/run-tests.js Normal file
View File

@ -0,0 +1,148 @@
/* eslint-env mocha */
const { promisify } = require('util');
const fs = require('fs');
const path = require('path');
const root = require('rootrequire');
const { fromBuffer: filetype } = require('file-type');
const { expect } = require('chai');
const toUint8 = require('buffer-to-uint8array');
const pixelmatch = require('pixelmatch');
const { PNG } = require('pngjs');
const jpegJs = require('jpeg-js');
const readFile = promisify(fs.readFile);
module.exports = function runTests(convert) {
it('exports a function', () => {
expect(convert).to.be.a('function');
});
const decode = {
'image/png': buffer => PNG.sync.read(Buffer.from(buffer)),
'image/jpeg': buffer => jpegJs.decode(Buffer.from(buffer))
};
const readControl = async name => {
const buffer = await readFile(path.resolve(root, `temp/${name}`));
return decode['image/png'](buffer);
};
const compare = (expected, actual, width, height, errString = 'actual image did not match control image') => {
const result = pixelmatch(toUint8(Buffer.from(expected)), toUint8(Buffer.from(actual)), null, width, height, {
threshold: 0.1
});
// allow 5% of pixels to be different
expect(result).to.be.below(width * height * 0.05, errString);
};
const assertImage = async (buffer, mime, control) => {
expect(buffer).to.be.instanceOf(Uint8Array);
const type = await filetype(buffer);
expect(type.mime).to.equal(mime);
const actual = decode[mime](buffer);
expect(actual.width).to.equal(control.width);
expect(actual.height).to.equal(control.height);
compare(control.data, actual.data, control.width, control.height);
};
it('converts known image to jpeg', async () => {
const control = await readControl('0002-control.png');
const buffer = await readFile(path.resolve(root, 'temp', '0002.heic'));
// quality of 92%
const output92 = await convert({ buffer, format: 'JPEG' });
await assertImage(output92, 'image/jpeg', control);
// quality of 100%
const output100 = await convert({ buffer, format: 'JPEG', quality: 1 });
await assertImage(output100, 'image/jpeg', control);
expect(output92).to.not.deep.equal(output100);
expect(output92.length).to.be.below(output100.length);
});
it('converts known image to png', async () => {
const control = await readControl('0002-control.png');
const buffer = await readFile(path.resolve(root, 'temp', '0002.heic'));
const output = await convert({ buffer, format: 'PNG' });
await assertImage(output, 'image/png', control);
});
it('converts multiple images inside a single file to jpeg', async () => {
const controls = await Promise.all([
readControl('0003-0-control.png'),
readControl('0003-1-control.png'),
]);
const buffer = await readFile(path.resolve(root, 'temp', '0003.heic'));
const images = await convert.all({ buffer, format: 'JPEG' });
expect(images).to.have.lengthOf(3);
for (let { i, control } of [
{ i: 0, control: controls[0] },
{ i: 1, control: controls[1] },
{ i: 2, control: controls[1] },
]) {
expect(images[i]).to.have.a.property('convert').and.to.be.a('function');
await assertImage(await images[i].convert(), 'image/jpeg', control);
}
});
it('converts multiple images inside a single file to png', async () => {
const controls = await Promise.all([
readControl('0003-0-control.png'),
readControl('0003-1-control.png'),
]);
const buffer = await readFile(path.resolve(root, 'temp', '0003.heic'));
const images = await convert.all({ buffer, format: 'PNG' });
expect(images).to.have.lengthOf(3);
for (let { i, control } of [
{ i: 0, control: controls[0] },
{ i: 1, control: controls[1] },
{ i: 2, control: controls[1] },
]) {
expect(images[i]).to.have.a.property('convert').and.to.be.a('function');
await assertImage(await images[i].convert(), 'image/png', control);
}
});
[
{ when: 'converting only the main image', method: convert },
{ when: 'converting all images', method: convert.all }
].forEach(({ when, method }) => {
it(`errors for an unknown output format when ${when}`, async () => {
const buffer = Buffer.from(Math.random().toString() + Math.random().toString());
let error;
await method({ buffer, format: 'PINEAPPLES' }).catch(err => {
error = err;
});
expect(error).to.be.instanceof(Error)
.and.to.have.property('message', 'output format needs to be one of [JPEG,PNG]');
});
it(`errors if data other than a HEIC image is passed in when ${when}`, async () => {
const buffer = Buffer.from(Math.random().toString() + Math.random().toString());
let error;
await method({ buffer, format: 'JPEG' }).catch(err => {
error = err;
});
expect(error).to.be.instanceof(TypeError)
.and.to.have.property('message', 'input buffer is not a HEIC image');
});
});
}