feat(web): api client and display formatters
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0a540208e1
commit
0bb871cd19
4 files changed
+604
No files matched your search
@@ -0,0 +1,68 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { formatDateRange, formatPartialDate, formatRating, parsePartialDate, rollupLabel } from "../src/format.ts";
|
||||
|
||||
describe("formatRating", () => {
|
||||
test("5 stars with halves", () => {
|
||||
expect(formatRating(90, "5half")).toBe("★★★★½");
|
||||
expect(formatRating(100, "5half")).toBe("★★★★★");
|
||||
expect(formatRating(80, "5half")).toBe("★★★★☆");
|
||||
expect(formatRating(0, "5half")).toBe("☆☆☆☆☆");
|
||||
});
|
||||
test("null is empty on every scale", () => {
|
||||
expect(formatRating(null, "5half")).toBe("");
|
||||
expect(formatRating(null, "10")).toBe("");
|
||||
expect(formatRating(undefined, "100")).toBe("");
|
||||
});
|
||||
test("whole stars, 10 and 100 point scales", () => {
|
||||
expect(formatRating(90, "5")).toBe("★★★★★");
|
||||
expect(formatRating(70, "5")).toBe("★★★★☆");
|
||||
expect(formatRating(90, "10")).toBe("9/10");
|
||||
expect(formatRating(85, "10")).toBe("8.5/10");
|
||||
expect(formatRating(73, "100")).toBe("73/100");
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatPartialDate", () => {
|
||||
test("renders by precision", () => {
|
||||
expect(formatPartialDate({ value: "2025-03", precision: "month" })).toBe("Mar 2025");
|
||||
expect(formatPartialDate({ value: "2019", precision: "year" })).toBe("2019");
|
||||
expect(formatPartialDate({ value: "2026-09-14", precision: "day" })).toBe("14 Sep 2026");
|
||||
expect(formatPartialDate({ value: "2026-09-04T23:30:00-05:00", precision: "day" })).toBe("4 Sep 2026");
|
||||
expect(formatPartialDate({ value: "", precision: "unknown" })).toBe("");
|
||||
expect(formatPartialDate(null)).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatDateRange", () => {
|
||||
test("flags dates that are not exact", () => {
|
||||
expect(formatDateRange(null, { value: "2025-03", precision: "month" })).toBe("Mar 2025 (no exact date)");
|
||||
expect(formatDateRange({ value: "2026-09-02", precision: "day" }, { value: "2026-09-14", precision: "day" })).toBe(
|
||||
"2 Sep – 14 Sep 2026",
|
||||
);
|
||||
expect(formatDateRange({ value: "2025-12-30", precision: "day" }, { value: "2026-01-02", precision: "day" })).toBe(
|
||||
"30 Dec 2025 – 2 Jan 2026",
|
||||
);
|
||||
expect(formatDateRange({ value: "2026-09-02", precision: "day" }, null)).toBe("Started 2 Sep 2026");
|
||||
expect(formatDateRange(null, null)).toBe("No dates");
|
||||
});
|
||||
});
|
||||
|
||||
describe("parsePartialDate", () => {
|
||||
test("accepts year, month and day, rejects the rest", () => {
|
||||
expect(parsePartialDate("2019")).toEqual({ value: "2019", precision: "year" });
|
||||
expect(parsePartialDate(" 2025-03 ")).toEqual({ value: "2025-03", precision: "month" });
|
||||
expect(parsePartialDate("2024-02-29")).toEqual({ value: "2024-02-29", precision: "day" });
|
||||
expect(parsePartialDate("2023-02-29")).toBeNull();
|
||||
expect(parsePartialDate("03/04/2019")).toBeNull();
|
||||
expect(parsePartialDate("")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("rollupLabel", () => {
|
||||
test("children roll up as 'season 3 of 5'", () => {
|
||||
expect(rollupLabel("show", { total: 5, completed: 3 })).toBe("season 3 of 5");
|
||||
expect(rollupLabel("show", { total: 5, completed: 0 })).toBe("5 seasons");
|
||||
expect(rollupLabel("podcast", { total: 200, completed: 200 })).toBe("all 200 episodes");
|
||||
expect(rollupLabel("book", null)).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user