From 7a8316706c8c7d5720b4a964ebb4aae5ff78fbec Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Tue, 10 Mar 2026 10:49:39 -0400 Subject: [PATCH] Tests: cover grapheme terminal width --- src/terminal/ansi.test.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/terminal/ansi.test.ts b/src/terminal/ansi.test.ts index 30ae4c82eb3..3970868d3f8 100644 --- a/src/terminal/ansi.test.ts +++ b/src/terminal/ansi.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { sanitizeForLog, stripAnsi } from "./ansi.js"; +import { sanitizeForLog, splitGraphemes, stripAnsi, visibleWidth } from "./ansi.js"; describe("terminal ansi helpers", () => { it("strips ANSI and OSC8 sequences", () => { @@ -11,4 +11,16 @@ describe("terminal ansi helpers", () => { 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); + }); });