Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add statistics to regression.js #1932

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dist
test/regression-fixtures
test/regression-diffs
test/cli/output
tmp
coverage
.DS_Store
.vscode
Expand Down
62 changes: 57 additions & 5 deletions test/regression.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import fs from 'node:fs/promises';
import fsSync from 'node:fs';
import http from 'http';
import os from 'os';
import path from 'path';
Expand All @@ -18,11 +19,21 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
const width = 960;
const height = 720;

const FILE_PATTERN = new RegExp('.*');
SethFalco marked this conversation as resolved.
Show resolved Hide resolved
let configFileName;
const DEFAULT_CONFIG = {
floatPrecision: 4,
};
const CONFIG = configFileName ? readConfigFile(configFileName) : DEFAULT_CONFIG;
SethFalco marked this conversation as resolved.
Show resolved Hide resolved

const stats = {};

/** @type {PageScreenshotOptions} */
const screenshotOptions = {
omitBackground: true,
clip: { x: 0, y: 0, width, height },
animations: 'disabled',
timeout: 80000,
SethFalco marked this conversation as resolved.
Show resolved Hide resolved
};

/**
Expand All @@ -38,9 +49,15 @@ const runTests = async (list) => {
* @param {string} name
*/
const processFile = async (page, name) => {
await page.goto(`http://localhost:5000/original/${name}`);
const fileStats = {};
stats[name.replaceAll('\\', '/')] = fileStats;
await page.goto(`http://localhost:5000/original/${name}`, {
timeout: 80000,
});
const originalBuffer = await page.screenshot(screenshotOptions);
await page.goto(`http://localhost:5000/optimized/${name}`);
await page.goto(`http://localhost:5000/optimized/${name}`, {
timeout: 80000,
});
const optimizedBufferPromise = page.screenshot(screenshotOptions);

const writeDiffs = process.env.NO_DIFF == null;
Expand All @@ -58,9 +75,11 @@ const runTests = async (list) => {
if (matched <= 4) {
console.info(`${name} is passed`);
passed++;
fileStats.result = 'pass';
} else {
mismatched++;
console.error(`${name} is mismatched`);
fileStats.result = 'mismatch';
if (diff) {
const file = path.join(
__dirname,
Expand All @@ -76,6 +95,9 @@ const runTests = async (list) => {
let item;
const page = await context.newPage();
while ((item = list.pop())) {
if (!FILE_PATTERN.test(item)) {
continue;
}
await processFile(page, item);
}
await page.close();
Expand All @@ -95,13 +117,20 @@ const runTests = async (list) => {
return mismatched === 0;
};

function readConfigFile(fileName) {
const data = fsSync.readFileSync(fileName);
const json = JSON.parse(data);
return json;
}

(async () => {
try {
const start = process.hrtime.bigint();
const fixturesDir = path.join(__dirname, 'regression-fixtures');
const filesPromise = fs.readdir(fixturesDir, { recursive: true });
const server = http.createServer(async (req, res) => {
const name = req.url.slice(req.url.indexOf('/', 1));
const statsName = name.substring(1);
let file;
try {
file = await fs.readFile(path.join(fixturesDir, name), 'utf-8');
Expand All @@ -112,14 +141,15 @@ const runTests = async (list) => {
}

if (req.url.startsWith('/original/')) {
stats[statsName].lengthOrig = file.length;
res.setHeader('Content-Type', 'image/svg+xml');
res.end(file);
return;
}
if (req.url.startsWith('/optimized/')) {
const optimized = optimize(file, {
floatPrecision: 4,
});
const optimized = optimize(file, CONFIG);
stats[statsName].lengthOpt = optimized.data.length;
SethFalco marked this conversation as resolved.
Show resolved Hide resolved

res.setHeader('Content-Type', 'image/svg+xml');
res.end(optimized.data);
return;
Expand All @@ -134,6 +164,28 @@ const runTests = async (list) => {
server.close();
const end = process.hrtime.bigint();
const diff = (end - start) / BigInt(1e6);

// Write statistics.
const statArray = [
['Name', 'Result', 'Orig Len', 'Opt Len', 'Reduction'].join('\t'),
SethFalco marked this conversation as resolved.
Show resolved Hide resolved
];
let totalReduction = 0;
for (const name of Object.keys(stats).sort()) {
const fileStats = stats[name];
const orig = fileStats.lengthOrig;
const opt = fileStats.lengthOpt;
const reduction = orig - opt;
totalReduction += reduction;
statArray.push([name, fileStats.result, orig, opt, reduction].join('\t'));
}
const statsFileName = `tmp/regression-stats-${new Date()
.toISOString()
.replaceAll(':', '')
.substring(0, 17)}.tsv`;
await fs.mkdir(path.dirname(statsFileName), { recursive: true });
await fs.writeFile(statsFileName, statArray.join('\n'));

console.info(`Total reduction ${totalReduction} bytes`);
if (passed) {
console.info(`Regression tests successfully completed in ${diff}ms`);
} else {
Expand Down