feat(dates): read a bare ISO date as one boundary

bluearchive.wiki gives each boundary its own column and writes it as a
plain 2026-08-04, so unlike every reader here there is no range to split
and no field order to infer. Day precision, because the page states no
time of day.

Anchored at both ends, which matters more for this shape than for any
other in the module: it is the least distinctive one, and unanchored it
would happily find a date inside an article slug or a version string.

Also names the two readers the paragraph below the table was describing.
"The last two" stopped being true when rows were appended after them, and
the examples belong to parseAdjacentFullRange either way.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
Lucas Winther
2026-08-17 23:23:06 +02:00
co-authored by Claude Opus 5
parent 02dd7b3ed4
commit 77921e88f5
3 changed files with 60 additions and 2 deletions
+37
View File
@@ -2,6 +2,7 @@ import { describe, expect, test } from "bun:test";
import {
parseAdjacentFullRange,
parseFullRange,
parseIsoDay,
parseLabelledStartEnd,
parseMonthDayRange,
parseMonthDayYear,
@@ -330,3 +331,39 @@ describe("parseOrdinalDateTimeRange", () => {
expect(range?.start.iso).toBe("2026-08-13T10:00:00.000Z");
});
});
describe("parseIsoDay", () => {
test("parses a bare ISO date at day precision", () => {
expect(parseIsoDay("2026-08-04")).toEqual({
iso: "2026-08-04T00:00:00.000Z",
precision: "day",
});
});
test("tolerates the whitespace a table cell carries", () => {
expect(parseIsoDay(" 2026-09-15 ")?.iso).toBe("2026-09-15T00:00:00.000Z");
});
test("rejects an impossible calendar date", () => {
expect(parseIsoDay("2026-02-30")).toBeNull();
expect(parseIsoDay("2026-13-01")).toBeNull();
});
test("refuses a date embedded in anything else", () => {
// Anchored at both ends because this is the least distinctive shape in this
// module. Unanchored it finds dates in article slugs and version strings.
expect(parseIsoDay("Rerun 2026-08-04")).toBeNull();
expect(parseIsoDay("2026-08-04 - 2026-08-18")).toBeNull();
// The page's other schedule tables write their boundaries this way, with a
// wall clock and no timezone anywhere. Reading one as UTC would invent the
// fact that matters most, so this reader takes none of them.
expect(parseIsoDay("08/12/2026 11:00")).toBeNull();
});
test("does not accept a partial date", () => {
expect(parseIsoDay("2026-08")).toBeNull();
expect(parseIsoDay("2026")).toBeNull();
expect(parseIsoDay("TBA")).toBeNull();
expect(parseIsoDay("")).toBeNull();
});
});