// src/data/flights.test.mjs // Focused tests for the pure analyst-record mapper (analyst query engine seam). // Pure function — no viewer/DOM needed; imported directly. import { test } from 'node:test'; import assert from 'node:assert/strict'; import * as Cesium from 'cesium'; import flightsLayer, { _addFlightTrackingCandidateForTest, _applyPendingFlightTrackingRestoreForTest, _armFlightTrackingRestoreForTest, _militaryLayerSuppressesForTest, _pendingFlightTrackingRestoreForTest, _setFlightTrackingRefreshOutcomeForTest, _setTrackedFlightRefreshStateForTest, _floorGroundedDisplayPositionForTest, _clearDisplayFloorStateForTest, mapAnalystRecord, } from './flights.js'; import { setMilitaryLayerActive } from './militaryRegistry.js'; import { GROUND_FLOOR_LIFT_M, reportMeshFloorCell, setMeshFloorPreferred, _clearMeshFloorCellsForTest, } from './groundFloor.js'; import { _setTrackedOverlayHostForTest, destroyTrackedReadout, initTrackedReadout, } from './trackedReadout.js'; test('share-Follow absence requires an accepted OpenSky snapshot', async () => { _setFlightTrackingRefreshOutcomeForTest({ status: 'source-unavailable' }); assert.equal( (await flightsLayer.resolveTrackingRestoreTarget('abc123')).status, 'source-unavailable', ); _setFlightTrackingRefreshOutcomeForTest({ status: 'accepted', ids: ['different'], }); const missing = await flightsLayer.resolveTrackingRestoreTarget('abc123'); assert.equal(missing.status, 'missing'); assert.equal(missing.reason, 'target-absent-from-snapshot'); }); const FULL_INFO = { callsign: 'SWA696 ', rawLat: 30.1945, rawLon: -97.6699, altitude: 1234.5, velocity: 210.2, true_track: 187.4, verticalRate: -4.5, onGround: false, klass: 'airliner', originCountry: 'United States', airline: 'Southwest Airlines', route: { origin: { code: 'AUS' }, destination: { code: 'LAX' } }, }; test('flights analyst record: full record maps every contract field', () => { const r = mapAnalystRecord('a1b2c3', FULL_INFO, { military: false, routeOk: true, }); assert.deepEqual(r, { id: 'SWA696', icao24: 'a1b2c3', callsign: 'SWA696', lat: 30.1945, lon: -97.6699, altitudeM: 1234.5, speedMps: 210.2, heading: 187.4, verticalRateMps: -4.5, onGround: false, military: false, aircraftClass: 'airliner', originCountry: 'United States', operator: 'Southwest Airlines', squawk: null, emergency: false, emergencyKind: null, emergencySource: null, emergencyBroadcast: null, lastContactAtMs: null, routeOrigin: 'AUS', routeDestination: 'LAX', }); }); test('flights analyst record: implausible route is suppressed (routeOk=false)', () => { const r = mapAnalystRecord('a1b2c3', FULL_INFO, { routeOk: false }); assert.equal(r.routeOrigin, null); assert.equal(r.routeDestination, null); }); test('flights analyst record: empty info yields nulls, never NaN/undefined', () => { const r = mapAnalystRecord('abc123', undefined); assert.equal(r.id, 'abc123'); // callsign fallback assert.equal(r.callsign, null); assert.equal(r.onGround, false); assert.equal(r.military, false); for (const [key, value] of Object.entries(r)) { assert.notEqual(value, undefined, `${key} must not be undefined`); if (typeof value === 'number') assert.ok(Number.isFinite(value), `${key} must not be NaN`); } }); test('flights analyst record: no callsign falls back to registration, then icao24', () => { const r = mapAnalystRecord('abc123', { ...FULL_INFO, callsign: ' ' }); assert.equal(r.id, 'abc123'); // FULL_INFO carries no registration assert.equal(r.callsign, null); assert.equal( mapAnalystRecord('abc123', { ...FULL_INFO, callsign: '', registration: 'N123AB', }).id, 'N123AB', ); assert.equal( mapAnalystRecord('abc123', { callsign: '', registration: ' ' }).id, 'abc123', ); }); test('flights analyst record: NaN kinematics become null, military flag passes through', () => { const r = mapAnalystRecord( 'ae01ce', { ...FULL_INFO, velocity: NaN, true_track: undefined, verticalRate: null, }, { military: true }, ); assert.equal(r.speedMps, null); assert.equal(r.heading, null); assert.equal(r.verticalRateMps, null); assert.equal(r.military, true); }); test('flights analyst record: output is JSON-safe (no Cesium types)', () => { const r = mapAnalystRecord('a1b2c3', FULL_INFO, { routeOk: true }); assert.deepEqual(JSON.parse(JSON.stringify(r)), r); }); test('flights first update forwards caller cancellation into the feed request', async () => { const realFetch = globalThis.fetch; let observedSignal = null; globalThis.fetch = (_url, options = {}) => new Promise((_resolve, reject) => { observedSignal = options.signal; options.signal?.addEventListener( 'abort', () => { reject(new DOMException('aborted', 'AbortError')); }, { once: true }, ); }); try { const controller = new AbortController(); const work = flightsLayer.update( { camera: { positionCartographic: null }, scene: {} }, { signal: controller.signal, }, ); await Promise.resolve(); assert.ok(observedSignal); controller.abort(); await assert.rejects(work, { name: 'AbortError' }); assert.equal(observedSignal.aborted, true); } finally { globalThis.fetch = realFetch; } }); test('nonempty OpenSky payload with zero usable rows cannot prove share target absence', async () => { _setTrackedFlightRefreshStateForTest({ icao24: 'abc123', entity: { gevLabelModel: { title: 'WARM', details: [] } }, billboard: { show: false }, billboardCollection: { show: true, remove() {} }, viewer: { camera: { positionCartographic: null }, scene: {} }, meta: { rawLat: 30.2, rawLon: -97.7, onGround: false }, }); const realFetch = globalThis.fetch; globalThis.fetch = async () => ({ ok: true, status: 200, headers: { get: () => null }, json: async () => ({ states: [null, {}, ['abc123', null, null, null, null, null, null]], }), }); try { await flightsLayer.update({ camera: { positionCartographic: null }, scene: {}, }); const resolution = await flightsLayer.resolveTrackingRestoreTarget('abc123'); assert.equal(resolution.status, 'source-unavailable'); assert.match( flightsLayer.getStats().error, /Malformed OpenSky aircraft rows/, ); assert.equal( flightsLayer.getAnalystRecords().length, 1, 'warm aircraft data is preserved', ); } finally { globalThis.fetch = realFetch; } }); test('a newly seen aircraft appears at its delayed position, not ahead of it', async () => { // The fleet renders RENDER_DELAY_SEC behind real time, so a fresh contact's // first displayed position is its fix projected back to that delayed time. // Creating the billboard at the raw fix drew it ahead until the next fleet // tick, which then jumped it back about one delay of travel. const added = []; const billboardCollection = { show: false, add(options) { const billboard = { ...options }; added.push(billboard); return billboard; }, remove() {}, }; const viewer = { camera: { positionCartographic: null }, scene: {} }; _setTrackedFlightRefreshStateForTest({ icao24: 'seed00', entity: null, billboard: { show: false, position: Cesium.Cartesian3.fromDegrees(0, 0, 0), }, billboardCollection, viewer, meta: { rawLat: 0, rawLon: 0, onGround: false }, tracked: false, }); const icao24 = 'fresh1'; const fixLon = -97.6; const fixLat = 30.3; const speedMps = 250; const nowSec = Math.floor(Date.now() / 1000); const realFetch = globalThis.fetch; globalThis.fetch = async (url) => { if (!String(url).startsWith('/api/flights')) { return { ok: true, status: 200, json: async () => ({ ac: [] }) }; } return { ok: true, status: 200, headers: { get: () => null }, json: async () => ({ time: nowSec, states: [ [ icao24, 'NEW123 ', 'United States', nowSec - 2, nowSec - 2, fixLon, fixLat, 10_668, false, speedMps, 90, 0, null, 10_700, null, null, null, 5, ], ], }), }; }; try { await flightsLayer.update(viewer); const billboard = added.find((entry) => entry.id === icao24); assert.ok(billboard, 'the new contact gets a billboard'); const shown = Cesium.Cartographic.fromCartesian(billboard.position); const fix = Cesium.Cartesian3.fromDegrees(fixLon, fixLat, 10_700); const behindM = Cesium.Cartesian3.distance( Cesium.Cartesian3.fromRadians(shown.longitude, shown.latitude, 10_700), fix, ); // Eastbound, so the delayed position is west of the fix by the travel // between the delayed time and the fix (about 28 s). assert.ok( Cesium.Math.toDegrees(shown.longitude) < fixLon, 'drawn behind the fix', ); assert.ok( behindM > speedMps * 25 && behindM < speedMps * 31, `expected about ${speedMps * 28} m behind the fix, got ${Math.round(behindM)} m`, ); } finally { globalThis.fetch = realFetch; } }); test('flights poll refreshes tracked callsign/FL/kts and marks a missed poll STALE', async () => { const icao24 = 'a1b2c3'; const entity = { gevLabelModel: { title: 'OLD', details: [] } }; const billboard = { position: Cesium.Cartesian3.fromDegrees(-97.7, 30.2, 9_000), color: Cesium.Color.WHITE, show: false, }; const billboardCollection = { show: false, remove() {} }; const viewer = { camera: { positionCartographic: null }, scene: {} }; _setTrackedFlightRefreshStateForTest({ icao24, entity, billboard, billboardCollection, viewer, meta: { callsign: 'OLD1', altitude: 9_000, renderAltitudeM: 9_050, velocity: 180, true_track: 80, klass: 'airliner', onGround: false, wasAirborne: true, turnRateDps: 0, rawLat: 30.2, rawLon: -97.7, }, }); const realFetch = globalThis.fetch; const nowSec = Math.floor(Date.now() / 1000); let openskyPoll = 0; globalThis.fetch = async (url) => { if (!String(url).startsWith('/api/flights')) { return { ok: true, status: 200, json: async () => ({ ac: [] }) }; } const states = openskyPoll++ === 0 ? [ [ icao24, 'DAL123 ', 'United States', nowSec, nowSec, -97.6, 30.3, 10_668, false, 250, 95, 5, null, 10_700, null, null, null, 5, ], ] : []; return { ok: true, status: 200, headers: { get: () => null }, json: async () => ({ time: nowSec, states }), }; }; try { await flightsLayer.update(viewer); assert.equal(entity.gevLabelModel.title, 'DAL123'); assert.match(entity.gevLabelModel.details.join(' · '), /FL350/); assert.match(entity.gevLabelModel.details.join(' · '), /486 kts/); await flightsLayer.update(viewer); assert.match( [entity.gevLabelModel.title, ...entity.gevLabelModel.details].join(' · '), /STALE/, ); } finally { globalThis.fetch = realFetch; } }); test('real civil track path creates no native label and publishes every cached host line', async () => { const icao24 = 'civ001'; const position = Cesium.Cartesian3.fromDegrees(-97.6699, 30.1945, 10_668); const now = Cesium.JulianDate.now(); const entities = new Cesium.EntityCollection(); const trackedEntityChanged = new Cesium.Event(); let trackedEntity; let cancelledFlights = 0; let appliedFrames = 0; const viewer = { entities, trackedEntityChanged, clock: { currentTime: now }, camera: { cancelFlight() { cancelledFlights += 1; }, position: new Cesium.Cartesian3(0, -10_000, 7_000), positionWC: new Cesium.Cartesian3(0, -10_000, 7_000), direction: Cesium.Cartesian3.UNIT_Y, transform: Cesium.Matrix4.IDENTITY, viewMatrix: Cesium.Matrix4.IDENTITY, frustum: { projectionMatrix: Cesium.Matrix4.IDENTITY }, lookAtTransform() { appliedFrames += 1; }, }, scene: { canvas: { clientWidth: 1600, clientHeight: 900 }, frameState: { frameNumber: 41, mode: Cesium.SceneMode.SCENE3D }, preUpdate: new Cesium.Event(), screenSpaceCameraController: null, }, isDestroyed: () => false, }; Object.defineProperty(viewer, 'trackedEntity', { get: () => trackedEntity, set(value) { trackedEntity = value; trackedEntityChanged.raiseEvent(value); }, }); viewer.scene.camera = viewer.camera; const billboard = { position, rotation: 0.3, show: true, width: 20, height: 20, color: Cesium.Color.WHITE, scale: 1, }; const publications = []; const host = { setEntries(sourceId, entries, options) { publications.push({ sourceId, entries, options }); }, setVisible() {}, clearSource() {}, }; const realWindow = globalThis.window; const realFetch = globalThis.fetch; globalThis.window = new EventTarget(); const selectionEvents = []; globalThis.window.addEventListener( 'gev:awareness-subject-selected', (event) => { selectionEvents.push(event.detail); }, ); globalThis.fetch = async () => ({ ok: false }); _setTrackedOverlayHostForTest(host); try { initTrackedReadout(viewer); _setTrackedFlightRefreshStateForTest({ icao24, entity: null, billboard, billboardCollection: { show: true, remove() {} }, viewer, tracked: false, history: [ { time: now, epochMs: Date.now(), position, velocity: 250, track: 95, }, ], meta: { callsign: 'N12345', altitude: 10_668, renderAltitudeM: 10_700, velocity: 250, true_track: 95, verticalRate: 0, klass: 'airliner', onGround: false, wasAirborne: true, turnRateDps: 0, rawLat: 30.1945, rawLon: -97.6699, airline: 'TEST AIR', typeName: 'A320', route: { origin: { code: 'AUS', lat: 30.1975, lon: -97.6664 }, destination: { code: 'LAX', lat: 33.9416, lon: -118.4085 }, }, }, }); assert.equal( flightsLayer.trackById(icao24, { origin: 'programmatic' }), true, ); const entity = viewer.trackedEntity; assert.ok( entity instanceof Cesium.Entity, 'trackById must create the real Cesium entity', ); assert.equal(entity.label, undefined); assert.ok( entities.values.every((candidate) => candidate.label === undefined), ); assert.deepEqual(entity.gevLabelModel, { title: 'N12345 · FL350 · 486 kts', details: ['TEST AIR · A320', 'AUS → LAX'], accent: '#39d0ff', }); viewer.scene.preUpdate.raiseEvent(); const initialAppliedFrames = appliedFrames; const initialCancelledFlights = cancelledFlights; assert.equal(flightsLayer.trackById(icao24, { origin: 'user' }), true); assert.equal( cancelledFlights, initialCancelledFlights, 'ordinary repeated tracking stays camera-idempotent', ); assert.equal( selectionEvents.at(-1)?.origin, 'user', 'same-target selection upgrades durable authority', ); assert.equal(entity.gevSelectionOrigin, 'user'); assert.equal(flightsLayer.refocusTrackedById('different-flight'), false); assert.equal( flightsLayer.refocusTrackedById(icao24, { origin: 'voice' }), true, ); assert.equal( selectionEvents.at(-1)?.origin, 'voice', 'same-target refocus forwards explicit authority', ); assert.equal(flightsLayer.refocusTrackedById(icao24), true); viewer.scene.preUpdate.raiseEvent(); assert.equal( viewer.trackedEntity, entity, 'refocus must retain the exact tracked entity', ); assert.equal( appliedFrames, initialAppliedFrames + 1, 'repeated refocus keeps one camera-frame owner', ); assert.equal( cancelledFlights, initialCancelledFlights + 2, 'only explicit refocus requests cancel camera flights', ); const publication = publications.at(-1); assert.equal(publication.sourceId, 'tracked'); const entry = publication.entries[0]; assert.equal(entry.protected, true); assert.equal(entry.paintLane, 'tracked'); assert.equal(entry.title, entity.gevLabelModel.title); assert.deepEqual(entry.details, entity.gevLabelModel.details); const display = entity.position.getValue(now); assert.ok(display, 'tracked position callback must seed its frame cache'); assert.equal( entry.position(), display, 'host must reuse the exact cached display Cartesian', ); flightsLayer.setParams( { selectedFlightsTrackingId: 'late001' }, { origin: 'share-restore' }, ); assert.equal(_pendingFlightTrackingRestoreForTest(), 'late001'); assert.equal(flightsLayer.trackById(icao24, { origin: 'user' }), true); assert.equal( _pendingFlightTrackingRestoreForTest(), null, 'new user selection cancels stale restore', ); _addFlightTrackingCandidateForTest({ icao24: 'late001', billboard: { ...billboard, position: Cesium.Cartesian3.fromDegrees(-97.5, 30.4, 9_000), }, meta: { ...FULL_INFO, callsign: 'LATE1', rawLat: 30.4, rawLon: -97.5 }, history: [], }); _applyPendingFlightTrackingRestoreForTest(); assert.equal(flightsLayer.getParams().selectedFlightsTrackingId, icao24); flightsLayer.stopTracking(); flightsLayer.setParams( { selectedFlightsTrackingId: 'late002' }, { origin: 'local-restore' }, ); assert.equal(_pendingFlightTrackingRestoreForTest(), 'late002'); flightsLayer.stopTracking({ origin: 'user' }); assert.equal( _pendingFlightTrackingRestoreForTest(), null, 'explicit clear cancels stale restore', ); _addFlightTrackingCandidateForTest({ icao24: 'late002', billboard: { ...billboard, position: Cesium.Cartesian3.fromDegrees(-97.4, 30.5, 8_000), }, meta: { ...FULL_INFO, callsign: 'LATE2', rawLat: 30.5, rawLon: -97.4 }, history: [], }); _applyPendingFlightTrackingRestoreForTest(); assert.equal(flightsLayer.getParams().selectedFlightsTrackingId, null); flightsLayer.setParams( { selectedFlightsTrackingId: 'late003' }, { origin: 'share-restore' }, ); assert.equal(_pendingFlightTrackingRestoreForTest(), 'late003'); flightsLayer.setParams({ models3d: false }, { origin: 'user' }); assert.equal( _pendingFlightTrackingRestoreForTest(), null, 'a newer explicit non-selection option cancels stale restore', ); _addFlightTrackingCandidateForTest({ icao24: 'late003', billboard: { ...billboard, position: Cesium.Cartesian3.fromDegrees(-97.3, 30.6, 7_000), }, meta: { ...FULL_INFO, callsign: 'LATE3', rawLat: 30.6, rawLon: -97.3 }, history: [], }); _applyPendingFlightTrackingRestoreForTest(); assert.equal(flightsLayer.getParams().selectedFlightsTrackingId, null); flightsLayer.setParams( { selectedFlightsTrackingId: 'late004' }, { origin: 'local-restore' }, ); assert.equal(_pendingFlightTrackingRestoreForTest(), 'late004'); _addFlightTrackingCandidateForTest({ icao24: 'late004', billboard: { ...billboard, position: Cesium.Cartesian3.fromDegrees(-97.2, 30.7, 6_000), }, meta: { ...FULL_INFO, callsign: 'LATE4', rawLat: 30.7, rawLon: -97.2 }, history: [], }); assert.equal(_applyPendingFlightTrackingRestoreForTest(), true); assert.equal(flightsLayer.getParams().selectedFlightsTrackingId, 'late004'); flightsLayer.setParams( { selectedFlightsTrackingId: 'late005' }, { origin: 'share-restore' }, ); assert.equal( flightsLayer.trackById(icao24, { origin: 'programmatic' }), true, ); assert.equal( _pendingFlightTrackingRestoreForTest(), 'late005', 'passive autofocus cannot revoke the shared target still waiting for its feed row', ); _addFlightTrackingCandidateForTest({ icao24: 'late005', billboard: { ...billboard, position: Cesium.Cartesian3.fromDegrees(-97.1, 30.8, 5_000), }, meta: { ...FULL_INFO, callsign: 'LATE5', rawLat: 30.8, rawLon: -97.1 }, history: [], }); assert.equal(_applyPendingFlightTrackingRestoreForTest(), true); assert.equal(flightsLayer.getParams().selectedFlightsTrackingId, 'late005'); } finally { flightsLayer.stopTracking(); viewer.scene.preUpdate.raiseEvent(); destroyTrackedReadout(); _setTrackedOverlayHostForTest(); globalThis.fetch = realFetch; globalThis.window = realWindow; } }); // --------------------------------------------------------------------------- // Label convention: callsign → registration → icao24 // // A callsign-less civil contact used to read as its raw ICAO hex ("ae1fa4") // even once adsbdb enrichment had supplied a registration ("N123AB"). The // military layer already resolved callsign → registration → hex; these lock // the civil layer to the same chain across EVERY public label surface, and // pin the invariant that identity stays icao24 (the `id`/`icao24`/`sourceId` // keys that tracking, declutter and the Context cohorts actually key on). // --------------------------------------------------------------------------- const LABEL_ICAO = 'ae1fa4'; const LABEL_POSITION = Cesium.Cartesian3.fromDegrees(-97.71, 30.21, 10_668); /** Seed one civil contact through the production refresh seam. */ function seedLabelContact({ callsign, registration, tracked = false, // Per-test metadata overrides, spread last so a test can set a field to // `undefined` to model "the feed never sent it" — a default parameter // could not express that, it would just re-supply the default. meta: metaOverrides = {}, }) { _setTrackedFlightRefreshStateForTest({ icao24: LABEL_ICAO, entity: null, billboard: { position: LABEL_POSITION, color: Cesium.Color.WHITE, show: true, }, billboardCollection: { show: true, remove() {} }, viewer: { camera: { positionCartographic: null }, scene: {} }, tracked, meta: { callsign, registration, altitude: 10_668, renderAltitudeM: 10_700, velocity: 250, true_track: 95, verticalRate: 0, klass: 'airliner', onGround: false, wasAirborne: true, turnRateDps: 0, rawLat: 30.21, rawLon: -97.71, ...metaOverrides, }, }); } /** Every public label string the civil layer publishes for one contact. */ function labelsFor({ callsign, registration }) { seedLabelContact({ callsign, registration, tracked: false }); const nearby = flightsLayer.getNearby(LABEL_POSITION, 250_000, 50)[0]; const detected = flightsLayer.getDetectableObjects({ maxCount: 50 })[0]; const all = flightsLayer.getAllPositions(50)[0]; seedLabelContact({ callsign, registration, tracked: true }); const subject = flightsLayer.getTrackedSubject(); return { getNearby: nearby?.id, getDetectableObjects: detected?.id, getAllPositions: all?.label, getTrackedSubject: subject?.label, analyst: mapAnalystRecord(LABEL_ICAO, { callsign, registration }).id, // Identity keys — these must NOT move with the label. _identity: { nearby: nearby?.icao24, detected: detected?.sourceId, all: all?.id, subject: subject?.id, }, }; } test('civil label chain: a callsign wins on every label surface', () => { const labels = labelsFor({ callsign: 'SWA696 ', registration: 'N123AB' }); for (const [surface, value] of Object.entries(labels)) { if (surface === '_identity') continue; assert.equal(value, 'SWA696', `${surface} must show the callsign`); } }); test('civil label chain: a blank callsign falls back to the registration, not the ICAO hex', () => { const labels = labelsFor({ callsign: ' ', registration: 'N123AB ' }); for (const [surface, value] of Object.entries(labels)) { if (surface === '_identity') continue; assert.equal( value, 'N123AB', `${surface} must show the registration, not ${LABEL_ICAO}`, ); } }); test('civil label chain: no callsign and no registration still reads as the ICAO hex', () => { for (const registration of [undefined, null, ' ']) { const labels = labelsFor({ callsign: null, registration }); for (const [surface, value] of Object.entries(labels)) { if (surface === '_identity') continue; assert.equal( value, LABEL_ICAO, `${surface} must fall through to the hex`, ); } } }); test('civil label chain: the cockpit descriptor exposes a trimmed registration', () => { // ui.js builds the Cockpit callsign readout as // `info.callsign || info.registration || info.icao24` off getTrackedInfo(), // so an untrimmed " N123AB " would render with its padding and a // whitespace-only value would win over the hex. seedLabelContact({ callsign: ' ', registration: ' N123AB ', tracked: true }); assert.equal(flightsLayer.getTrackedInfo()?.registration, 'N123AB'); seedLabelContact({ callsign: ' ', registration: ' ', tracked: true }); assert.equal(flightsLayer.getTrackedInfo()?.registration, null); }); test('the tracked descriptor publishes the reported vertical rate', () => { // `mapAnalystRecord` has always published `verticalRateMps`; the tracked // seam did not, so a consumer that needs climb/descent (a flight-phase // classifier, the cockpit) had to reach past getTrackedInfo() into the // raw record. Both seams now answer with the same field name and unit. seedLabelContact({ callsign: 'SWA696', registration: 'N123AB', tracked: true, meta: { verticalRate: -6.4 }, }); assert.equal(flightsLayer.getTrackedInfo()?.verticalRateMps, -6.4); assert.equal( mapAnalystRecord(LABEL_ICAO, { verticalRate: -6.4 }).verticalRateMps, -6.4, 'the analyst seam and the tracked seam must agree', ); }); test('an unreported vertical rate stays null, never a level-flight zero', () => { // Absent is not level. `stickyNumber` seeds this field with null, so a // contact that has never transmitted a rate must not read as 0 m/s — a // phase classifier would call that cruise while the aircraft climbs. for (const missing of [undefined, null, Number.NaN]) { seedLabelContact({ callsign: 'SWA696', registration: 'N123AB', tracked: true, meta: { verticalRate: missing }, }); assert.equal( flightsLayer.getTrackedInfo()?.verticalRateMps, null, `vertical rate ${String(missing)} must publish as null`, ); } }); test('civil label chain: identity stays icao24 while the label moves', () => { for (const fixture of [ { callsign: 'SWA696', registration: 'N123AB' }, { callsign: ' ', registration: 'N123AB' }, { callsign: null, registration: null }, ]) { const { _identity } = labelsFor(fixture); for (const [key, value] of Object.entries(_identity)) { assert.equal( value, LABEL_ICAO, `${key} identity must remain the ICAO hex`, ); } } }); // The `labelsFor` sweep above reads only the RETURNED label surfaces. The // selection EVENT is a separate publication path (`_publishTrackedSelection` // → `gev:awareness-subject-selected`), consumed by Context/awareness, and it // regressed to a raw `callsign || icao24` while every returned surface stayed // green. Observe the event itself so the chain cannot rot on that seam again. /** Capture the awareness selection event emitted for one seeded contact. */ function selectionEventFor({ callsign, registration }) { const realWindow = globalThis.window; globalThis.window = new EventTarget(); const events = []; globalThis.window.addEventListener( 'gev:awareness-subject-selected', (event) => events.push(event.detail), ); try { seedLabelContact({ callsign, registration, tracked: true }); flightsLayer.trackById(LABEL_ICAO, { origin: 'user' }); return events.at(-1) || null; } finally { globalThis.window = realWindow; } } test('civil label chain: the awareness selection EVENT uses the canonical chain', () => { for (const [fixture, expected] of [ [{ callsign: 'SWA696 ', registration: 'N123AB' }, 'SWA696'], // The regression: a callsign-less enriched contact must publish its // registration, never the raw ICAO hex. [{ callsign: ' ', registration: ' N123AB ' }, 'N123AB'], [{ callsign: null, registration: 'N123AB' }, 'N123AB'], // Only a contact with neither falls through to the hex. [{ callsign: null, registration: null }, LABEL_ICAO], [{ callsign: ' ', registration: ' ' }, LABEL_ICAO], ]) { const detail = selectionEventFor(fixture); assert.ok(detail, `no selection event for ${JSON.stringify(fixture)}`); assert.equal( detail.label, expected, `selection event label for ${JSON.stringify(fixture)}`, ); // Identity must NOT move with the label. assert.equal( detail.id, LABEL_ICAO, 'selection event identity stays the ICAO hex', ); assert.equal(detail.layerId, 'flights'); } }); test('civil tracked readout: a callsign-less enriched contact reads as its registration', async () => { const entity = { gevLabelModel: { title: 'OLD', details: [] } }; seedLabelContact({ callsign: ' ', registration: ' N123AB ', tracked: true }); _setTrackedFlightRefreshStateForTest({ icao24: LABEL_ICAO, entity, billboard: { position: LABEL_POSITION, color: Cesium.Color.WHITE, show: false, }, billboardCollection: { show: false, remove() {} }, viewer: { camera: { positionCartographic: null }, scene: {} }, meta: { callsign: ' ', registration: ' N123AB ', altitude: 10_668, renderAltitudeM: 10_700, velocity: 250, true_track: 95, klass: 'airliner', onGround: false, wasAirborne: true, turnRateDps: 0, rawLat: 30.21, rawLon: -97.71, }, }); const realFetch = globalThis.fetch; globalThis.fetch = async () => ({ ok: true, status: 200, headers: { get: () => null }, json: async () => ({ time: 0, states: [] }), }); try { await flightsLayer.update({ camera: { positionCartographic: null }, scene: {}, }); assert.match(entity.gevLabelModel.title, /^N123AB\b/); assert.doesNotMatch( [entity.gevLabelModel.title, ...entity.gevLabelModel.details].join(' · '), /ae1fa4/, ); } finally { globalThis.fetch = realFetch; } }); // --------------------------------------------------------------------------- // Military suppression must not fake a feed failure. // // `acceptedSnapshotIcaos` is built BEFORE the military-suppression `continue`, // so a mil-registry hex is provably present in a healthy snapshot while having // no billboard. `trackById` then fails and the share restore reported // "could not be restored — feed unavailable" about a feed that was fine. // This layer still OWNS a contact it is holding on its restore latch, so that // contact is exempt from suppression exactly like the tracked one. // --------------------------------------------------------------------------- const MIL_HEX = 'ae1234'; test('military suppression exempts the contact this layer is still restoring', () => { const realWindow = globalThis.window; globalThis.window = new EventTarget(); try { _armFlightTrackingRestoreForTest(null); setMilitaryLayerActive(false); assert.equal( _militaryLayerSuppressesForTest(MIL_HEX), false, 'nothing is suppressed while the Military layer is off', ); setMilitaryLayerActive(true); assert.equal( _militaryLayerSuppressesForTest(MIL_HEX), true, 'an ordinary mil-registry duplicate is suppressed', ); // The regression: a pending restore target was suppressed, so it could // never render, never track, and reported a feed failure instead. _armFlightTrackingRestoreForTest(MIL_HEX); assert.equal( _militaryLayerSuppressesForTest(MIL_HEX), false, 'a contact held on the restore latch must still render in this layer', ); assert.equal( _militaryLayerSuppressesForTest('bb9999'), true, 'the exemption is scoped to the pending target only', ); _armFlightTrackingRestoreForTest(null); assert.equal(_militaryLayerSuppressesForTest(MIL_HEX), true); } finally { setMilitaryLayerActive(false); _armFlightTrackingRestoreForTest(null); globalThis.window = realWindow; } }); // --------------------------------------------------------------------------- // Display-time ground floor (2026-08-19 — qa-floor-verify FAIL at KAUS). // // A grounded contact's renderAltitudeM is chosen ONCE per poll from the floor // of the FIX's coarse cell. What actually renders is the dead-reckoned display // position, which drifts across cells for the whole 30 s segment and, while a // stale ground contact coasts, for up to 300 s / several hundred metres. On a // graded apron (KAUS spans ~119–140 m ellipsoidal) the sprite then renders // under the mesh it drifted over — measured to −15.5 m. These pin the fix at // the point of DISPLAY: read-only against the shared floor cache, grounded // contacts only, never when a 3D model owns the visual (T7 one-shot). // --------------------------------------------------------------------------- const _floorCarto = (pos) => Cesium.Cartographic.fromCartesian(pos, Cesium.Ellipsoid.WGS84); test('a newly seen taxiing aircraft starts on the floor under its delayed position', async () => { // A grounded contact is drawn at its delayed position lifted onto the floor // under it. Creating the billboard without that lift started it on the // floor of its reported fix, then the next fleet tick raised it. _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const added = []; const billboardCollection = { show: false, add(options) { const billboard = { ...options }; added.push(billboard); return billboard; }, remove() {}, }; const viewer = { camera: { positionCartographic: null }, scene: {} }; _setTrackedFlightRefreshStateForTest({ icao24: 'seed00', entity: null, billboard: { show: false, position: Cesium.Cartesian3.fromDegrees(0, 0, 0), }, billboardCollection, viewer, meta: { rawLat: 0, rawLon: 0, onGround: false }, tracked: false, }); const icao24 = 'taxi01'; const fixLon = -97.66; const fixLat = 30.2; const speedMps = 10; // The reported fix sits on a 100 m floor; the apron it taxied from is higher. reportMeshFloorCell(fixLat, fixLon, 100); for (let k = 1; k <= 40; k += 1) { reportMeshFloorCell(fixLat, fixLon - k * 0.0001, 131.5); } const nowSec = Math.floor(Date.now() / 1000); const realFetch = globalThis.fetch; globalThis.fetch = async (url) => { if (!String(url).startsWith('/api/flights')) { return { ok: true, status: 200, json: async () => ({ ac: [] }) }; } return { ok: true, status: 200, headers: { get: () => null }, json: async () => ({ time: nowSec, states: [ [ icao24, 'TAXI01 ', 'United States', nowSec - 2, nowSec - 2, fixLon, fixLat, null, true, speedMps, 90, 0, null, null, null, null, null, 5, ], ], }), }; }; try { await flightsLayer.update(viewer); const billboard = added.find((entry) => entry.id === icao24); assert.ok(billboard, 'the new contact gets a billboard'); const shown = _floorCarto(billboard.position); assert.ok( Cesium.Math.toDegrees(shown.longitude) < fixLon, 'drawn behind the fix', ); assert.ok( Math.abs(shown.height - (131.5 + GROUND_FLOOR_LIFT_M)) < 0.05, `height ${shown.height} should be the delayed position's floor, 131.5 + lift`, ); } finally { globalThis.fetch = realFetch; _clearMeshFloorCellsForTest(); _clearDisplayFloorStateForTest(); } }); test('display floor: a grounded contact that drifted onto a higher cell is lifted', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); // Fix cell floor was 124.7; the display has taxied into a 140.2 m cell. reportMeshFloorCell(30.2004, -97.6604, 140.2); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); const out = _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, ); const c = _floorCarto(out); assert.ok( Math.abs(c.height - (140.2 + GROUND_FLOOR_LIFT_M)) < 0.05, `height ${c.height} should be 140.2 + lift`, ); // Lifted straight up — the drifted lat/lon is preserved exactly. assert.ok(Math.abs(Cesium.Math.toDegrees(c.latitude) - 30.2004) < 1e-6); assert.ok(Math.abs(Cesium.Math.toDegrees(c.longitude) + 97.6604) < 1e-6); }); test('display floor: an AIRBORNE contact over the same cell is never lifted', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 140.2); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); const out = _floorGroundedDisplayPositionForTest( { onGround: false }, pos, false, ); assert.equal(out, pos, 'airborne display positions pass through untouched'); }); test('display floor: T7 — a model-owned grounded contact keeps its billboard datum', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 140.2); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); const out = _floorGroundedDisplayPositionForTest( { onGround: true }, pos, true, ); assert.equal( out, pos, 'moving it would drag groundSnap past its 50 m re-sample threshold', ); }); test('display floor: a contact already above the floor is passed through unchanged', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 124.7); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 140.2); const out = _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, ); assert.equal(out, pos, 'no rebuild when nothing needs lifting'); }); test('display floor: a cold display cell leaves the contact where it is', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); const out = _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, ); assert.equal(out, pos, 'no floor data → no clamp (never invent a surface)'); }); test('display floor: mesh cells are ignored outside the google-3d regime', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 140.2); setMeshFloorPreferred(false); // globe stack: the DEM IS the rendered terrain const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); const out = _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, ); assert.equal(out, pos); setMeshFloorPreferred(true); }); // --- F6: cell-boundary hysteresis, end to end ------------------------------ test('display floor: jitter across a cell edge does not alternate the floor', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); // Two neighbouring cells with a 6 m step between their floors. reportMeshFloorCell(30.2004, -97.6604, 140); reportMeshFloorCell(30.2014, -97.6604, 146); const at = (lat) => { const out = _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, lat, 120), false, 'jitter', ); return _floorCarto(out).height; }; const settled = at(30.2004); // squarely inside the low cell assert.ok( Math.abs(settled - (140 + GROUND_FLOOR_LIFT_M)) < 0.05, `settled ${settled}`, ); // 30.2006 belongs to the HIGH cell but is only ~11 m past the boundary. assert.ok( Math.abs(at(30.2006) - settled) < 0.05, 'held the low cell across the edge', ); assert.ok(Math.abs(at(30.2004) - settled) < 0.05, 'and back again — no pop'); }); test('display floor: a real crossing does adopt the next cell', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 140); reportMeshFloorCell(30.2014, -97.6604, 146); const at = (lat) => _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, lat, 120), false, 'crossing', ), ).height; at(30.2004); const crossed = at(30.2014); // properly into the next cell assert.ok( Math.abs(crossed - (146 + GROUND_FLOOR_LIFT_M)) < 0.05, `crossed ${crossed}`, ); }); // --- F7: no rebuild when nothing changed ----------------------------------- // A clamped stationary contact (parked, or coasting on a zero-velocity fix) // hits the clamp at fleet-tick rate forever. The "no rebuild" claim was false // for exactly that case: its raw height stays below the floor, so every tick // rebuilt an identical Cartesian. test('display floor: a clamped stationary contact reuses its previous output', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 140); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 120); const first = _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'parked', ); const second = _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'parked', ); assert.notEqual( first, pos, 'it really is clamped (not the pass-through case)', ); assert.equal( second, first, 'same input + same floor ⇒ the very same object, no rebuild', ); }); test('display floor: the cached output is dropped when the floor changes under it', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 140); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 120); const before = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'warming', ), ).height; // A late mesh sample raises this cell (a fresh module state stands in for the // one-shot latch, which never overwrites). _clearMeshFloorCellsForTest(); reportMeshFloorCell(30.2004, -97.6604, 175); const after = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'warming', ), ).height; assert.ok(Math.abs(before - 141.5) < 0.05, `before ${before}`); assert.ok( Math.abs(after - 176.5) < 0.05, `after ${after} — a stale cache would still read 141.5`, ); }); // --- F8: hold the last known floor through a floor-data gap ---------------- // // Owner incident 2026-08-21: four `[terrain-heights-proxy] refresh incomplete` // events in a row (Re:Earth timing out), and a parked contact at a Texas field // popped BELOW the photoreal mesh for a few seconds. A cold cell used to mean // "no clamp", which is only safe if the un-clamped height is a real reading — // and for a grounded contact reporting no altitude it is the geoid, tens of // metres under the mesh inland. Owner: "hold the last known altitude until a // fresh one comes in. Never render otherwise." test('display floor: a cold cell HOLDS the last floor that resolved for this contact', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 140.2); // On the warm cell: clamped onto the floor as usual. const warm = _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7), false, 'held', ); assert.ok( Math.abs(_floorCarto(warm).height - (140.2 + GROUND_FLOOR_LIFT_M)) < 0.05, ); // Taxis ~550 m onto a cell nothing has resolved, still at the geoid-ish // height the poll path handed it. Pre-fix this passed straight through — // buried. const cold = _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, 30.2054, 124.7), false, 'held', ); const h = _floorCarto(cold).height; assert.ok( Math.abs(h - (140.2 + GROUND_FLOOR_LIFT_M)) < 0.05, `held ${h} — a cold cell must hold 140.2 + lift, never the 124.7 it arrived with`, ); }); test('display floor: with NO prior anywhere the contact is left exactly where it is', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); const out = _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'fresh', ); assert.equal( out, pos, 'nothing measured anywhere ⇒ nothing invented — same object, no clamp', ); }); test('display floor: a fresh contact on a cold cell adopts a resolved NEIGHBOUR', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); // Two adjacent cells resolved; the contact stands on the unresolved one // between them. The LOWER neighbour wins — a high reading next to a cold // cell is as likely to be a roof as ground, and only a low one is inert. reportMeshFloorCell(30.2014, -97.6604, 141.0); reportMeshFloorCell(30.1994, -97.6604, 152.0); const out = _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7), false, 'neighbour', ); const h = _floorCarto(out).height; assert.ok( Math.abs(h - (141.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `neighbour hold ${h} — expected the lower of the two resolved neighbours`, ); }); // Drives a stationary contact at the production 80 ms fleet cadence and reports // the largest DOWNWARD step any single tick produced, plus where it settled. // `mutate` runs before the tick at that index, so a target can be moved // mid-approach. function _driveEase(id, pos, fromMs, ticks, mutate = () => {}) { let previous = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, id, fromMs, ), ).height; const opened = previous; let maxStepM = 0; for (let i = 1; i <= ticks; i += 1) { mutate(i); const h = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, id, fromMs + i * 80, ), ).height; maxStepM = Math.max(maxStepM, previous - h); previous = h; } return { opened, settled: previous, maxStepM }; } test('display floor: a hold released onto a LOWER floor eases down, never snaps', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); // Holds 200 m borrowed from the warm neighbours (the lowest of the pair). reportMeshFloorCell(30.2014, -97.6604, 200.0); reportMeshFloorCell(30.1994, -97.6604, 240.0); const r = _driveEase('ease', pos, 1000, 60, (i) => { if (i === 1) reportMeshFloorCell(30.2004, -97.6604, 160.0); // its own cell resolves lower }); const totalDropM = r.opened - (160.0 + GROUND_FLOOR_LIFT_M); assert.ok( Math.abs(r.opened - (200.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `opened at ${r.opened}`, ); assert.ok( r.maxStepM <= totalDropM * 0.25, `largest single-tick drop ${r.maxStepM.toFixed(1)} m of ${totalDropM.toFixed(1)} m — a snap is the whole drop at once`, ); assert.ok( Math.abs(r.settled - (160.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `settled at ${r.settled}`, ); }); test('display floor: a hold released onto a HIGHER floor rises immediately', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); const at = (ms) => _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'rise', ms, ), ).height; reportMeshFloorCell(30.2014, -97.6604, 160.0); reportMeshFloorCell(30.1994, -97.6604, 190.0); assert.ok(Math.abs(at(1000) - (160.0 + GROUND_FLOOR_LIFT_M)) < 0.05); reportMeshFloorCell(30.2004, -97.6604, 205.0); // No easing UP: an eased rise is time spent under the mesh, which is the // whole failure this path exists to prevent. assert.ok( Math.abs(at(1001) - (205.0 + GROUND_FLOOR_LIFT_M)) < 0.05, 'the next tick is already on the higher floor', ); }); // --- F9: the hold is a live state machine, not a one-shot ------------------ // Both were reproduced against an earlier cut of this change. A parked contact // never moves and its cell never warms, so an input-keyed memo returned the // unresolved answer forever; and the hold outlived the grounded-billboard // regime that owns it. test('display floor: a STATIONARY unresolved contact still adopts a floor that arrives later', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); const at = (ms) => _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'parked-cold', ms, ); assert.equal(at(1000), pos, 'nothing anywhere yet — passes through'); // The poll's warm batch lands the cells NEXT DOOR (this contact's own cell // is still cold, so only the hold chain can see them). reportMeshFloorCell(30.2014, -97.6604, 138.0); reportMeshFloorCell(30.1994, -97.6604, 160.0); const adopted = _floorCarto(at(1600)).height; // past the probe throttle assert.ok( Math.abs(adopted - (138.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `stationary contact ${adopted} — a memoized unresolved answer would still read 124.7`, ); }); test('display floor: a stationary contact FOLLOWS the neighbourhood as it fills in', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); const at = (ms) => _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'upgrade', ms, ), ).height; reportMeshFloorCell(30.2014, -97.6604, 200.0); reportMeshFloorCell(30.1994, -97.6604, 240.0); assert.ok(Math.abs(at(1000) - (200.0 + GROUND_FLOOR_LIFT_M)) < 0.05); // A third neighbour warms BELOW the pair — the first two were the terminal // side, this is the apron. A borrowed floor is never owned: the contact must // follow rather than keep its first answer. reportMeshFloorCell(30.2004, -97.6614, 120.0); let h = 0; for (let ms = 1600; ms <= 6000; ms += 80) h = at(ms); assert.ok( Math.abs(h - (120.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `followed to ${h} — a borrowed floor must not outlive a better one`, ); }); test('display floor: an on_ground FLAP mid-takeoff-roll never dips below the runway', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); // JFK: ~4 m MSL field, geoid N ~ -32.5 m, so the runway is ~-28.5 m // ellipsoidal and the geoid is 4 m UNDER it. OpenSky's on_ground flag flaps // through a rotation, and at the same moment the fix's height source switches // from the resolved surface to baro + geoid N — which at a sea-level field IS // the geoid. Deleting the hold on the airborne poll made that switch visible: // the contact came back grounded with no prior, outrunning its own floor // cells at 23 m/s, and sat under the runway (owner sighting, VIR138M). const GROUND = -28.5, GEOID = -32.5, LON = -73.78; reportMeshFloorCell(40.64, LON, GROUND); // only the cell it STARTED on is warm let lat = 40.64; const grounded = []; for (let i = 0; i <= 22; i += 1) { const onGround = i !== 10; // one airborne poll mid-roll const out = _floorGroundedDisplayPositionForTest( { onGround }, Cesium.Cartesian3.fromDegrees(LON, lat, GEOID), false, 'VIR138M', 1000 + i * 80, ); if (onGround) grounded.push(_floorCarto(out).height); lat += 0.00021; // ~23 m per tick at 45 kt } const dipped = grounded.filter((h) => h < GROUND - 0.05); assert.deepEqual( dipped, [], `${dipped.length} of ${grounded.length} grounded ticks rendered below the runway`, ); assert.ok( Math.abs(grounded[grounded.length - 1] - (GROUND + GROUND_FLOOR_LIFT_M)) < 0.05, 'and it is still standing on the floor it held, not on nothing', ); }); test('display floor: the rehydration seed EXPIRES on its own age, with NO calls in between', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const field = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); reportMeshFloorCell(30.2014, -97.6604, 200.0); reportMeshFloorCell(30.1994, -97.6604, 240.0); assert.ok( Math.abs( _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, field, false, 'longhaul', 1000, ), ).height - (200.0 + GROUND_FLOOR_LIFT_M), ) < 0.05, 'holding 200 m before departure', ); // ONE airborne tick parks the seed, and then this contact is not seen again // for 198 s: off the poll on a cruise, outside the corridor radius, tab // hidden. Nothing runs in between, so the retire path never gets a second // chance to expire it — the age has to be judged where it comes BACK. // An earlier cut checked expiry only on the retire path and cleared // `retiredMs` before validating it, so this reused the 200 m floor. _floorGroundedDisplayPositionForTest( { onGround: false }, field, false, 'longhaul', 2000, ); _clearMeshFloorCellsForTest(); // a different airport: nothing warm here const back = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); assert.equal( _floorGroundedDisplayPositionForTest( { onGround: true }, back, false, 'longhaul', 200000, ), back, 'an expired seed is gone — no floor is invented from a 198-second-old measurement', ); }); test('display floor: the seed expires the same way when the contact keeps reporting', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const field = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); reportMeshFloorCell(30.2014, -97.6604, 200.0); reportMeshFloorCell(30.1994, -97.6604, 240.0); _floorGroundedDisplayPositionForTest( { onGround: true }, field, false, 'cruise', 1000, ); // The other half of the same clock: an airborne contact that IS still being // ticked. The window is the window either way. _floorGroundedDisplayPositionForTest( { onGround: false }, field, false, 'cruise', 2000, ); _floorGroundedDisplayPositionForTest( { onGround: false }, field, false, 'cruise', 200000, ); _clearMeshFloorCellsForTest(); const back = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); assert.equal( _floorGroundedDisplayPositionForTest( { onGround: true }, back, false, 'cruise', 201000, ), back, 'no memory of the departure field survives the grace window', ); }); // --- The seed is a MEMORY, and ranks below anything freshly measured --------- // It exists for the flap window, where a rotation outruns its own floor cells // and nothing nearby is warm either. The moment the neighbourhood CAN answer, // it is the neighbourhood that knows where the ground is. test('display floor: a rehydrated seed ranks BELOW fresh neighbour evidence', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const departed = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 50); reportMeshFloorCell(30.2004, -97.6604, 200.0); assert.ok( Math.abs( _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, departed, false, 'short-hop', 1000, ), ).height - (200.0 + GROUND_FLOOR_LIFT_M), ) < 0.05, 'standing on its own 200 m cell', ); _floorGroundedDisplayPositionForTest( { onGround: false }, departed, false, 'short-hop', 2000, ); // Re-grounds 0.56 km away — INSIDE HELD_FLOOR_MAX_DRIFT_KM, so the drift // bound does not save us here; the tier order has to. Its own cell is cold, // but two adjacent cells have since resolved, and they are 100 m of ground. _clearMeshFloorCellsForTest(); reportMeshFloorCell(30.2044, -97.6604, 100.0); reportMeshFloorCell(30.2064, -97.6604, 105.0); const moved = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2054, 50); const rendered = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, moved, false, 'short-hop', 3000, ), ).height; assert.ok( Math.abs(rendered - (100.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `rendered at ${rendered} — a seed that outranked the neighbourhood read 201.5, 100 m in the air`, ); }); test('display floor: with nothing fresh to contradict it, the seed still answers', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); // The other side of the same rule, and the reason the seed exists: the flap // window, where the contact has outrun its own cells and no neighbour has // warmed either. Demoting the seed must not mean discarding it. const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 50); reportMeshFloorCell(30.2004, -97.6604, 200.0); _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'flap', 1000, ); _floorGroundedDisplayPositionForTest( { onGround: false }, pos, false, 'flap', 2000, ); _clearMeshFloorCellsForTest(); // the whole neighbourhood goes cold const held = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, 30.2014, 50), false, 'flap', 3000, ), ).height; assert.ok( Math.abs(held - (200.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `held ${held} — with no measurement anywhere the seed is the best thing available`, ); }); test('display floor: re-measuring its own cell makes a seeded contact authoritative again', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pad = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); reportMeshFloorCell(30.2004, -97.6604, 300.0); _floorGroundedDisplayPositionForTest( { onGround: true }, pad, false, 'relatch', 1000, ); _floorGroundedDisplayPositionForTest( { onGround: false }, pad, false, 'relatch', 2000, ); // Re-grounds on its own, still-warm 300 m cell: that is a live reading, so the // demotion is over and the ordinary tier order applies again. assert.ok( Math.abs( _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, pad, false, 'relatch', 3000, ), ).height - (300.0 + GROUND_FLOOR_LIFT_M), ) < 0.05, 'back on its own measured cell', ); // It now taxis 220 m onto a cold cell whose two adjacent cells read 100 m. An // own floor it measured while standing here outranks a borrowed one — the // seed flag has to have been cleared by that reading, or the contact drops // 200 m onto someone else's ground. reportMeshFloorCell(30.2014, -97.6604, 100.0); reportMeshFloorCell(30.2034, -97.6604, 100.0); const taxied = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, 30.2024, 100), false, 'relatch', 4000, ), ).height; assert.ok( Math.abs(taxied - (300.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `taxied at ${taxied} — a still-seeded contact would have taken the 100 m neighbours`, ); }); test('display floor: taking off and landing elsewhere does NOT inherit the old field floor', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const field = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); reportMeshFloorCell(30.2004, -97.6604, 200.0); // 1. grounded on a 200 m floor. assert.ok( Math.abs( _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, field, false, 'trip', 1000, ), ).height - (200.0 + GROUND_FLOOR_LIFT_M), ) < 0.05, ); // 2. it taxis ~330 m onto ground nothing has resolved, so 200 m is now being // HELD — this is the state that must not survive the trip. const heldAt = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2034, 124.7); assert.ok( Math.abs( _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, heldAt, false, 'trip', 1500, ), ).height - (200.0 + GROUND_FLOOR_LIFT_M), ) < 0.05, 'the hold is active before takeoff', ); // 3. airborne — the hold belongs to the grounded-billboard regime, not to the // contact, so leaving that regime must retire it. _floorGroundedDisplayPositionForTest( { onGround: false }, heldAt, false, 'trip', 2000, ); // 4. lands at another field on a real 100 m floor. reportMeshFloorCell(31.5004, -97.6604, 100.0); const landed = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, 31.5004, 60), false, 'trip', 3000, ), ).height; assert.ok( Math.abs(landed - (100.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `landed at ${landed} — a stale hold would arrive at 201.5 and ease down from it`, ); }); test('display floor: a model-owned interval retires the hold too', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); reportMeshFloorCell(30.2004, -97.6604, 200.0); _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'handoff', 1000, ); // It moves onto unresolved ground, so 200 m is being HELD. const heldAt = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2034, 124.7); _floorGroundedDisplayPositionForTest( { onGround: true }, heldAt, false, 'handoff', 1500, ); // T7: the 3D model takes the visual. Our state is retired (nothing visual is // touched — groundSnap's one-shot input is untouched either way). _floorGroundedDisplayPositionForTest( { onGround: true }, heldAt, true, 'handoff', 2000, ); // The billboard resumes over ground that has since resolved LOWER. A stale // heldActive would read this as a hold release and ease; it is a fresh start. reportMeshFloorCell(30.2034, -97.6604, 150.0); const back = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, heldAt, false, 'handoff', 3000, ), ).height; assert.ok( Math.abs(back - (150.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `resumed at ${back} — no ease, because there was no hold to release`, ); }); test('display floor: a model handoff back onto a COLD cell takes the neighbourhood, not the seed', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); // Same handoff as above with the FAVOURABLE half removed: the cell the // billboard resumes on is still cold, so the live read cannot overrule the // seed and the tier order is the only thing standing between the contact and // a floor it measured 330 m ago. Two adjacent cells have resolved at 150 m. const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); reportMeshFloorCell(30.2004, -97.6604, 200.0); _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'cold-handoff', 1000, ); const heldAt = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2034, 124.7); _floorGroundedDisplayPositionForTest( { onGround: true }, heldAt, false, 'cold-handoff', 1500, ); _floorGroundedDisplayPositionForTest( { onGround: true }, heldAt, true, 'cold-handoff', 2000, ); _clearMeshFloorCellsForTest(); reportMeshFloorCell(30.2024, -97.6604, 150.0); reportMeshFloorCell(30.2044, -97.6604, 155.0); const back = _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, heldAt, false, 'cold-handoff', 3000, ), ).height; assert.ok( Math.abs(back - (150.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `resumed at ${back} — a seed that outranked the neighbourhood would resume at 201.5`, ); }); // --- F10: no contact waits on another -------------------------------------- // A probe is eight synchronous Map reads against the shared floor cache — no // fetch, no sampleHeight, nothing async — so there is no shared resource to // ration. An earlier draft added a global per-tick budget with a fairness queue // anyway; it protected ~2 ms of cache reads (measured: 200 synchronised // all-cold contacts = 2.1 ms, 2.6% of one 80 ms fleet tick) and cost two // starvation defects. This pins the property that replaced it. test('display floor: every grounded contact is floored on the tick it asks', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const N = 85; // the fleet size the old scheduler was measured starving at const latOf = (i) => 30.2 + i * 0.003; for (let i = 0; i < N; i += 1) { reportMeshFloorCell(latOf(i) + 0.001, -97.66, 300 + i); reportMeshFloorCell(latOf(i) - 0.001, -97.66, 340 + i); // the pair's high side } const heights = []; for (let i = 0; i < N; i += 1) { heights.push( _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.66, latOf(i), 100), false, `q${i}`, 1000, ), ).height, ); } const unfloored = heights .map((h, i) => Math.abs(h - (300 + i + GROUND_FLOOR_LIFT_M)) < 0.05 ? null : i, ) .filter((i) => i != null); assert.deepEqual( unfloored, [], 'a global budget would leave the tail of the fleet on the geoid for later ticks', ); }); test('display floor: a re-probe that finds a LOWER neighbour eases down, never snaps', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); reportMeshFloorCell(30.2014, -97.6604, 200.0); reportMeshFloorCell(30.1994, -97.6604, 240.0); // borrowed floor = the low one, 200 m // A third neighbour warms far below — the apron beside the terminal. The // borrowed floor recomputes to 120 m. An 80 m drop, and not a step. const target = 120.0 + GROUND_FLOOR_LIFT_M; const r = _driveEase('relatch', pos, 1000, 80, (i) => { if (i === 8) reportMeshFloorCell(30.2004, -97.6614, 120.0); // past the 500 ms probe throttle }); const totalDropM = r.opened - target; assert.ok( r.maxStepM <= totalDropM * 0.25, `largest single-tick drop ${r.maxStepM.toFixed(1)} m of ${totalDropM.toFixed(1)} m`, ); assert.ok( Math.abs(r.settled - target) < 0.05, `settled at ${r.settled}, expected ${target}`, ); }); test('display floor: a SECOND lower re-latch mid-approach retargets without a jump', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); reportMeshFloorCell(30.2014, -97.6604, 400.0); reportMeshFloorCell(30.1994, -97.6604, 440.0); // borrowed floor = 400 m // Two lower neighbours arrive in sequence, the second while the approach to // the first is still running. A from/duration ease re-evaluated against a // moved target jumps by the eased fraction of the change — measured at 100 m // in one tick. An approach from the DISPLAYED value has no such seam. const target = 100.0 + GROUND_FLOOR_LIFT_M; const r = _driveEase('retarget', pos, 1000, 120, (i) => { if (i === 8) reportMeshFloorCell(30.2004, -97.6614, 300.0); // -> 300 m if (i === 16) reportMeshFloorCell(30.2004, -97.6594, 100.0); // -> 100 m, mid-approach }); const totalDropM = r.opened - target; assert.ok( r.maxStepM <= totalDropM * 0.25, `largest single-tick drop ${r.maxStepM.toFixed(1)} m of ${totalDropM.toFixed(1)} m — the retarget must not be a seam`, ); assert.ok( Math.abs(r.settled - target) < 0.05, `settled at ${r.settled}, expected ${target}`, ); }); test('display floor: a DELAYED tick cannot close more of the gap than a prompt one', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); const at = (ms) => _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'stall', ms, ), ).height; reportMeshFloorCell(30.2014, -97.6604, 400.0); reportMeshFloorCell(30.1994, -97.6604, 440.0); // borrowed floor = 400 m const opened = at(1000); reportMeshFloorCell(30.2004, -97.6604, 100.0); // own cell resolves 300 m lower const totalDropM = opened - (100.0 + GROUND_FLOOR_LIFT_M); // A hidden tab, a long frame, a GC pause: the tick after the drop arrives // late. The exponential alone would close 28% at 120 ms and 75% after a // 500 ms stall — the snap this approach exists to prevent, reintroduced by // the schedule rather than by the code. let previous = opened; let maxStepM = 0; let clock = 1000; for (const dt of [120, 500, 2000, 80, 80, 80, 80, 80]) { clock += dt; const h = at(clock); maxStepM = Math.max(maxStepM, previous - h); previous = h; } assert.ok( maxStepM <= totalDropM * 0.25, `largest step ${maxStepM.toFixed(1)} m of ${totalDropM.toFixed(1)} m across a stalled schedule`, ); assert.ok(previous < opened, 'and it is still making progress downward'); }); test('display floor: a floor rising MID-APPROACH is taken whole, on that tick', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); const pos = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 100); reportMeshFloorCell(30.2014, -97.6604, 400.0); reportMeshFloorCell(30.1994, -97.6604, 440.0); // borrowed floor = 400 m const at = (ms) => _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, pos, false, 'riseMid', ms, ), ).height; at(1000); reportMeshFloorCell(30.2004, -97.6604, 150.0); // own cell resolves far below let h = 0; for (let i = 1; i <= 4; i += 1) h = at(1000 + i * 80); // approach is under way assert.ok(h < 400.0 && h > 160.0, `mid-approach at ${h}`); // Now the floor RISES above where the contact is currently drawn. Easing up // would leave it under the mesh for the duration; it must arrive at once. _clearMeshFloorCellsForTest(); reportMeshFloorCell(30.2004, -97.6604, 500.0); const risen = at(1000 + 5 * 80); assert.ok( Math.abs(risen - (500.0 + GROUND_FLOOR_LIFT_M)) < 0.05, `rose to ${risen} — an eased rise is time spent under the mesh`, ); }); test('display floor: a held floor is dropped once the contact leaves the ground it describes', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 200.0); const at = (lat, ms) => _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, lat, 124.7), false, 'drift', ms, ); assert.ok( Math.abs( _floorCarto(at(30.2004, 1000)).height - (200.0 + GROUND_FLOOR_LIFT_M), ) < 0.05, ); // ~670 m on: cold cell, but that is inside one poll's rollout. Hold stands. assert.ok( Math.abs( _floorCarto(at(30.2064, 2000)).height - (200.0 + GROUND_FLOOR_LIFT_M), ) < 0.05, 'inside the drift bound the held floor still describes the ground', ); // ~3.3 km on: the held value is no longer a measurement of anywhere this // contact has been, so it is dropped rather than stretched. const far = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2304, 124.7); assert.equal( _floorGroundedDisplayPositionForTest( { onGround: true }, far, false, 'drift', 3000, ), far, 'past the drift bound: back to no clamp, not a stretched one', ); }); test('display floor: an ordinary cell-to-cell floor DROP keeps its existing timing', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); // Both cells resolved throughout — no hold is ever in play, so the release // ease must stay out of it. Only a RELEASE eases; the everyday path is // untouched by this round. reportMeshFloorCell(30.2004, -97.6604, 200.0); reportMeshFloorCell(30.2044, -97.6604, 160.0); const at = (lat, ms) => _floorCarto( _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, lat, 124.7), false, 'plain', ms, ), ).height; assert.ok(Math.abs(at(30.2004, 1000) - (200.0 + GROUND_FLOOR_LIFT_M)) < 0.05); assert.ok( Math.abs(at(30.2044, 1050) - (160.0 + GROUND_FLOOR_LIFT_M)) < 0.05, 'the very next tick is on the new cell — no ease was introduced here', ); }); test('display floor: the hold never applies to an airborne contact or a modelled one', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 140.2); const on = Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 124.7); _floorGroundedDisplayPositionForTest({ onGround: true }, on, false, 'gates'); const cold = Cesium.Cartesian3.fromDegrees(-97.6704, 30.2104, 124.7); assert.equal( _floorGroundedDisplayPositionForTest( { onGround: false }, cold, false, 'gates', ), cold, 'airborne heights belong to the fix-time clamp, held floor or not', ); assert.equal( _floorGroundedDisplayPositionForTest( { onGround: true }, cold, true, 'gates', ), cold, 'T7: a model-owned contact keeps its billboard datum, held floor or not', ); }); test('display floor: two contacts on the same cell get their own outputs', () => { _clearDisplayFloorStateForTest(); _clearMeshFloorCellsForTest(); setMeshFloorPreferred(true); reportMeshFloorCell(30.2004, -97.6604, 140); const a = _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.6604, 30.2004, 120), false, 'A', ); const b = _floorGroundedDisplayPositionForTest( { onGround: true }, Cesium.Cartesian3.fromDegrees(-97.66041, 30.20041, 121), false, 'B', ); assert.notEqual( a, b, 'a shared scratch would hand both contacts the same object', ); assert.ok(Math.abs(_floorCarto(a).height - _floorCarto(b).height) < 0.05); });