// Tests the crawler's headline-date scanner (extracted from module source so we // don't widen the module's public surface just for tests). import { readFileSync } from "fs"; const src = readFileSync(new URL("../lib/crawl.js", import.meta.url), "utf8"); const monthsLine = /const MONTHS = .*;\n/.exec(src); const fnBlock = /function headlineDateAge[\s\S]*?\n\}\n/.exec(src); if (!monthsLine || !fnBlock) { console.log("FAIL could not locate headlineDateAge in source"); process.exit(1); } const fn = new Function(monthsLine[0] + fnBlock[0] + "; return headlineDateAge;")(); const now = new Date("2026-08-30T12:00:00Z").getTime(); let fails = 0; const ok = (c, msg) => { if (!c) { fails++; console.log(" FAIL " + msg); } else console.log(" ok " + msg); }; console.log("headlineDateAge:"); const march = fn("Peso weakens to 59.735 on March 13, 2026", now); ok(march !== null && march > 160, `"March 13, 2026" is ~5 months old (got ${march?.toFixed(0)}d)`); const yest = fn("On Aug 29, the monetary board decided", now); ok(yest !== null && yest >= 0 && yest < 2, `"Aug 29" reads as ~1 day (got ${yest?.toFixed(1)}d)`); const july = fn("Inflation quickens in July 2026", now); ok(july !== null && july > 25 && july < 90, `"July 2026" is a month+ old (got ${july?.toFixed(0)}d)`); ok(fn("Diesel prices climb for third straight week", now) === null, "no month-date in text -> null (pubDate governs)"); ok(fn("2025 inflation sinks to nine-year low", now) === null, "bare year (no month) -> null, conservative"); const dayfirst = fn("recorded 13 March 2026 by the BSP", now); ok(dayfirst !== null && dayfirst > 160, `"13 March 2026" day-first form also caught (got ${dayfirst?.toFixed(0)}d)`); const future = fn("Summit begins September 15, 2026", now); ok(future === null, "a date in the future is ignored, not treated as ancient"); console.log(fails ? `\n${fails} FAILED` : "\nall passed"); process.exit(fails ? 1 : 0);