Skip to content

Commit ed138d7

Browse files
committed
test(ui): tighten UTF-16 truncation coverage
1 parent b89a490 commit ed138d7

1 file changed

Lines changed: 14 additions & 65 deletions

File tree

ui/src/lib/format.test.ts

Lines changed: 14 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -274,81 +274,30 @@ describe("formatTokens", () => {
274274
});
275275
});
276276

277-
describe("clampText surrogate-safe truncation", () => {
278-
it("does not split an emoji across the truncation boundary", () => {
279-
// 121 UTF-16 units: 119 'a's then an emoji (surrogate pair at 119-120).
280-
// With max = 120, naive slice(0, 119) keeps only the emoji's high surrogate.
281-
const value = `${"a".repeat(119)}\u{1F600}`;
282-
expect(value.length).toBe(121);
283-
284-
const result = clampText(value, 120);
285-
286-
// The emoji should be entirely dropped, leaving the 119 'a's + "…"
287-
expect(result).toBe(`${"a".repeat(119)}…`);
288-
// No dangling surrogates
289-
for (let i = 0; i < result.length; i++) {
290-
const cu = result.charCodeAt(i);
291-
if (cu >= 0xd800 && cu <= 0xdbff) {
292-
expect(result.charCodeAt(i + 1) >= 0xdc00 && result.charCodeAt(i + 1) <= 0xdfff).toBe(true);
293-
}
294-
if (cu >= 0xdc00 && cu <= 0xdfff) {
295-
expect(
296-
i > 0 && result.charCodeAt(i - 1) >= 0xd800 && result.charCodeAt(i - 1) <= 0xdbff,
297-
).toBe(true);
298-
}
299-
}
277+
describe("text truncation", () => {
278+
it("keeps clampText output valid when the ellipsis boundary bisects an emoji", () => {
279+
expect(clampText(`${"a".repeat(118)}😀x`, 120)).toBe(`${"a".repeat(118)}…`);
300280
});
301281

302-
it("leaves short text unchanged", () => {
303-
expect(clampText("hello", 120)).toBe("hello");
304-
});
305-
306-
it("appends ellipsis when truncated", () => {
307-
expect(clampText("x".repeat(200), 120)).toMatch(/$/);
282+
it("keeps truncateText output valid when the boundary bisects an emoji", () => {
283+
expect(truncateText(`${"a".repeat(120)}😀`, 121)).toEqual({
284+
text: "a".repeat(120),
285+
truncated: true,
286+
total: 122,
287+
});
308288
});
309-
});
310289

311-
describe("truncateText surrogate-safe truncation", () => {
312-
it("does not split an emoji across the truncation boundary", () => {
313-
// 121 UTF-16 units: 120 'a's then an emoji at index 120.
314-
const value = `${"a".repeat(120)}\u{1F600}`;
315-
expect(value.length).toBe(122);
316-
317-
const result = truncateText(value, 121);
318-
319-
expect(result.truncated).toBe(true);
320-
// The emoji should be dropped entirely
321-
expect(result.text).not.toContain("\u{1F600}");
322-
// No dangling surrogates
323-
for (let i = 0; i < result.text.length; i++) {
324-
const cu = result.text.charCodeAt(i);
325-
if (cu >= 0xd800 && cu <= 0xdbff) {
326-
expect(
327-
result.text.charCodeAt(i + 1) >= 0xdc00 && result.text.charCodeAt(i + 1) <= 0xdfff,
328-
).toBe(true);
329-
}
330-
if (cu >= 0xdc00 && cu <= 0xdfff) {
331-
expect(
332-
i > 0 &&
333-
result.text.charCodeAt(i - 1) >= 0xd800 &&
334-
result.text.charCodeAt(i - 1) <= 0xdbff,
335-
).toBe(true);
336-
}
337-
}
338-
});
339-
340-
it("returns truncated: false for short text", () => {
290+
it("leaves short text unchanged", () => {
291+
expect(clampText("hello", 120)).toBe("hello");
341292
expect(truncateText("hello", 120)).toEqual({
342293
text: "hello",
343294
truncated: false,
344295
total: 5,
345296
});
346297
});
347298

348-
it("reports correct total for truncated text", () => {
349-
const result = truncateText("x".repeat(200), 120);
350-
expect(result.truncated).toBe(true);
351-
expect(result.total).toBe(200);
352-
expect(result.text.length).toBeLessThan(200);
299+
it("preserves ordinary truncation behavior", () => {
300+
expect(clampText("abc", 2)).toBe("a…");
301+
expect(truncateText("abc", 2)).toEqual({ text: "ab", truncated: true, total: 3 });
353302
});
354303
});

0 commit comments

Comments
 (0)