Files
assistant-ui--assistant-ui/apps/docs/lib/assistant-analytics-helpers.test.ts
wehub-resource-sync e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:40:13 +08:00

80 lines
2.1 KiB
TypeScript

import { expect, it } from "vitest";
import {
consumeRunStartedAt,
getComposerMessageMetrics,
pruneStaleRunStarts,
queueMicrotaskSafe,
recordRunStartedAt,
} from "./assistant-analytics-helpers";
it("getComposerMessageMetrics returns undefined for empty composer", () => {
const metrics = getComposerMessageMetrics({
isEmpty: true,
text: "ignored",
attachments: [{}, {}],
});
expect(metrics).toBeUndefined();
});
it("getComposerMessageMetrics returns message and attachment sizes", () => {
const metrics = getComposerMessageMetrics({
isEmpty: false,
text: "Hello",
attachments: [{ id: "a" }, { id: "b" }],
});
expect(metrics).toEqual({
messageLength: 5,
attachmentsCount: 2,
});
});
it("getComposerMessageMetrics keeps attachment-only sends", () => {
const metrics = getComposerMessageMetrics({
isEmpty: false,
text: "",
attachments: [{ id: "attachment" }],
});
expect(metrics).toEqual({
messageLength: 0,
attachmentsCount: 1,
});
});
it("queueMicrotaskSafe reads state after synchronous updates", async () => {
let value = 1;
const captured = await new Promise<number>((resolve) => {
queueMicrotaskSafe(() => resolve(value));
value = 2;
});
expect(captured).toBe(2);
});
it("run-start tracking keeps separate start times per thread run", () => {
const runStarts = new Map<string, number[]>();
recordRunStartedAt(runStarts, "thread-1", 100);
recordRunStartedAt(runStarts, "thread-1", 200);
expect(consumeRunStartedAt(runStarts, "thread-1")).toBe(100);
expect(consumeRunStartedAt(runStarts, "thread-1")).toBe(200);
expect(consumeRunStartedAt(runStarts, "thread-1")).toBeUndefined();
});
it("run-start cleanup removes only stale entries", () => {
const runStarts = new Map<string, number[]>();
recordRunStartedAt(runStarts, "thread-1", 100);
recordRunStartedAt(runStarts, "thread-1", 300);
recordRunStartedAt(runStarts, "thread-2", 350);
pruneStaleRunStarts(runStarts, 400, 150);
expect(runStarts.get("thread-1")).toEqual([300]);
expect(runStarts.get("thread-2")).toEqual([350]);
});