mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 15:52:21 +00:00
Navara now matches Cesium where the review found it diverging: a flight holds the camera inputs, camera.changed counts turns as Cesium does, render requests made during a frame survive it, follow pinches zoom, ground widths follow the pixel ratio and Cyber sonar reaches glyph caches and models. On Cesium, a staged imagery swap keeps loading tiles, setView replaces a running flight, and a cleared weather detail goes away. The contract gains MoverSet.failed, maps.terrainRevision, render.maxTextureSize and surface.sampleTerrainMostDetailed on every engine, so layers retry failed models, key road heights by terrain, size weather textures to the GPU and place Bhote Koshi cards on detailed terrain. Engine switches keep the live view, follows, focus, layer options and cards: a pick hands over the exact pose, applies no address options and pans no carried-over card; a history visit still applies its entry. Layers put GhostMaps pins, cable landings, OSM Places and directions on the measured surface without per-frame sampling, draw the Cockpit contact dot, hide disabled CCTV on attach, and keep ALPR running outside secure contexts. KML imports draw raised polygon fills, rotated and coloured ground overlays and north-referenced icon headings, and report files with nothing to draw. QA scripts read the contract instead of Cesium internals (test:track is 109/109 again), wait for the camera to rest before clicking, and give cold switches and parked engines realistic time. Docs follow the code.
77 lines
2.2 KiB
JavaScript
77 lines
2.2 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { quantile, slope } from './qa-strict-session.mjs';
|
|
import { strictArguments, waitForCameraAtRest } from './qa-strict-harness.mjs';
|
|
|
|
test('slope is the least-squares growth per step', () => {
|
|
assert.equal(slope([[0, 5]]), 0);
|
|
assert.equal(
|
|
slope([
|
|
[20, 100],
|
|
[50, 103],
|
|
[100, 108],
|
|
]).toFixed(3),
|
|
'0.100',
|
|
);
|
|
assert.equal(
|
|
slope([
|
|
[1, 7],
|
|
[2, 7],
|
|
[3, 7],
|
|
]),
|
|
0,
|
|
);
|
|
});
|
|
|
|
test('quantile takes the nearest rank', () => {
|
|
assert.equal(quantile([], 0.5), null);
|
|
assert.equal(quantile([5, 1, 3, 2, 4], 0.5), 3);
|
|
assert.equal(
|
|
quantile(
|
|
[...Array(100)].map((_, i) => i + 1),
|
|
0.95,
|
|
),
|
|
95,
|
|
);
|
|
});
|
|
|
|
test('the runner hands each scenario its layers and its manifest path', () => {
|
|
assert.deepEqual(
|
|
strictArguments(['node', 'x', '--layers=a,b', '--evidence=/tmp/e.json']),
|
|
{ layers: ['a', 'b'], evidence: '/tmp/e.json' },
|
|
);
|
|
assert.deepEqual(strictArguments(['node', 'x', '--layers=']), {
|
|
layers: null,
|
|
evidence: process.env.QA_STRICT_EVIDENCE ?? null,
|
|
});
|
|
});
|
|
|
|
test('the camera is at rest once a flight has landed and it stays still', async () => {
|
|
// A selection's flight holds the inputs off; once they are on, the camera
|
|
// still moves one more sample before it stays put.
|
|
const poses = [0, 400, 900, 900, 1250, 1250, 1250];
|
|
const inputs = [false, false, false, false, true, true, true];
|
|
let frame = 0;
|
|
const engine = {
|
|
camera: { pose: () => ({ position: { x: poses[frame], y: 0, z: 6.4e6 } }) },
|
|
input: { cameraInputsEnabled: () => inputs[frame] },
|
|
};
|
|
const previous = globalThis.window;
|
|
globalThis.window = { __godsEyeView: { engine } };
|
|
const page = {
|
|
evaluate: async (fn) => fn(),
|
|
async waitForFunction(fn) {
|
|
for (; frame < poses.length; frame++) if (fn()) return;
|
|
throw new Error('timed out');
|
|
},
|
|
};
|
|
try {
|
|
await waitForCameraAtRest(page);
|
|
// Not while the flight holds the inputs (sample 3 repeats a pose), nor
|
|
// while the camera moves (sample 4).
|
|
assert.equal(frame, 5);
|
|
} finally {
|
|
globalThis.window = previous;
|
|
}
|
|
});
|