worldmap-viewer

git clone https://git.godosa.eu/worldmap-viewer

master

raw ยท 3389 bytes

import './_planet.mjs';
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { parse, serialize, DEFAULT, carryHash } from '../js/urlstate.js';

test('round trip', () => {
  const s = { ...DEFAULT, layer: 'biomes', view: 'equal_earth', lat: 40.5, lon: -10.25, alt: 0.5, zoom: 3, overlays: ['coast', 'pins'] };
  assert.deepEqual(parse(serialize(s)), s);
  const t = { ...s, over: 'biomes', op: 0.35, sky: true, day: 100, mo: 12345, alt: 0.0004, zoom: 20000 };
  assert.deepEqual(parse(serialize(t)), t);
});

test('new keys clamp and default', () => {
  const s = parse('#op=7&day=300&mo=-5&sky=maybe&alt=0.00001&zoom=1e9');
  assert.equal(s.op, 1);
  assert.equal(s.day, 215);
  assert.equal(s.mo, 0);
  assert.equal(s.sky, false);
  assert.equal(s.alt, 0.00001);   // above the 20 m floor now
  assert.equal(s.zoom, 20000);
  assert.equal(s.over, '');
});

test('garbage and out-of-range values fall back or clamp', () => {
  const s = parse('#view=nope&lat=abc&lon=200&alt=99&zoom=0');
  assert.equal(s.view, DEFAULT.view);
  assert.equal(s.lat, DEFAULT.lat);
  assert.equal(s.lon, -160);
  assert.equal(s.alt, 5);
  assert.equal(s.zoom, 1);
  assert.deepEqual(parse(''), DEFAULT);
});

test('clamps come from the shared view limits', async () => {
  const { MIN_ALT, MAX_ALT, MAX_ZOOM } = await import('../js/limits.js');
  const s = parse('#alt=1e-9&zoom=1e12');
  assert.equal(s.alt, MIN_ALT);
  assert.equal(s.zoom, MAX_ZOOM);
  assert.equal(parse('#alt=1e9').alt, MAX_ALT);
});

test('tilt and 3D: round trip, clamps, only written when they differ from the default', () => {
  const s = { ...DEFAULT, alt: 0.001, hd: 30.5, pt: 45, terrain: 2.5 };
  assert.deepEqual(parse(serialize(s)), s);
  assert.deepEqual(parse(serialize({ ...DEFAULT, terrain: 0 })), { ...DEFAULT, terrain: 0 });
  assert.ok(!/hd=|pt=|3d=/.test(serialize(DEFAULT)));
  assert.ok(!/hd=|pt=/.test(serialize({ ...DEFAULT, view: 'equal_earth', hd: 30, pt: 40 })), 'flat views have no tilt');
  const c = parse('#hd=-90&pt=95&3d=9');
  assert.deepEqual([c.hd, c.pt, c.terrain], [270, 80, 5]);
  assert.equal(parse('#3d=0.4').terrain, 1);
  assert.equal(parse('#3d=-2').terrain, 0);
  assert.equal(parse('#3d=abc').terrain, 1);
});

test('era and water round-trip; defaults stay out of the URL', () => {
  const s = { ...DEFAULT, era: 'age-of-legends', water: false };
  assert.deepEqual(parse(serialize(s)), s);
  assert.doesNotMatch(serialize(DEFAULT), /era=|water=/);
  assert.equal(parse('#water=1').water, true);
  assert.equal(parse('#era=').era, '');
});

test('the sea floor replaces relief only on the 3D globe with the water off', async () => {
  const { drawnLayer } = await import('../js/urlstate.js');
  const s = { ...DEFAULT, water: false };
  assert.equal(drawnLayer(s, 'globe'), 'seafloor');
  assert.equal(drawnLayer({ ...s, terrain: 0 }, 'globe'), 'relief', '3D off: the water toggle is hidden');
  assert.equal(drawnLayer(s, 'equal_earth'), 'relief');
  assert.equal(drawnLayer({ ...s, layer: 'biomes' }, 'globe'), 'biomes');
  assert.equal(drawnLayer(DEFAULT, 'globe'), 'relief');
});

test('carryHash keeps the view, drops era and time', () => {
  assert.equal(carryHash('#layer=ground&view=globe&lat=10&era=high-fantasy&sky=1&day=50&mo=9'), '#layer=ground&view=globe&lat=10&sky=1');
  assert.equal(carryHash('#era=x'), '');
  assert.equal(carryHash(''), '');
});