test/shared/dates-labels.test.ts
Rama main · réplica de lectura del repositorio original.
import { assertArrayIncludes } from "@std/assert";
import { expect } from "@std/expect";
import { describe, it as test } from "@std/testing/bdd";
import {
calendarGridDates,
formatDateLabel,
formatDateRangeLabel,
formatDateRangeLabelCompactEn,
formatMonthLabel,
monthsAround,
shiftMonth,
} from "#shared/date-labels.ts";
import { DAY_NAMES } from "#shared/day-names.ts";
import { useSetting } from "#test-utils/settings.ts";
describe("dates", () => {
useSetting({ timezone: "UTC" });
describe("shiftMonth", () => {
test("advances to the next month", () => {
expect(shiftMonth("2026-07", 1)).toBe("2026-08");
});
test("steps back to the previous month", () => {
expect(shiftMonth("2026-07", -1)).toBe("2026-06");
});
test("crosses the year boundary forward", () => {
expect(shiftMonth("2026-12", 1)).toBe("2027-01");
});
test("crosses the year boundary backward", () => {
expect(shiftMonth("2026-01", -1)).toBe("2025-12");
});
test("shifts by several months at once", () => {
expect(shiftMonth("2026-07", 6)).toBe("2027-01");
});
});
describe("formatMonthLabel", () => {
test("formats a mid-year month", () => {
expect(formatMonthLabel("2026-07")).toBe("July 2026");
});
test("formats January", () => {
expect(formatMonthLabel("2026-01")).toBe("January 2026");
});
test("formats December", () => {
expect(formatMonthLabel("2026-12")).toBe("December 2026");
});
});
describe("monthsAround", () => {
test("spans the requested years either side of the month's year", () => {
const months = monthsAround("2026-03", 5);
expect(months[0]).toBe("2021-01");
expect(months[months.length - 1]).toBe("2031-12");
});
test("returns twelve months for every year in range", () => {
expect(monthsAround("2026-03", 5)).toHaveLength(11 * 12);
});
test("centres on the year, ignoring the month part", () => {
expect(monthsAround("2026-12", 1)).toEqual(monthsAround("2026-01", 1));
});
test("includes the centre month itself", () => {
assertArrayIncludes(monthsAround("2026-03", 5), ["2026-03"]);
});
});
describe("calendarGridDates", () => {
test("starts on the Monday a full week before the month's first week", () => {
// 1 March 2026 is a Sunday; its Monday is 23 Feb, minus one week = 16 Feb.
expect(calendarGridDates("2026-03")[0]).toBe("2026-02-16");
});
test("ends on the Sunday a full week after the month's last week", () => {
const grid = calendarGridDates("2026-03");
expect(grid[grid.length - 1]).toBe("2026-04-12");
});
test("always spans whole weeks", () => {
expect(calendarGridDates("2026-03").length % 7).toBe(0);
expect(calendarGridDates("2026-07").length % 7).toBe(0);
expect(calendarGridDates("2024-02").length % 7).toBe(0);
});
test("begins on a Monday and ends on a Sunday", () => {
const grid = calendarGridDates("2026-07");
expect(DAY_NAMES[new Date(`${grid[0]}T00:00:00Z`).getUTCDay()]).toBe(
"Monday",
);
expect(
DAY_NAMES[new Date(`${grid[grid.length - 1]}T00:00:00Z`).getUTCDay()],
).toBe("Sunday");
});
test("includes every day of the target month", () => {
const grid = calendarGridDates("2026-07");
assertArrayIncludes(grid, ["2026-07-01"]);
assertArrayIncludes(grid, ["2026-07-31"]);
});
test("includes the leap day in a leap February", () => {
assertArrayIncludes(calendarGridDates("2024-02"), ["2024-02-29"]);
});
});
describe("formatDateLabel", () => {
test("formats a Monday date", () => {
// 2026-02-09 is a Monday
expect(formatDateLabel("2026-02-09")).toBe("Monday 9 February 2026");
});
test("formats a Saturday date", () => {
// 2026-02-14 is a Saturday
expect(formatDateLabel("2026-02-14")).toBe("Saturday 14 February 2026");
});
test("formats a Sunday date", () => {
// 2026-02-15 is a Sunday
expect(formatDateLabel("2026-02-15")).toBe("Sunday 15 February 2026");
});
test("formats dates across different months", () => {
// 2026-12-25 is a Friday
expect(formatDateLabel("2026-12-25")).toBe("Friday 25 December 2026");
});
});
describe("formatDateRangeLabelCompactEn", () => {
const cases: [label: string, start: string, end: string, out: string][] = [
["same day", "2027-02-02", "2027-02-02", "2 February 2027"],
["same month + year", "2027-02-02", "2027-02-03", "2–3 February 2027"],
[
"cross-month, same year",
"2027-02-02",
"2027-03-03",
"2 February – 3 March 2027",
],
[
"cross-year",
"2027-02-02",
"2028-02-03",
"2 February 2027 – 3 February 2028",
],
];
for (const [label, start, end, out] of cases) {
test(label, () => {
expect(formatDateRangeLabelCompactEn(start, end)).toBe(out);
});
}
});
describe("formatDateRangeLabel", () => {
test("returns single-day label when duration is 1 day", () => {
expect(
formatDateRangeLabel(
"2026-02-09T00:00:00Z",
"2026-02-10T00:00:00.000Z",
),
).toBe("Monday 9 February 2026");
});
test("returns compact range when duration is multi-day", () => {
expect(
formatDateRangeLabel(
"2027-02-02T00:00:00Z",
"2027-02-05T00:00:00.000Z",
),
).toBe("2–4 February 2027");
});
test("returns empty string when start is null", () => {
expect(formatDateRangeLabel(null, null)).toBe("");
});
test("collapses to single-day label when end is null but start is set", () => {
// Defensive path for rows that somehow have start_at but no end_at —
// callers in the admin template still render something sensible.
expect(formatDateRangeLabel("2026-02-09T00:00:00Z", null)).toBe(
"Monday 9 February 2026",
);
});
});
});