mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
59 lines
3.1 KiB
JavaScript
59 lines
3.1 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { readFile } from 'node:fs/promises';
|
|
import { buildSourceShotPaths, SOURCE_PATH_BEAT_IDS } from './bhoteKoshiShotPaths.js';
|
|
import { BHOTE_KOSHI_FLOOD_PATH } from './bhoteKoshiFloodPath.js';
|
|
|
|
const event = JSON.parse(await readFile(new URL('../../public/events/bhote-koshi-2026/event.json', import.meta.url)));
|
|
|
|
test('overview and evidence paths start at the lake reach, never the earlier trigger reach', () => {
|
|
const lakeStart = [85.48476, 28.33255];
|
|
assert.deepEqual(BHOTE_KOSHI_FLOOD_PATH[0], lakeStart);
|
|
assert.equal(BHOTE_KOSHI_FLOOD_PATH.some(([lon, lat]) => lon === 85.5306 && lat === 28.2916), false);
|
|
const paths = buildSourceShotPaths(event);
|
|
const first = paths.get('debris-dammed-lake')[0];
|
|
assert.deepEqual([first.lon, first.lat], lakeStart);
|
|
assert.deepEqual(BHOTE_KOSHI_FLOOD_PATH.slice(0, paths.get('debris-dammed-lake').length),
|
|
paths.get('debris-dammed-lake').map(({lon, lat}) => [lon, lat]));
|
|
});
|
|
|
|
test('ten shot paths use only the existing centreline and join at shared endpoints', () => {
|
|
const paths = buildSourceShotPaths(event);
|
|
assert.deepEqual([...paths.keys()], SOURCE_PATH_BEAT_IDS);
|
|
const vertices = new Set(BHOTE_KOSHI_FLOOD_PATH.map(([lon, lat]) => `${lon},${lat}`));
|
|
const boundary = event.reconstruction.corridor.at(-1);
|
|
vertices.add(`${boundary.lon},${boundary.lat}`); // Exact sourced comparison handoff.
|
|
for (const points of paths.values()) {
|
|
assert.ok(points.length >= 2);
|
|
assert.ok(points.every(({ lon, lat, fallbackElevationM }) => (
|
|
vertices.has(`${lon},${lat}`) && Number.isFinite(fallbackElevationM)
|
|
)));
|
|
}
|
|
const coordinate = (point) => [point.lon, point.lat];
|
|
for (const ids of [SOURCE_PATH_BEAT_IDS.slice(0, 2), SOURCE_PATH_BEAT_IDS.slice(2)]) {
|
|
for (let index = 1; index < ids.length; index++) {
|
|
assert.deepEqual(coordinate(paths.get(ids[index - 1]).at(-1)), coordinate(paths.get(ids[index])[0]));
|
|
}
|
|
}
|
|
assert.deepEqual(coordinate(paths.get('bidur-trishuli-bridge').at(-1)), BHOTE_KOSHI_FLOOD_PATH.at(-1));
|
|
for (const id of ['immediate-collapse-viewpoint', 'devighat-taadi-khola-bridge', 'charaudi']) {
|
|
assert.equal(paths.has(id), false, 'out-of-coverage media must not gain a fabricated river route');
|
|
}
|
|
});
|
|
|
|
test('missing and distant observations fail closed without connecting witness coordinates', () => {
|
|
const broken = structuredClone(event);
|
|
broken.evidenceSpine.find(({ id }) => id === 'dhunche').lon = 0;
|
|
const paths = buildSourceShotPaths(broken);
|
|
assert.equal(paths.has('dhunche'), false);
|
|
assert.equal(paths.has('mailung-upper-trishuli'), false);
|
|
assert.equal(buildSourceShotPaths({}).size, 0);
|
|
});
|
|
|
|
test('Dhunche starts at the exact comparison endpoint without stepping upstream first', () => {
|
|
const boundary = event.reconstruction.corridor.at(-1);
|
|
const path = buildSourceShotPaths(event).get('dhunche');
|
|
assert.deepEqual([path[0].lon, path[0].lat], [boundary.lon, boundary.lat]);
|
|
assert.ok(path[1].lat < boundary.lat, 'the first new vertex is downstream of the comparison endpoint');
|
|
});
|