| import { describe, expect, it } from "vitest"; |
| import { sanitizeForLog, splitGraphemes, stripAnsi, visibleWidth } from "./ansi.js"; |
|
|
| describe("terminal ansi helpers", () => { |
| it("strips ANSI and OSC8 sequences", () => { |
| expect(stripAnsi("\u001B[31mred\u001B[0m")).toBe("red"); |
| expect(stripAnsi("\u001B]8;;https://openclaw.ai\u001B\\link\u001B]8;;\u001B\\")).toBe("link"); |
| }); |
|
|
| it("sanitizes control characters for log-safe interpolation", () => { |
| const input = "\u001B[31mwarn\u001B[0m\r\nnext\u0000line\u007f"; |
| expect(sanitizeForLog(input)).toBe("warnnextline"); |
| }); |
|
|
| it("measures wide graphemes by terminal cell width", () => { |
| expect(visibleWidth("abc")).toBe(3); |
| expect(visibleWidth("πΈ skill")).toBe(8); |
| expect(visibleWidth("葨")).toBe(2); |
| expect(visibleWidth("\u001B[31mπΈ\u001B[0m")).toBe(2); |
| }); |
|
|
| it("keeps emoji zwj sequences as single graphemes", () => { |
| expect(splitGraphemes("π¨βπ©βπ§βπ¦")).toEqual(["π¨βπ©βπ§βπ¦"]); |
| expect(visibleWidth("π¨βπ©βπ§βπ¦")).toBe(2); |
| }); |
| }); |
|
|