mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-01 09:33:36 +00:00
test(shared): add unit tests for surrogate-safe UTF-16 string slicing helpers (#97805)
* test(shared): add unit tests for surrogate-safe UTF-16 string slicing helpers Add unit tests for sliceUtf16Safe and truncateUtf16Safe functions in src/shared/utf16-slice.ts to verify UTF-16 string slicing behavior. Tests cover: - sliceUtf16Safe slices ASCII string normally - sliceUtf16Safe handles negative start/end - sliceUtf16Safe handles start/end beyond length - sliceUtf16Safe swaps start and end when start > end - sliceUtf16Safe preserves emoji with surrogate pairs - sliceUtf16Safe avoids splitting surrogate pair at start/end - truncateUtf16Safe returns input when shorter than limit - truncateUtf16Safe truncates when longer than limit - truncateUtf16Safe handles zero/negative limit - truncateUtf16Safe floors decimal limit - truncateUtf16Safe preserves emoji with surrogate pairs - truncateUtf16Safe avoids splitting surrogate pair * fix: replace tautological surrogate assertions with exact output checks Replace vague 'result.length >= 0' assertions with exact expected output checks for surrogate pair boundary cases. The helper returns empty string when slicing at surrogate pair boundaries.
This commit is contained in:
88
src/shared/utf16-slice.test.ts
Normal file
88
src/shared/utf16-slice.test.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
// Tests for surrogate-safe UTF-16 string slicing helpers.
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { sliceUtf16Safe, truncateUtf16Safe } from "./utf16-slice.js";
|
||||
|
||||
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("swaps start and end when start > end", () => {
|
||||
expect(sliceUtf16Safe("hello", 3, 1)).toBe("el");
|
||||
});
|
||||
|
||||
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("preserves emoji with surrogate pairs", () => {
|
||||
const emoji = "👨👩👧👦";
|
||||
const result = truncateUtf16Safe(emoji, 10);
|
||||
// Should not return dangling surrogate
|
||||
expect(result.length).toBeLessThanOrEqual(emoji.length);
|
||||
});
|
||||
|
||||
it("returns empty string when truncating at surrogate pair boundary", () => {
|
||||
const input = "👨👩";
|
||||
expect(truncateUtf16Safe(input, 1)).toBe("");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user