From 88897d1c582574325cd31bcf2a3900d28b491345 Mon Sep 17 00:00:00 2001 From: John Kenny Date: Fri, 11 Oct 2024 18:26:33 -0700 Subject: [PATCH 1/7] Add color parsing. --- lib/color.js | 125 ++++++++++++++++++++++++++++++++++++++++ test/lib/colors.test.js | 25 ++++++++ 2 files changed, 150 insertions(+) create mode 100644 lib/color.js create mode 100644 test/lib/colors.test.js diff --git a/lib/color.js b/lib/color.js new file mode 100644 index 0000000..fd4761e --- /dev/null +++ b/lib/color.js @@ -0,0 +1,125 @@ +import { colorsNames, colorsShortNames } from '../plugins/_collections.js'; +import { AttValue } from './attvalue.js'; + +export class ColorValue extends AttValue { + /** + * @param {string|undefined} strVal + */ + constructor(strVal) { + super(strVal); + } + + /** + * @param {string} value + * @returns {ColorValue} + */ + static #createColorObj(value) { + value = value.trim(); + if (value.startsWith('#')) { + const obj = HexColor.create(value.substring(1)); + if (obj) { + return obj; + } + } else if (colorsNames[value.toLowerCase()]) { + return new ExtendedColor(value); + } + return new ColorValue(value); + } + + /** + * @param {string|AttValue} value + * @returns {ColorValue} + */ + static getColorObj(value) { + if (typeof value === 'string') { + return this.#createColorObj(value); + } + if (value instanceof ColorValue) { + return value; + } + throw value; + } + + /** + * @returns {ColorValue} + */ + getMinifiedValue() { + return this; + } +} + +class HexColor extends ColorValue { + /** + * @param {string} hexDigits + * @returns {HexColor|undefined} + */ + static create(hexDigits) { + if (hexDigits.length !== 3 && hexDigits.length !== 6) { + return; + } + for (const char of hexDigits.toLowerCase()) { + switch (char) { + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + default: + return; + } + } + + return new HexColor('#' + hexDigits); + } + + /** + * @returns {ColorValue} + */ + getMinifiedValue() { + let value = this.toString().toLowerCase(); + + if (value.length === 7) { + // See if it can be shortened to 3 characters. + if ( + value[1] === value[2] && + value[3] === value[4] && + value[5] === value[6] + ) { + return new HexColor( + '#' + value[1] + value[3] + value[5], + ).getMinifiedValue(); + } + } + const name = colorsShortNames[value]; + if (name && name.length <= value.length) { + return new ExtendedColor(name); + } + return new HexColor(value); + } +} + +class ExtendedColor extends ColorValue { + /** + * @returns {ColorValue} + */ + getMinifiedValue() { + let value = this.toString().toLowerCase(); + const hexString = colorsNames[value]; + if (hexString.length < value.length) { + return new HexColor(hexString); + } + return new ExtendedColor(value); + } +} diff --git a/test/lib/colors.test.js b/test/lib/colors.test.js new file mode 100644 index 0000000..763f8ae --- /dev/null +++ b/test/lib/colors.test.js @@ -0,0 +1,25 @@ +import { ColorValue } from '../../lib/color.js'; + +describe('test parsing and minifying', () => { + /** @type {{in:string,minified?:string}[]} */ + const testCases = [ + { in: '#ffffff', minified: '#fff' }, + { in: '#aABBcc', minified: '#abc' }, + { in: '#F00', minified: 'red' }, + { in: 'cadetBlue', minified: '#5f9ea0' }, + { in: 'coRal', minified: 'coral' }, + { in: 'wHatEveR' }, + ]; + // TODO: + // CASE SENSITIVITY + // INVALID VALUES + // alpha channel + for (const testCase of testCases) { + it(`${testCase.in}`, () => { + const attValue = ColorValue.getColorObj(testCase.in); + expect(attValue.toString()).toBe(testCase.in); + const minified = attValue.getMinifiedValue(); + expect(minified.toString()).toBe(testCase.minified ?? testCase.in); + }); + } +}); From b4c4650fe71459acfc8d7429d34a3390bd492f66 Mon Sep 17 00:00:00 2001 From: John Kenny Date: Fri, 11 Oct 2024 19:18:45 -0700 Subject: [PATCH 2/7] Added rgb() colors. --- lib/color.js | 81 +++++++++++++++++++++++++++++++++++++---- test/lib/colors.test.js | 3 ++ 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/lib/color.js b/lib/color.js index fd4761e..a934f94 100644 --- a/lib/color.js +++ b/lib/color.js @@ -1,6 +1,9 @@ import { colorsNames, colorsShortNames } from '../plugins/_collections.js'; import { AttValue } from './attvalue.js'; +const REGEX_RGB = /rgb\((.*)\)/i; +const REGEX_RGB_ARGS = /\s|,/; + export class ColorValue extends AttValue { /** * @param {string|undefined} strVal @@ -15,13 +18,19 @@ export class ColorValue extends AttValue { */ static #createColorObj(value) { value = value.trim(); + const lower = value.toLowerCase(); if (value.startsWith('#')) { const obj = HexColor.create(value.substring(1)); if (obj) { return obj; } - } else if (colorsNames[value.toLowerCase()]) { + } else if (colorsNames[lower]) { return new ExtendedColor(value); + } else if (lower.startsWith('rgb(')) { + let obj = RGBColor.create(value); + if (obj) { + return obj; + } } return new ColorValue(value); } @@ -48,6 +57,20 @@ export class ColorValue extends AttValue { } } +class ExtendedColor extends ColorValue { + /** + * @returns {ColorValue} + */ + getMinifiedValue() { + let value = this.toString().toLowerCase(); + const hexString = colorsNames[value]; + if (hexString.length < value.length) { + return new HexColor(hexString); + } + return new ExtendedColor(value); + } +} + class HexColor extends ColorValue { /** * @param {string} hexDigits @@ -110,16 +133,58 @@ class HexColor extends ColorValue { } } -class ExtendedColor extends ColorValue { +class RGBColor extends ColorValue { + #rgb; + + /** + * @param {string} fn + * @param {[number,number,number]} rgb + */ + constructor(fn, rgb) { + super(fn); + this.#rgb = rgb; + } + + /** + * @param {string} fn + * @returns {RGBColor|undefined} + */ + static create(fn) { + const match = REGEX_RGB.exec(fn); + if (!match) { + return; + } + const strArgs = match[1]; + if (!strArgs) { + return; + } + const rawArgs = strArgs.split(REGEX_RGB_ARGS); + const args = rawArgs.filter((a) => a !== ''); + if (args.length !== 3) { + return; + } + const nums = args.map((str) => { + const n = parseInt(str); + if (n < 0 || n > 255) { + return; + } + if (str === n.toString()) { + return n; + } + }); + if (nums.some((n) => n === undefined)) { + return; + } + // @ts-ignore - undefined values excluded above + return new RGBColor(fn, nums); + } + /** * @returns {ColorValue} */ getMinifiedValue() { - let value = this.toString().toLowerCase(); - const hexString = colorsNames[value]; - if (hexString.length < value.length) { - return new HexColor(hexString); - } - return new ExtendedColor(value); + return new HexColor( + this.#rgb.reduce((str, val) => str + val.toString(16), '#'), + ).getMinifiedValue(); } } diff --git a/test/lib/colors.test.js b/test/lib/colors.test.js index 763f8ae..54c3d70 100644 --- a/test/lib/colors.test.js +++ b/test/lib/colors.test.js @@ -9,8 +9,11 @@ describe('test parsing and minifying', () => { { in: 'cadetBlue', minified: '#5f9ea0' }, { in: 'coRal', minified: 'coral' }, { in: 'wHatEveR' }, + { in: 'rGb( 50 100 , 150 )', minified: '#326496' }, ]; // TODO: + // rgb values + // rgb pct. // CASE SENSITIVITY // INVALID VALUES // alpha channel From 11c298f18fb4c5a9eb13e1158c69b42b645800aa Mon Sep 17 00:00:00 2001 From: John Kenny Date: Fri, 11 Oct 2024 19:43:02 -0700 Subject: [PATCH 3/7] Added rgb percentage colors. --- lib/color.js | 60 ++++++++++++++++++++++++++++++++++++++++- test/lib/colors.test.js | 1 + 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/lib/color.js b/lib/color.js index a934f94..8fc4281 100644 --- a/lib/color.js +++ b/lib/color.js @@ -27,7 +27,9 @@ export class ColorValue extends AttValue { } else if (colorsNames[lower]) { return new ExtendedColor(value); } else if (lower.startsWith('rgb(')) { - let obj = RGBColor.create(value); + const obj = value.includes('%') + ? RGBPctColor.create(value) + : RGBColor.create(value); if (obj) { return obj; } @@ -188,3 +190,59 @@ class RGBColor extends ColorValue { ).getMinifiedValue(); } } + +class RGBPctColor extends ColorValue { + #rgb; + + /** + * @param {string} fn + * @param {[number,number,number]} rgb + */ + constructor(fn, rgb) { + super(fn); + this.#rgb = rgb; + } + + /** + * @param {string} fn + * @returns {RGBColor|undefined} + */ + static create(fn) { + const match = REGEX_RGB.exec(fn); + if (!match) { + return; + } + const strArgs = match[1]; + if (!strArgs) { + return; + } + const rawArgs = strArgs.split(REGEX_RGB_ARGS); + const args = rawArgs.filter((a) => a !== ''); + if (args.length !== 3) { + return; + } + const nums = args.map((str) => { + if (str.length === 1 || !str.endsWith('%')) { + return; + } + const numStr = str.substring(0, str.length - 1); + const n = parseFloat(numStr); + if (n < 0 || n > 100 || numStr !== n.toString()) { + return; + } + return n; + }); + if (nums.some((n) => n === undefined)) { + return; + } + // @ts-ignore - undefined values excluded above + return new RGBPctColor(fn, nums); + } + + /** + * @returns {ColorValue} + */ + getMinifiedValue() { + return new ColorValue(`rgb(${this.#rgb.map((n) => n + '%').join(',')})`); + } +} diff --git a/test/lib/colors.test.js b/test/lib/colors.test.js index 54c3d70..454d00f 100644 --- a/test/lib/colors.test.js +++ b/test/lib/colors.test.js @@ -10,6 +10,7 @@ describe('test parsing and minifying', () => { { in: 'coRal', minified: 'coral' }, { in: 'wHatEveR' }, { in: 'rGb( 50 100 , 150 )', minified: '#326496' }, + { in: 'rgb( 49.5%, 33.49% ,22.5% )', minified: 'rgb(49.5%,33.49%,22.5%)' }, ]; // TODO: // rgb values From 1a717d5eb5e5e78f0e542c1757e5d145acfe4538 Mon Sep 17 00:00:00 2001 From: John Kenny Date: Sat, 12 Oct 2024 08:06:39 -0700 Subject: [PATCH 4/7] Create minifyColors plugin. --- lib/builtin.js | 2 + plugins/minifyColors.js | 79 ++++++++++++++++++++++++++++ plugins/plugins-types.d.ts | 1 + plugins/preset-default.js | 4 +- plugins/preset-next.js | 4 +- test/fixtures/files/colors.1.svg | 18 +++++++ test/lib/colors.test.js | 8 +-- test/plugins/minifyColors.01.svg.txt | 24 +++++++++ test/plugins/minifyColors.02.svg.txt | 27 ++++++++++ test/plugins/minifyColors.03.svg.txt | 35 ++++++++++++ test/plugins/minifyColors.04.svg.txt | 23 ++++++++ test/regression.js | 11 ++-- 12 files changed, 223 insertions(+), 13 deletions(-) create mode 100644 plugins/minifyColors.js create mode 100644 test/fixtures/files/colors.1.svg create mode 100644 test/plugins/minifyColors.01.svg.txt create mode 100644 test/plugins/minifyColors.02.svg.txt create mode 100644 test/plugins/minifyColors.03.svg.txt create mode 100644 test/plugins/minifyColors.04.svg.txt diff --git a/lib/builtin.js b/lib/builtin.js index a77cef2..48a2f08 100644 --- a/lib/builtin.js +++ b/lib/builtin.js @@ -22,6 +22,7 @@ import * as convertStyleToAttrs from '../plugins/convertStyleToAttrs.js'; import * as createGroups from '../plugins/createGroups.js'; import * as inlineStyles from '../plugins/inlineStyles.js'; import * as mergePaths from '../plugins/mergePaths.js'; +import * as minifyColors from '../plugins/minifyColors.js'; import * as minifyPathData from '../plugins/minifyPathData.js'; import * as minifyStyles from '../plugins/minifyStyles.js'; import * as minifyTransforms from '../plugins/minifyTransforms.js'; @@ -89,6 +90,7 @@ export const builtin = Object.freeze([ createGroups, inlineStyles, mergePaths, + minifyColors, minifyPathData, minifyStyles, minifyTransforms, diff --git a/plugins/minifyColors.js b/plugins/minifyColors.js new file mode 100644 index 0000000..d7708b6 --- /dev/null +++ b/plugins/minifyColors.js @@ -0,0 +1,79 @@ +import { ColorValue } from '../lib/color.js'; +import { getStyleDeclarations } from '../lib/css-tools.js'; +import { writeStyleAttribute } from '../lib/css.js'; +import { svgSetAttValue } from '../lib/svg-parse-att.js'; + +export const name = 'minifyColors'; +export const description = + 'minifies color values used in attributes and style properties'; + +/** + * @type {import('./plugins-types.js').Plugin<'minifyColors'>}; +'>} + */ +export const fn = (root, params, info) => { + const styleData = info.docData.getStyles(); + if ( + info.docData.hasScripts() || + styleData === null || + styleData.hasAttributeSelector() + ) { + return; + } + + return { + element: { + enter: (element) => { + // Minify attribute values. + for (const [attName, attVal] of Object.entries(element.attributes)) { + switch (attName) { + case 'fill': + case 'flood-color': + case 'lighting-color': + case 'stop-color': + case 'stroke': + { + const value = ColorValue.getColorObj(attVal); + const min = value.getMinifiedValue(); + if (min) { + svgSetAttValue(element, attName, min); + } + } + break; + } + } + + // Minify style properties. + const props = getStyleDeclarations(element); + if (!props) { + return; + } + let propChanged = false; + for (const [propName, propValue] of props.entries()) { + switch (propName) { + case 'fill': + case 'flood-color': + case 'lighting-color': + case 'stop-color': + case 'stroke': + { + const value = ColorValue.getColorObj(propValue.value); + const min = value.getMinifiedValue(); + if (min) { + propChanged = true; + props.set(propName, { + value: min, + important: propValue.important, + }); + } + } + break; + } + } + if (propChanged) { + writeStyleAttribute(element, props); + } + }, + }, + }; +}; diff --git a/plugins/plugins-types.d.ts b/plugins/plugins-types.d.ts index 607a83e..8f8907d 100644 --- a/plugins/plugins-types.d.ts +++ b/plugins/plugins-types.d.ts @@ -93,6 +93,7 @@ type DefaultPlugins = { floatPrecision?: number; noSpaceAfterFlags?: boolean; }; + minifyColors: void; minifyPathData: void; minifyStyles: void; minifyTransforms: void; diff --git a/plugins/preset-default.js b/plugins/preset-default.js index e728829..b8f5123 100644 --- a/plugins/preset-default.js +++ b/plugins/preset-default.js @@ -4,11 +4,11 @@ import * as cleanupStyleAttributes from './cleanupStyleAttributes.js'; import * as cleanupXlink from './cleanupXlink.js'; import * as collapseGroups from './collapseGroups.js'; import * as combineStyleElements from './combineStyleElements.js'; -import * as convertColors from './convertColors.js'; import * as convertEllipseToCircle from './convertEllipseToCircle.js'; import * as convertShapeToPath from './convertShapeToPath.js'; import * as createGroups from './createGroups.js'; import * as inlineStyles from './inlineStyles.js'; +import * as minifyColors from './minifyColors.js'; import * as minifyPathData from './minifyPathData.js'; import * as minifyStyles from './minifyStyles.js'; import * as minifyTransforms from './minifyTransforms.js'; @@ -42,7 +42,7 @@ const presetDefault = createPreset({ inlineStyles, minifyStyles, cleanupIds, - convertColors, + minifyColors, removeUnknownsAndDefaults, removeNonInheritableGroupAttrs, removeUselessStrokeAndFill, diff --git a/plugins/preset-next.js b/plugins/preset-next.js index bde6835..c947499 100644 --- a/plugins/preset-next.js +++ b/plugins/preset-next.js @@ -4,11 +4,11 @@ import * as cleanupStyleAttributes from './cleanupStyleAttributes.js'; import * as cleanupXlink from './cleanupXlink.js'; import * as collapseGroups from './collapseGroups.js'; import * as combineStyleElements from './combineStyleElements.js'; -import * as convertColors from './convertColors.js'; import * as convertEllipseToCircle from './convertEllipseToCircle.js'; import * as convertShapeToPath from './convertShapeToPath.js'; import * as createGroups from './createGroups.js'; import * as inlineStyles from './inlineStyles.js'; +import * as minifyColors from './minifyColors.js'; import * as minifyPathData from './minifyPathData.js'; import * as minifyStyles from './minifyStyles.js'; import * as minifyTransforms from './minifyTransforms.js'; @@ -42,7 +42,7 @@ const presetNext = createPreset({ inlineStyles, minifyStyles, cleanupIds, - convertColors, + minifyColors, removeUnknownsAndDefaults, removeNonInheritableGroupAttrs, removeUselessStrokeAndFill, diff --git a/test/fixtures/files/colors.1.svg b/test/fixtures/files/colors.1.svg new file mode 100644 index 0000000..32b2039 --- /dev/null +++ b/test/fixtures/files/colors.1.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/test/lib/colors.test.js b/test/lib/colors.test.js index 454d00f..de4d767 100644 --- a/test/lib/colors.test.js +++ b/test/lib/colors.test.js @@ -11,13 +11,9 @@ describe('test parsing and minifying', () => { { in: 'wHatEveR' }, { in: 'rGb( 50 100 , 150 )', minified: '#326496' }, { in: 'rgb( 49.5%, 33.49% ,22.5% )', minified: 'rgb(49.5%,33.49%,22.5%)' }, + { in: 'rgb(165,42,42)', minified: 'brown' }, + { in: 'rgb( 50 100 150 /.1)', minified: 'rgb( 50 100 150 /.1)' }, ]; - // TODO: - // rgb values - // rgb pct. - // CASE SENSITIVITY - // INVALID VALUES - // alpha channel for (const testCase of testCases) { it(`${testCase.in}`, () => { const attValue = ColorValue.getColorObj(testCase.in); diff --git a/test/plugins/minifyColors.01.svg.txt b/test/plugins/minifyColors.01.svg.txt new file mode 100644 index 0000000..9af2e74 --- /dev/null +++ b/test/plugins/minifyColors.01.svg.txt @@ -0,0 +1,24 @@ +Convert attribute values. + +=== + + + + + + + + + + +@@@ + + + + + + + + + + diff --git a/test/plugins/minifyColors.02.svg.txt b/test/plugins/minifyColors.02.svg.txt new file mode 100644 index 0000000..d41aad8 --- /dev/null +++ b/test/plugins/minifyColors.02.svg.txt @@ -0,0 +1,27 @@ +Convert flood-color values. + +=== + + + + + + + + + + + + +@@@ + + + + + + + + + + + diff --git a/test/plugins/minifyColors.03.svg.txt b/test/plugins/minifyColors.03.svg.txt new file mode 100644 index 0000000..a0c32fd --- /dev/null +++ b/test/plugins/minifyColors.03.svg.txt @@ -0,0 +1,35 @@ +Convert lighting-color values. + +=== + + + + + + + + + + + + + + + + +@@@ + + + + + + + + + + + + + + + diff --git a/test/plugins/minifyColors.04.svg.txt b/test/plugins/minifyColors.04.svg.txt new file mode 100644 index 0000000..9e38ab5 --- /dev/null +++ b/test/plugins/minifyColors.04.svg.txt @@ -0,0 +1,23 @@ +Convert property values. + +=== + + + + + + + + + + +@@@ + + + + + + + + + diff --git a/test/regression.js b/test/regression.js index c1871ba..96d8673 100644 --- a/test/regression.js +++ b/test/regression.js @@ -176,13 +176,18 @@ async function performTests(options) { if (req.url === undefined) { throw new Error(); } - const name = decodeURI(req.url.slice(req.url.indexOf('/', 1))); + const name = decodeURI(req.url.slice(req.url.indexOf('/', 1))) + .replaceAll('(', '%28') + .replaceAll(')', '%29'); const statsName = name.substring(1); let file; try { file = await fs.readFile(path.join(fixturesDir, name), 'utf-8'); } catch { - console.error(`error reading file ${name}`); + if (name.endsWith('.svg')) { + console.error(`error reading file ${name} (url=${req.url})`); + notOptimized.add(name.substring(1)); + } res.statusCode = 404; res.end(); return; @@ -252,7 +257,7 @@ program .option( '-b, --browser ', 'Browser engine to use in testing', - 'chromium', + 'webkit', ) .option( '-i, --inputdir ', From 7d02ac76bafd613191ead481db31e8942db8dd3d Mon Sep 17 00:00:00 2001 From: John Kenny Date: Sat, 12 Oct 2024 08:36:25 -0700 Subject: [PATCH 5/7] Clean up test files. --- test/regression.js | 7 +++++-- test/svgo/keyframe-selectors.svg.txt | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/test/regression.js b/test/regression.js index 96d8673..b88a27a 100644 --- a/test/regression.js +++ b/test/regression.js @@ -184,9 +184,12 @@ async function performTests(options) { try { file = await fs.readFile(path.join(fixturesDir, name), 'utf-8'); } catch { - if (name.endsWith('.svg')) { + if ( + req.url.startsWith('/original/') || + req.url.startsWith('/optimized/') + ) { console.error(`error reading file ${name} (url=${req.url})`); - notOptimized.add(name.substring(1)); + notOptimized.add(statsName); } res.statusCode = 404; res.end(); diff --git a/test/svgo/keyframe-selectors.svg.txt b/test/svgo/keyframe-selectors.svg.txt index 628a633..8314859 100644 --- a/test/svgo/keyframe-selectors.svg.txt +++ b/test/svgo/keyframe-selectors.svg.txt @@ -9,5 +9,5 @@ - + From 89f2c5db1e37bc11b31d6846cfb1714b55ed7079 Mon Sep 17 00:00:00 2001 From: John Kenny Date: Sat, 12 Oct 2024 08:53:21 -0700 Subject: [PATCH 6/7] Fixed hex conversion bug. --- lib/color.js | 5 ++++- test/lib/colors.test.js | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/color.js b/lib/color.js index 8fc4281..c8588c7 100644 --- a/lib/color.js +++ b/lib/color.js @@ -186,7 +186,10 @@ class RGBColor extends ColorValue { */ getMinifiedValue() { return new HexColor( - this.#rgb.reduce((str, val) => str + val.toString(16), '#'), + this.#rgb.reduce((str, val) => { + const hex = val.toString(16); + return str + (hex.length === 1 ? '0' + hex : hex); + }, '#'), ).getMinifiedValue(); } } diff --git a/test/lib/colors.test.js b/test/lib/colors.test.js index de4d767..144b0a4 100644 --- a/test/lib/colors.test.js +++ b/test/lib/colors.test.js @@ -10,6 +10,7 @@ describe('test parsing and minifying', () => { { in: 'coRal', minified: 'coral' }, { in: 'wHatEveR' }, { in: 'rGb( 50 100 , 150 )', minified: '#326496' }, + { in: 'rgb(203,0,254)', minified: '#cb00fe' }, { in: 'rgb( 49.5%, 33.49% ,22.5% )', minified: 'rgb(49.5%,33.49%,22.5%)' }, { in: 'rgb(165,42,42)', minified: 'brown' }, { in: 'rgb( 50 100 150 /.1)', minified: 'rgb( 50 100 150 /.1)' }, From 3cd2d4ef0a6c156f430ba48915c7463733d2e717 Mon Sep 17 00:00:00 2001 From: John Kenny Date: Sat, 12 Oct 2024 09:17:10 -0700 Subject: [PATCH 7/7] Fixed,regression warnings. --- test/regression.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/test/regression.js b/test/regression.js index b88a27a..0f86b4d 100644 --- a/test/regression.js +++ b/test/regression.js @@ -63,13 +63,6 @@ async function performTests(options) { * @param {string} name */ const processFile = async (page, name) => { - const fileStats = { - lengthOrig: 0, - lengthOpt: 0, - pixels: -1, - }; - stats.set(name.replace(/\\/g, '/'), fileStats); - await page.goto(`http://localhost:5000/original/${name}`); const originalBuffer = await page.screenshot(screenshotOptions); await page.goto(`http://localhost:5000/optimized/${name}`); @@ -90,6 +83,10 @@ async function performTests(options) { return; } + const fileStats = stats.get(name.replace(/\\/g, '/')); + if (!fileStats) { + throw new Error(); + } fileStats.pixels = mismatchCount; totalPixelMismatches += mismatchCount; if (mismatchCount <= 0) { @@ -184,10 +181,7 @@ async function performTests(options) { try { file = await fs.readFile(path.join(fixturesDir, name), 'utf-8'); } catch { - if ( - req.url.startsWith('/original/') || - req.url.startsWith('/optimized/') - ) { + if (stats.has(statsName)) { console.error(`error reading file ${name} (url=${req.url})`); notOptimized.add(statsName); } @@ -226,6 +220,16 @@ async function performTests(options) { server.listen(5000, resolve); }); const list = (await filesPromise).filter((name) => name.endsWith('.svg')); + + // Initialize statistics array. + list.forEach((name) => + stats.set(name, { + lengthOrig: 0, + lengthOpt: 0, + pixels: -1, + }), + ); + const passed = await runTests(list); server.close(); const end = process.hrtime.bigint();