tests/sidePanel.test.ts
Rama main · réplica de lectura del repositorio original.
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { SECTION_IDS, isCollapsed, moveSection, orderOf, parseStackPrefs, serializeStackPrefs } from "../client/sidePanel.ts";
describe("side panel: stored preferences", () => {
it("reads nothing, garbage and old shapes as a usable default", () => {
for (const raw of [null, "", "{", "null", "[]", '"x"', '{"order":5,"sizes":"no"}']) {
const p = parseStackPrefs(raw);
assert.deepEqual(p.order, [...SECTION_IDS], String(raw));
assert.deepEqual(p.collapsed, {});
}
});
it("round-trips what it writes", () => {
const p = parseStackPrefs(null);
p.order = moveSection(p.order, p.order, "backlinks", 0);
p.collapsed.localgraph = true;
assert.deepEqual(parseStackPrefs(serializeStackPrefs(p)), p);
});
it("starts history folded and everything else open", () => {
const p = parseStackPrefs(null);
assert.equal(isCollapsed(p, "history"), true);
for (const id of SECTION_IDS.filter((x) => x !== "history")) assert.equal(isCollapsed(p, id), false, id);
});
it("takes each section's old flag when nothing newer is stored, and only then", () => {
const legacy = (id: string) => (id === "localgraph" ? true : id === "history" ? false : null);
const fresh = parseStackPrefs(null, legacy);
assert.equal(isCollapsed(fresh, "localgraph"), true);
assert.equal(isCollapsed(fresh, "history"), false);
const stored = parseStackPrefs(serializeStackPrefs(parseStackPrefs(null)), legacy);
assert.equal(isCollapsed(stored, "localgraph"), false);
});
it("keeps 3.45.0's folds and order but not the heights it stored beside them", () => {
const old = '{"v":1,"order":["backlinks","outline"],"collapsed":{"localgraph":true},"sizes":{"backlinks":120}}';
const p = parseStackPrefs(old);
assert.equal(p.order[0], "backlinks");
assert.equal(isCollapsed(p, "localgraph"), true);
assert.equal("sizes" in p, false);
assert.equal(serializeStackPrefs(p).includes("sizes"), false);
});
});
describe("side panel: order", () => {
it("drops unknowns and duplicates and puts a missing section back after its neighbour", () => {
const order = orderOf(["backlinks", "zzz", "outline", "backlinks"]);
assert.equal(order.length, SECTION_IDS.length);
assert.equal(order[0], "backlinks");
assert.ok(order.indexOf("backlinks") < order.indexOf("outline"));
// footnotes follows outline by default and nearby follows backlinks, so
// each lands right after its neighbour.
assert.equal(order.indexOf("footnotes"), order.indexOf("outline") + 1);
assert.equal(order.indexOf("nearby"), order.indexOf("backlinks") + 1);
});
it("moves among the visible sections and keeps hidden ones beside their neighbours", () => {
const order = [...SECTION_IDS];
const visible = ["outline", "localgraph", "history", "backlinks", "nearby"] as const;
const moved = moveSection(order, visible, "nearby", 0);
assert.deepEqual(moved.filter((id) => (visible as readonly string[]).includes(id)), ["nearby", "outline", "localgraph", "history", "backlinks"]);
// footnotes was between outline and localgraph and still is.
assert.ok(moved.indexOf("footnotes") > moved.indexOf("outline") && moved.indexOf("footnotes") < moved.indexOf("localgraph"));
const down = moveSection(order, visible, "outline", 9);
assert.equal(down.filter((id) => (visible as readonly string[]).includes(id)).at(-1), "outline");
assert.deepEqual(moveSection(order, visible, "outline", 0), order);
});
});