mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 20:05:46 -06:00
151 lines
4.3 KiB
TypeScript
151 lines
4.3 KiB
TypeScript
// Tests for surrogate-safe UTF-16 string slicing helpers.
|
|
import { describe, expect, it } from "vitest";
|
|
import {
|
|
avoidTrailingHighSurrogateBreak,
|
|
sliceUtf16Safe,
|
|
truncateUtf16Safe,
|
|
truncateWithMarker,
|
|
} from "./utf16-slice.js";
|
|
|
|
describe("avoidTrailingHighSurrogateBreak", () => {
|
|
it("keeps ordinary and terminal boundaries unchanged", () => {
|
|
expect(avoidTrailingHighSurrogateBreak("hello", 0, 3)).toBe(3);
|
|
expect(avoidTrailingHighSurrogateBreak("hello", 0, 5)).toBe(5);
|
|
});
|
|
|
|
it("moves a split before a surrogate pair when room remains", () => {
|
|
expect(avoidTrailingHighSurrogateBreak("a🤖b", 0, 2)).toBe(1);
|
|
});
|
|
|
|
it("includes the full pair when a one-unit chunk starts with it", () => {
|
|
expect(avoidTrailingHighSurrogateBreak("🤖b", 0, 1)).toBe(2);
|
|
});
|
|
});
|
|
|
|
describe("sliceUtf16Safe", () => {
|
|
it("slices ASCII string normally", () => {
|
|
expect(sliceUtf16Safe("hello world", 0, 5)).toBe("hello");
|
|
});
|
|
|
|
it("handles negative start", () => {
|
|
expect(sliceUtf16Safe("hello world", -5)).toBe("world");
|
|
});
|
|
|
|
it("handles negative end", () => {
|
|
expect(sliceUtf16Safe("hello world", 0, -6)).toBe("hello");
|
|
});
|
|
|
|
it("handles start beyond length", () => {
|
|
expect(sliceUtf16Safe("hello", 10)).toBe("");
|
|
});
|
|
|
|
it("handles end beyond length", () => {
|
|
expect(sliceUtf16Safe("hello", 0, 10)).toBe("hello");
|
|
});
|
|
|
|
it("returns empty when start > end, matching String.prototype.slice", () => {
|
|
expect(sliceUtf16Safe("hello", 3, 1)).toBe("");
|
|
});
|
|
|
|
it("preserves emoji with surrogate pairs", () => {
|
|
const emoji = "👨👩👧👦";
|
|
expect(sliceUtf16Safe(emoji, 0)).toBe(emoji);
|
|
});
|
|
|
|
it("returns empty string when slicing middle of surrogate pair", () => {
|
|
const input = "👨👩";
|
|
// Slicing at position 1-3 hits middle of surrogate pairs
|
|
expect(sliceUtf16Safe(input, 1, 3)).toBe("");
|
|
});
|
|
|
|
it("returns empty string when slicing at start of surrogate pair", () => {
|
|
const input = "👨👩";
|
|
// Slicing at position 0-1 would cut surrogate pair, adjust to 0
|
|
expect(sliceUtf16Safe(input, 0, 1)).toBe("");
|
|
});
|
|
|
|
it("handles empty string", () => {
|
|
expect(sliceUtf16Safe("", 0)).toBe("");
|
|
});
|
|
|
|
it("handles undefined end", () => {
|
|
expect(sliceUtf16Safe("hello", 2)).toBe("llo");
|
|
});
|
|
});
|
|
|
|
describe("truncateUtf16Safe", () => {
|
|
it("returns input when shorter than limit", () => {
|
|
expect(truncateUtf16Safe("hello", 10)).toBe("hello");
|
|
});
|
|
|
|
it("truncates when longer than limit", () => {
|
|
expect(truncateUtf16Safe("hello world", 5)).toBe("hello");
|
|
});
|
|
|
|
it("handles zero limit", () => {
|
|
expect(truncateUtf16Safe("hello", 0)).toBe("");
|
|
});
|
|
|
|
it("handles negative limit", () => {
|
|
expect(truncateUtf16Safe("hello", -1)).toBe("");
|
|
});
|
|
|
|
it("floors decimal limit", () => {
|
|
expect(truncateUtf16Safe("hello world", 5.7)).toBe("hello");
|
|
});
|
|
|
|
it("returns empty string when truncating at surrogate pair boundary", () => {
|
|
const input = "👨👩";
|
|
expect(truncateUtf16Safe(input, 1)).toBe("");
|
|
});
|
|
});
|
|
|
|
describe("truncateWithMarker", () => {
|
|
it.each([
|
|
{
|
|
name: "returns values at the boundary unchanged",
|
|
value: "hello",
|
|
max: 5,
|
|
options: { marker: "...", reserve: 3, trimEnd: false },
|
|
expected: "hello",
|
|
},
|
|
{
|
|
name: "reserves marker width",
|
|
value: "hello world",
|
|
max: 8,
|
|
options: { marker: "...", reserve: 3, trimEnd: false },
|
|
expected: "hello...",
|
|
},
|
|
{
|
|
name: "supports markers outside the limit",
|
|
value: "hello world",
|
|
max: 5,
|
|
options: { marker: "...", reserve: 0, trimEnd: false },
|
|
expected: "hello...",
|
|
},
|
|
{
|
|
name: "trims only the truncated prefix",
|
|
value: "hello world",
|
|
max: 9,
|
|
options: { marker: "...", reserve: 3, trimEnd: true },
|
|
expected: "hello...",
|
|
},
|
|
{
|
|
name: "keeps surrogate pairs well formed",
|
|
value: "ab🚀tail",
|
|
max: 4,
|
|
options: { marker: "…", reserve: 1, trimEnd: false },
|
|
expected: "ab…",
|
|
},
|
|
{
|
|
name: "preserves marker output at zero limits",
|
|
value: "hello",
|
|
max: 0,
|
|
options: { marker: "…", reserve: 1, trimEnd: false },
|
|
expected: "…",
|
|
},
|
|
] as const)("$name", ({ value, max, options, expected }) => {
|
|
expect(truncateWithMarker(value, max, options)).toBe(expected);
|
|
});
|
|
});
|