jenot/priv/static/js/test-utils.js
Adrian Gruntkowski f944a3a436 Reorganize tests
2024-11-28 19:12:40 +01:00

101 lines
2.4 KiB
JavaScript

let counter = 1;
let tests = [];
const body = document.querySelector("body");
const log = document.querySelector("#test-log");
class AssertError extends Error {
constructor(message, options) {
super(message, options);
}
}
const setup = (idx) => {
const container = document.createElement("div", { id: `test-${idx}` });
body.appendChild(container);
return container;
};
export async function assert(assertion, timeout) {
timeout = timeout || 100;
const interval = Math.max(timeout / 10, 10);
const start = performance.now();
let now = performance.now();
while (true) {
let result;
let error;
try {
result = assertion();
} catch (error) {
result = false;
error = error;
}
if (result === true) break;
if (now - start >= timeout) {
const assertionStr = assertion.toString();
const opts = error ? { cause: error } : {};
throw new AssertError(`Assertion failed: ${assertionStr}`, opts);
}
await new Promise((r) => setTimeout(r, interval));
now = performance.now();
}
}
export function runTests(globalOptions) {
tests.forEach(async ({ label, testFun, idx, options }) => {
const logRow = document.createElement("li");
if (globalOptions.only && globalOptions.only.indexOf(idx) < 0) {
return;
}
if (options.skip) {
const message = `[SKIPPED] ${label}`;
logRow.textContent = message;
log.appendChild(logRow);
console.info(message);
}
const container = setup(idx);
logRow.textContent = `[RUNNING] ${label}`;
log.appendChild(logRow);
try {
await testFun(container);
const message = `[OK] ${label}`;
console.info(message);
logRow.textContent = message;
logRow.classList.add("success");
} catch (error) {
const message = `[ERROR] ${label}`;
console.error(message, error);
logRow.textContent = message;
logRow.classList.add("failure");
const errorOutput = document.createElement("pre");
errorOutput.textContent = `${error.name}: ${error.message}`;
if (error.stack) {
errorOutput.textContent += `\n${error.stack}`;
}
logRow.appendChild(errorOutput);
}
container.remove();
});
}
export function test(label, testFun, options) {
options = options || {};
tests.push({
label: label,
testFun: testFun,
idx: counter,
options: options,
});
counter++;
}