import './_planet.mjs';
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { MeasurePath } from '../js/measure.js';
import { R_KM } from '../js/geo.js';
import { FakeEl, installFakeDom } from './fakedom.mjs';
const A = { lat: 0, lon: 0 }, B = { lat: 0, lon: 90 }, C = { lat: 90, lon: 0 };
const near = (a, b, eps) => assert.ok(Math.abs(a - b) <= eps, `${a} vs ${b}`);
test('open path: segments and total', () => {
const m = new MeasurePath();
[A, B, C].forEach(p => m.add(p));
assert.equal(m.segmentsKm().length, 2);
near(m.totalKm(), R_KM * Math.PI, 1e-6); // two quarter circles
assert.equal(m.areaKm2(), null);
assert.equal(m.lines()[0].length, 3);
});
test('closing needs three points; a closed path adds the return leg and an area', () => {
const m = new MeasurePath();
m.add(A);
m.add(B);
assert.equal(m.close(), false);
m.add(C);
assert.equal(m.close(), true);
assert.equal(m.segmentsKm().length, 3);
near(m.areaKm2(), (4 * Math.PI * R_KM ** 2) / 8, 1);
assert.deepEqual(m.lines()[0].at(-1), A);
});
test('undo reopens then removes; repeats ignored; adding after a close starts over', () => {
const m = new MeasurePath();
[A, B, C].forEach(p => m.add(p));
m.close();
m.undo();
assert.equal(m.closed, false);
assert.equal(m.points.length, 3);
m.undo();
assert.equal(m.points.length, 2);
m.add(B); // a double-click lands twice on the same spot
assert.equal(m.points.length, 2);
m.add(C);
m.close();
m.add(A);
assert.deepEqual(m.points, [A]);
});
test('panel never renders null/undefined children (DOM would print "null")', async () => {
installFakeDom();
const { renderMeasure } = await import('../js/measure.js');
const box = new FakeEl('section'), noop = () => {};
const m = new MeasurePath();
for (const pts of [[], [A], [A, B]]) {
m.clear();
pts.forEach(p => m.add(p));
renderMeasure(box, m, { undo: noop, close: noop, clear: noop });
assert.ok(box.kids.every(k => k !== null && k !== undefined), `${pts.length} points: ${box.kids.map(String)}`);
}
});
test('elevation chart: an svg profile; hovering reports the nearest sample', async () => {
installFakeDom();
const { renderProfile, renderMeasure } = await import('../js/measure.js');
const box = new FakeEl('div'), seen = [];
const prof = { samples: [{ d_km: 0, lat: 0, lon: 0, z_m: -100, water: true }, { d_km: 10, lat: 0, lon: 0.1, z_m: 500, water: false }],
stats: { min_m: -100, max_m: 500, ascent_m: 600, descent_m: 0, water_km: 5, length_km: 10 } };
renderProfile(box, prof, p => seen.push(p));
const chart = box.kids[0];
assert.equal(chart.tag, 'svg');
assert.ok(chart.find(e => e.tag === 'path'));
chart.fire('pointermove', { clientX: 300 });
assert.equal(seen.at(-1).d_km, 10);
assert.match(box.textContent, /Highest 500 m/);
chart.fire('pointerleave');
assert.equal(seen.at(-1), null);
const mbox = new FakeEl('section'), m = new MeasurePath();
m.add(A);
m.add(B);
const pbox = renderMeasure(mbox, m, { undo() {}, close() {}, clear() {} });
assert.ok(mbox.kids.includes(pbox));
});