Spaces:
Running
Running
File size: 3,167 Bytes
6c3af4e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | import { describe, expect, it } from "vitest";
import { buildActivity, intensityLevel } from "./searchActivity";
/** Local timestamp for a given calendar day (noon avoids DST edges). */
const at = (year: number, month1: number, day: number, hour = 12) =>
new Date(year, month1 - 1, day, hour).getTime();
const NOW = at(2026, 7, 8); // Wed, 8 Jul 2026, local noon
describe("intensityLevel", () => {
it("returns 0 for empty days or an empty window", () => {
expect(intensityLevel(0, 6)).toBe(0);
expect(intensityLevel(3, 0)).toBe(0);
});
it("scales 1-4 relative to the busiest day", () => {
expect(intensityLevel(1, 6)).toBe(1);
expect(intensityLevel(6, 6)).toBe(4);
expect(intensityLevel(3, 6)).toBe(2);
});
});
describe("buildActivity", () => {
const timestamps = [
at(2026, 7, 8),
at(2026, 7, 8), // today: 2
at(2026, 7, 7), // 1
at(2026, 7, 6), // 1
at(2026, 7, 5), // 1
at(2026, 7, 3),
at(2026, 7, 3),
at(2026, 7, 3), // 3
at(2026, 7, 2), // 1
at(2026, 6, 28), // 6 -> six entries below
at(2026, 6, 28),
at(2026, 6, 28),
at(2026, 6, 28),
at(2026, 6, 28),
at(2026, 6, 28),
];
it("clamps a short span up to the minimum window and squares off weeks", () => {
const data = buildActivity(timestamps, NOW);
expect(data.weeks).toBe(12);
expect(data.columns).toHaveLength(12);
for (const column of data.columns) {
expect(column).toHaveLength(7);
}
});
it("buckets searches onto the correct local day", () => {
const data = buildActivity(timestamps, NOW);
const cells = data.columns.flat();
expect(cells.find((c) => c.date === "2026-07-08")?.count).toBe(2);
expect(cells.find((c) => c.date === "2026-06-28")?.count).toBe(6);
expect(cells.find((c) => c.date === "2026-07-04")?.count).toBe(0);
});
it("computes streaks, active days, and the busiest day", () => {
const { stats } = buildActivity(timestamps, NOW);
expect(stats.currentStreak).toBe(4); // Jul 5,6,7,8
expect(stats.longestStreak).toBe(4);
expect(stats.daysActive).toBe(7);
expect(stats.busiestCount).toBe(6);
expect(stats.total).toBe(15);
});
it("marks days after today as future filler, not zero activity", () => {
const data = buildActivity(timestamps, NOW);
const future = data.columns.flat().filter((c) => c.future);
expect(future.every((c) => c.count === 0)).toBe(true);
// Wed 8 Jul -> Thu/Fri/Sat remain in the trailing week.
expect(future).toHaveLength(3);
});
it("labels the month only when it changes across columns", () => {
const data = buildActivity(timestamps, NOW);
const labels = data.monthLabels.filter(Boolean);
expect(labels).toContain("Jul");
// No month name repeats in consecutive labelled columns.
expect(new Set(labels).size).toBe(labels.length);
});
it("returns an empty-but-valid grid with no searches", () => {
const data = buildActivity([], NOW);
expect(data.weeks).toBe(12);
expect(data.maxCount).toBe(0);
expect(data.stats.currentStreak).toBe(0);
expect(data.columns.flat().every((c) => c.count === 0)).toBe(true);
});
});
|