mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
109 lines
3.3 KiB
JavaScript
109 lines
3.3 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { FlightRecords } from './records.js';
|
|
|
|
function records() {
|
|
return new FlightRecords({
|
|
geoidHeight: () => 40,
|
|
cachedGroundFloor: () => null,
|
|
floorAltitudeM: (altitude) => altitude,
|
|
approxDistanceKm: () => 0,
|
|
});
|
|
}
|
|
const view = () => ({
|
|
viewerLatDeg: null,
|
|
viewerLonDeg: null,
|
|
trackedId: null,
|
|
floorWarmPoints: [],
|
|
});
|
|
const observation = (fields = {}) => ({
|
|
id: 'abc123',
|
|
reference: 'abc123',
|
|
longitude: -77,
|
|
latitude: 39,
|
|
callsign: 'TEST1',
|
|
baroAltitudeM: 1000,
|
|
ellipsoidAltitudeM: null,
|
|
onGround: false,
|
|
speedMps: 120,
|
|
courseDeg: 90,
|
|
positionTimeMs: 1700000000000,
|
|
...fields,
|
|
});
|
|
|
|
test('civil records keep aviation units separate from render height and survive missing fields', () => {
|
|
const store = records();
|
|
store.geoidReady = true;
|
|
const first = store.receive(observation(), view());
|
|
assert.equal(first.meta.altitude, 1000);
|
|
assert.equal(first.meta.renderAltitudeM, 1040);
|
|
assert.equal(first.fixEpochMs, 1700000000000);
|
|
first.meta.typeCode = 'B738';
|
|
const second = store.receive(
|
|
observation({
|
|
callsign: '',
|
|
baroAltitudeM: null,
|
|
speedMps: null,
|
|
courseDeg: null,
|
|
}),
|
|
view(),
|
|
);
|
|
assert.equal(second.prevMeta, first.meta);
|
|
assert.equal(second.meta.callsign, 'TEST1');
|
|
assert.equal(second.meta.altitude, 1000);
|
|
assert.equal(second.meta.renderAltitudeM, 1040);
|
|
assert.equal(second.meta.velocity, 120);
|
|
assert.equal(second.meta.true_track, 90);
|
|
assert.equal(second.meta.typeCode, 'B738');
|
|
assert.equal(Object.hasOwn(second.meta, 'cullPosition'), false);
|
|
assert.deepEqual(JSON.parse(JSON.stringify(second.meta)), second.meta);
|
|
});
|
|
|
|
test('civil record owners isolate state and preserve partial, missing-poll and landed retention', () => {
|
|
const store = records();
|
|
const other = records();
|
|
const { meta } = store.receive(observation(), view());
|
|
assert.equal(other.data.size, 0);
|
|
assert.equal(
|
|
store.absence('abc123', { complete: false, likelyLanded: false }),
|
|
'retain',
|
|
);
|
|
assert.equal(store.missingPolls.size, 0);
|
|
meta.observedReceiptMs = Date.now() - 300001;
|
|
assert.equal(
|
|
store.absence('abc123', { complete: false, likelyLanded: false }),
|
|
'stale',
|
|
);
|
|
assert.equal(
|
|
store.absence('abc123', { complete: true, likelyLanded: false }),
|
|
'stale',
|
|
);
|
|
assert.equal(
|
|
store.absence('abc123', { complete: true, likelyLanded: false }),
|
|
'remove',
|
|
);
|
|
// Admission decides removal; follow teardown can still read the record first.
|
|
assert.equal(store.data.get('abc123'), meta);
|
|
store.forget('abc123');
|
|
assert.equal(store.data.size, 0);
|
|
assert.equal(store.missingPolls.size, 0);
|
|
assert.equal(store.geoidNCache.size, 0);
|
|
store.receive(observation(), view());
|
|
assert.equal(
|
|
store.absence('abc123', { complete: true, likelyLanded: true }),
|
|
'remove',
|
|
);
|
|
});
|
|
|
|
test('ground transitions preserve last render height while a surface cell is cold', () => {
|
|
const store = records();
|
|
store.receive(observation({ ellipsoidAltitudeM: 1040 }), view());
|
|
const next = store.receive(
|
|
observation({ onGround: true, baroAltitudeM: null }),
|
|
view(),
|
|
);
|
|
assert.equal(next.groundFlipped, true);
|
|
assert.equal(next.meta.renderAltitudeM, 1040);
|
|
assert.equal(next.meta.wasAirborne, true);
|
|
});
|