mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
test(migration): establish W2 native oracle and release removed overlay identities
Add the sequential W2/completion plan and deterministic earthquake ground-raster, geometry, lifecycle and strict runtime QA. Prove the comparator rejects incomplete evidence and release deleted overlay entries from the collision arbiter. Record native dev/preview acceptance and full checkpoint gates.
This commit is contained in:
1 parent
0600964249
commit
e8870a4766
4 files changed
+154
-7
No files matched your search
@@ -0,0 +1,47 @@
|
||||
// USGS-shaped fixed observations; source parsers remain the production ones.
|
||||
export const W2_EPOCH_MS = 1792152000000;
|
||||
export function earthquakeFixture() {
|
||||
const features = [];
|
||||
for (const [region, lon, lat] of [
|
||||
['sf', -122.42, 37.77],
|
||||
['austin', -97.74, 30.27],
|
||||
['alaska', -150.4, 61.0],
|
||||
]) {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
features.push({
|
||||
type: 'Feature',
|
||||
id: `qa-${region}-${i}`,
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [
|
||||
lon + (i - 2) * 0.24,
|
||||
lat + (i % 2) * 0.3,
|
||||
[8, 70, 300, 301, 45][i],
|
||||
],
|
||||
},
|
||||
properties: {
|
||||
mag: [2.5, 3, 4, 5, 5.5][i],
|
||||
place: `W2 ${region} event ${i}`,
|
||||
time: W2_EPOCH_MS - i * 60000,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
features.push({
|
||||
type: 'Feature',
|
||||
id: 'qa-below',
|
||||
geometry: { type: 'Point', coordinates: [-122.42, 37.77, 5] },
|
||||
properties: { mag: 2.4 },
|
||||
});
|
||||
features.push({
|
||||
type: 'Feature',
|
||||
id: 'qa-missing-mag',
|
||||
geometry: { type: 'Point', coordinates: [-122.4, 37.7, 5] },
|
||||
properties: { mag: null },
|
||||
});
|
||||
return {
|
||||
type: 'FeatureCollection',
|
||||
metadata: { generated: W2_EPOCH_MS },
|
||||
features,
|
||||
};
|
||||
}
|
||||
@@ -1179,5 +1179,8 @@
|
||||
"src/globe/navara/movers/frameCamera.test.mjs",
|
||||
"src/layers/localAdsb/qaDrawn.js",
|
||||
"src/layers/localAdsb/qaDrawn.test.mjs",
|
||||
"src/tooling/w1RuntimeEvidence.test.mjs"
|
||||
"src/tooling/w1RuntimeEvidence.test.mjs",
|
||||
"scripts/qa-w2-layers.mjs",
|
||||
"scripts/fixtures/w2/earthquakes.mjs",
|
||||
"src/tooling/w2QaComparison.test.mjs"
|
||||
]
|
||||
@@ -951,6 +951,14 @@ export function registerWorldOverlayPaintLane(laneId, painter, options = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
// Removed entries cannot paint an exit fade: their source no longer owns
|
||||
// them. Release the arbiter identity too, so later layout changes cannot
|
||||
// wake the idle renderer for an invisible minimum-lifetime/fade state.
|
||||
function forgetOverlayEntry(entry) {
|
||||
_records.delete(entry._overlayKey);
|
||||
_domains.get(entry.collisionGroup)?.arbiter.remove(entry._overlayKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all entries owned by a source atomically.
|
||||
* @param {string} sourceId
|
||||
@@ -968,7 +976,7 @@ export function setOverlayEntries(sourceId, entries, options = {}) {
|
||||
const next = new Map();
|
||||
for (const entry of normalized) next.set(entry.id, entry);
|
||||
for (const entry of source.entries.values()) {
|
||||
if (!next.has(entry.id)) _records.delete(entry._overlayKey);
|
||||
if (!next.has(entry.id)) forgetOverlayEntry(entry);
|
||||
const replacement = next.get(entry.id);
|
||||
if (replacement && isProtected(entry) !== isProtected(replacement))
|
||||
getOrCreateDomain(entry.collisionGroup).arbiter.remove(entry._overlayKey);
|
||||
@@ -1005,9 +1013,10 @@ export function removeOverlayEntry(sourceId, entryId) {
|
||||
const source = _sources.get(assertSourceId(sourceId));
|
||||
if (!source) return false;
|
||||
const id = String(entryId);
|
||||
const removed = source.entries.delete(id);
|
||||
if (!removed) return false;
|
||||
_records.delete(entryKey(source.id, id));
|
||||
const entry = source.entries.get(id);
|
||||
if (!entry) return false;
|
||||
source.entries.delete(id);
|
||||
forgetOverlayEntry(entry);
|
||||
rebuildSourceCohorts(source);
|
||||
updateEntryDiagnostics();
|
||||
invalidateHost();
|
||||
@@ -1023,8 +1032,7 @@ export function clearOverlaySource(sourceId) {
|
||||
if (_destroyed) return false;
|
||||
const source = _sources.get(assertSourceId(sourceId));
|
||||
if (!source) return false;
|
||||
for (const entry of source.entries.values())
|
||||
_records.delete(entry._overlayKey);
|
||||
for (const entry of source.entries.values()) forgetOverlayEntry(entry);
|
||||
source.entries.clear();
|
||||
source.cohortDomainIds.length = 0;
|
||||
source.cohortLists.length = 0;
|
||||
|
||||
@@ -2378,3 +2378,92 @@ test('the host takes a globe engine and refuses a bare viewer', async () => {
|
||||
assert.equal(engine.frames.postRender.numberOfListeners, 1);
|
||||
env.cleanup();
|
||||
});
|
||||
|
||||
// Source deletion is final: invisible candidates must not retain minimum-life
|
||||
// or fade state which wakes a dormant scene on a later UI/layout invalidation.
|
||||
for (const [name, remove] of [
|
||||
["clear", () => clearOverlaySource("deleted-static")],
|
||||
["remove", () => removeOverlayEntry("deleted-static", "event")],
|
||||
["replace-empty", () => setOverlayEntries("deleted-static", [])],
|
||||
]) {
|
||||
test(`removed static labels stay dormant after ${name}`, () => {
|
||||
const env = installMockEnvironment();
|
||||
try {
|
||||
initWorldOverlay(env.engine);
|
||||
setOverlayEntries(
|
||||
"deleted-static",
|
||||
[
|
||||
selectedEntry("event", {
|
||||
selected: false,
|
||||
protected: false,
|
||||
variant: "card",
|
||||
collisionGroup: "deleted-static",
|
||||
priority: 100,
|
||||
verticalOnly: true,
|
||||
}),
|
||||
],
|
||||
{ collisionCapacity: 1, maxVisible: 1 },
|
||||
);
|
||||
env.advanceTime(600);
|
||||
env.postRender.raise();
|
||||
env.advanceTime(600);
|
||||
env.postRender.raise();
|
||||
assert.ok(getWorldOverlayDiagnostics().selectedCount > 0);
|
||||
remove();
|
||||
env.postRender.raise();
|
||||
env.viewer.scene.requestRenderCount = 0;
|
||||
for (let i = 0; i < 16; i++) {
|
||||
env.advanceTime(250);
|
||||
for (const observer of env.resizeObservers) observer.callback();
|
||||
env.postRender.raise();
|
||||
}
|
||||
assert.equal(getWorldOverlayDiagnostics().paintedCount, 0);
|
||||
assert.equal(
|
||||
env.viewer.scene.requestRenderCount,
|
||||
0,
|
||||
"removed source must not retain fades/minimum lifetimes and wake idle",
|
||||
);
|
||||
} finally {
|
||||
env.cleanup();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
test("clearing one static source preserves another source in the same label domain", () => {
|
||||
const env = installMockEnvironment();
|
||||
try {
|
||||
initWorldOverlay(env.engine);
|
||||
for (const [source, x] of [
|
||||
["left", -0.5],
|
||||
["right", 0.5],
|
||||
])
|
||||
setOverlayEntries(
|
||||
source,
|
||||
[
|
||||
selectedEntry("event", {
|
||||
position: new Cesium.Cartesian3(x, 0, 0),
|
||||
selected: false,
|
||||
protected: false,
|
||||
collisionGroup: "ambient-card",
|
||||
verticalOnly: true,
|
||||
}),
|
||||
],
|
||||
{ collisionCapacity: 1, maxVisible: 1 },
|
||||
);
|
||||
env.advanceTime(100);
|
||||
env.postRender.raise();
|
||||
env.advanceTime(600);
|
||||
env.postRender.raise();
|
||||
assert.deepEqual(getWorldOverlayDiagnostics().paintedBySource, {
|
||||
left: 1,
|
||||
right: 1,
|
||||
});
|
||||
clearOverlaySource("left");
|
||||
env.postRender.raise();
|
||||
assert.deepEqual(getWorldOverlayDiagnostics().paintedBySource, {
|
||||
right: 1,
|
||||
});
|
||||
} finally {
|
||||
env.cleanup();
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user