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(''), '');
});