mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
Terminal snapshots now carry soft-wrap row metadata only to clients that advertise support, so restored output can resize like live output without breaking older clients.
50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
||
import { renderTerminalSnapshotToAnsi } from "./terminal-snapshot";
|
||
import type { TerminalState } from "./messages";
|
||
|
||
function cells(text: string): TerminalState["grid"][number] {
|
||
return [...text].map((char) => ({ char }));
|
||
}
|
||
|
||
describe("renderTerminalSnapshotToAnsi", () => {
|
||
it("renders soft-wrapped rows as one contiguous logical line when wrap flags are present", () => {
|
||
// The server soft-wrapped one logical line "ABCDEFGHIJKLMNOP" at 10 cols into
|
||
// two grid rows. gridWrapped[0] = true marks row 0 as continuing into row 1.
|
||
const state: TerminalState = {
|
||
rows: 2,
|
||
cols: 10,
|
||
scrollback: [],
|
||
scrollbackWrapped: [],
|
||
grid: [cells("ABCDEFGHIJ"), cells("KLMNOP")],
|
||
gridWrapped: [true, false],
|
||
cursor: { row: 1, col: 6 },
|
||
};
|
||
|
||
const ansi = renderTerminalSnapshotToAnsi(state);
|
||
|
||
// The rows must arrive unbroken so xterm re-wraps them itself (and can later
|
||
// reflow them) — no hard newline injected between "...IJ" and "KL...".
|
||
expect(ansi).toContain("ABCDEFGHIJKLMNOP");
|
||
// Auto-wrap must stay enabled; disabling it (ESC[?7l) is what makes xterm mark
|
||
// the rows non-wrapped and refuse to reflow them on resize.
|
||
expect(ansi).not.toContain("[?7l");
|
||
});
|
||
|
||
it("falls back to verbatim per-row replay when wrap flags are absent (old daemon)", () => {
|
||
// No gridWrapped/scrollbackWrapped: the client cannot tell soft-wraps from hard
|
||
// newlines, so it must keep today's exact behaviour rather than guess.
|
||
const state: TerminalState = {
|
||
rows: 2,
|
||
cols: 10,
|
||
scrollback: [],
|
||
grid: [cells("ABCDEFGHIJ"), cells("KLMNOP")],
|
||
cursor: { row: 1, col: 6 },
|
||
};
|
||
|
||
const ansi = renderTerminalSnapshotToAnsi(state);
|
||
|
||
expect(ansi).toContain("[?7l");
|
||
expect(ansi).toContain("ABCDEFGHIJ\r\nKLMNOP");
|
||
});
|
||
});
|