Files
context-mod/tests/imageProcessing.test.ts
2022-08-30 16:13:35 -04:00

183 lines
5.8 KiB
TypeScript

import {describe, it} from 'mocha';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import express, {Request, Response} from "express";
import {resolvePath} from "../src/util";
import {pathToFileURL, URL} from "url";
import ImageData from "../src/Common/ImageData";
import leven from "leven";
chai.use(chaiAsPromised);
const assert = chai.assert;
let app = express();
app.use('/assets', express.static(`${__dirname}/assets`));
const rickOriginalFile = pathToFileURL(resolvePath('./tests/assets/rick-original.jpg', './'));
const rickCopyFile = pathToFileURL(resolvePath('./tests/assets/rick-copy.jpg', './'));
const rickSmallerFile = pathToFileURL(resolvePath('./tests/assets/rick-smaller.jpg', './'));
const rickBorderedFile = pathToFileURL(resolvePath('./tests/assets/rick-border.jpg', './'));
const rickFlippedFile = pathToFileURL(resolvePath('./tests/assets/rick-flipped.jpg', './'));
const rickWhiteBG = pathToFileURL(resolvePath('./tests/assets/rick-whitebg.jpg', './'));
const rickRatio = pathToFileURL(resolvePath('./tests/assets/rick-ratio.jpg', './'));
const rickSaturation = pathToFileURL(resolvePath('./tests/assets/rick-saturated.jpg', './'));
describe('Image Resource Parsing', function () {
before(() => {
// @ts-ignore
app.server = app.listen(5999);
});
after(() => {
// @ts-ignore
app.server.close();
});
it('Handles local resource', async function () {
const local = new ImageData({
path: rickOriginalFile
});
await assert.isFulfilled(local.sharp());
assert.exists(local.width);
});
it('Handles remote resource', async function () {
const local = new ImageData({
path: new URL('http://localhost:5999/assets/rick-original.jpg')
});
await assert.isFulfilled(local.sharp());
assert.exists(local.width);
});
it('Throws when remote resource extension is not a known image type', async function () {
assert.throws(() => {
const local = new ImageData({
path: new URL('http://localhost:5999/assets/nonImage.txt')
});
})
});
it('Throws when remote resource is not an image', async function () {
const local = new ImageData({
path: new URL('http://localhost:5999/assets/nonImage.txt')
}, true);
await assert.isRejected(local.sharp());
});
});
describe('Image Normalization', function () {
it('Removes borders', async function () {
const original = new ImageData({
path: rickOriginalFile
});
await original.sharp();
const bordered = new ImageData({
path: rickBorderedFile
});
await bordered.sharp();
assert.equal(original.width, bordered.width);
assert.equal(original.height, bordered.height);
});
});
describe('Hash Comparisons', function () {
const original = new ImageData({
path: rickOriginalFile
});
before(async () => {
await original.hash(32);
});
it('Detects identical images as the same', async function () {
const compareImg = new ImageData({
path: rickCopyFile
});
await compareImg.hash(32);
const distanceNormal = leven(original.hashResult as string, compareImg.hashResult as string);
const diffNormal = (distanceNormal/(original.hashResult as string).length)*100;
assert.equal(diffNormal, 0);
});
it('Detects images with only saturation differences as the same', async function () {
const compareImg = new ImageData({
path: rickSaturation
});
await compareImg.hash(32);
const distanceNormal = leven(original.hashResult as string, compareImg.hashResult as string);
const diffNormal = (distanceNormal/(original.hashResult as string).length)*100;
assert.isAtMost(diffNormal, 4);
});
it('Detects images with different resolutions as the same', async function () {
const compareImg = new ImageData({
path: rickSmallerFile
});
await compareImg.hash(32);
const distanceNormal = leven(original.hashResult as string, compareImg.hashResult as string);
const diffNormal = (distanceNormal/(original.hashResult as string).length)*100;
assert.equal(diffNormal, 0);
});
it('Detects flipped versions as the same', async function () {
const flipped = new ImageData({
path: rickFlippedFile
});
await flipped.hash(32);
const distanceNormal = leven(original.hashResult as string, flipped.hashResult as string);
const diffNormal = (distanceNormal/(original.hashResult as string).length)*100;
assert.isAtLeast(diffNormal, 50);
const distanceFlipped = leven(original.hashResult as string, flipped.hashResultFlipped as string);
const diffFlipped = (distanceFlipped/(original.hashResult as string).length)*100;
assert.isAtMost(diffFlipped, 4);
});
it('Detects images with minor ratio differences as the same', async function () {
const compareImg = new ImageData({
path: rickRatio
});
await compareImg.hash(32);
const distanceNormal = leven(original.hashResult as string, compareImg.hashResult as string);
const diffNormal = (distanceNormal/(original.hashResult as string).length)*100;
assert.isAtMost(diffNormal, 10);
});
it('Detects different images as different', async function () {
const compareImg = new ImageData({
path: rickWhiteBG
});
await compareImg.hash(32);
const distanceNormal = leven(original.hashResult as string, compareImg.hashResult as string);
const diffNormal = (distanceNormal/(original.hashResult as string).length)*100;
assert.isAtLeast(diffNormal, 50);
});
});