import './_planet.mjs';
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { keyAction, exportName } from '../js/nav.js';
const k = (key, extra = {}) => keyAction({ key, target: { tagName: 'CANVAS' }, ...extra });
test('keys map to actions', () => {
assert.deepEqual(k('ArrowLeft'), ['pan', -0.2, 0]);
assert.deepEqual(k('ArrowDown'), ['pan', 0, 0.2]);
assert.deepEqual(k('+'), ['zoom', 0.6]);
assert.deepEqual(k('='), ['zoom', 0.6]);
assert.deepEqual(k('-'), ['zoom', 1 / 0.6]);
assert.deepEqual(k('Home'), ['home']);
assert.deepEqual(k('f'), ['fullscreen']);
assert.deepEqual(k('/'), ['search']);
assert.equal(k('x'), null);
});
test('typing and modifier chords are left alone', () => {
for (const tagName of ['INPUT', 'TEXTAREA', 'SELECT']) assert.equal(keyAction({ key: 'ArrowLeft', target: { tagName } }), null);
assert.equal(k('f', { ctrlKey: true }), null);
assert.equal(k('ArrowUp', { metaKey: true }), null);
assert.equal(k('-', { altKey: true }), null);
});
test('export file names', () => {
assert.equal(exportName({ layer: 'relief', over: '', view: 'globe' }), 'world-relief-globe.png');
assert.equal(exportName({ layer: 'relief', over: 'biomes', view: 'equal_earth' }), 'world-relief+biomes-equal_earth.png');
});
test('exports note procedural detail when tiles are showing', async () => {
const { exportNotes } = await import('../js/nav.js');
assert.deepEqual(exportNotes({ view: { tiles: { active: true } } }), ['procedural detail — not data']);
assert.deepEqual(exportNotes({ view: { tiles: { active: false } } }), []);
assert.deepEqual(exportNotes({ view: {} }), []);
});
test('Shift+arrows turn and tilt; plain arrows still pan; N points north', () => {
const k = (key, o = {}) => keyAction({ key, target: { tagName: 'CANVAS' }, ...o });
assert.deepEqual(k('ArrowLeft', { shiftKey: true }), ['turn', -15, 0]);
assert.deepEqual(k('ArrowUp', { shiftKey: true }), ['turn', 0, 10]);
assert.deepEqual(k('ArrowLeft'), ['pan', -0.2, 0]);
assert.deepEqual(k('n'), ['north']);
assert.equal(k('n', { target: { tagName: 'INPUT' } }), null);
});
test('G goes to ground view, ? shows the controls', () => {
assert.deepEqual(k('g'), ['ground']);
assert.deepEqual(k('?', { shiftKey: true }), ['help']);
assert.equal(k('g', { target: { tagName: 'INPUT' } }), null);
});
test('ground view: the eye above the spot looked at, close and tilted, heading kept', async () => {
const { groundPose, GROUND_RANGE, GROUND_PITCH } = await import('../js/nav.js');
const ahead = GROUND_RANGE * Math.sin(GROUND_PITCH * Math.PI / 180) * 180 / Math.PI; // degrees of arc
const n = groundPose({ lat: 0, lon: 10, range: 0.5, heading: 0, pitch: 0 });
assert.ok(Math.abs(n.lat - ahead) < 1e-9 && Math.abs(n.lon - 10) < 1e-9, 'looking north: the target lies ahead');
assert.equal(n.range, GROUND_RANGE);
assert.equal(n.pitch, GROUND_PITCH);
const e = groundPose({ lat: 0, lon: 10, range: 0.5, heading: 90, pitch: 0 });
assert.ok(Math.abs(e.lat) < 1e-9 && Math.abs(e.lon - 10 - ahead) < 1e-9 && e.heading === 90);
assert.ok(GROUND_RANGE * 12742 < 5 && GROUND_PITCH >= 70);
});