Files
Termix/plugins/ssh-terminal/tests/frontend/lib/terminal-local-echo.test.ts
T

71 lines
2.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
TerminalLocalEcho,
resolveLocalEchoMode,
} from "../../../src/frontend/lib/terminal-local-echo";
describe("TerminalLocalEcho", () => {
it("renders immediately and suppresses the matching remote echo", () => {
const echo = new TerminalLocalEcho("on");
expect(echo.handleInput("a")).toBe("a");
expect(echo.handleOutput("a")).toBe("");
});
it("rolls back a prediction when remote output differs", () => {
const echo = new TerminalLocalEcho("on");
echo.handleInput("a");
expect(echo.handleOutput("z")).toBe("\x1b[1D\x1b[1Xz");
});
it("only erases the predicted cells during rollback", () => {
const echo = new TerminalLocalEcho("on");
echo.handleInput("a");
echo.handleInput("b");
expect(echo.handleOutput("\x1b[C")).toBe("\x1b[2D\x1b[2X\x1b[C");
});
it.each([
["split prompt", ["Pass", "word: "]],
["sudo prompt", ["[sudo] password for alice: "]],
["ssh-keygen prompt", ["Enter passphrase (empty for no passphrase): "]],
["passwd prompt", ["New password: "]],
])("does not expose input after a %s", (_name, chunks) => {
const echo = new TerminalLocalEcho("on");
for (const chunk of chunks) expect(echo.handleOutput(chunk)).toBe(chunk);
expect(echo.handleInput("s")).toBe("");
});
it("does not treat ordinary password text as a hidden-input prompt", () => {
const echo = new TerminalLocalEcho("on");
expect(echo.handleOutput("Your password has expired\r\n$ ")).toBe(
"Your password has expired\r\n$ ",
);
expect(echo.handleInput("s")).toBe("s");
});
it("does not predict control input, paste, or wide characters", () => {
const echo = new TerminalLocalEcho("on");
expect(echo.handleInput("\t")).toBe("");
expect(echo.handleInput("paste")).toBe("");
expect(echo.handleInput("界")).toBe("");
});
it("enables automatic prediction after repeated slow echoes", () => {
let now = 0;
const echo = new TerminalLocalEcho("auto", () => now, 100);
expect(echo.handleInput("a")).toBe("");
now = 150;
expect(echo.handleOutput("a")).toBe("a");
expect(echo.handleInput("b")).toBe("");
now = 300;
expect(echo.handleOutput("b")).toBe("b");
expect(echo.handleInput("c")).toBe("c");
});
it("uses an explicit host mode before the global mode", () => {
expect(resolveLocalEchoMode("off", "on")).toBe("off");
expect(resolveLocalEchoMode("default", "on")).toBe("on");
expect(resolveLocalEchoMode(undefined, null)).toBe("auto");
});
});