mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 20:05:46 -06:00
0303af17f3
* test: remove low-value implementation assertions * test: refresh native i18n inventory
58 lines
2.1 KiB
TypeScript
58 lines
2.1 KiB
TypeScript
// Telegram tests cover plain-text chunk-splitting behavior.
|
|
import { describe, expect, it } from "vitest";
|
|
import { splitTelegramPlainTextChunks } from "./rich-plain-fallback.js";
|
|
|
|
function containsLoneSurrogate(text: string): boolean {
|
|
for (let index = 0; index < text.length; index += 1) {
|
|
const code = text.charCodeAt(index);
|
|
const isHigh = code >= 0xd800 && code <= 0xdbff;
|
|
const isLow = code >= 0xdc00 && code <= 0xdfff;
|
|
if (isHigh) {
|
|
const next = text.charCodeAt(index + 1);
|
|
if (!(next >= 0xdc00 && next <= 0xdfff)) {
|
|
return true;
|
|
}
|
|
index += 1;
|
|
} else if (isLow) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
describe("splitTelegramPlainTextChunks", () => {
|
|
it("does not split an astral char across the chunk boundary", () => {
|
|
// Emoji surrogate pair straddles index 10 (limit): high at 9, low at 10.
|
|
const input = `${"A".repeat(9)}😀${"B".repeat(20)}`;
|
|
const chunks = splitTelegramPlainTextChunks(input, 10);
|
|
expect(chunks.length).toBeGreaterThan(1);
|
|
expect(chunks.join("")).toBe(input);
|
|
for (const chunk of chunks) {
|
|
expect(containsLoneSurrogate(chunk)).toBe(false);
|
|
}
|
|
});
|
|
|
|
it("does not hang when limit=1 and text starts with an astral char", () => {
|
|
// Regression: with limit=1 the clamp would return start (no advance),
|
|
// causing the while-loop to spin forever. The surrogate pair must be
|
|
// emitted as a unit (2 code units) so the loop always advances.
|
|
const input = "😀X";
|
|
const chunks = splitTelegramPlainTextChunks(input, 1);
|
|
expect(chunks.join("")).toBe(input);
|
|
for (const chunk of chunks) {
|
|
expect(containsLoneSurrogate(chunk)).toBe(false);
|
|
}
|
|
});
|
|
|
|
it("does not hang when limit=1 and an astral char appears mid-string at a chunk boundary", () => {
|
|
// 'A' + emoji: with limit=1, second iteration starts at index 1 (high
|
|
// surrogate) — same stall condition as above, now mid-string.
|
|
const input = "A😀B";
|
|
const chunks = splitTelegramPlainTextChunks(input, 1);
|
|
expect(chunks.join("")).toBe(input);
|
|
for (const chunk of chunks) {
|
|
expect(containsLoneSurrogate(chunk)).toBe(false);
|
|
}
|
|
});
|
|
});
|