WIP! A BB-style forum, on the ATmosphere!
We're still working... we'll be back soon when we have something to show off!
node
typescript
hono
htmx
atproto
1import { describe, it, expect, vi, afterEach } from "vitest";
2import { timeAgo } from "../time.js";
3
4describe("timeAgo", () => {
5 afterEach(() => {
6 vi.useRealTimers();
7 });
8
9 function setNow(iso: string) {
10 vi.useFakeTimers();
11 vi.setSystemTime(new Date(iso));
12 }
13
14 it("returns 'just now' for under 60 seconds", () => {
15 setNow("2026-01-01T12:00:30Z");
16 expect(timeAgo(new Date("2026-01-01T12:00:00Z"))).toBe("just now");
17 });
18
19 it("returns '1 minute ago' (singular)", () => {
20 setNow("2026-01-01T12:01:00Z");
21 expect(timeAgo(new Date("2026-01-01T12:00:00Z"))).toBe("1 minute ago");
22 });
23
24 it("returns 'N minutes ago' for under 60 minutes", () => {
25 setNow("2026-01-01T12:05:00Z");
26 expect(timeAgo(new Date("2026-01-01T12:00:00Z"))).toBe("5 minutes ago");
27 });
28
29 it("returns '1 hour ago' (singular)", () => {
30 setNow("2026-01-01T13:00:00Z");
31 expect(timeAgo(new Date("2026-01-01T12:00:00Z"))).toBe("1 hour ago");
32 });
33
34 it("returns 'N hours ago' for under 24 hours", () => {
35 setNow("2026-01-01T15:00:00Z");
36 expect(timeAgo(new Date("2026-01-01T12:00:00Z"))).toBe("3 hours ago");
37 });
38
39 it("returns '1 day ago' (singular)", () => {
40 setNow("2026-01-02T12:00:00Z");
41 expect(timeAgo(new Date("2026-01-01T12:00:00Z"))).toBe("1 day ago");
42 });
43
44 it("returns 'N days ago' for under 30 days", () => {
45 setNow("2026-01-08T12:00:00Z");
46 expect(timeAgo(new Date("2026-01-01T12:00:00Z"))).toBe("7 days ago");
47 });
48
49 it("returns ISO date (YYYY-MM-DD) for 30+ days old", () => {
50 setNow("2026-02-01T12:00:00Z");
51 expect(timeAgo(new Date("2026-01-01T12:00:00Z"))).toBe("2026-01-01");
52 });
53});