import { describe, it, expect } from 'vitest'; import { bodyToOurs, vesselToOurs, buildSnapshot, krpcSituationToOurs, type KRPCBody, type KRPCState, } from '../src/convert.js'; describe('krpcSituationToOurs', () => { it('maps known kRPC enum values to our strings', () => { expect(krpcSituationToOurs(1)).toBe('ORBITING'); expect(krpcSituationToOurs(2)).toBe('ESCAPING'); expect(krpcSituationToOurs(3)).toBe('LANDED'); expect(krpcSituationToOurs(4)).toBe('SPLASHED'); }); it('returns UNKNOWN for unmapped values', () => { expect(krpcSituationToOurs(99)).toBe('UNKNOWN'); expect(krpcSituationToOurs(-1)).toBe('UNKNOWN'); }); }); describe('bodyToOurs', () => { it('normalizes the body name to a lowercase id', () => { const ksp: KRPCBody = { name: 'Kerbin', kind: 'planet', parentId: 'Kerbol', radius: 600_000, sphereOfInfluence: 84_159_286, gravitationalParameter: 3.5316e12, rotationPeriod: 21_600, axialTilt: 0, orbit: { semiMajorAxis: 13_599_840_256, eccentricity: 0.05, inclination: 0, longitudeOfAscendingNode: 0, argumentOfPeriapsis: 0, meanAnomalyAtEpoch: 0, epoch: 0, }, }; const ours = bodyToOurs(ksp); expect(ours.id).toBe('kerbin'); expect(ours.parentId).toBe('kerbol'); expect(ours.name).toBe('Kerbin'); expect(ours.kind).toBe('planet'); expect(ours.radius).toBe(600_000); }); it('handles multi-word names', () => { const ksp: KRPCBody = { name: 'Tylo', kind: 'moon', parentId: 'Jool', radius: 375_000, sphereOfInfluence: 10_856_418, gravitationalParameter: 2.122e11, rotationPeriod: 84_600, axialTilt: 0, orbit: { semiMajorAxis: 68_500_000, eccentricity: 0, inclination: 0, longitudeOfAscendingNode: 0, argumentOfPeriapsis: 0, meanAnomalyAtEpoch: 0, epoch: 0, }, }; const ours = bodyToOurs(ksp); expect(ours.id).toBe('tylo'); }); it('preserves null parentId for the star', () => { const ksp: KRPCBody = { name: 'Kerbol', kind: 'star', parentId: null, radius: 261_600_000, sphereOfInfluence: 1e30, gravitationalParameter: 1.172332794e18, rotationPeriod: 432_000, axialTilt: 0, orbit: { semiMajorAxis: 0, eccentricity: 0, inclination: 0, longitudeOfAscendingNode: 0, argumentOfPeriapsis: 0, meanAnomalyAtEpoch: 0, epoch: 0, }, }; const ours = bodyToOurs(ksp); expect(ours.parentId).toBeNull(); }); }); describe('vesselToOurs', () => { it('maps situation enum and assigns ACTIVE status', () => { const ours = vesselToOurs({ id: 'v-1', name: 'Probe', type: 'Probe', owner: 'KASA', situation: 'ORBITING', orbit: { semiMajorAxis: 7e6, eccentricity: 0, inclination: 0, longitudeOfAscendingNode: 0, argumentOfPeriapsis: 0, meanAnomalyAtEpoch: 0, epoch: 0, }, referenceBodyId: 'kerbin', createdAt: '2026-01-01T00:00:00Z', }); expect(ours.situation).toBe('ORBITING'); expect(ours.status).toBe('ACTIVE'); expect(ours.retiredAt).toBeNull(); expect(ours.owner).toBe('KASA'); }); }); describe('buildSnapshot', () => { it('produces a valid UniverseSnapshot from a KRPCState', () => { const state: KRPCState = { ut: 100, bodies: [ { name: 'Kerbol', kind: 'star', parentId: null, radius: 1, sphereOfInfluence: 1e30, gravitationalParameter: 1, rotationPeriod: 1, axialTilt: 0, orbit: { semiMajorAxis: 0, eccentricity: 0, inclination: 0, longitudeOfAscendingNode: 0, argumentOfPeriapsis: 0, meanAnomalyAtEpoch: 0, epoch: 0, }, }, { name: 'Kerbin', kind: 'planet', parentId: 'Kerbol', radius: 600_000, sphereOfInfluence: 84_159_286, gravitationalParameter: 3.5316e12, rotationPeriod: 21_600, axialTilt: 0, orbit: { semiMajorAxis: 13_599_840_256, eccentricity: 0, inclination: 0, longitudeOfAscendingNode: 0, argumentOfPeriapsis: 0, meanAnomalyAtEpoch: 0, epoch: 0, }, }, ], vessels: [ { id: 'v1', name: 'Probe', type: 'Probe', owner: 'KASA', situation: 1, // ORBITING orbit: { semiMajorAxis: 7e6, eccentricity: 0, inclination: 0, longitudeOfAscendingNode: 0, argumentOfPeriapsis: 0, meanAnomalyAtEpoch: 0, epoch: 0, }, referenceBodyId: 'Kerbin', createdAt: '2026-01-01T00:00:00Z', }, ], groundStations: [ { id: 'montana', name: 'Montana', bodyId: 'Kerbin', lat: 47, lon: -110, alt: 0 }, ], }; const snap = buildSnapshot(state, '2026-01-01T00:00:00Z'); expect(snap.ut).toBe(100); expect(snap.capturedAt).toBe('2026-01-01T00:00:00Z'); expect(snap.bodies).toHaveLength(2); expect(snap.bodies[0]!.id).toBe('kerbol'); expect(snap.bodies[0]!.parentId).toBeNull(); expect(snap.bodies[1]!.id).toBe('kerbin'); expect(snap.bodies[1]!.parentId).toBe('kerbol'); expect(snap.vessels).toHaveLength(1); expect(snap.vessels[0]!.situation).toBe('ORBITING'); expect(snap.vessels[0]!.referenceBodyId).toBe('kerbin'); expect(snap.groundStations).toHaveLength(1); }); });