
























@@ -10,6 +10,15 @@ import {
1010type DiagnosticStabilitySnapshot,
1111} from "./diagnostic-stability.js";
121213+function expectFields(value: unknown, expected: Record<string, unknown>): void {
14+expect(value).toBeTypeOf("object");
15+expect(value).not.toBeNull();
16+const record = value as Record<string, unknown>;
17+for (const [key, expectedValue] of Object.entries(expected)) {
18+expect(record[key], key).toEqual(expectedValue);
19+}
20+}
21+1322describe("diagnostic stability recorder", () => {
1423beforeEach(() => {
1524resetDiagnosticStabilityRecorderForTest();
@@ -60,18 +69,18 @@ describe("diagnostic stability recorder", () => {
6069const snapshot = getDiagnosticStabilitySnapshot({ limit: 10 });
61706271expect(snapshot.count).toBe(3);
63-expect(snapshot.summary.byType).toMatchObject({
72+expectFields(snapshot.summary.byType, {
6473"webhook.error": 1,
6574"tool.loop": 1,
6675"talk.event": 1,
6776});
68-expect(snapshot.events[0]).toMatchObject({
77+expectFields(snapshot.events[0], {
6978type: "webhook.error",
7079channel: "telegram",
7180});
7281expect(snapshot.events[0]).not.toHaveProperty("error");
7382expect(snapshot.events[0]).not.toHaveProperty("chatId");
74-expect(snapshot.events[1]).toMatchObject({
83+expectFields(snapshot.events[1], {
7584type: "tool.loop",
7685toolName: "poll",
7786level: "warning",
@@ -82,7 +91,7 @@ describe("diagnostic stability recorder", () => {
8291expect(snapshot.events[1]).not.toHaveProperty("message");
8392expect(snapshot.events[1]).not.toHaveProperty("sessionId");
8493expect(snapshot.events[1]).not.toHaveProperty("sessionKey");
85-expect(snapshot.events[2]).toMatchObject({
94+expectFields(snapshot.events[2], {
8695type: "talk.event",
8796talkEventType: "latency.metrics",
8897mode: "realtime",
@@ -116,11 +125,11 @@ describe("diagnostic stability recorder", () => {
116125117126const snapshot = getDiagnosticStabilitySnapshot({ limit: 10 });
118127119-expect(snapshot.events[0]).toMatchObject({
128+expectFields(snapshot.events[0], {
120129type: "payload.large",
121130reason: "json_body_limit",
122131});
123-expect(snapshot.events[1]).toMatchObject({
132+expectFields(snapshot.events[1], {
124133type: "message.processed",
125134outcome: "error",
126135});
@@ -152,7 +161,7 @@ describe("diagnostic stability recorder", () => {
152161153162const snapshot = getDiagnosticStabilitySnapshot({ limit: 10 });
154163155-expect(snapshot.events[0]).toMatchObject({
164+expectFields(snapshot.events[0], {
156165type: "context.assembled",
157166provider: "openai",
158167model: "gpt-5.4",
@@ -199,12 +208,12 @@ describe("diagnostic stability recorder", () => {
199208200209const snapshot = getDiagnosticStabilitySnapshot({ limit: 10 });
201210202-expect(snapshot.events[0]).toMatchObject({
211+expectFields(snapshot.events[0], {
203212type: "tool.execution.error",
204213toolName: "read",
205214});
206215expect(snapshot.events[0]).not.toHaveProperty("reason");
207-expect(snapshot.events[1]).toMatchObject({
216+expectFields(snapshot.events[1], {
208217type: "model.call.error",
209218provider: "openai",
210219model: "gpt-5.4",
@@ -262,15 +271,15 @@ describe("diagnostic stability recorder", () => {
262271263272const snapshot = getDiagnosticStabilitySnapshot();
264273265-expect(snapshot.summary.memory).toMatchObject({
266-latest: {
267-rssBytes: 120,
268-heapUsedBytes: 50,
269-},
274+expectFields(snapshot.summary.memory, {
270275maxRssBytes: 120,
271276maxHeapUsedBytes: 50,
272277pressureCount: 1,
273278});
279+expectFields(snapshot.summary.memory?.latest, {
280+rssBytes: 120,
281+heapUsedBytes: 50,
282+});
274283expect(snapshot.summary.payloadLarge).toEqual({
275284count: 1,
276285rejected: 1,
@@ -300,7 +309,7 @@ describe("diagnostic stability recorder", () => {
300309expect(snapshot.dropped).toBe(5);
301310expect(snapshot.firstSeq).toBe(6);
302311expect(snapshot.lastSeq).toBe(1005);
303-expect(snapshot.events[0]).toMatchObject({ seq: 6, queueDepth: 5 });
312+expectFields(snapshot.events[0], { seq: 6, queueDepth: 5 });
304313});
305314306315it("filters snapshots by type, sequence, and limit", () => {
@@ -317,13 +326,12 @@ describe("diagnostic stability recorder", () => {
317326});
318327319328expect(snapshot.count).toBe(1);
320-expect(snapshot.events).toMatchObject([
321-{
322-seq: 3,
323-type: "payload.large",
324-action: "chunked",
325-},
326-]);
329+expect(snapshot.events).toHaveLength(1);
330+expectFields(snapshot.events[0], {
331+seq: 3,
332+type: "payload.large",
333+action: "chunked",
334+});
327335});
328336329337it("applies query filters to persisted snapshots without mutating the source", () => {
@@ -352,21 +360,24 @@ describe("diagnostic stability recorder", () => {
352360limit: 1,
353361});
354362355-expect(selected).toMatchObject({
363+expectFields(selected, {
356364count: 2,
357365firstSeq: 2,
358366lastSeq: 3,
359-events: [{ seq: 3, type: "payload.large", action: "chunked" }],
360-summary: {
361-byType: {
362-"payload.large": 2,
363-},
364-payloadLarge: {
365-count: 2,
366-rejected: 1,
367-chunked: 1,
368-},
369-},
367+});
368+expect(selected.events).toHaveLength(1);
369+expectFields(selected.events[0], {
370+seq: 3,
371+type: "payload.large",
372+action: "chunked",
373+});
374+expectFields(selected.summary.byType, {
375+"payload.large": 2,
376+});
377+expectFields(selected.summary.payloadLarge, {
378+count: 2,
379+rejected: 1,
380+chunked: 1,
370381});
371382expect(snapshot.events).toHaveLength(3);
372383});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。