import { test } from 'node:test'; import assert from 'node:assert/strict'; import { directionFromAngles } from '../src/astronomy/direction.ts'; import { fromKstInput, kstClock, kstFields } from '../src/ui/time.ts'; import { calculateSun } from '../src/astronomy/sunCalculator.ts'; import { observer } from '../src/config/observer.ts'; test('N/E/S/W and zenith map to the specified fixed world axes', () => { for (const [az, alt, expected] of [ [0, 0, [0, 0, -1]], [90, 0, [1, 0, 0]], [180, 0, [0, 0, 1]], [270, 0, [-1, 0, 0]], [0, 90, [0, 1, 0]], ] as const) { const actual = directionFromAngles(az, alt); actual.forEach((value, i) => assert.ok(Math.abs(value - expected[i]) < 1e-12)); } assert.ok(directionFromAngles(90, 20)[1] > directionFromAngles(90, 10)[1]); }); test('KST inputs preserve midnight, last minute and year rollover regardless of host timezone', () => { assert.equal(fromKstInput('2026-01-01', 0).toISOString(), '2025-12-31T15:00:00.000Z'); assert.equal(fromKstInput('2026-01-01', 1439).toISOString(), '2026-01-01T14:59:00.000Z'); assert.deepEqual(kstFields(new Date('2026-10-28T15:00:00Z')), { date: '2026-10-29', minutes: 0 }); }); test('sunrise belongs to the selected KST date even at midnight and 23:59', () => { for (const minutes of [0, 720, 1439]) { const result = calculateSun(fromKstInput('2026-10-29', minutes), observer); assert.equal(kstFields(result.sunrise!).date, '2026-10-29'); assert.equal(kstFields(result.sunset!).date, '2026-10-29'); } }); test('observer height advances sunrise and delays sunset relative to the 0m horizon', () => { const result = calculateSun(fromKstInput('2026-10-29', 720), observer); assert.ok(result.sunrise!.getTime() < result.standardSunrise!.getTime()); assert.ok(result.sunset!.getTime() > result.standardSunset!.getTime()); }); test('date inputs and labels consistently use Asia/Seoul historical offsets', () => { for (const date of ['1901-01-01', '1988-06-01', '2026-10-29']) { const instant = fromKstInput(date, 720); assert.equal(kstClock(instant), '12:00:00'); assert.deepEqual(kstFields(instant), { date, minutes: 720 }); } });