// The hash router: the route table, the fallbacks, and the capability hashes
// (#add= #key= #g=) that must pass through untouched.
import test from "node:test";
import assert from "node:assert/strict";
import { boot, vectors } from "./harness.mjs";
const v = vectors("router");
const foreign = vectors("router-foreign-init");
test("initRouter / hashchange / go replay the recorded script", async () => {
const { env, views, lib } = await boot();
const snap = () => ({
hash: env.location.hash,
on: Object.entries(views).filter(([, el]) => el.classList.contains("on")).map(([k]) => k),
current: [...env.body.querySelectorAll("#tabs a")]
.filter((a) => a.getAttribute("aria-current") === "page")
.map((a) => a.getAttribute("href")),
events: env.events.splice(0),
});
const out = [];
env.location.hash = v.script[0];
lib.initRouter();
out.push({ step: `init hash=${JSON.stringify(v.script[0])}`, ...snap() });
for (const hashValue of v.script.slice(1)) {
env.location.hash = hashValue;
env.window._fire("hashchange", {});
out.push({ step: `hashchange ${JSON.stringify(hashValue)}`, ...snap() });
}
for (const view of ["apps", "you", "you"]) {
lib.go(view);
env.window._fire("hashchange", {});
out.push({ step: `go(${view})`, ...snap() });
}
assert.deepEqual(out, v.out);
});
test("first paint from a capability hash shows a view and leaves the hash alone", async () => {
const { env, views, lib } = await boot({ hash: foreign.script });
env.events.splice(0);
lib.initRouter();
assert.deepEqual(
{
hash: env.location.hash,
on: Object.entries(views).filter(([, el]) => el.classList.contains("on")).map(([k]) => k),
events: env.events.splice(0),
},
foreign.out,
);
});