Merge pull request #65 from fiddlerwoaroof/fix/socket-close-routing
fix(harness): restore the watchdog close-routing guard PR #61 deleted
This commit is contained in:
+4
-1
@@ -4,6 +4,7 @@
|
||||
import init, { Client } from "./pkg/improvise_wasm_client.js";
|
||||
import {
|
||||
COL_PX,
|
||||
HANDSHAKE_TIMEOUT_MS,
|
||||
ROW_PX,
|
||||
createShell,
|
||||
extentOf,
|
||||
@@ -40,13 +41,15 @@ const client = new Client();
|
||||
|
||||
// A peer that never answers the handshake, and the two facts `#status` shows.
|
||||
// Both are decided in shell.js; this is the wire to the element.
|
||||
const HANDSHAKE_TIMEOUT_MS = 8000;
|
||||
const shell = createShell({
|
||||
onStatus: (text) => {
|
||||
el.status.textContent = text;
|
||||
},
|
||||
timeoutMs: HANDSHAKE_TIMEOUT_MS,
|
||||
});
|
||||
// The harness asks whether the watchdog is ARMED, because a negative assertion
|
||||
// about it is vacuous where it is not (clients.md). Read by tests, nothing else.
|
||||
window.__improviseShell = shell;
|
||||
|
||||
// What the grid's own frame costs, in whole cells, as of the last repaint —
|
||||
// measured off the painted model, never predicted. context/code/clients.md.
|
||||
|
||||
@@ -27,6 +27,11 @@ export function indicator(collapsed) {
|
||||
export const ROW_PX = 26;
|
||||
export const COL_PX = 110;
|
||||
|
||||
/** How long a peer has to answer the handshake. Exported because the harness
|
||||
* must jump *past* it: a spec with its own copy can understate it silently
|
||||
* and every watchdog assertion then passes vacuously (clients.md). */
|
||||
export const HANDSHAKE_TIMEOUT_MS = 8000;
|
||||
|
||||
/** The extent a box of this size can show, in whole DATA cells: the frame is
|
||||
* charged for first, and at least one cell is always asked for. */
|
||||
export function extentOf(box, frameCost, metrics = { rowPx: ROW_PX, colPx: COL_PX }) {
|
||||
@@ -107,6 +112,7 @@ export function createShell({ onStatus, timeoutMs, setTimer = setTimeout, clearT
|
||||
let shell = "";
|
||||
let model = "";
|
||||
let watchdog = null;
|
||||
let arms = 0;
|
||||
const paint = () => onStatus(composeStatus(shell, model));
|
||||
|
||||
return {
|
||||
@@ -121,6 +127,7 @@ export function createShell({ onStatus, timeoutMs, setTimer = setTimeout, clearT
|
||||
/** A peer that never answers the handshake. Deliberately about the *first
|
||||
* frame*, not either peer's own failure modes — clients.md. */
|
||||
arm(message) {
|
||||
arms += 1;
|
||||
clearTimer(watchdog);
|
||||
watchdog = setTimer(() => {
|
||||
watchdog = null;
|
||||
@@ -140,5 +147,8 @@ export function createShell({ onStatus, timeoutMs, setTimer = setTimeout, clearT
|
||||
this.setShell(text);
|
||||
},
|
||||
armed: () => watchdog !== null,
|
||||
/** How many times the watchdog has been armed. A test denying its message
|
||||
* needs this to be nonzero, or it is denying an unreachable event. */
|
||||
timesArmed: () => arms,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,13 @@ import { fileURLToPath } from "node:url";
|
||||
|
||||
const read = (rel) => readFileSync(fileURLToPath(new URL(rel, import.meta.url)), "utf8");
|
||||
|
||||
/// Comments name model fields routinely, so a field mentioned only in one
|
||||
/// would read as painted. Strip them before asking what the code touches.
|
||||
const code = (rel) =>
|
||||
read(rel)
|
||||
.replace(/\/\*[\s\S]*?\*\//g, " ")
|
||||
.replace(/(^|[^:"'`])\/\/.*$/gm, "$1");
|
||||
|
||||
/// Fields the page deliberately does not read, each with the reason. A field
|
||||
/// belongs here only with an argument; the list is the debt, written down.
|
||||
// improvise-z754 put the title bar's facts in one shared cache and taught
|
||||
@@ -32,7 +39,7 @@ function renderModelFields() {
|
||||
|
||||
test("every field the render model projects is painted, or named as debt", () => {
|
||||
// Both halves of the page: `app.js` paints, `shell.js` plans the grid.
|
||||
const page = read("../app.js") + read("../shell.js");
|
||||
const page = code("../app.js") + code("../shell.js");
|
||||
const unpainted = renderModelFields().filter((field) => !page.includes(`model.${field}`));
|
||||
assert.deepEqual(
|
||||
unpainted.sort(),
|
||||
|
||||
Reference in New Issue
Block a user