style: format the phase 2 files and add them to the format scope

Prettier on the 13 new test files that failed --check; format-scope.json
now lists every file phase 2 added (src/globe/**, engineChoice, navaraMode,
cameraAngles, the QA scripts and pages, build/navaraAssets and tests).
This commit is contained in:
German Khokhlov committed 2026-10-15 22:34:25 +04:00
1 parent 312ed416e9
commit 80cc0b536e
14 files changed
+229 -46

No files matched your search

+58 -1
View File
@@ -1002,5 +1002,62 @@
"src/tools/globePanel.test.mjs",
"src/costEndpointThrottle.test.mjs",
"src/sources/gbfsStations.test.mjs",
"scripts/qa-gbfs-names.mjs"
"scripts/qa-gbfs-names.mjs",
"build/navaraAssets.js",
"scripts/qa-engine-bench.mjs",
"scripts/qa-engine-shell.mjs",
"scripts/qa/navara-contract.html",
"scripts/qa/navaraContractPage.js",
"src/annotations/resolverEngine.test.mjs",
"src/app/controls.test.mjs",
"src/app/engineChoice.js",
"src/app/engineChoice.test.mjs",
"src/app/navaraMode.js",
"src/app/navaraScene.test.mjs",
"src/app/viewerlessTools.test.mjs",
"src/cameraAngles.js",
"src/cameraAngles.test.mjs",
"src/data/cameraArrival.test.mjs",
"src/data/cameraSensitivity.test.mjs",
"src/globe/cesium/camera.js",
"src/globe/cesium/convert.js",
"src/globe/cesium/createCesiumEngine.js",
"src/globe/cesium/credits.js",
"src/globe/cesium/events.js",
"src/globe/cesium/frames.js",
"src/globe/cesium/input.js",
"src/globe/cesium/maps.js",
"src/globe/cesium/picker.js",
"src/globe/cesium/projector.js",
"src/globe/cesium/render.js",
"src/globe/cesium/surface.js",
"src/globe/contract.js",
"src/globe/navara/cameraMath.js",
"src/globe/navara/cameraMath.test.mjs",
"src/globe/navara/cameraModel.js",
"src/globe/navara/cameraModel.test.mjs",
"src/globe/navara/createNavaraEngine.js",
"src/globe/navara/createNavaraEngine.test.mjs",
"src/globe/navara/credits.js",
"src/globe/navara/credits.test.mjs",
"src/globe/navara/groundFloor.js",
"src/globe/navara/groundFloor.test.mjs",
"src/globe/navara/index.js",
"src/globe/navara/input.js",
"src/globe/navara/input.test.mjs",
"src/globe/navara/internals.js",
"src/globe/navara/internals.test.mjs",
"src/globe/navara/maps.js",
"src/globe/navara/maps.test.mjs",
"src/globe/navara/surface.js",
"src/globe/navara/surface.test.mjs",
"src/globe/navara/viewOptions.js",
"src/globe/navara/viewOptions.test.mjs",
"src/globe/testing/contractSuite.mjs",
"src/globe/testing/fakeEngine.js",
"src/mapStackController.test.mjs",
"src/orbit.test.mjs",
"src/services/groundSnap.test.mjs",
"src/sharelinkPose.test.mjs",
"src/tooling/navaraAssets.test.mjs"
]
+18 -4
View File
@@ -33,7 +33,10 @@ test('viewportBias reads the engine view rectangle', () => {
east: geo.math.toRadians(-97.5),
north: geo.math.toRadians(30.5),
});
assert.equal(resolver.viewportBias(engine), '30.0000,-98.0000|30.5000,-97.5000');
assert.equal(
resolver.viewportBias(engine),
'30.0000,-98.0000|30.5000,-97.5000',
);
engine.fake.script('viewRectangle', undefined);
assert.equal(resolver.viewportBias(engine), null);
});
@@ -43,7 +46,9 @@ test('pickWorldFromScreen tries the depth pick, then the ellipsoid, then the glo
const depth = geo.cartesian3.fromDegrees(-97.7, 30.3, 210);
engine.fake.script('pickPosition', depth);
const picked = resolver.pickWorldFromScreen(engine, 0.5, 0.5);
assert.ok(Math.abs(picked.lat - 30.3) < 1e-9 && Math.abs(picked.height - 210) < 1e-6);
assert.ok(
Math.abs(picked.lat - 30.3) < 1e-9 && Math.abs(picked.height - 210) < 1e-6,
);
const [screen] = engine.fake.callsOf('picker.pickPosition')[0].args;
assert.deepEqual([screen.x, screen.y], [512, 384]);
@@ -53,7 +58,10 @@ test('pickWorldFromScreen tries the depth pick, then the ellipsoid, then the glo
assert.ok(Math.abs(ellipsoid.height) < 1e-3);
engine.fake.script('pickEllipsoid', undefined);
engine.fake.script('pickGlobe', geo.cartesian3.fromDegrees(-97.71, 30.25, 300));
engine.fake.script(
'pickGlobe',
geo.cartesian3.fromDegrees(-97.71, 30.25, 300),
);
const globe = resolver.pickWorldFromScreen(engine, 0.5, 0.5);
assert.ok(Math.abs(globe.height - 300) < 1e-6);
engine.fake.script('pickGlobe', undefined);
@@ -71,7 +79,13 @@ test('near-view recovery centres on the engine camera when nothing is picked', a
return [];
},
};
await resolver.placesNearViewRecovery(engine, 'cafe', null, undefined, placeSearch);
await resolver.placesNearViewRecovery(
engine,
'cafe',
null,
undefined,
placeSearch,
);
assert.equal(centres.length, 1);
assert.ok(Math.abs(centres[0].latitude - 48.85) < 1e-9);
assert.ok(Math.abs(centres[0].longitude - 2.35) < 1e-9);
+4 -1
View File
@@ -11,7 +11,10 @@ const read = (relative) =>
test('the controls pass the scene engine to the shell', () => {
const controls = read('./controls.js');
assert.match(controls, /scene: \{ viewer, engine, mapStackController, operations \}/);
assert.match(
controls,
/scene: \{ viewer, engine, mapStackController, operations \}/,
);
assert.match(controls, /new Controls\(viewer, \{[\s\S]*?\n\s+engine,\n/);
});
+8 -2
View File
@@ -12,8 +12,14 @@ test('claims on a globe engine set its camera sensitivity and share one ledger',
assert.equal(claimCameraSensitivity(engine, 'traffic', 0.05), 0.05);
assert.equal(engine.camera.percentageChanged, 0.05);
// The engine and its camera are the same claimant.
assert.equal(claimCameraSensitivity(engine.camera, 'installations', 0.01), 0.01);
assert.deepEqual(cameraSensitivityClaims(engine), ['traffic', 'installations']);
assert.equal(
claimCameraSensitivity(engine.camera, 'installations', 0.01),
0.01,
);
assert.deepEqual(cameraSensitivityClaims(engine), [
'traffic',
'installations',
]);
assert.equal(releaseCameraSensitivity(engine, 'installations'), 0.05);
assert.equal(releaseCameraSensitivity(engine.camera, 'traffic'), 0.5);
assert.equal(engine.camera.percentageChanged, 0.5);
+12 -5
View File
@@ -56,7 +56,12 @@ function cameraAt(lon, lat, height, heading, pitch, roll, size = [1280, 800]) {
test('heading π/2 at pitch 0 looks east with up along the local up', () => {
const position = cartesian3.fromDegrees(-120, 35, 3000);
const { direction, up } = orientationVectors(position, math.PI_OVER_TWO, 0, 0);
const { direction, up } = orientationVectors(
position,
math.PI_OVER_TWO,
0,
0,
);
const axes = axesAt(position);
near(dot(direction, axes.east), 1, 1e-12, 'direction·east');
near(dot(up, axes.up), 1, 1e-12, 'up·up');
@@ -183,11 +188,11 @@ test('viewProjection agrees with projectToWindow', () => {
test('horizonVisible: the nadir is visible and the antipode hidden', () => {
const eye = cartesian3.fromDegrees(20, 10, 1e6);
assert.equal(horizonVisible(eye, cartesian3.fromDegrees(20, 10, 0)), true);
assert.equal(horizonVisible(eye, cartesian3.fromDegrees(-160, -10, 0)), false);
assert.equal(
horizonVisible(eye, cartesian3.fromDegrees(-70, 10, 2e7)),
true,
horizonVisible(eye, cartesian3.fromDegrees(-160, -10, 0)),
false,
);
assert.equal(horizonVisible(eye, cartesian3.fromDegrees(-70, 10, 2e7)), true);
});
test("viewRectangle matches Cesium's computeViewRectangle (S4 reference poses)", () => {
@@ -255,7 +260,9 @@ test('rectangleViewPosition frames a rectangle at the centre of a nadir view', (
[rectangle.east, rectangle.north],
]) {
const corner = projectToWindow(camera, cartesian3.fromRadians(lon, lat));
assert.ok(corner.x >= 0 && corner.x <= 1280 && corner.y >= 0 && corner.y <= 800);
assert.ok(
corner.x >= 0 && corner.x <= 1280 && corner.y >= 0 && corner.y <= 800,
);
}
});
+24 -7
View File
@@ -326,9 +326,11 @@ test('lookAt locks the transform, aims at the target and release keeps the pose'
target,
geo.ellipsoid.WGS84,
);
camera.transform().forEach((value, index) =>
near(value, frame[index], 1e-9, `transform[${index}]`),
);
camera
.transform()
.forEach((value, index) =>
near(value, frame[index], 1e-9, `transform[${index}]`),
);
camera.release();
assert.deepEqual(camera.transform(), [...matrix4.IDENTITY]);
near(
@@ -395,8 +397,15 @@ test('picks, projection and view rectangle come from the pose and canvas size',
const back = model.worldToWindow(hit);
near(back.x, centre.x, 1e-6, 'x');
const rectangle = camera.viewRectangle();
assert.ok(rectangle.west < math.toRadians(20) && math.toRadians(20) < rectangle.east);
near(camera.pose().fovy, 2 * Math.atan(Math.tan(Math.PI / 6) / 1.6), 1e-15, 'fovy');
assert.ok(
rectangle.west < math.toRadians(20) && math.toRadians(20) < rectangle.east,
);
near(
camera.pose().fovy,
2 * Math.atan(Math.tan(Math.PI / 6) / 1.6),
1e-15,
'fovy',
);
});
test('destroy cancels a running flight and stops the moveEnd timer', () => {
@@ -452,7 +461,12 @@ test('livePosition is one engine-owned object holding the current position; heig
const moved = cartesian3.fromDegrees(21, 11, 9e5);
port.drawn = { position: moved, ...orientationVectors(moved, 0.3, -1, 0) };
frame();
near(cartesian3.distance(camera.livePosition, moved), 0, 1e-9, 'follows Navara');
near(
cartesian3.distance(camera.livePosition, moved),
0,
1e-9,
'follows Navara',
);
near(camera.height(), 9e5, 1e-6, 'height after a user move');
const pose = camera.pose();
assert.notEqual(pose.position, live, 'pose shares the live object');
@@ -469,7 +483,10 @@ test('commanded fires before each camera command and never for reads', () => {
assert.equal(raised, 0);
const target = cartesian3.fromDegrees(10, 10, 0);
camera.setView({ destination: cartesian3.fromDegrees(10, 10, 1e6) });
camera.flyTo({ destination: cartesian3.fromDegrees(11, 10, 1e6), duration: 0 });
camera.flyTo({
destination: cartesian3.fromDegrees(11, 10, 1e6),
duration: 0,
});
camera.flyToSphere({ center: target, radius: 10 }, { duration: 0 });
camera.lookAt(target, { heading: 0, pitch: -1, range: 500 });
camera.cancelFlight();
+39 -9
View File
@@ -18,14 +18,31 @@ function fakeView() {
parentElement: { id: 'container' },
});
const position = cartesian3.fromDegrees(0, 0, 1e7);
const { direction, up } = orientationVectors(position, 0, -math.PI_OVER_TWO, 0);
const { direction, up } = orientationVectors(
position,
0,
-math.PI_OVER_TWO,
0,
);
// three's camera.matrixWorld: columns right, up, back (−direction), position.
const right = cartesian3.cross(direction, up, cartesian3.create());
const elements = [
right.x, right.y, right.z, 0,
up.x, up.y, up.z, 0,
-direction.x, -direction.y, -direction.z, 0,
position.x, position.y, position.z, 1,
right.x,
right.y,
right.z,
0,
up.x,
up.y,
up.z,
0,
-direction.x,
-direction.y,
-direction.z,
0,
position.x,
position.y,
position.z,
1,
];
const view = {
canvas,
@@ -58,7 +75,9 @@ function fakeView() {
view.calls.push(['setCamera', pose]);
},
flyTo(pose, options) {
return new Promise((resolve) => view.flights.push({ pose, options, resolve }));
return new Promise((resolve) =>
view.flights.push({ pose, options, resolve }),
);
},
forceUpdate() {
view.calls.push(['forceUpdate']);
@@ -135,7 +154,12 @@ test("the camera starts from Navara's drawn camera and pushes poses with setCame
test("Navara's fov follows Cesium's vertical fov, also after a resize", () => {
const { view, engine } = setup();
near(view.camera.fovs.at(-1), math.toDegrees(cesiumFovy(1280, 800)), 1e-12, 'fov');
near(
view.camera.fovs.at(-1),
math.toDegrees(cesiumFovy(1280, 800)),
1e-12,
'fov',
);
view.canvas.clientWidth = 600;
view.canvas.clientHeight = 900;
view.emit('resize', 600, 900);
@@ -187,7 +211,10 @@ test('the projector agrees with the camera', () => {
const window = engine.projector.worldToWindow(ahead);
near(window.x, 640, 1e-6, 'x');
near(window.y, 400, 1e-6, 'y');
assert.equal(engine.projector.horizonVisible(cartesian3.fromDegrees(0, 0)), true);
assert.equal(
engine.projector.horizonVisible(cartesian3.fromDegrees(0, 0)),
true,
);
});
test('destroy removes its Navara listeners, keeps the view and is idempotent', () => {
@@ -224,7 +251,10 @@ test('pickGlobe meets the terrain along the pick ray, or the ellipsoid', () => {
const place = geo.cartographic.fromCartesian(raised);
near(place.height, 2000, 0.5, 'terrain height (m)');
near(math.toDegrees(place.longitude), 0, 1e-6, 'longitude');
assert.equal(engine.picker.pickGlobe(cartesian2.create(640, -1e7)), undefined);
assert.equal(
engine.picker.pickGlobe(cartesian2.create(640, -1e7)),
undefined,
);
});
test('a user gesture cancels a flight without raising camera.commanded', () => {
+6 -2
View File
@@ -12,7 +12,9 @@ function fakeAttribution() {
},
add(items) {
for (const item of items)
if (!shown.some((entry) => entry.attributionHtml === item.attributionHtml))
if (
!shown.some((entry) => entry.attributionHtml === item.attributionHtml)
)
shown.push(item);
},
remove(items) {
@@ -31,7 +33,9 @@ test('addStatic shows HTML in the attribution and the remover is idempotent', ()
const attribution = fakeAttribution();
const { credits } = createNavaraCredits({ attribution });
const remove = credits.addStatic('<a href="x">X</a>', { onScreen: true });
assert.deepEqual(attribution.shown, [{ attributionHtml: '<a href="x">X</a>' }]);
assert.deepEqual(attribution.shown, [
{ attributionHtml: '<a href="x">X</a>' },
]);
remove();
remove();
assert.deepEqual(attribution.shown, []);
+4 -1
View File
@@ -107,7 +107,10 @@ test('modifiers: a listener fires only for its own key, an unmodified one only w
test('on validates its arguments and returns an idempotent remover', () => {
const { canvas, input } = setup();
assert.throws(() => input.on('wheel', () => {}), TypeError);
assert.throws(() => input.on('click', () => {}, { modifier: 'meta' }), TypeError);
assert.throws(
() => input.on('click', () => {}, { modifier: 'meta' }),
TypeError,
);
let count = 0;
const off = input.on('down', () => count++);
off();
+6 -1
View File
@@ -24,7 +24,12 @@ test('Navara internals are pinned: package.json and internals.js name the same e
const PRIVATE_ACCESS = /\.\s*_[A-Za-z]|\[\s*['"`]_[A-Za-z]/;
test('the private-member pattern catches dotted and bracketed access', () => {
for (const code of ['view._isIdle', 'view?._scenes', "view['_isIdle']", 'v[ "_x" ]'])
for (const code of [
'view._isIdle',
'view?._scenes',
"view['_isIdle']",
'v[ "_x" ]',
])
assert.ok(PRIVATE_ACCESS.test(code), code);
for (const code of ['view.isIdle', 'a_b.c', "map['key']"])
assert.ok(!PRIVATE_ACCESS.test(code), code);
+24 -7
View File
@@ -71,14 +71,19 @@ test('setBaseImagery builds Navara raster layers for OSM and Esri, one at a time
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
);
assert.equal(layer.desc.source, view.sources[0]);
assert.ok(view.shown.some((item) => /OpenStreetMap/.test(JSON.stringify(item))));
assert.ok(
view.shown.some((item) => /OpenStreetMap/.test(JSON.stringify(item))),
);
await maps.setBaseImagery({
descriptor: { id: 'esri-imagery', kind: 'esri-imagery' },
credit: '<a href="https://www.esri.com">Powered by Esri</a>',
});
assert.equal(layersOf(view, 'raster').length, 1);
assert.equal(view.sources.length, 1);
assert.match(view.sources[0].desc.url, /World_Imagery\/MapServer\/tile\/\{z\}\/\{y\}\/\{x\}$/);
assert.match(
view.sources[0].desc.url,
/World_Imagery\/MapServer\/tile\/\{z\}\/\{y\}\/\{x\}$/,
);
assert.deepEqual(view.shown, [
{ attributionHtml: '<a href="https://www.esri.com">Powered by Esri</a>' },
]);
@@ -100,7 +105,10 @@ test('an imagery source Navara cannot build rejects and the current one stays',
await maps.setBaseImagery({ kind: 'osm' });
await assert.rejects(maps.setBaseImagery({ kind: 'ion', style: 2 }), /ion/);
await assert.rejects(maps.setBaseImagery({ kind: 'nope' }), TypeError);
assert.equal(view.sources[0].desc.url, 'https://tile.openstreetmap.org/{z}/{x}/{y}.png');
assert.equal(
view.sources[0].desc.url,
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
);
});
test('setTerrain: keyless Re:Earth mesh, flat ellipsoid, and ion world terrain with a token', async () => {
@@ -150,7 +158,10 @@ test('a newer terrain request wins over an older one still resolving', async ()
});
const world = maps.setTerrain({ kind: 'world', accessToken: 't' });
await maps.setTerrain({ kind: 'keyless' });
answer({ ok: true, json: async () => ({ url: 'https://x/', accessToken: 'y' }) });
answer({
ok: true,
json: async () => ({ url: 'https://x/', accessToken: 'y' }),
});
await world;
const [terrain] = layersOf(view, 'terrain');
assert.match(terrain.desc.source.desc.url, /reearth/);
@@ -240,7 +251,11 @@ test('current() returns the passed sources: base while the globe shows, tiles wh
await maps.setBaseImagery(esri);
const [raster] = layersOf(view, 'raster');
assert.match(raster.desc.source.desc.url, /World_Imagery/);
assert.equal(raster.desc.raster?.show, false, 'the new layer shows over tiles');
assert.equal(
raster.desc.raster?.show,
false,
'the new layer shows over tiles',
);
assert.ok(
!view.shown.some((item) => /esri/i.test(JSON.stringify(item))),
'its credit shows over tiles',
@@ -250,7 +265,10 @@ test('current() returns the passed sources: base while the globe shows, tiles wh
await maps.setPhotorealTiles(null);
assert.deepEqual(maps.current(), { baseImagery: esri, photoreal: null });
assert.notEqual(raster.desc.raster?.show, false, 'base not back');
assert.ok(view.shown.some((item) => /esri/i.test(JSON.stringify(item))), 'credit not back');
assert.ok(
view.shown.some((item) => /esri/i.test(JSON.stringify(item))),
'credit not back',
);
});
test('the same tiles under a new source object count as that source', async () => {
@@ -277,4 +295,3 @@ test('releasePhotorealTiles forgets the source and takes its tiles away if shown
assert.equal(maps.current().photoreal, null);
assert.equal(layersOf(view, '3d-tiles').length, 0);
});
+6 -1
View File
@@ -52,7 +52,12 @@ function tileAt(lon, lat, height, half = 100) {
return { tile, mesh };
}
function setup({ tiles = [], terrain = () => undefined, idle = true, retain } = {}) {
function setup({
tiles = [],
terrain = () => undefined,
idle = true,
retain,
} = {}) {
const view = {
sampleTerrainHeight: (place) => terrain(place),
};
+12 -3
View File
@@ -21,20 +21,29 @@ test('orbit locks onto the target every frame from the current heading, and stop
});
const target = geo.cartesian3.fromDegrees(-97.74, 30.27, 30);
const orbit = new OrbitController(engine);
assert.equal(orbit.toggle(target, { radius: 800, pitch: -20, speed: 10 }), true);
assert.equal(
orbit.toggle(target, { radius: 800, pitch: -20, speed: 10 }),
true,
);
assert.ok(getRenderGovernorDiagnostics().holds.includes('camera-orbit'));
t.mock.timers.tick(500);
engine.fake.frame();
const [first] = engine.fake.callsOf('camera.lookAt');
assert.deepEqual(first.args[0], target);
assert.ok(Math.abs(first.args[1].heading - (0.4 + geo.math.toRadians(5))) < 1e-9);
assert.ok(
Math.abs(first.args[1].heading - (0.4 + geo.math.toRadians(5))) < 1e-9,
);
assert.equal(first.args[1].pitch, geo.math.toRadians(-20));
assert.equal(first.args[1].range, 800);
assert.equal(orbit.toggle(), false);
assert.equal(engine.fake.callsOf('camera.release').length, 1);
assert.ok(!getRenderGovernorDiagnostics().holds.includes('camera-orbit'));
engine.fake.frame();
assert.equal(engine.fake.callsOf('camera.lookAt').length, 1, 'no frames after stop');
assert.equal(
engine.fake.callsOf('camera.lookAt').length,
1,
'no frames after stop',
);
});
test('orbit needs a target', () => {
+8 -2
View File
@@ -15,7 +15,10 @@ function linkFor(pose) {
const params = new URLSearchParams(manager._buildHashParams().toString());
manager.destroy();
return Object.fromEntries(
['lat', 'lon', 'alt', 'heading', 'pitch', 'roll'].map((k) => [k, params.get(k)]),
['lat', 'lon', 'alt', 'heading', 'pitch', 'roll'].map((k) => [
k,
params.get(k),
]),
);
}
@@ -43,7 +46,10 @@ test('a straight-down view writes roll 0; other angles round as before', () => {
assert.equal(down.roll, '0');
assert.equal(down.pitch, '-90');
const oblique = linkFor(at(45.4, -29.6, 2));
assert.deepEqual([oblique.heading, oblique.pitch, oblique.roll], ['45', '-30', '2']);
assert.deepEqual(
[oblique.heading, oblique.pitch, oblique.roll],
['45', '-30', '2'],
);
assert.equal(linkFor(at(359.7, -30)).heading, '360');
});