mirror of
https://github.com/zoldar/jenot.git
synced 2026-01-05 07:02:55 +00:00
Reorganize tests
This commit is contained in:
parent
9119a66bea
commit
f944a3a436
3 changed files with 148 additions and 118 deletions
41
priv/static/js/components-test.js
Normal file
41
priv/static/js/components-test.js
Normal 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);
|
||||||
|
});
|
||||||
|
|
@ -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 URL_PARAMS = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
const CONCRETE_TEST = URL_PARAMS.get("t");
|
const CONCRETE_TEST = URL_PARAMS.get("t");
|
||||||
|
|
||||||
let counter = 1;
|
runTests({
|
||||||
|
only: CONCRETE_TEST ? [parseInt(CONCRETE_TEST)] : null,
|
||||||
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>");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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)
|
|
||||||
})
|
|
||||||
|
|
|
||||||
101
priv/static/js/test-utils.js
Normal file
101
priv/static/js/test-utils.js
Normal 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++;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue