From 22b8fb08fa2a3ef109b8517014e9b5910717a23b Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Thu, 4 Jun 2026 07:43:34 -0500 Subject: [PATCH] test: failing repro for text-passthrough --- test/text-passthrough.test.ts | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 test/text-passthrough.test.ts diff --git a/test/text-passthrough.test.ts b/test/text-passthrough.test.ts new file mode 100644 index 0000000..0cb84ad --- /dev/null +++ b/test/text-passthrough.test.ts @@ -0,0 +1,45 @@ +import { beforeEach, describe, expect, it } from "./suite.ts"; +import { createTerm, type Term } from "../term.ts"; +import { close, grow, open, text } from "../ops.ts"; + +const decode = (b: Uint8Array) => new TextDecoder().decode(b); +const ESC = String.fromCharCode(0x1b); + +describe("text escape passthrough", () => { + let term: Term; + beforeEach(async () => { + term = await createTerm({ width: 40, height: 3 }); + }); + + it("preserves embedded SGR color escape bytes verbatim", () => { + let input = ESC + "[32mgreen" + ESC + "[0m normal"; + let ansi = decode( + term.render([ + open("root", { + layout: { width: grow(), height: grow(), direction: "ttb" }, + }), + text(input, { passthrough: true } as never), + close(), + ]).output, + ); + // the raw input SGR open byte must survive into the output + expect(ansi).toContain(ESC + "[32m"); + // and the reset byte too + expect(ansi).toContain(ESC + "[0m normal"); + }); + + it("does not substitute U+FFFD for embedded ESC bytes", () => { + let input = ESC + "[32mx" + ESC + "[0m"; + let ansi = decode( + term.render([ + open("root", { + layout: { width: grow(), height: grow(), direction: "ttb" }, + }), + text(input, { passthrough: true } as never), + close(), + ]).output, + ); + // no replacement glyph should appear where the ESC bytes were stripped + expect(ansi.includes("�")).toBe(false); + }); +}); -- 2.51.2