Files
fusion/packages/dashboard/app/hooks/__tests__/createChatStreamHandlers.test.ts
Fusion (runfusion.ai) 25bc5d3a18 test(FN-4835): broaden chunk-boundary whitespace regressions
Fusion-Task-Id: FN-4835
Fusion-Task-Lineage: 09eb6339-a476-4cf1-b7e5-e60fa6c263ce
2026-05-17 00:14:59 -07:00

66 lines
1.7 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { createChatStreamHandlers } from "../createChatStreamHandlers";
describe("createChatStreamHandlers", () => {
it.each([
{
name: "empty delta sandwiched between spaced chunks",
chunks: ["Hello.", "", " World."],
expected: "Hello. World.",
},
{
name: "multiple sentence boundaries across four chunks",
chunks: ["One.", " Two.", " Three.", " Four."],
expected: "One. Two. Three. Four.",
},
{
name: "whitespace-only final delta immediately before done",
chunks: ["Trailing", " "],
expected: "Trailing ",
},
])("preserves whitespace across streamed text deltas (%s)", ({ chunks, expected }) => {
vi.useFakeTimers();
let text = "";
const onDone = vi.fn();
const onError = vi.fn();
const cancelStreamingFlushesRef = { current: null } as { current: (() => void) | null };
const { handlers } = createChatStreamHandlers({
sessionId: "s-1",
tempUserMessageId: "temp-1",
setStreamingText: (value) => {
text = typeof value === "function" ? value(text) : value;
},
setStreamingThinking: vi.fn(),
setStreamingToolCalls: vi.fn(),
cancelStreamingFlushesRef,
onDone,
onError,
});
for (const chunk of chunks) {
handlers.onText(chunk);
}
vi.advanceTimersToNextTimer();
expect(text).toBe(expected);
handlers.onDone({ messageId: "m-1" });
expect(onDone).toHaveBeenCalledWith({
messageId: "m-1",
message: undefined,
accumulated: {
text: expected,
thinking: "",
toolCalls: [],
fallbackInfo: undefined,
},
});
expect(onError).not.toHaveBeenCalled();
vi.useRealTimers();
});
});