|
1 | 1 | import { describe, it, expect } from "vitest"; |
2 | | -import { getWeekId, getCurrentWeekId } from "./week.js"; |
| 2 | +import { getWeekId, getCurrentWeekId, isoWeekToMonday } from "./week.js"; |
3 | 3 |
|
4 | 4 | describe("getWeekId", () => { |
5 | 5 | // ------------------------------------------------------------------- |
@@ -220,3 +220,63 @@ describe("getCurrentWeekId", () => { |
220 | 220 | expect(result.path).toBe("2026/W01"); |
221 | 221 | }); |
222 | 222 | }); |
| 223 | + |
| 224 | +describe("isoWeekToMonday", () => { |
| 225 | + const dayOfWeek = (d: Date): string => |
| 226 | + d.toLocaleDateString("en-US", { weekday: "long", timeZone: "UTC" }); |
| 227 | + const fmt = (d: Date): string => |
| 228 | + d.toISOString().slice(0, 10); |
| 229 | + |
| 230 | + it("returns Monday for 2026 W14 (Mar 30)", () => { |
| 231 | + const mon = isoWeekToMonday(2026, 14); |
| 232 | + expect(fmt(mon)).toBe("2026-03-30"); |
| 233 | + expect(dayOfWeek(mon)).toBe("Monday"); |
| 234 | + }); |
| 235 | + |
| 236 | + it("returns Monday for 2026 W1 (Dec 29, 2025)", () => { |
| 237 | + // ISO 2026 W1 starts on Mon Dec 29 2025 |
| 238 | + const mon = isoWeekToMonday(2026, 1); |
| 239 | + expect(fmt(mon)).toBe("2025-12-29"); |
| 240 | + expect(dayOfWeek(mon)).toBe("Monday"); |
| 241 | + }); |
| 242 | + |
| 243 | + it("returns Monday for 2025 W1 (Dec 30, 2024)", () => { |
| 244 | + const mon = isoWeekToMonday(2025, 1); |
| 245 | + expect(fmt(mon)).toBe("2024-12-30"); |
| 246 | + expect(dayOfWeek(mon)).toBe("Monday"); |
| 247 | + }); |
| 248 | + |
| 249 | + it("handles 2024 W1 (Jan 1, 2024 is Monday)", () => { |
| 250 | + const mon = isoWeekToMonday(2024, 1); |
| 251 | + expect(fmt(mon)).toBe("2024-01-01"); |
| 252 | + expect(dayOfWeek(mon)).toBe("Monday"); |
| 253 | + }); |
| 254 | + |
| 255 | + it("handles last week of year: 2026 W52", () => { |
| 256 | + const mon = isoWeekToMonday(2026, 52); |
| 257 | + expect(fmt(mon)).toBe("2026-12-21"); |
| 258 | + expect(dayOfWeek(mon)).toBe("Monday"); |
| 259 | + }); |
| 260 | + |
| 261 | + it("handles W53 in a long year (2020 has 53 weeks)", () => { |
| 262 | + const mon = isoWeekToMonday(2020, 53); |
| 263 | + expect(fmt(mon)).toBe("2020-12-28"); |
| 264 | + expect(dayOfWeek(mon)).toBe("Monday"); |
| 265 | + }); |
| 266 | + |
| 267 | + it("Sunday is always 6 days after Monday", () => { |
| 268 | + const cases = [ |
| 269 | + { year: 2026, week: 1 }, |
| 270 | + { year: 2026, week: 14 }, |
| 271 | + { year: 2026, week: 52 }, |
| 272 | + { year: 2020, week: 53 }, |
| 273 | + { year: 2024, week: 1 }, |
| 274 | + ]; |
| 275 | + cases.forEach(({ year, week }) => { |
| 276 | + const mon = isoWeekToMonday(year, week); |
| 277 | + const sun = new Date(mon.getTime() + 6 * 86_400_000); |
| 278 | + expect(dayOfWeek(mon)).toBe("Monday"); |
| 279 | + expect(dayOfWeek(sun)).toBe("Sunday"); |
| 280 | + }); |
| 281 | + }); |
| 282 | +}); |
0 commit comments