const assert = require("node:assert/strict"); const { test } = require("node:test"); const fs = require("node:fs"); const vm = require("node:vm"); const factory = new vm.Script(fs.readFileSync("src/features/preferences/table-sorting.js", "utf8") + "\ncreateTableSorting;").runInNewContext(); const plain = value => JSON.parse(JSON.stringify(value)); const columns = [{ key: "number", type: "number" }, { key: "date", type: "date" }, { key: "name" }]; test("table preferences survive recreation, remain independent and reject obsolete or malformed settings", () => { const saved = new Map(); const environment = { localStorage: { getItem: key => saved.get(key), setItem: (key, value) => saved.set(key, value) } }; const helper = factory({ environment }); const a = helper.create("a", columns); a.toggle("number"); a.toggle("number"); const restored = factory({ environment }); assert.deepEqual(plain(restored.read("a", columns)), { key: "number", direction: "descending" }); assert.equal(restored.read("b", columns).key, ""); for (const invalid of ["{", 'null', '{"key":"removed","direction":"ascending"}', '{"key":"number","direction":"wrong"}']) { saved.set("opportunities-extension-table-sort-v1-b", invalid); assert.equal(restored.read("b", columns).key, ""); } a.toggle("unknown"); assert.equal(a.get().key, "number"); }); test("sorting is typed, stable, immutable and keeps missing values last in both directions", () => { const sorting = factory({ environment: {} }).create("table", columns); const rows = [{ number: "10", date: "2026-02-01", name: "Item 10" }, { number: 2, date: "2026-01-31", name: "Item 2" }, { number: null }, { number: 2 }]; sorting.toggle("number"); assert.deepEqual([...sorting.select(rows)], [rows[1], rows[3], rows[0], rows[2]]); sorting.toggle("number"); assert.deepEqual([...sorting.select(rows)], [rows[0], rows[1], rows[3], rows[2]]); sorting.toggle("date"); assert.deepEqual([...sorting.select(rows)], [rows[1], rows[0], rows[2], rows[3]]); sorting.toggle("name"); assert.deepEqual([...sorting.select(rows)], [rows[1], rows[0], rows[2], rows[3]]); assert.equal(rows[0].number, "10"); }); test("blocked storage retains a usable in-memory preference", () => { const helper = factory({ environment: { get localStorage() { throw new Error("Blocked"); } } }); helper.create("a", columns).toggle("name"); assert.equal(helper.create("a", columns).get().key, "name"); });