Answer stability round 1: 0 🔴, 5 🟡 (0 misread); test the setting and idless-nav rules, fix discovery's header
CI / full-gate (push) Successful in 3m19s

This commit is contained in:
2026-11-08 20:47:52 +01:00
parent fdef624300
commit f8a611992a
2 changed files with 22 additions and 2 deletions
+20
View File
@@ -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. // 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"), []); 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" }] }),
]), []);
});
+2 -2
View File
@@ -1,6 +1,6 @@
// Plugin discovery: scan plugins/, import each folder's plugin.ts default export, // 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 // validate it, assemble the loaded Plugin[]. The imperative shell over the pure rules in plugin.ts
// (isValidPluginId, checkApiVersion, findConflicts). Fails loud: every per-plugin problem and // (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 // 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. // (older-minor apiVersion, shared permission name) log and load continues. Folder name = id.