Create new @reviq/common package with environment-agnostic utilities: - Date formatting: formatDate, formatDateTime, formatLongDate, formatRelativeDate, formatRelativeTime - User utilities: getUserInitials, formatRole Consolidate date formatting from publisher-dashboard into shared package. All utilities include comprehensive test coverage with bun:test. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
140 lines
4.3 KiB
TypeScript
140 lines
4.3 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import {
|
|
formatDate,
|
|
formatDateTime,
|
|
formatLongDate,
|
|
formatRelativeDate,
|
|
formatRelativeTime,
|
|
} from "./format-date.js";
|
|
|
|
describe("formatDate", () => {
|
|
test("formats a Date object", () => {
|
|
const date = new Date("2024-01-15T12:00:00Z");
|
|
expect(formatDate(date)).toBe("Jan 15, 2024");
|
|
});
|
|
|
|
test("formats a date string", () => {
|
|
expect(formatDate("2024-01-15T12:00:00Z")).toBe("Jan 15, 2024");
|
|
});
|
|
|
|
test("formats different months correctly", () => {
|
|
expect(formatDate("2024-06-01T12:00:00Z")).toBe("Jun 1, 2024");
|
|
expect(formatDate("2024-12-25T12:00:00Z")).toBe("Dec 25, 2024");
|
|
});
|
|
});
|
|
|
|
describe("formatDateTime", () => {
|
|
test("formats date with time", () => {
|
|
const date = new Date("2024-01-15T15:30:00Z");
|
|
const result = formatDateTime(date);
|
|
// Contains date parts
|
|
expect(result).toContain("Jan");
|
|
expect(result).toContain("15");
|
|
expect(result).toContain("2024");
|
|
// Contains time (format may vary by locale)
|
|
expect(result).toMatch(/\d{1,2}:\d{2}/);
|
|
});
|
|
|
|
test("formats a date string with time", () => {
|
|
const result = formatDateTime("2024-01-15T08:00:00Z");
|
|
expect(result).toContain("Jan");
|
|
expect(result).toContain("15");
|
|
expect(result).toContain("2024");
|
|
});
|
|
});
|
|
|
|
describe("formatLongDate", () => {
|
|
test("formats date in long form", () => {
|
|
const date = new Date("2024-01-15T12:00:00Z");
|
|
expect(formatLongDate(date)).toBe("January 15, 2024");
|
|
});
|
|
|
|
test("formats a date string in long form", () => {
|
|
expect(formatLongDate("2024-06-01T12:00:00Z")).toBe("June 1, 2024");
|
|
});
|
|
|
|
test("formats December correctly", () => {
|
|
expect(formatLongDate("2024-12-25T12:00:00Z")).toBe("December 25, 2024");
|
|
});
|
|
});
|
|
|
|
describe("formatRelativeDate", () => {
|
|
const now = new Date("2024-01-15T12:00:00Z");
|
|
|
|
test("returns 'Today' for same day", () => {
|
|
const today = new Date("2024-01-15T08:00:00Z");
|
|
expect(formatRelativeDate(today, { now })).toBe("Today");
|
|
});
|
|
|
|
test("returns 'Yesterday' for previous day", () => {
|
|
const yesterday = new Date("2024-01-14T12:00:00Z");
|
|
expect(formatRelativeDate(yesterday, { now })).toBe("Yesterday");
|
|
});
|
|
|
|
test("returns 'X days ago' for 2-6 days", () => {
|
|
expect(formatRelativeDate("2024-01-13T12:00:00Z", { now })).toBe(
|
|
"2 days ago",
|
|
);
|
|
expect(formatRelativeDate("2024-01-12T12:00:00Z", { now })).toBe(
|
|
"3 days ago",
|
|
);
|
|
expect(formatRelativeDate("2024-01-09T12:00:00Z", { now })).toBe(
|
|
"6 days ago",
|
|
);
|
|
});
|
|
|
|
test("returns '1 week ago' for exactly 7 days", () => {
|
|
const oneWeekAgo = new Date("2024-01-08T12:00:00Z");
|
|
expect(formatRelativeDate(oneWeekAgo, { now })).toBe("1 week ago");
|
|
});
|
|
|
|
test("returns 'X weeks ago' for 2-4 weeks", () => {
|
|
expect(formatRelativeDate("2024-01-01T12:00:00Z", { now })).toBe(
|
|
"2 weeks ago",
|
|
);
|
|
expect(formatRelativeDate("2023-12-25T12:00:00Z", { now })).toBe(
|
|
"3 weeks ago",
|
|
);
|
|
});
|
|
|
|
test("returns formatted date for older dates in same year", () => {
|
|
// Use a "now" later in the year to test same-year formatting
|
|
const laterNow = new Date("2024-06-15T12:00:00Z");
|
|
const result = formatRelativeDate("2024-01-15T12:00:00Z", { now: laterNow });
|
|
expect(result).toBe("Jan 15");
|
|
});
|
|
|
|
test("returns formatted date with year for different year", () => {
|
|
const result = formatRelativeDate("2023-06-15T12:00:00Z", { now });
|
|
expect(result).toBe("Jun 15, 2023");
|
|
});
|
|
|
|
test("accepts string input", () => {
|
|
expect(formatRelativeDate("2024-01-15T08:00:00Z", { now })).toBe("Today");
|
|
});
|
|
});
|
|
|
|
describe("formatRelativeTime", () => {
|
|
const now = new Date("2024-01-15T12:00:00Z");
|
|
|
|
test("returns 'Never' for null", () => {
|
|
expect(formatRelativeTime(null)).toBe("Never");
|
|
});
|
|
|
|
test("returns 'Never' for undefined", () => {
|
|
expect(formatRelativeTime(undefined)).toBe("Never");
|
|
});
|
|
|
|
test("returns relative date for valid input", () => {
|
|
expect(formatRelativeTime("2024-01-15T08:00:00Z", { now })).toBe("Today");
|
|
expect(formatRelativeTime("2024-01-14T12:00:00Z", { now })).toBe(
|
|
"Yesterday",
|
|
);
|
|
});
|
|
|
|
test("handles Date objects", () => {
|
|
const date = new Date("2024-01-13T12:00:00Z");
|
|
expect(formatRelativeTime(date, { now })).toBe("2 days ago");
|
|
});
|
|
});
|