test: share tool stream event helpers

This commit is contained in:
Peter Steinberger
2026-04-20 22:39:07 +01:00
parent b33ce7a371
commit 171077037a

View File

@@ -2,6 +2,7 @@ import { beforeAll, describe, expect, it, vi } from "vitest";
import { handleAgentEvent, type FallbackStatus, type ToolStreamEntry } from "./app-tool-stream.ts";
type ToolStreamHost = Parameters<typeof handleAgentEvent>[0];
type AgentEvent = Parameters<typeof handleAgentEvent>[1];
type MutableHost = ToolStreamHost & {
compactionStatus?: unknown;
compactionClearTimer?: number | null;
@@ -28,6 +29,37 @@ function createHost(overrides?: Partial<MutableHost>): MutableHost {
};
}
function agentEvent(
runId: string,
seq: number,
stream: AgentEvent["stream"],
data: AgentEvent["data"],
sessionKey = "main",
): AgentEvent {
return {
runId,
seq,
stream,
ts: Date.now(),
sessionKey,
data,
};
}
function expectCompactionCompleteAndAutoClears(host: MutableHost) {
expect(host.compactionStatus).toEqual({
phase: "complete",
runId: "run-1",
startedAt: expect.any(Number),
completedAt: expect.any(Number),
});
expect(host.compactionClearTimer).not.toBeNull();
vi.advanceTimersByTime(5_000);
expect(host.compactionStatus).toBeNull();
expect(host.compactionClearTimer).toBeNull();
}
describe("app-tool-stream fallback lifecycle handling", () => {
beforeAll(() => {
const globalWithWindow = globalThis as typeof globalThis & {
@@ -146,14 +178,7 @@ describe("app-tool-stream fallback lifecycle handling", () => {
vi.useFakeTimers();
const host = createHost();
handleAgentEvent(host, {
runId: "run-1",
seq: 1,
stream: "compaction",
ts: Date.now(),
sessionKey: "main",
data: { phase: "start" },
});
handleAgentEvent(host, agentEvent("run-1", 1, "compaction", { phase: "start" }));
expect(host.compactionStatus).toEqual({
phase: "active",
@@ -162,14 +187,14 @@ describe("app-tool-stream fallback lifecycle handling", () => {
completedAt: null,
});
handleAgentEvent(host, {
runId: "run-1",
seq: 2,
stream: "compaction",
ts: Date.now(),
sessionKey: "main",
data: { phase: "end", willRetry: true, completed: true },
});
handleAgentEvent(
host,
agentEvent("run-1", 2, "compaction", {
phase: "end",
willRetry: true,
completed: true,
}),
);
expect(host.compactionStatus).toEqual({
phase: "retrying",
@@ -179,14 +204,7 @@ describe("app-tool-stream fallback lifecycle handling", () => {
});
expect(host.compactionClearTimer).toBeNull();
handleAgentEvent(host, {
runId: "run-2",
seq: 3,
stream: "lifecycle",
ts: Date.now(),
sessionKey: "main",
data: { phase: "end" },
});
handleAgentEvent(host, agentEvent("run-2", 3, "lifecycle", { phase: "end" }));
expect(host.compactionStatus).toEqual({
phase: "retrying",
@@ -195,26 +213,9 @@ describe("app-tool-stream fallback lifecycle handling", () => {
completedAt: null,
});
handleAgentEvent(host, {
runId: "run-1",
seq: 4,
stream: "lifecycle",
ts: Date.now(),
sessionKey: "main",
data: { phase: "end" },
});
handleAgentEvent(host, agentEvent("run-1", 4, "lifecycle", { phase: "end" }));
expect(host.compactionStatus).toEqual({
phase: "complete",
runId: "run-1",
startedAt: expect.any(Number),
completedAt: expect.any(Number),
});
expect(host.compactionClearTimer).not.toBeNull();
vi.advanceTimersByTime(5_000);
expect(host.compactionStatus).toBeNull();
expect(host.compactionClearTimer).toBeNull();
expectCompactionCompleteAndAutoClears(host);
vi.useRealTimers();
});
@@ -223,23 +224,16 @@ describe("app-tool-stream fallback lifecycle handling", () => {
vi.useFakeTimers();
const host = createHost();
handleAgentEvent(host, {
runId: "run-1",
seq: 1,
stream: "compaction",
ts: Date.now(),
sessionKey: "main",
data: { phase: "start" },
});
handleAgentEvent(host, agentEvent("run-1", 1, "compaction", { phase: "start" }));
handleAgentEvent(host, {
runId: "run-1",
seq: 2,
stream: "compaction",
ts: Date.now(),
sessionKey: "main",
data: { phase: "end", willRetry: true, completed: true },
});
handleAgentEvent(
host,
agentEvent("run-1", 2, "compaction", {
phase: "end",
willRetry: true,
completed: true,
}),
);
expect(host.compactionStatus).toEqual({
phase: "retrying",
@@ -248,26 +242,9 @@ describe("app-tool-stream fallback lifecycle handling", () => {
completedAt: null,
});
handleAgentEvent(host, {
runId: "run-1",
seq: 3,
stream: "lifecycle",
ts: Date.now(),
sessionKey: "main",
data: { phase: "error", error: "boom" },
});
handleAgentEvent(host, agentEvent("run-1", 3, "lifecycle", { phase: "error", error: "boom" }));
expect(host.compactionStatus).toEqual({
phase: "complete",
runId: "run-1",
startedAt: expect.any(Number),
completedAt: expect.any(Number),
});
expect(host.compactionClearTimer).not.toBeNull();
vi.advanceTimersByTime(5_000);
expect(host.compactionStatus).toBeNull();
expect(host.compactionClearTimer).toBeNull();
expectCompactionCompleteAndAutoClears(host);
vi.useRealTimers();
});
@@ -276,35 +253,21 @@ describe("app-tool-stream fallback lifecycle handling", () => {
vi.useFakeTimers();
const host = createHost();
handleAgentEvent(host, {
runId: "run-1",
seq: 1,
stream: "compaction",
ts: Date.now(),
sessionKey: "main",
data: { phase: "start" },
});
handleAgentEvent(host, agentEvent("run-1", 1, "compaction", { phase: "start" }));
handleAgentEvent(host, {
runId: "run-1",
seq: 2,
stream: "compaction",
ts: Date.now(),
sessionKey: "main",
data: { phase: "end", willRetry: true, completed: false },
});
handleAgentEvent(
host,
agentEvent("run-1", 2, "compaction", {
phase: "end",
willRetry: true,
completed: false,
}),
);
expect(host.compactionStatus).toBeNull();
expect(host.compactionClearTimer).toBeNull();
handleAgentEvent(host, {
runId: "run-1",
seq: 3,
stream: "lifecycle",
ts: Date.now(),
sessionKey: "main",
data: { phase: "error", error: "boom" },
});
handleAgentEvent(host, agentEvent("run-1", 3, "lifecycle", { phase: "error", error: "boom" }));
expect(host.compactionStatus).toBeNull();
expect(host.compactionClearTimer).toBeNull();