Package the portable DSH profiles, local plugins, desktop integration, Firefox wrapper, and ownership-aware installer lifecycle. Bundle checksum-pinned OpenVSCode, editor extensions, translation assets, and cloudflared so unreliable upstream artifact downloads cannot break a clean installation.
36 lines
1.5 KiB
JavaScript
36 lines
1.5 KiB
JavaScript
import { strict as assert } from "node:assert";
|
|
import { test } from "node:test";
|
|
import { hasNameConflict, isExactIdSet, nextSortIndex, parseName } from "../lib/tree-utils.js";
|
|
|
|
test("parseName trims and rejects empty/oversized", () => {
|
|
assert.equal(parseName(" hello "), "hello");
|
|
assert.equal(parseName(""), undefined);
|
|
assert.equal(parseName(" "), undefined);
|
|
assert.equal(parseName(42), undefined);
|
|
assert.equal(parseName("x".repeat(81)), undefined);
|
|
assert.equal(parseName("x".repeat(80)).length, 80);
|
|
});
|
|
|
|
test("hasNameConflict is case-insensitive and parent-scoped", () => {
|
|
const records = [
|
|
{ id: "a", parent: "p1", name: "Backend" },
|
|
{ id: "b", parent: "p2", name: "Backend" }
|
|
];
|
|
const inP1 = (r) => r.parent === "p1";
|
|
assert.equal(hasNameConflict(records, inP1, "backend"), true);
|
|
assert.equal(hasNameConflict(records, inP1, "backend", "a"), false);
|
|
assert.equal(hasNameConflict(records, (r) => r.parent === "p3", "backend"), false);
|
|
});
|
|
|
|
test("nextSortIndex returns max+1, tolerating missing indices", () => {
|
|
assert.equal(nextSortIndex([]), 1);
|
|
assert.equal(nextSortIndex([{ sortIndex: 2 }, {}, { sortIndex: 5 }]), 6);
|
|
});
|
|
|
|
test("isExactIdSet requires a permutation", () => {
|
|
const allowed = new Set(["a", "b", "c"]);
|
|
assert.equal(isExactIdSet(["c", "a", "b"], allowed), true);
|
|
assert.equal(isExactIdSet(["a", "b"], allowed), false);
|
|
assert.equal(isExactIdSet(["a", "b", "b"], allowed), false);
|
|
assert.equal(isExactIdSet(["a", "b", "d"], allowed), false);
|
|
});
|