openskynet / src /tui /components /chat-log.test.ts
Darochin's picture
Mirror OpenSkyNet workspace snapshot from Git HEAD
fc93158 verified
import { describe, expect, it } from "vitest";
import { ChatLog } from "./chat-log.js";
describe("ChatLog", () => {
it("caps component growth to avoid unbounded render trees", () => {
const chatLog = new ChatLog(20);
for (let i = 1; i <= 40; i++) {
chatLog.addSystem(`system-${i}`);
}
expect(chatLog.children.length).toBe(20);
const rendered = chatLog.render(120).join("\n");
expect(rendered).toContain("system-40");
expect(rendered).not.toContain("system-1");
});
it("drops stale streaming references when old components are pruned", () => {
const chatLog = new ChatLog(20);
chatLog.startAssistant("first", "run-1");
for (let i = 0; i < 25; i++) {
chatLog.addSystem(`overflow-${i}`);
}
// Should not throw if the original streaming component was pruned.
chatLog.updateAssistant("recreated", "run-1");
const rendered = chatLog.render(120).join("\n");
expect(chatLog.children.length).toBe(20);
expect(rendered).toContain("recreated");
});
it("does not append duplicate assistant components when a run is started twice", () => {
const chatLog = new ChatLog(40);
chatLog.startAssistant("first", "run-dup");
chatLog.startAssistant("second", "run-dup");
const rendered = chatLog.render(120).join("\n");
expect(rendered).toContain("second");
expect(rendered).not.toContain("first");
expect(chatLog.children.length).toBe(1);
});
it("drops stale tool references when old components are pruned", () => {
const chatLog = new ChatLog(20);
chatLog.startTool("tool-1", "read_file", { path: "a.txt" });
for (let i = 0; i < 25; i++) {
chatLog.addSystem(`overflow-${i}`);
}
// Should no-op safely after the tool component is pruned.
chatLog.updateToolResult("tool-1", { content: [{ type: "text", text: "done" }] });
expect(chatLog.children.length).toBe(20);
});
});