Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
117 lines
3.9 KiB
TypeScript
117 lines
3.9 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { readFileSync } from "node:fs";
|
|
|
|
import {
|
|
isTerminalCloseGenerationCurrent,
|
|
resolveConnectionLogCapturePayload,
|
|
resolveHibernateSnapshotCapturePayload,
|
|
scheduleTerminalCloseTeardown,
|
|
} from "./terminalCloseCapture.ts";
|
|
|
|
test("resolveConnectionLogCapturePayload returns null when finalize produces empty data", () => {
|
|
assert.equal(
|
|
resolveConnectionLogCapturePayload(() => ""),
|
|
null,
|
|
);
|
|
});
|
|
|
|
test("resolveConnectionLogCapturePayload returns buffered connection log data", () => {
|
|
assert.deepEqual(
|
|
resolveConnectionLogCapturePayload(() => "line one\r\nline two"),
|
|
{ data: "line one\r\nline two", source: "connection-log" },
|
|
);
|
|
});
|
|
|
|
test("resolveHibernateSnapshotCapturePayload prefers combined snapshot fields", () => {
|
|
assert.deepEqual(
|
|
resolveHibernateSnapshotCapturePayload({
|
|
snapshot: "full snapshot",
|
|
viewportSnapshot: "viewport",
|
|
scrollbackSnapshot: "scrollback",
|
|
alternateScreen: false,
|
|
}),
|
|
{ data: "full snapshot", source: "hibernate-serialize" },
|
|
);
|
|
|
|
assert.deepEqual(
|
|
resolveHibernateSnapshotCapturePayload({
|
|
snapshot: "",
|
|
viewportSnapshot: "viewport",
|
|
scrollbackSnapshot: "scrollback",
|
|
alternateScreen: false,
|
|
}),
|
|
{ data: "scrollbackviewport", source: "hibernate-serialize" },
|
|
);
|
|
});
|
|
|
|
test("scheduleTerminalCloseTeardown runs teardown asynchronously", async () => {
|
|
let ran = false;
|
|
scheduleTerminalCloseTeardown(() => {
|
|
ran = true;
|
|
});
|
|
assert.equal(ran, false);
|
|
await new Promise<void>((resolve) => {
|
|
setTimeout(resolve, 0);
|
|
});
|
|
assert.equal(ran, true);
|
|
});
|
|
|
|
test("isTerminalCloseGenerationCurrent rejects stale close generations", () => {
|
|
assert.equal(isTerminalCloseGenerationCurrent(1, 1), true);
|
|
assert.equal(isTerminalCloseGenerationCurrent(1, 2), false);
|
|
});
|
|
|
|
test("terminal close fully drains pending output before finalizing capture", () => {
|
|
const source = readFileSync(
|
|
new URL("../useTerminalEffects.ts", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const cleanupStart = source.indexOf("return () => {", source.indexOf("void boot();"));
|
|
const flushIndex = source.indexOf("await flushPendingTerminalWritesBeforeHibernate(term)", cleanupStart);
|
|
const incompleteIndex = source.indexOf("if (!flushed)", flushIndex);
|
|
const finalizeIndex = source.indexOf("resolveConnectionLogCapturePayload(finalizeTerminalLogData)", cleanupStart);
|
|
|
|
assert.ok(cleanupStart >= 0);
|
|
assert.ok(flushIndex > cleanupStart);
|
|
assert.ok(incompleteIndex > flushIndex);
|
|
assert.ok(finalizeIndex > flushIndex);
|
|
});
|
|
|
|
test("never-connected StrictMode cleanup sync-disposes its owned xterm runtime", () => {
|
|
const source = readFileSync(
|
|
new URL("../useTerminalEffects.ts", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const cleanupStart = source.indexOf("return () => {", source.indexOf("void boot();"));
|
|
assert.ok(cleanupStart >= 0);
|
|
const neverConnectedClose = source.indexOf(
|
|
"if (!hasConnectedRef.current)",
|
|
cleanupStart,
|
|
);
|
|
assert.ok(neverConnectedClose > cleanupStart);
|
|
const branch = source.slice(
|
|
neverConnectedClose,
|
|
source.indexOf("const persistCloseCapture", neverConnectedClose),
|
|
);
|
|
assert.match(branch, /if \(!attachExistingSession\)/);
|
|
assert.match(branch, /disposeOwnedRuntime\(\);/);
|
|
assert.match(branch, /return;/);
|
|
assert.ok(
|
|
branch.indexOf("disposeOwnedRuntime();") < branch.indexOf("return;"),
|
|
"orphaned StrictMode xterm must be disposed before leaving cleanup",
|
|
);
|
|
});
|
|
|
|
test("createXTermRuntime clears orphaned .xterm children before open", () => {
|
|
const source = readFileSync(
|
|
new URL("./createXTermRuntime.ts", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const openAt = source.indexOf("term.open(ctx.container);");
|
|
assert.ok(openAt > 0);
|
|
const beforeOpen = source.slice(Math.max(0, openAt - 350), openAt);
|
|
assert.match(beforeOpen, /querySelectorAll\(":scope > \.xterm"\)/);
|
|
assert.match(beforeOpen, /orphan\.remove\(\)/);
|
|
});
|