import assert from 'node:assert/strict'; import { test } from 'node:test'; import { toLocalDate, toLocalTime, parseLocalDateTime, formatFriendlyDateTime, } from './datetimeInput'; // All helpers work in the LOCAL timezone. We construct Dates with the local // component constructor so the assertions hold regardless of where tests run. test('toLocalDate: zero-pads month and day', () => { assert.equal(toLocalDate(new Date(2026, 0, 5, 9, 3)), '2026-01-05'); assert.equal(toLocalDate(new Date(2026, 11, 25, 0, 0)), '2026-12-25'); }); test('toLocalTime: zero-pads hours and minutes (24h)', () => { assert.equal(toLocalTime(new Date(2026, 0, 5, 9, 3)), '09:03'); assert.equal(toLocalTime(new Date(2026, 0, 5, 23, 59)), '23:59'); assert.equal(toLocalTime(new Date(2026, 0, 5, 0, 0)), '00:00'); }); test('toLocalDate/toLocalTime round-trip through parseLocalDateTime', () => { const d = new Date(2026, 5, 15, 14, 30, 0, 0); const parsed = parseLocalDateTime(toLocalDate(d), toLocalTime(d)); assert.ok(parsed); assert.equal(parsed.getTime(), d.getTime()); }); test('parseLocalDateTime: returns null for missing parts', () => { assert.equal(parseLocalDateTime('', '09:00'), null); assert.equal(parseLocalDateTime('2026-01-05', ''), null); assert.equal(parseLocalDateTime('', ''), null); }); test('parseLocalDateTime: returns null for an invalid combination', () => { assert.equal(parseLocalDateTime('not-a-date', '09:00'), null); assert.equal(parseLocalDateTime('2026-13-40', '09:00'), null); }); test('parseLocalDateTime: valid input yields the local wall-clock time', () => { const parsed = parseLocalDateTime('2026-01-05', '09:03'); assert.ok(parsed); assert.equal(parsed.getFullYear(), 2026); assert.equal(parsed.getMonth(), 0); assert.equal(parsed.getDate(), 5); assert.equal(parsed.getHours(), 9); assert.equal(parsed.getMinutes(), 3); }); test('formatFriendlyDateTime: uses Today/Tomorrow/date prefixes', () => { const now = new Date(2026, 0, 5, 10, 0).getTime(); const laterToday = new Date(2026, 0, 5, 15, 30).getTime(); const tomorrow = new Date(2026, 0, 6, 9, 0).getTime(); const nextWeek = new Date(2026, 0, 12, 9, 0).getTime(); const prefs = { hour24Clock: true, dateFormatString: 'D MMM YYYY' }; assert.equal(formatFriendlyDateTime(laterToday, prefs, now), 'Today at 15:30'); assert.equal(formatFriendlyDateTime(tomorrow, prefs, now), 'Tomorrow at 09:00'); assert.equal(formatFriendlyDateTime(nextWeek, prefs, now), '12 Jan 2026 at 09:00'); assert.equal( formatFriendlyDateTime(nextWeek, { hour24Clock: false, dateFormatString: 'MM/DD/YYYY' }, now), '01/12/2026 at 09:00 AM', ); }); test('formatFriendlyDateTime: Tomorrow rolls over month/year boundaries', () => { const nye = new Date(2026, 11, 31, 23, 0).getTime(); const jan1 = new Date(2027, 0, 1, 9, 0).getTime(); assert.ok( formatFriendlyDateTime(jan1, { hour24Clock: true, dateFormatString: '' }, nye).startsWith( 'Tomorrow at ', ), ); });