


























@@ -76,16 +76,13 @@ describe("buildPeakErrorHours", () => {
76767777const result = buildPeakErrorHours([session], "utc");
787879-// All hours with errors should appear, sorted by error rate desc
80-expect(result.length).toBeGreaterThan(0);
81-expect(result.length).toBeLessThanOrEqual(5);
82-83-// The hours present should correspond to UTC hours 0, 1, 9, 23.
84-// formatHourLabel uses Date.setHours so labels depend on locale,
85-// but we can verify error rates and sub info.
86-const highestRate = result[0];
8779// hour 0: 5/10 = 50%, hour 23: 4/8 = 50%, hour 9: 3/15 = 20%, hour 1: 2/20 = 10%
88-expect(highestRate?.value).toMatch(/50\.00%/);
80+expect(result.map(({ value, sub }) => ({ value, sub }))).toStrictEqual([
81+{ value: "50.00%", sub: "5 errors · 10 msgs" },
82+{ value: "50.00%", sub: "4 errors · 8 msgs" },
83+{ value: "20.00%", sub: "3 errors · 15 msgs" },
84+{ value: "10.00%", sub: "2 errors · 20 msgs" },
85+]);
8986});
90879188it("aggregates multiple quarter-hour buckets into the same hour in UTC mode", () => {
@@ -99,8 +96,7 @@ describe("buildPeakErrorHours", () => {
9996expect(result.length).toBe(1);
10097// Aggregated: 5 errors / 15 total = 33.33%
10198expect(result[0].value).toBe("33.33%");
102-expect(result[0].sub).toContain("5 errors");
103-expect(result[0].sub).toContain("15 msgs");
99+expect(result[0].sub).toBe("5 errors · 15 msgs");
104100});
105101106102it("shifts UTC quarter-hour buckets to local timezone in local mode", () => {
@@ -119,10 +115,10 @@ describe("buildPeakErrorHours", () => {
119115const result = buildPeakErrorHours([session], "local");
120116expect(result.length).toBe(2);
121117122-// Verify the sub info matches aggregated values
123-const subs = result.map((r) => r.sub);
124-expect(subs).toContain("3 errors · 10 msgs"); // local hour 5
125-expect(subs).toContain("4 errors · 20 msgs"); // local hour 15
118+expect(result.map(({ value, sub }) => ({ value, sub }))).toStrictEqual([
119+ { value: "30.00%", sub: "3 errors · 10 msgs" }, // local hour 5
120+ { value: "20.00%", sub: "4 errors · 20 msgs" }, // local hour 15
121+]);
126122});
127123128124it("wraps correctly for negative local timezone (UTC-8)", () => {
@@ -139,8 +135,7 @@ describe("buildPeakErrorHours", () => {
139135const result = buildPeakErrorHours([session], "local");
140136expect(result.length).toBe(1);
141137expect(result[0].value).toBe("50.00%");
142-expect(result[0].sub).toContain("5 errors");
143-expect(result[0].sub).toContain("10 msgs");
138+expect(result[0].sub).toBe("5 errors · 10 msgs");
144139});
145140146141it("wraps correctly for positive local timezone near midnight (UTC+8, late quarter)", () => {
@@ -157,8 +152,7 @@ describe("buildPeakErrorHours", () => {
157152const result = buildPeakErrorHours([session], "local");
158153expect(result.length).toBe(1);
159154expect(result[0].value).toBe("50.00%");
160-expect(result[0].sub).toContain("6 errors");
161-expect(result[0].sub).toContain("12 msgs");
155+expect(result[0].sub).toBe("6 errors · 12 msgs");
162156});
163157164158it("returns empty array when no sessions have errors", () => {
@@ -207,10 +201,13 @@ describe("buildPeakErrorHours", () => {
207201expect(result.length).toBe(5);
208202209203// Should be sorted by rate descending — highest rate first
210-const rates = result.map((r) => Number.parseFloat(r.value));
211-for (let i = 1; i < rates.length; i++) {
212-expect(rates[i - 1]).toBeGreaterThanOrEqual(rates[i]);
213-}
204+expect(result.map((r) => r.value)).toStrictEqual([
205+"16.00%",
206+"14.00%",
207+"12.00%",
208+"10.00%",
209+"8.00%",
210+]);
214211});
215212216213it("aggregates across multiple sessions", () => {
@@ -225,8 +222,7 @@ describe("buildPeakErrorHours", () => {
225222expect(result.length).toBe(1);
226223// quarterIndex 20 → hour 5: aggregated 10 errors / 30 msgs = 33.33%
227224expect(result[0].value).toBe("33.33%");
228-expect(result[0].sub).toContain("10 errors");
229-expect(result[0].sub).toContain("30 msgs");
225+expect(result[0].sub).toBe("10 errors · 30 msgs");
230226});
231227232228it("falls back to proportional allocation when utcQuarterHourMessageCounts is absent", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。