Skip to content
Open
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
82 changes: 56 additions & 26 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const childProcess = require("node:child_process");
const exec = require("util").promisify(childProcess.exec)
const assert = require("node:assert");

const TEST_TIMEOUT = 60000;

const testPath = path.join(__dirname, 'tests');

let testCategories = fs.readdirSync(testPath).sort((a, b) => parseInt(a) - parseInt(b));
Expand Down Expand Up @@ -40,11 +42,18 @@ for (const testCategory of testCategories) {
fs.writeFileSync(testPath, testCode);
let testDescription = testCode.split('\n')[0].slice(2).trim();

const skip = testDescription.endsWith('OFF')
const secondLine = (testCode.split('\n')[1] || '').trim();
let marker = null;
let skipReason = null;
const markerMatch = secondLine.match(/^\/\/\s*(SKIP_V4|SKIP_V5|OFF)(?::\s*(.*))?$/);
if (markerMatch) {
marker = markerMatch[1];
skipReason = markerMatch[2] || null;
}

await new Promise(resolve => {
test(testDescription, async (t) => {
if (skip) {
if (marker === 'OFF') {
t.skip();
return resolve();
}
Expand All @@ -55,24 +64,37 @@ for (const testCategory of testCategories) {
throw `${module} timed out`;
};

let execTest = async (testPath) => {
return (await exec(`node ${testPath}`, {maxBuffer: 1024 * 1024 * 100})).stdout
}

try {
// Run with Express 4
timeout = setTimeout(() => timeoutFunc('express'), 60000);
let expressOutput = (await exec(`node ${testPath}`, {maxBuffer: 1024 * 1024 * 100})).stdout;
clearTimeout(timeout);
let express4Output = null;
if (marker !== 'SKIP_V4') {
timeout = setTimeout(() => timeoutFunc('express'), TEST_TIMEOUT);
express4Output = await execTest(testPath);
clearTimeout(timeout);
} else {
t.diagnostic(skipReason ? `express4: SKIPPED (${skipReason})` : 'express4: SKIPPED');
}

// Run with Express 5
// Run with Express 5 (skip if SKIP_V5)
let express5Output = null;
let express5Error = null;
const express5Code = testCode.replace(`const express = require("express");`, `const express = require("express5");`);
fs.writeFileSync(testPath, express5Code);
try {
timeout = setTimeout(() => timeoutFunc('express5'), 60000);
express5Output = (await exec(`node ${testPath}`, {maxBuffer: 1024 * 1024 * 100})).stdout;
clearTimeout(timeout);
} catch(e) {
clearTimeout(timeout);
express5Error = e;
if (marker !== 'SKIP_V5') {
const express5Code = testCode.replace(`const express = require("express");`, `const express = require("express5");`);
fs.writeFileSync(testPath, express5Code);
try {
timeout = setTimeout(() => timeoutFunc('express5'), TEST_TIMEOUT);
express5Output = await execTest(testPath);
clearTimeout(timeout);
} catch(e) {
clearTimeout(timeout);
express5Error = e;
}
} else {
t.diagnostic(skipReason ? `express5: SKIPPED (${skipReason})` : 'express5: SKIPPED');
}

// Run with ultimate-express
Expand All @@ -81,20 +103,28 @@ for (const testCategory of testCategories) {
throw new Error("Test code does not contain require express");
}
fs.writeFileSync(testPath, newCode);
timeout = setTimeout(() => timeoutFunc('ultimate-express'), 60000)
let uExpressOutput = (await exec(`node ${testPath}`, {maxBuffer: 1024 * 1024 * 100})).stdout;
timeout = setTimeout(() => timeoutFunc('ultimate-express'), TEST_TIMEOUT)
let uExpressOutput = await execTest(testPath);
clearTimeout(timeout);

// Compare with Express 4 (strict)
assert.strictEqual(uExpressOutput, expressOutput);

// Compare with Express 5 (diagnostic)
if(express5Error) {
t.diagnostic(`express5: ERROR - ${(express5Error.stderr || express5Error.message || String(express5Error)).split('\n')[0]}`);
} else if(uExpressOutput === express5Output) {
t.diagnostic('express5: PASS');
// Compare outputs
if (marker === 'SKIP_V4') {
// Strict compare against Express 5
assert.strictEqual(uExpressOutput, express5Output);
} else {
t.diagnostic('express5: MISMATCH');
// Strict compare against Express 4 (default + SKIP_V5)
assert.strictEqual(uExpressOutput, express4Output);
}

// Compare with Express 5 (diagnostic, only when Express 5 ran)
if (marker !== 'SKIP_V5' && marker !== 'SKIP_V4') {
if(express5Error) {
t.diagnostic(`express5: ERROR - ${(express5Error.stderr || express5Error.message || String(express5Error)).split('\n')[0]}`);
} else if(uExpressOutput === express5Output) {
t.diagnostic('express5: PASS');
} else {
t.diagnostic('express5: MISMATCH');
}
}
} catch (error) {
throw error;
Expand Down
1 change: 1 addition & 0 deletions tests/tests/app/app-delete.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// must support app.delete() and app.del()
// SKIP_V5: app.del() removed in Express 5

const express = require("express");

Expand Down
1 change: 1 addition & 0 deletions tests/tests/app/app-param-deprecated.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// must support app.param() with deprecated callback syntax (function as first argument)
// SKIP_V5: deprecated callback syntax removed in Express 5

const express = require("express");

Expand Down
Loading