Reorganize tests

This commit is contained in:
Adrian Gruntkowski 2024-11-28 19:12:18 +01:00
parent 9119a66bea
commit f944a3a436
3 changed files with 148 additions and 118 deletions

View file

@ -0,0 +1,41 @@
import { test, assert } from "./test-utils.js";
import "./components.js";
test("editable-area renders", async (container) => {
container.innerHTML = `<editable-area>Test 123</editable-area>`;
const textarea = container.querySelector("textarea");
const display = container.querySelector("p");
await assert(() => textarea.value === "Test 123");
await assert(() => display.classList.contains("display"));
await assert(() => display.innerHTML === "Test 123<br>");
});
test("editable-area updates on input", async (container) => {
container.innerHTML = `<editable-area></editable-area>`;
const textarea = container.querySelector("textarea");
const display = container.querySelector("p");
let eventCalled = false;
container.addEventListener("contentChange", () => {
eventCalled = true;
});
textarea.value = "Some new content\nwith a newline";
textarea.dispatchEvent(
new Event("input", { bubbles: true, cancelable: true }),
);
await assert(() => display.innerHTML === `Some new content<br>with a newline<br>`);
await assert(() => eventCalled === true);
});
test("editable-area respects readonly attribute", async (container) => {
container.innerHTML = `<editable-area readonly>Some text</editable-area>`;
const textarea = container.querySelector("textarea");
await assert(() => textarea.disabled);
});

View file

@ -1,123 +1,11 @@
import "./components.js";
import { runTests } from "./test-utils.js";
// tests to run
import "./components-test.js";
const URL_PARAMS = new URLSearchParams(window.location.search);
const CONCRETE_TEST = URL_PARAMS.get("t");
let counter = 1;
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;
};
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();
}
}
function test(label, testFun) {
if (CONCRETE_TEST && CONCRETE_TEST != counter) {
counter++;
return;
}
const container = setup(counter);
const logRow = document.createElement("li");
logRow.textContent = `[RUNNING] ${label}`;
log.appendChild(logRow);
try {
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();
counter++;
}
test("editable-area renders", (container) => {
container.innerHTML = `<editable-area>Test 123</editable-area>`;
const textarea = container.querySelector("textarea");
const display = container.querySelector("p");
assert(() => textarea.value === "Test 123");
assert(() => display.classList.contains("display"));
assert(() => display.innerHTML === "Test 123<br>");
runTests({
only: CONCRETE_TEST ? [parseInt(CONCRETE_TEST)] : null,
});
test("editable-area updates on input", (container) => {
container.innerHTML = `<editable-area></editable-area>`;
const textarea = container.querySelector("textarea");
const display = container.querySelector("p");
let eventCalled = false;
container.addEventListener("contentChange", () => {
eventCalled = true;
});
textarea.value = "Some new content\nwith a newline";
textarea.dispatchEvent(
new Event("input", { bubbles: true, cancelable: true }),
);
assert(() => display.innerHTML === `Some new content<br>with a newline<br>`);
assert(() => eventCalled === true);
});
test("editable-area respects readonly attribute", (container) => {
container.innerHTML = `<editable-area readonly>Some text</editable-area>`;
const textarea = container.querySelector("textarea");
assert(() => textarea.disabled)
})

View file

@ -0,0 +1,101 @@
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++;
}