electron+tests: zoom plumbing (construction-only lights), hermeticity fence for the jobs suite
- ZOOM: the ⌘±/⌘0 ladder is owned, not stock roles — applyZoom sets the factor and broadcasts 'lh:zoom'; the renderer publishes --lh-zoom; the gutter lengths (.lh-lights-gutter / .lh-closed-toggle) divide by it so their RENDERED size is a physical constant at every zoom — the graph button stays glued next to the lights, nothing slides under them. before-input-event catches ⌘=/layout variants the menu's Plus may not claim; did-finish-load re-pushes on reload; getZoom covers first paint. The lights themselves stay at construction position — Electron 44 has NO setTrafficLightPosition (options-only; the first run crashed on it). HIG-acceptable: native lights hug the corner; the web chrome compensates around them. - JOBS SUITE FLAKE, actually fixed this time: the seams are module-global and the sweep scans every record — a timed-out async test left a running orphan + late wake that poisoned its NEIGHBORS (respawned 3 !== 0). New afterEach fence: settle every tracked running job, unregister aborts, seams reset to inert no-ops — every test starts from identical state regardless of upstream flake. Verified: two consecutive full-suite runs 1326/1326.
This commit is contained in:
+28
-1
@@ -26,7 +26,7 @@
|
||||
import assert from "node:assert/strict";
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import { after, describe, it } from "node:test";
|
||||
import { after, afterEach, describe, it } from "node:test";
|
||||
import { createFauxCore, fauxAssistantMessage, fauxText, fauxToolCall, type AssistantMessage, type FauxResponseStep } from "@earendil-works/pi-ai";
|
||||
import {
|
||||
accumulateJobUsage,
|
||||
@@ -123,6 +123,33 @@ function trackJob(id: string) {
|
||||
createdJobs.push(id);
|
||||
}
|
||||
|
||||
/* THE HERMETICITY FENCE (owner round 7, 2026-10-05): the jobs seams are
|
||||
* MODULE-GLOBAL (setJobRespawn / setTurnRunner / the abort registry) and
|
||||
* the sweep scans EVERY job in the store. An async test that times out
|
||||
* under full-suite load leaves a "running" record and a late wake behind
|
||||
* — and that stray state then poisons the NEXT test (a foreign respawn
|
||||
* lands in its counter; a foreign orphan in its sweep). Under isolation
|
||||
* nothing ever times out, which is why the file passes alone and flaked
|
||||
* in the full run. The fence makes every test's start state identical:
|
||||
* all tracked jobs settled, aborts unregistered, seams inert. */
|
||||
afterEach(() => {
|
||||
for (const id of createdJobs) {
|
||||
try {
|
||||
const job = jobStore.getJob(id);
|
||||
if (job && job.status === "running") {
|
||||
jobStore.updateJob(id, { status: "done", activity: "settled (fence)" });
|
||||
}
|
||||
unregisterJobAbort(id);
|
||||
} catch {
|
||||
/* already gone */
|
||||
}
|
||||
}
|
||||
// Late wakes from a prior test must be inert: a no-op respawn can't
|
||||
// increment anyone's counter, a no-op runner can't spawn real work.
|
||||
setJobRespawn(() => {});
|
||||
setTurnRunner(async () => 200);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
for (const id of createdChats) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user