diff options
Diffstat (limited to 'viewer/tests/nav.test.mjs')
| -rw-r--r-- | viewer/tests/nav.test.mjs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/viewer/tests/nav.test.mjs b/viewer/tests/nav.test.mjs new file mode 100644 index 0000000..4efde7f --- /dev/null +++ b/viewer/tests/nav.test.mjs @@ -0,0 +1,64 @@ +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); +}); |
