Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
49 lines
2.6 KiB
JavaScript
49 lines
2.6 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { offer, _reset } from "./mounts.js";
|
|
import { loadFeatures } from "./features.js";
|
|
|
|
const host = () => { const nodes = []; return { childNodes: nodes, append: (n) => nodes.push(n) }; };
|
|
const hubs = {
|
|
ok: { id: "ok", mount: "a", setup: ({ host: h }) => h.append({ remove() {} }) },
|
|
throws: { id: "throws", mount: "a", setup: () => { throw new Error("boom"); } },
|
|
nowhere: { id: "nowhere", mount: "zzz", setup() {} },
|
|
needy: { id: "needy", mount: "a", needs: ["gpu"], setup() {} },
|
|
};
|
|
const run = (names) => loadFeatures(names, { load: async (n) => ({ default: hubs[n] }), has: () => false });
|
|
|
|
test("a feature that loads is mounted; one that throws, names no region, or lacks a need is hidden, and the rest still load", async () => {
|
|
_reset(); offer("a", host());
|
|
const { mounted, hidden } = await run(["throws", "nowhere", "needy", "ok"]);
|
|
assert.deepEqual(mounted.map((m) => m.id), ["ok"]);
|
|
assert.deepEqual(hidden.map((h) => [h.id, h.why.split(" ")[0]]), [["throws", "boom"], ["nowhere", "no"], ["needy", "needs"]]);
|
|
});
|
|
|
|
test("what a feature put on the page before it threw is taken away", async () => {
|
|
_reset(); const h = host(); offer("a", h);
|
|
hubs.throws.setup = ({ host: x }) => { x.append({ remove() { h.childNodes.length = 0; } }); throw new Error("late"); };
|
|
await run(["throws"]);
|
|
assert.equal(h.childNodes.length, 0);
|
|
});
|
|
|
|
test("a feature that subscribed and then threw stops hearing the app", async () => {
|
|
_reset(); offer("a", host());
|
|
const heard = new Set();
|
|
const app = { on: (fn) => { heard.add(fn); return () => heard.delete(fn); } };
|
|
hubs.throws.setup = ({ app: a }) => { a.on(() => {}); throw new Error("late"); };
|
|
await loadFeatures(["throws"], { load: async (n) => ({ default: hubs[n] }), app, has: () => true });
|
|
assert.equal(heard.size, 0);
|
|
});
|
|
|
|
test("a feature whose backend module is not installed is hidden; unknown (server down) hides nothing", async () => {
|
|
_reset(); offer("a", host());
|
|
const mod = { id: "needs-render", mount: "a", modules: ["render"], setup() {} };
|
|
const load = async () => ({ default: mod });
|
|
const gone = await loadFeatures(["x"], { load, app: { hasModule: (id) => id !== "render" }, has: () => true });
|
|
assert.deepEqual(gone.hidden.map((h) => h.why), ["module render is not installed"]);
|
|
const here = await loadFeatures(["x"], { load, app: { hasModule: () => true }, has: () => true });
|
|
assert.equal(here.mounted.length, 1);
|
|
const unknown = await loadFeatures(["x"], { load, app: {}, has: () => true }); // no hasModule: nothing to judge by
|
|
assert.equal(unknown.mounted.length, 1);
|
|
});
|