Add vitest and 17 tests covering computeDateRange (all periods including January rollover) and buildMonthOptions (length, order, rollover, label formatting). Add test/test:watch npm scripts. Ref #33 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
123 lines
4 KiB
TypeScript
123 lines
4 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
import { computeDateRange, buildMonthOptions } from "./dateRange";
|
|
|
|
describe("computeDateRange", () => {
|
|
beforeEach(() => {
|
|
// Fix "now" to 2025-07-15 for deterministic tests
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(new Date(2025, 6, 15)); // July 15, 2025
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it('returns empty object for "all" period', () => {
|
|
expect(computeDateRange("all")).toEqual({});
|
|
});
|
|
|
|
it('returns custom range for "custom" period', () => {
|
|
expect(computeDateRange("custom", "2025-01-01", "2025-06-30")).toEqual({
|
|
dateFrom: "2025-01-01",
|
|
dateTo: "2025-06-30",
|
|
});
|
|
});
|
|
|
|
it('falls back to default when "custom" has missing dates', () => {
|
|
const result = computeDateRange("custom");
|
|
// Should fall through to default (same as "month")
|
|
expect(result.dateFrom).toBe("2025-07-01");
|
|
expect(result.dateTo).toBe("2025-07-15");
|
|
});
|
|
|
|
it('computes "month" period (first of current month to today)', () => {
|
|
const result = computeDateRange("month");
|
|
expect(result).toEqual({ dateFrom: "2025-07-01", dateTo: "2025-07-15" });
|
|
});
|
|
|
|
it('computes "3months" period (3 months back)', () => {
|
|
const result = computeDateRange("3months");
|
|
expect(result).toEqual({ dateFrom: "2025-05-01", dateTo: "2025-07-15" });
|
|
});
|
|
|
|
it('computes "6months" period (6 months back)', () => {
|
|
const result = computeDateRange("6months");
|
|
expect(result).toEqual({ dateFrom: "2025-02-01", dateTo: "2025-07-15" });
|
|
});
|
|
|
|
it('computes "year" period (Jan 1st of current year)', () => {
|
|
const result = computeDateRange("year");
|
|
expect(result).toEqual({ dateFrom: "2025-01-01", dateTo: "2025-07-15" });
|
|
});
|
|
|
|
it('computes "12months" period (12 months back)', () => {
|
|
const result = computeDateRange("12months");
|
|
expect(result).toEqual({ dateFrom: "2024-08-01", dateTo: "2025-07-15" });
|
|
});
|
|
|
|
it("handles January rollover for 3months period", () => {
|
|
vi.setSystemTime(new Date(2025, 1, 10)); // Feb 10, 2025
|
|
const result = computeDateRange("3months");
|
|
expect(result).toEqual({ dateFrom: "2024-12-01", dateTo: "2025-02-10" });
|
|
});
|
|
|
|
it("handles January rollover for 6months period", () => {
|
|
vi.setSystemTime(new Date(2025, 0, 20)); // Jan 20, 2025
|
|
const result = computeDateRange("6months");
|
|
expect(result).toEqual({ dateFrom: "2024-08-01", dateTo: "2025-01-20" });
|
|
});
|
|
|
|
it("handles January rollover for 12months period", () => {
|
|
vi.setSystemTime(new Date(2025, 0, 5)); // Jan 5, 2025
|
|
const result = computeDateRange("12months");
|
|
expect(result).toEqual({ dateFrom: "2024-02-01", dateTo: "2025-01-05" });
|
|
});
|
|
});
|
|
|
|
describe("buildMonthOptions", () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(new Date(2025, 6, 15)); // July 15, 2025
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it("returns 24 month options", () => {
|
|
const options = buildMonthOptions("fr");
|
|
expect(options).toHaveLength(24);
|
|
});
|
|
|
|
it("starts with the current month", () => {
|
|
const options = buildMonthOptions("en");
|
|
expect(options[0].key).toBe("2025-7");
|
|
expect(options[0].value).toBe("2025-7");
|
|
});
|
|
|
|
it("ends 23 months ago", () => {
|
|
const options = buildMonthOptions("en");
|
|
expect(options[23].key).toBe("2023-8");
|
|
expect(options[23].value).toBe("2023-8");
|
|
});
|
|
|
|
it("handles January rollover correctly", () => {
|
|
vi.setSystemTime(new Date(2025, 0, 15)); // Jan 15, 2025
|
|
const options = buildMonthOptions("en");
|
|
expect(options[0].key).toBe("2025-1");
|
|
expect(options[1].key).toBe("2024-12");
|
|
expect(options[12].key).toBe("2024-1");
|
|
});
|
|
|
|
it("capitalizes the first letter of labels", () => {
|
|
const options = buildMonthOptions("fr");
|
|
for (const opt of options) {
|
|
expect(opt.label[0]).toBe(opt.label[0].toUpperCase());
|
|
}
|
|
});
|
|
|
|
it("labels contain year information", () => {
|
|
const options = buildMonthOptions("en");
|
|
expect(options[0].label).toContain("2025");
|
|
});
|
|
});
|