mirror of
https://github.com/ZHANGTIANYAO1/teamspeak-music-bot.git
synced 2026-10-02 04:52:50 +08:00
68 lines
2.4 KiB
TypeScript
68 lines
2.4 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { splitTextIntoChunks } from "./text-chunk.js";
|
|
|
|
const bytes = (s: string) => Buffer.byteLength(s, "utf8");
|
|
|
|
describe("splitTextIntoChunks", () => {
|
|
it("returns a single chunk for a short string", () => {
|
|
const chunks = splitTextIntoChunks("hello world", 900);
|
|
expect(chunks).toEqual(["hello world"]);
|
|
});
|
|
|
|
it("splits a multi-line string longer than maxBytes into multiple chunks on line boundaries", () => {
|
|
const lines = Array.from({ length: 50 }, (_, i) => `line number ${i}`);
|
|
const text = lines.join("\n");
|
|
const chunks = splitTextIntoChunks(text, 60);
|
|
|
|
expect(chunks.length).toBeGreaterThan(1);
|
|
for (const c of chunks) {
|
|
expect(bytes(c)).toBeLessThanOrEqual(60);
|
|
}
|
|
// No hard-split of any line occurred, so rejoining with "\n" is lossless.
|
|
expect(chunks.join("\n")).toBe(text);
|
|
});
|
|
|
|
it("bounds by BYTES not chars: multibyte (Chinese) content stays under the cap", () => {
|
|
// Each Chinese char is 3 bytes in UTF-8. 40 chars/line = 120 bytes/line.
|
|
const lines = Array.from({ length: 10 }, () => "歌词".repeat(20));
|
|
const text = lines.join("\n");
|
|
const chunks = splitTextIntoChunks(text, 150);
|
|
|
|
expect(chunks.length).toBeGreaterThan(1);
|
|
for (const c of chunks) {
|
|
expect(bytes(c)).toBeLessThanOrEqual(150);
|
|
}
|
|
expect(chunks.join("\n")).toBe(text);
|
|
});
|
|
|
|
it("hard-splits a single over-long line so no chunk exceeds the cap", () => {
|
|
const longLine = "a".repeat(500);
|
|
const chunks = splitTextIntoChunks(longLine, 100);
|
|
|
|
expect(chunks.length).toBeGreaterThan(1);
|
|
for (const c of chunks) {
|
|
expect(bytes(c)).toBeLessThanOrEqual(100);
|
|
}
|
|
// Content is preserved (hard-split introduces split points, not \n).
|
|
expect(chunks.join("")).toBe(longLine);
|
|
});
|
|
|
|
it("never splits a multibyte character across a hard-split boundary", () => {
|
|
// 200 Chinese chars = 600 bytes on ONE line, cap 40 bytes.
|
|
const longLine = "歌".repeat(200);
|
|
const chunks = splitTextIntoChunks(longLine, 40);
|
|
|
|
for (const c of chunks) {
|
|
expect(bytes(c)).toBeLessThanOrEqual(40);
|
|
// A clean re-decode: every chunk is valid UTF-8 with no replacement char.
|
|
expect(c.includes("�")).toBe(false);
|
|
}
|
|
expect(chunks.join("")).toBe(longLine);
|
|
});
|
|
|
|
it("preserves blank lines within a single chunk", () => {
|
|
const text = "a\n\nb";
|
|
expect(splitTextIntoChunks(text, 900)).toEqual([text]);
|
|
});
|
|
});
|