fix(cockpit): the sensor strip follows the view through a zoom step; the pre-load level test checks a worked number; the boundary gate's dependency-asset exemption is tested

This commit is contained in:
Sameh Khamis committed 2026-11-08 19:08:51 -08:00
1 parent 1453794573
commit 63aa45c520
4 files changed
+84 -14

No files matched your search

+46
View File
@@ -126,3 +126,49 @@ test('a lifecycle owner cannot acquire a layer panel even through an unused impo
);
await assert.rejects(checkPackageBoundaries(root), /unowned module.*panel/);
});
test('a declared dependency owns the asset files it ships, and only those', async (t) => {
const asset = (pkg) =>
`import url from './node_modules/${pkg}/flags/aa.svg?url&no-inline'; export const value = url;`;
const root = await fixture(t, asset('flags'));
for (const pkg of ['flags', 'flags-extra', 'stray']) {
await mkdir(path.join(root, 'node_modules', pkg, 'flags'), {
recursive: true,
});
await writeFile(
path.join(root, 'node_modules', pkg, 'flags/aa.svg'),
'<svg xmlns="http://www.w3.org/2000/svg"/>',
);
}
await writeFile(
path.join(root, 'package.json'),
JSON.stringify({
name: 'boundary-fixture',
type: 'module',
exports: { './feature': './entry.js' },
dependencies: { flags: '1.0.0' },
}),
);
await writeFile(
path.join(root, 'scripts/package-boundaries.json'),
JSON.stringify({
feature: {
exports: ['./feature'],
modules: ['entry.js'],
external: ['flags'],
},
}),
);
// The entry and the flag it ships.
assert.deepEqual(await checkPackageBoundaries(root), [
{ name: 'feature', exports: 1, modules: 2 },
]);
// An undeclared package's file, and one whose name only starts the same.
for (const pkg of ['stray', 'flags-extra']) {
await writeFile(path.join(root, 'entry.js'), asset(pkg));
await assert.rejects(
checkPackageBoundaries(root),
new RegExp(`unowned module.*node_modules/${pkg}/`),
);
}
});
+6 -1
View File
@@ -631,6 +631,11 @@ export function publishOrbitalView(info, transition = IDLE_TRANSITION) {
: canvasAspect(this.viewer);
const settledFov = fovForZoom(orbitalBaseFovRad(info.altitudeM), state.zoom);
const footprintKm = footprintWidthKm(info.altitudeM, settledFov, aspect);
// The strip is drawn over the picture, so it follows the view as a step
// zooms (republished every frame then), not the step it is heading for.
const shownKm = Number.isFinite(state.verticalFov)
? footprintWidthKm(info.altitudeM, state.verticalFov, aspect)
: footprintKm;
const maxZoom = orbitalMaxZoomFor.call(this, info);
const swathKm = sensorSwathKm(info);
const trackUp = Number.isFinite(info.groundTrackDeg);
@@ -687,7 +692,7 @@ export function publishOrbitalView(info, transition = IDLE_TRANSITION) {
// along, and a SAR images to one side of nadir, not under it.
stripFraction:
trackUp && info.sensor?.type !== 'SAR'
? sensorStripFraction(swathKm, footprintKm)
? sensorStripFraction(swathKm, shownKm)
: null,
zoom: sensorSwathZoom(info.altitudeM, swathKm, aspect, maxZoom),
},
+28 -11
View File
@@ -26,7 +26,6 @@ import {
} from '../cockpitOrbital.js';
import { vesselCockpitInfo } from '../layers/vessels/cockpitSubject.js';
import { prefetchImageryAhead } from './cockpitOrbitalView.js';
import { imageryLevelForView } from '../cockpitOrbital.js';
import { claimPointer, releasePointer } from '../data/inputOwnership.js';
const ISS = Object.freeze({
@@ -1161,6 +1160,27 @@ function imageryGlobe(viewer, { requestImage } = {}) {
const WORLDVIEW_ON_TRACK = Object.freeze({ ...WORLDVIEW, groundTrackDeg: 52 });
test('the sensor strip follows the view through a zoom step, not ahead of it', async (t) => {
const { cockpit, store, clock } = await orbitAt(t, {
satellite: WORLDVIEW,
reducedMotion: false,
});
const strip = () => store.orbital.sensor.stripFraction;
const atOne = strip();
assert.ok(atOne > 0 && atOne < 1);
press(cockpit, '+');
cockpit.update();
near(strip(), atOne, 'the step starts at 1x, and so does the strip');
clock.advance(ORBITAL_ZOOM_TRANSITION_MS / 2);
cockpit.update();
const midway = strip();
clock.advance(ORBITAL_ZOOM_TRANSITION_MS + 1000);
cockpit.update();
const atTwo = strip();
assert.ok(atTwo > atOne * 1.5, 'twice the zoom, about twice the share');
assert.ok(midway > atOne && midway < atTwo, 'part-way through the step');
});
test('from 16x the imagery ahead of the ground track is pre-loaded', async (t) => {
const { cockpit, viewer, store, clock } = await orbitAt(t, {
satellite: WORLDVIEW_ON_TRACK,
@@ -1444,16 +1464,13 @@ test('the pre-load is throttled, at the level Cesium draws, and waits out a tilt
);
assert.equal(request.type, Cesium.RequestType.IMAGERY);
}
// The level Cesium's own selection takes for this view.
const fov = fovForZoom(orbitalBaseFovRad(WORLDVIEW.altitudeM), 16);
const metresPerPixel =
(WORLDVIEW.altitudeM * 2 * Math.tan(fov / 2)) /
viewer.scene.canvas.clientHeight;
const expected = imageryLevelForView(new Cesium.WebMercatorTilingScheme(), {
metresPerPixel,
latitudeDeg: WORLDVIEW.latitude,
});
assert.equal(Number(requests[0].split('/')[0]), expected);
// The level Cesium's own selection takes for this view, worked by hand:
// at 16x from 617 km the 900 px canvas is ~49.5 m a pixel. The ellipsoid
// terrain's level-zero error is 6378137 · 2π / 4 / 130 ≈ 77,067 m; it first
// meets Cesium's screen-space error of 2 px (≤ 99 m) at level 10, 75.3 m.
// A Web Mercator level-zero texel at 30° is 6378137 · 2π · cos 30° / 256
// ≈ 135,566 m, so the imagery level is round(log2(135,566 / 75.3)) = 11.
assert.equal(Number(requests[0].split('/')[0]), 11);
});
test('the TLE age is measured from the time the satellite is shown at', async (t) => {