mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
refactor: separate Cockpit controller and presentation components
This commit is contained in:
1 parent
43db5c19bb
commit
8075c70e6e
24 files changed
+2258
-1928
No files matched your search
@@ -0,0 +1,99 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { CockpitViewController } from './cockpitController.js';
|
||||
|
||||
function environment() {
|
||||
const original = { document: globalThis.document, window: globalThis.window };
|
||||
const document = Object.assign(new EventTarget(), {
|
||||
getElementById: () => null,
|
||||
querySelectorAll: () => [],
|
||||
body: { classList: { remove() {} } },
|
||||
});
|
||||
const window = Object.assign(new EventTarget(), { clearTimeout, setTimeout });
|
||||
globalThis.document = document;
|
||||
globalThis.window = window;
|
||||
const callbacks = new Set();
|
||||
const event = { addEventListener(fn) { callbacks.add(fn); return () => callbacks.delete(fn); } };
|
||||
const viewer = {
|
||||
scene: { preUpdate: event, screenSpaceCameraController: { enableInputs: false } },
|
||||
trackedEntityChanged: event,
|
||||
entities: { contains: () => false },
|
||||
};
|
||||
return { viewer, callbacks, restore() { Object.assign(globalThis, original); } };
|
||||
}
|
||||
|
||||
test('Cockpit subscriptions are released once and retained actions cannot restart it', () => {
|
||||
const env = environment();
|
||||
try {
|
||||
const owner = new CockpitViewController(env.viewer, { services: {} });
|
||||
assert.equal(env.callbacks.size, 2);
|
||||
owner.dispose();
|
||||
owner.dispose();
|
||||
assert.equal(env.callbacks.size, 0);
|
||||
assert.equal(owner.enter(), false);
|
||||
assert.equal(owner.navigateContext(1), false);
|
||||
assert.equal(owner.toggleTrackedTr3b(), false);
|
||||
assert.equal(owner.update(), false);
|
||||
assert.equal(owner.active, false);
|
||||
} finally { env.restore(); }
|
||||
});
|
||||
|
||||
test('disposing an active Cockpit releases the supplied render owner without retracking', () => {
|
||||
const env = environment();
|
||||
try {
|
||||
const released = [];
|
||||
const owner = new CockpitViewController(env.viewer, {
|
||||
services: { releaseContinuousRender: reason => released.push(reason) },
|
||||
});
|
||||
owner.active = true;
|
||||
owner.dispose();
|
||||
owner.dispose();
|
||||
assert.deepEqual(released, ['cockpit']);
|
||||
assert.equal(env.viewer.scene.screenSpaceCameraController.enableInputs, true);
|
||||
assert.equal(env.viewer.trackedEntity, undefined);
|
||||
assert.equal(owner.active, false);
|
||||
} finally { env.restore(); }
|
||||
});
|
||||
|
||||
test('aircraft identity is read from the supplied layer instances', () => {
|
||||
const env = environment();
|
||||
try {
|
||||
const civilian = { icao24: 'abc123', layerId: 'flights', callsign: 'CIVIL' };
|
||||
const military = { icao24: 'def456', layerId: 'military', callsign: 'MILITARY' };
|
||||
const owner = new CockpitViewController(env.viewer, { services: {
|
||||
flightsLayer: { getTrackedInfo: () => civilian },
|
||||
militaryFlightsLayer: { getTrackedInfo: () => military },
|
||||
} });
|
||||
env.viewer.trackedEntity = { gevTrackedId: 'military:def456' };
|
||||
assert.deepEqual(owner.readAircraftInfo(), military);
|
||||
env.viewer.trackedEntity = { gevTrackedId: 'flights:abc123' };
|
||||
assert.deepEqual(owner.readAircraftInfo(), civilian);
|
||||
owner.dispose();
|
||||
} finally { env.restore(); }
|
||||
});
|
||||
|
||||
test('an obsolete regional briefing cannot publish after Cockpit disposal', async () => {
|
||||
const env = environment();
|
||||
try {
|
||||
let finish;
|
||||
let signal;
|
||||
const owner = new CockpitViewController(env.viewer, { services: {
|
||||
regionalDistanceM: () => Infinity,
|
||||
fetchRegionalBrief: (_lat, _lon, options) => {
|
||||
signal = options.signal;
|
||||
return new Promise(resolve => { finish = resolve; });
|
||||
},
|
||||
releaseContinuousRender() {},
|
||||
} });
|
||||
const published = [];
|
||||
owner.renderRegionalBrief = payload => published.push(payload);
|
||||
owner.active = true;
|
||||
owner.maybeRefreshRegionalBrief({ layerId: 'flights', icao24: 'abc123', latitude: 30, longitude: -97 });
|
||||
owner.dispose();
|
||||
assert.equal(signal.aborted, true);
|
||||
finish({ articles: [] });
|
||||
await new Promise(resolve => setImmediate(resolve));
|
||||
assert.deepEqual(published, []);
|
||||
assert.equal(owner.regionalBriefAbort, null);
|
||||
} finally { env.restore(); }
|
||||
});
|
||||
Reference in new issue
Block a user