import { describe, expect, test } from "vitest"; import { absoluteTime, isoTime, relativeTime, shortId } from "../../src/lib/format"; /** A fixed "now" so these never depend on when they run. */ const NOW = Date.UTC(2024, 0, 15, 12, 0, 0); const seconds = (date: number) => Math.floor(date / 1000); describe("relativeTime", () => { test("reads as how long ago, since that is how commit dates are read", () => { expect(relativeTime(seconds(NOW) - 3 * 24 * 60 * 60, NOW)).toBe("3 days ago"); expect(relativeTime(seconds(NOW) - 2 * 60 * 60, NOW)).toBe("2 hours ago"); expect(relativeTime(seconds(NOW) - 90, NOW)).toBe("1 minute ago"); }); test("picks the largest unit that fits", () => { expect(relativeTime(seconds(NOW) - 400 * 24 * 60 * 60, NOW)).toContain("year"); expect(relativeTime(seconds(NOW) - 45 * 24 * 60 * 60, NOW)).toContain("month"); expect(relativeTime(seconds(NOW) - 10 * 24 * 60 * 60, NOW)).toContain("week"); }); test("falls back to seconds for something that just happened", () => { expect(relativeTime(seconds(NOW) - 5, NOW)).toContain("second"); }); test("handles a commit dated in the future rather than going strange", () => { // Clock skew puts commits ahead of now more often than you would think. expect(relativeTime(seconds(NOW) + 2 * 60 * 60, NOW)).toBe("in 2 hours"); }); }); describe("isoTime", () => { test("is machine readable, for the datetime attribute", () => { expect(isoTime(seconds(NOW))).toBe("2024-01-15T12:00:00.000Z"); }); }); describe("absoluteTime", () => { test("gives a full timestamp for the tooltip", () => { // Locale-dependent, so this checks it produced something with the date in // it rather than pinning a format the test machine may not use. const formatted = absoluteTime(seconds(NOW)); expect(formatted).toMatch(/2024/u); expect(formatted.length).toBeGreaterThan(8); }); }); describe("shortId", () => { test("abbreviates the way git does", () => { expect(shortId("0123456789abcdef0123456789abcdef01234567")).toBe("0123456"); }); });