6c866dbad5
Enables importing .nmea logs into travel-day events with interval/change modes, optional GPS track, local encrypted archive, and a test fixture for the Kieler Förde route. Co-authored-by: Cursor <cursoragent@cursor.com>
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { nmeaPointsToWaypoints, parseNmeaFile } from './nmeaParse.js'
|
|
|
|
describe('parseNmeaFile', () => {
|
|
it('parses RMC position, course and speed', () => {
|
|
const text = [
|
|
'$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W',
|
|
'$GPRMC,133519,A,4808.038,N,01132.000,E,025.0,090.0,230394,003.1,W'
|
|
].join('\n')
|
|
|
|
const result = parseNmeaFile(text, 'test.nmea')
|
|
|
|
expect(result.stats.parsedLines).toBe(2)
|
|
expect(result.stats.sentenceTypes).toContain('RMC')
|
|
expect(result.points.length).toBeGreaterThanOrEqual(2)
|
|
|
|
const first = result.points[0]
|
|
expect(first.lat).toBeCloseTo(48.1173, 3)
|
|
expect(first.lng).toBeCloseTo(11.516667, 3)
|
|
expect(first.sog).toBe(22.4)
|
|
expect(first.cog).toBe(84.4)
|
|
expect(first.fixValid).toBe(true)
|
|
})
|
|
|
|
it('merges wind and depth sentences onto the same timestamp', () => {
|
|
const text = [
|
|
'$GPRMC,100000,A,5400.000,N,01000.000,E,5.0,180.0,010124,003.0,E',
|
|
'$IIMWV,270.0,R,12.5,N,A',
|
|
'$SDDPT,4.5,0.0'
|
|
].join('\n')
|
|
|
|
const result = parseNmeaFile(text, 'merged.nmea')
|
|
const last = result.points[result.points.length - 1]
|
|
|
|
expect(last.windDir).toBe(270)
|
|
expect(last.windSpeedKnots).toBe(12.5)
|
|
expect(last.depthM).toBe(4.5)
|
|
})
|
|
|
|
it('skips lines with invalid checksum', () => {
|
|
const text = '$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*FF'
|
|
const result = parseNmeaFile(text, 'bad.nmea')
|
|
|
|
expect(result.stats.checksumErrors).toBe(1)
|
|
expect(result.points).toHaveLength(0)
|
|
expect(result.warnings).toContain('no_samples')
|
|
})
|
|
|
|
it('warns when no position sentences are present', () => {
|
|
const text = '$IIMWV,090.0,R,8.0,N,A'
|
|
const result = parseNmeaFile(text, 'wind-only.nmea')
|
|
|
|
expect(result.warnings).toContain('no_position')
|
|
})
|
|
})
|
|
|
|
describe('nmeaPointsToWaypoints', () => {
|
|
it('maps points with coordinates to track waypoints', () => {
|
|
const waypoints = nmeaPointsToWaypoints([
|
|
{ timestamp: 1, lat: 54.0, lng: 10.0, sog: 6, cog: 90 },
|
|
{ timestamp: 2, windDir: 180 },
|
|
{ timestamp: 3, lat: 54.01, lng: 10.01, hdt: 95 }
|
|
])
|
|
|
|
expect(waypoints).toHaveLength(2)
|
|
expect(waypoints[0]).toMatchObject({ lat: 54, lng: 10, speedKnots: 6, heading: 90 })
|
|
expect(waypoints[1].heading).toBe(95)
|
|
})
|
|
})
|