import { describe, it, expect } from 'vitest'; import { toGpx, toKml, toCsv, parsePrediction, EXPORT_MIME, exportPrediction } from '$domain'; import type { PredictionStage } from '$domain'; const stages: PredictionStage[] = [ { stage: 'ascent', trajectory: [ { altitude: 0, datetime: '2026-01-01T00:00:00Z', latitude: 62.0, longitude: 129.0 }, { altitude: 30000, datetime: '2026-01-01T01:00:00Z', latitude: 62.1, longitude: 129.2 } ] }, { stage: 'descent', trajectory: [ { altitude: 30000, datetime: '2026-01-01T01:00:00Z', latitude: 62.1, longitude: 129.2 }, { altitude: 0, datetime: '2026-01-01T01:30:00Z', latitude: 62.05, longitude: 129.4 } ] } ]; const prediction = parsePrediction(stages); describe('toGpx', () => { it('emits one trkpt per sample with elevation and time', () => { const gpx = toGpx(prediction, 'Flight 1'); expect(gpx).toContain('30000.0'); expect(gpx).toContain(''); }); it('escapes the name so a quote cannot break the XML', () => { expect(toGpx(prediction, 'A & ')).toContain('A & <B>'); }); }); describe('toKml', () => { it('orders coordinates longitude-first and marks the key points', () => { const kml = toKml(prediction); expect(kml).toContain(''); // lon,lat,alt — the opposite order to GPX. expect(kml).toContain('129.000000,62.000000,0.0'); expect(kml).toContain('Launch'); expect(kml).toContain('Burst'); expect(kml).toContain('Landing'); }); }); describe('toCsv', () => { it('writes a header plus one row per sample', () => { const lines = toCsv(prediction).split('\n'); expect(lines[0]).toBe('datetime_utc,latitude,longitude,altitude_m'); expect(lines).toHaveLength(5); expect(lines[1]).toBe('2026-01-01T00:00:00.000Z,62.000000,129.000000,0.0'); }); }); describe('exportPrediction', () => { it('dispatches by format and exposes a mime type for each', () => { expect(exportPrediction(prediction, 'gpx')).toContain('