From b9e48f9a6d5f21c76e06aaf92e8480f157b370e8 Mon Sep 17 00:00:00 2001 From: Arthur Geel Date: Tue, 22 Oct 2024 20:31:11 +0200 Subject: [PATCH] Moar unit tests! --- src/pages/history/History.tsx | 8 +--- src/utils/date/formatHourDisplay.test.ts | 57 ++++++++++++++++++++++ src/utils/date/formatHourDisplay.ts | 8 ++++ src/utils/date/formatTime.test.ts | 60 ++++++++++++++++++++++++ src/utils/date/formatTime.ts | 7 +++ 5 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 src/utils/date/formatHourDisplay.test.ts create mode 100644 src/utils/date/formatHourDisplay.ts create mode 100644 src/utils/date/formatTime.test.ts create mode 100644 src/utils/date/formatTime.ts diff --git a/src/pages/history/History.tsx b/src/pages/history/History.tsx index d017dba..4bf231e 100644 --- a/src/pages/history/History.tsx +++ b/src/pages/history/History.tsx @@ -10,18 +10,12 @@ import { getHoursWithHistory, organiseHistory, } from "@/src/services/history"; +import { formatHourDisplay } from "@/src/utils/date/formatHourDisplay"; import HistoryItem from "./components/HistoryItem"; import SearchHeader from "./components/SearchHeader"; import TimelineView from "./components/TimelineView"; -const formatHourDisplay = (dateStr: string, hourStr: string) => { - const fullDateTime = `${dateStr}T${hourStr}:00:00Z`; - const date = new Date(fullDateTime); - // Format just the hour in local time - return format(date, "HH:00"); -}; - const History = () => { const [searchQuery, setSearchQuery] = useState(""); const { debouncedValue: debouncedSearchQuery } = useDebounce( diff --git a/src/utils/date/formatHourDisplay.test.ts b/src/utils/date/formatHourDisplay.test.ts new file mode 100644 index 0000000..05223a6 --- /dev/null +++ b/src/utils/date/formatHourDisplay.test.ts @@ -0,0 +1,57 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; + +import { formatHourDisplay } from "./formatHourDisplay"; + +const originalTimezone = process.env.TZ; + +// Test cases in different timezones +const timezones = ["UTC", "America/New_York", "Asia/Tokyo", "Europe/London"]; + +describe("Time formatting functions", () => { + describe("formatHourDisplay", () => { + for (const timezone of timezones) { + describe(`in ${timezone} timezone`, () => { + beforeAll(() => { + process.env.TZ = timezone; + }); + + afterAll(() => { + process.env.TZ = originalTimezone; + }); + + it("should format midnight UTC correctly", () => { + const result = formatHourDisplay("2024-01-01", "00"); + expect(result).toMatch(/^\d{2}:00$/); + }); + + it("should format noon UTC correctly", () => { + const result = formatHourDisplay("2024-01-01", "12"); + expect(result).toMatch(/^\d{2}:00$/); + }); + + it("should format evening UTC correctly", () => { + const result = formatHourDisplay("2024-01-01", "20"); + expect(result).toMatch(/^\d{2}:00$/); + }); + + it("should handle single-digit hours correctly", () => { + const result = formatHourDisplay("2024-01-01", "05"); + expect(result).toMatch(/^\d{2}:00$/); + }); + + it("should handle date transitions correctly", () => { + const result = formatHourDisplay("2024-01-01", "23"); + expect(result).toMatch(/^\d{2}:00$/); + }); + }); + } + + it("should handle invalid date strings gracefully", () => { + expect(() => formatHourDisplay("invalid-date", "12")).toThrow(); + }); + + it("should handle invalid hour strings gracefully", () => { + expect(() => formatHourDisplay("2024-01-01", "25")).toThrow(); + }); + }); +}); diff --git a/src/utils/date/formatHourDisplay.ts b/src/utils/date/formatHourDisplay.ts new file mode 100644 index 0000000..45164ec --- /dev/null +++ b/src/utils/date/formatHourDisplay.ts @@ -0,0 +1,8 @@ +import { format } from "date-fns"; + +export const formatHourDisplay = (dateStr: string, hourStr: string) => { + const fullDateTime = `${dateStr}T${hourStr}:00:00Z`; + const date = new Date(fullDateTime); + + return format(date, "HH:00"); +}; diff --git a/src/utils/date/formatTime.test.ts b/src/utils/date/formatTime.test.ts new file mode 100644 index 0000000..6cf015c --- /dev/null +++ b/src/utils/date/formatTime.test.ts @@ -0,0 +1,60 @@ +import { afterAll, beforeAll, describe, expect, it } from "vitest"; + +import { formatTime } from "./formatTime"; + +const originalTimezone = process.env.TZ; +const timezones = ["UTC", "America/New_York", "Asia/Tokyo", "Europe/London"]; + +describe("formatTime", () => { + for (const timezone of timezones) { + describe(`in ${timezone} timezone`, () => { + beforeAll(() => { + process.env.TZ = timezone; + }); + + afterAll(() => { + process.env.TZ = originalTimezone; + }); + + it("should format midnight correctly", () => { + const midnight = new Date("2024-01-01T00:00:00Z").getTime(); + const result = formatTime(midnight); + expect(result).toMatch(/^\d{2}:\d{2}:\d{2}$/); + }); + + it("should format noon correctly", () => { + const noon = new Date("2024-01-01T12:00:00Z").getTime(); + const result = formatTime(noon); + expect(result).toMatch(/^\d{2}:\d{2}:\d{2}$/); + }); + + it("should format time with seconds correctly", () => { + const timeWithSeconds = new Date("2024-01-01T12:34:56Z").getTime(); + const result = formatTime(timeWithSeconds); + expect(result).toMatch(/^\d{2}:\d{2}:\d{2}$/); + }); + + it("should handle millisecond precision", () => { + const timeWithMs = new Date("2024-01-01T12:34:56.789Z").getTime(); + const result = formatTime(timeWithMs); + expect(result).toMatch(/^\d{2}:\d{2}:\d{2}$/); + }); + }); + } + + it("should handle invalid timestamps gracefully", () => { + expect(() => formatTime(NaN)).toThrow(); + }); + + it("should handle very large timestamps", () => { + const farFuture = new Date("2100-01-01T00:00:00Z").getTime(); + const result = formatTime(farFuture); + expect(result).toMatch(/^\d{2}:\d{2}:\d{2}$/); + }); + + it("should handle very small timestamps", () => { + const farPast = new Date("1900-01-01T00:00:00Z").getTime(); + const result = formatTime(farPast); + expect(result).toMatch(/^\d{2}:\d{2}:\d{2}$/); + }); +}); diff --git a/src/utils/date/formatTime.ts b/src/utils/date/formatTime.ts new file mode 100644 index 0000000..3399ea8 --- /dev/null +++ b/src/utils/date/formatTime.ts @@ -0,0 +1,7 @@ +import { format } from "date-fns"; + +export const formatTime = (timestamp: number) => { + const date = new Date(timestamp); + + return format(date, "HH:mm:ss"); +};