import { describe, it, expect } from 'vitest' import { moonName, illumination, nextMoonPhase, interpolateDate, diffDays } from '../../../src/lib/api/moon.js' describe('moonName', () => { it('names the four principal phases', () => { expect(moonName(0.0)).toBe('New Moon') expect(moonName(0.25)).toBe('First Quarter') expect(moonName(0.5)).toBe('Full Moon') expect(moonName(0.75)).toBe('Last Quarter') }) it('names the intermediate phases', () => { expect(moonName(0.125)).toBe('Waxing Crescent') expect(moonName(0.375)).toBe('Waxing Gibbous') expect(moonName(0.625)).toBe('Waning Gibbous') expect(moonName(0.875)).toBe('Waning Crescent') }) it('wraps 1.0 back to new moon', () => { expect(moonName(1.0)).toBe('New Moon') expect(moonName(0.98)).toBe('Waning Crescent') }) }) describe('illumination', () => { it('is 0 at new moon and 1 at full', () => { expect(illumination(0)).toBeCloseTo(0, 5) expect(illumination(0.5)).toBeCloseTo(1, 5) }) it('is symmetric about full: quarter both ~0.5', () => { expect(illumination(0.25)).toBeCloseTo(0.5, 5) expect(illumination(0.75)).toBeCloseTo(0.5, 5) }) it('near new gives small illumination', () => { expect(illumination(0.912)).toBeLessThan(0.1) }) }) describe('interpolateDate / diffDays', () => { it('interpolates dates', () => { expect(interpolateDate('2026-09-10', '2026-09-12', 0.5)).toBe('2026-09-11') expect(interpolateDate('2026-09-10', '2026-09-12', 0)).toBe('2026-09-10') expect(interpolateDate('2026-09-10', '2026-09-12', 1)).toBe('2026-09-12') }) it('computes whole days between dates', () => { expect(diffDays('2026-09-08', '2026-09-10')).toBe(2) expect(diffDays('2026-09-08', '2026-09-08')).toBe(0) }) }) describe('nextMoonPhase', () => { const mk = (arr) => arr.map(([date, phase]) => ({ date, phase })) it('finds next new moon from a waning-crescent sample', () => { const days = mk([ ['2026-09-08', 0.912], ['2026-09-09', 0.948], ['2026-09-10', 0.985], ['2026-09-11', 0.020], ['2026-09-12', 0.054], ['2026-09-13', 0.088], ['2026-09-14', 0.121], ['2026-09-15', 0.153], ]) const r = nextMoonPhase(days) expect(r.name).toBe('New Moon') expect(r.daysUntil).toBe(2) expect(r.date).toBe('2026-09-10') }) it('finds next first quarter from a new-moon sample', () => { const days = mk([ ['2026-09-11', 0.020], ['2026-09-12', 0.054], ['2026-09-13', 0.088], ['2026-09-14', 0.121], ['2026-09-15', 0.153], ['2026-09-16', 0.184], ['2026-09-17', 0.215], ['2026-09-18', 0.245], ['2026-09-19', 0.276], ]) const r = nextMoonPhase(days) expect(r.name).toBe('First Quarter') expect(r.daysUntil).toBe(7) }) it('returns null with too few samples', () => { expect(nextMoonPhase(null)).toBeNull() expect(nextMoonPhase(mk([['2026-09-08', 0.5]]))).toBeNull() }) })