5b6b8905b1
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
55 lines
2.2 KiB
TypeScript
55 lines
2.2 KiB
TypeScript
/**
|
|
* stripAnsi unit tests: render-time removal of ANSI escape sequences from raw command/tool
|
|
* output (#102), including sequences split across stream chunks and cut off at end-of-string.
|
|
*/
|
|
import { describe, expect, it } from "vitest";
|
|
import { stripAnsi } from "../src/lib/strip-ansi";
|
|
|
|
describe("stripAnsi", () => {
|
|
it("returns text without escapes unchanged (fast path, same reference)", () => {
|
|
const s = "plain text, no escapes [36m literal brackets stay";
|
|
expect(stripAnsi(s)).toBe(s);
|
|
expect(stripAnsi("")).toBe("");
|
|
});
|
|
|
|
it("strips plain SGR color codes", () => {
|
|
expect(stripAnsi("\x1b[36mcyan\x1b[0m")).toBe("cyan");
|
|
expect(stripAnsi("\x1b[2mdim\x1b[0m and \x1b[32mgreen\x1b[0m")).toBe("dim and green");
|
|
});
|
|
|
|
it("strips multi-parameter SGR codes", () => {
|
|
expect(stripAnsi("\x1b[1;31mbold red\x1b[0m")).toBe("bold red");
|
|
expect(stripAnsi("\x1b[38;5;208morange\x1b[0m")).toBe("orange");
|
|
});
|
|
|
|
it("cleans the issue's nested-CLI gutter shape", () => {
|
|
// What #102 showed in the tool card: a nested `penguin run`'s colored call line.
|
|
const raw = "\x1b[36m[tool-752] $ \x1b[0m\x1b[36mcat todo.md\x1b[0m\n";
|
|
expect(stripAnsi(raw)).toBe("[tool-752] $ cat todo.md\n");
|
|
});
|
|
|
|
it("strips OSC sequences (BEL- and ST-terminated) and two-byte escapes", () => {
|
|
expect(stripAnsi("\x1b]0;window title\x07rest")).toBe("rest");
|
|
expect(stripAnsi("\x1b]8;;https://example.com\x1b\\link text\x1b]8;;\x1b\\")).toBe("link text");
|
|
expect(stripAnsi("a\x1bMb")).toBe("ab");
|
|
});
|
|
|
|
it("handles a sequence split across a chunk boundary once chunks are concatenated", () => {
|
|
const chunk1 = "before \x1b[3";
|
|
const chunk2 = "6mblue\x1b[0m after";
|
|
expect(stripAnsi(chunk1 + chunk2)).toBe("before blue after");
|
|
});
|
|
|
|
it("drops an incomplete trailing escape sequence (stream cut mid-sequence)", () => {
|
|
expect(stripAnsi("text\x1b")).toBe("text");
|
|
expect(stripAnsi("text\x1b[")).toBe("text");
|
|
expect(stripAnsi("text\x1b[36")).toBe("text");
|
|
expect(stripAnsi("text\x1b[1;3")).toBe("text");
|
|
expect(stripAnsi("text\x1b]0;half a title")).toBe("text");
|
|
});
|
|
|
|
it("keeps surrounding text intact when stripping mid-string sequences", () => {
|
|
expect(stripAnsi("ok\x1b[31mfail\x1b[0mok")).toBe("okfailok");
|
|
});
|
|
});
|