From f8a611992ac7413b603d4fc0674cf5a2dcaac2a9 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Sun, 8 Nov 2026 20:47:52 +0100 Subject: [PATCH] =?UTF-8?q?Answer=20stability=20round=201:=200=20?= =?UTF-8?q?=F0=9F=94=B4,=205=20=F0=9F=9F=A1=20(0=20misread);=20test=20the?= =?UTF-8?q?=20setting=20and=20idless-nav=20rules,=20fix=20discovery's=20he?= =?UTF-8?q?ader?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugin-host/conflicts.test.ts | 20 ++++++++++++++++++++ src/plugin-host/discovery.ts | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/plugin-host/conflicts.test.ts b/src/plugin-host/conflicts.test.ts index 2929d4f..37a6f49 100644 --- a/src/plugin-host/conflicts.test.ts +++ b/src/plugin-host/conflicts.test.ts @@ -71,3 +71,23 @@ test("findConflicts: each single slot (`home`/`dashboard`) may have one owner // One owner of each (even both on one plugin) is fine. assert.deepEqual(findConflicts([p({ id: "a", dashboard: handler, home: handler }), p({ id: "b" })]).filter((c) => c.kind === "home" || c.kind === "dashboard"), []); }); + +test("findConflicts: two settings that map to one environment variable are an error", () => { + // `a-b` + `c` and `a` + `bC` both become A_B_C. + const clash = findConflicts([ + p({ id: "a-b", settings: [{ key: "c", type: "string" }] }), + p({ id: "a", settings: [{ key: "bC", type: "string" }] }), + ]); + assert.ok(clash.some((c) => c.kind === "setting" && c.level === "error" && c.plugins.includes("a") && c.plugins.includes("a-b"))); + assert.deepEqual(findConflicts([ + p({ id: "a", settings: [{ key: "x", type: "string" }] }), + p({ id: "b", settings: [{ key: "x", type: "string" }] }), + ]), []); +}); + +test("findConflicts: nav nodes without an id never collide, at any depth", () => { + assert.deepEqual(findConflicts([ + p({ id: "a", nav: [{ children: [{ label: "A1" }], label: "A" }] }), + p({ id: "b", nav: [{ children: [{ label: "B1" }], label: "B" }] }), + ]), []); +}); diff --git a/src/plugin-host/discovery.ts b/src/plugin-host/discovery.ts index 60fedc3..9ec5e5a 100644 --- a/src/plugin-host/discovery.ts +++ b/src/plugin-host/discovery.ts @@ -1,6 +1,6 @@ // Plugin discovery: scan plugins/, import each folder's plugin.ts default export, -// validate it, assemble the loaded Plugin[]. The imperative shell over plugin.ts's pure rules -// (isValidPluginId, checkApiVersion, findConflicts). Fails loud: every per-plugin problem and +// validate it, assemble the loaded Plugin[]. The imperative shell over the pure rules in plugin.ts +// (isValidPluginId, checkApiVersion) and conflicts.ts (findConflicts). Fails loud: every per-plugin problem and // error-level conflict is collected into one boot-stopping Error; warn-level diagnostics // (older-minor apiVersion, shared permission name) log and load continues. Folder name = id.