Files
Flight-Ops/lib/geo.test.ts
2026-09-21 08:47:42 +00:00

58 lines
2.0 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { haversineKm, initialBearingDeg } from './geo';
describe('initialBearingDeg', () => {
it('is due north (0) for a point directly above', () => {
expect(initialBearingDeg(0, 0, 10, 0)).toBe(0);
});
it('is due east (90) along the equator', () => {
expect(initialBearingDeg(0, -10, 0, 10)).toBeCloseTo(90, 9);
});
it('is due south (180) for a point directly below', () => {
expect(initialBearingDeg(10, 0, 0, 0)).toBeCloseTo(180, 9);
});
it('is due west (270) along the equator — normalized into [0, 360)', () => {
expect(initialBearingDeg(0, 10, 0, -10)).toBeCloseTo(270, 9);
});
it('always normalizes to [0, 360) for arbitrary pairs', () => {
const pairs: Array<[number, number, number, number]> = [
[50.03, 8.57, 40.47, -3.56], // FRA → MAD (southwest-ish)
[40.47, -3.56, 50.03, 8.57], // reverse: northeast-ish
[65.66, -18.07, 50.03, 8.57], // far north → south-east wrap case
];
for (const [a1, a2, b1, b2] of pairs) {
const brg = initialBearingDeg(a1, a2, b1, b2);
expect(brg).toBeGreaterThanOrEqual(0);
expect(brg).toBeLessThan(360);
}
});
it('FRA → MAD points roughly south-southwest (between 180 and 270)', () => {
const brg = initialBearingDeg(50.03, 8.57, 40.47, -3.56);
expect(brg).toBeGreaterThan(180);
expect(brg).toBeLessThan(270);
});
});
describe('haversineKm', () => {
it('returns 0 for identical points', () => {
expect(haversineKm(50.03, 8.57, 50.03, 8.57)).toBeCloseTo(0, 10);
});
it('computes the London → Paris great-circle distance (~343 km)', () => {
const km = haversineKm(51.47, -0.454, 49.0097, 2.5479); // LHR → CDG
expect(km).toBeGreaterThan(330);
expect(km).toBeLessThan(360);
});
it('is symmetric', () => {
const a = haversineKm(50.03, 8.57, 40.47, -3.56); // FRA → MAD
const b = haversineKm(40.47, -3.56, 50.03, 8.57);
expect(a).toBeCloseTo(b, 10);
});
});