Files
NetMesh/domain/snippetPackage.test.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

149 lines
4.6 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import type { Snippet } from "./models.ts";
import {
applySnippetPackagePathChange,
collectSnippetPackageTreePaths,
deleteSnippetPackage,
renameSnippetPackage,
} from "./snippetPackage.ts";
const snippet = (overrides: Partial<Snippet> & Pick<Snippet, "id">): Snippet => ({
label: overrides.label ?? overrides.id,
command: overrides.command ?? "echo ok",
package: "",
...overrides,
});
test("deleteSnippetPackage removes the package and descendants but keeps snippet bodies", () => {
const result = deleteSnippetPackage(
["ops", "ops/linux", "db"],
[
snippet({ id: "keep-ops", label: "Restart", command: "systemctl restart nginx", package: "ops" }),
snippet({ id: "keep-child", label: "Disk", command: "df -h", package: "ops/linux" }),
snippet({ id: "untouched", label: "PSQL", command: "psql", package: "db" }),
snippet({ id: "root", command: "uptime" }),
],
"ops",
);
assert.deepEqual(result.packages, ["db"]);
assert.deepEqual(
result.snippets.map((item) => ({
id: item.id,
package: item.package,
command: item.command,
label: item.label,
})),
[
{ id: "keep-ops", package: "", command: "systemctl restart nginx", label: "Restart" },
{ id: "keep-child", package: "", command: "df -h", label: "Disk" },
{ id: "untouched", package: "db", command: "psql", label: "PSQL" },
{ id: "root", package: "", command: "uptime", label: "root" },
],
);
});
test("renameSnippetPackage rewrites the package and descendant snippet paths", () => {
const result = renameSnippetPackage(
["ops", "ops/linux", "db"],
[
snippet({ id: "a", package: "ops" }),
snippet({ id: "b", package: "ops/linux" }),
snippet({ id: "c", package: "db" }),
],
"ops",
"platform",
);
assert.equal(result.ok, true);
if (!result.ok) return;
assert.equal(result.newPath, "platform");
assert.deepEqual(result.packages, ["platform", "platform/linux", "db"]);
assert.deepEqual(
result.snippets.map((item) => item.package),
["platform", "platform/linux", "db"],
);
});
test("renameSnippetPackage preserves a leading slash on absolute packages", () => {
const result = renameSnippetPackage(["/ops"], [snippet({ id: "a", package: "/ops" })], "/ops", "infra");
assert.equal(result.ok, true);
if (!result.ok) return;
assert.equal(result.newPath, "/infra");
assert.deepEqual(result.packages, ["/infra"]);
assert.equal(result.snippets[0].package, "/infra");
});
test("renameSnippetPackage rejects empty, invalid, and duplicate names", () => {
assert.deepEqual(
renameSnippetPackage(["ops"], [], "ops", " "),
{ ok: false, error: "empty" },
);
assert.deepEqual(
renameSnippetPackage(["ops"], [], "ops", "ops/linux"),
{ ok: false, error: "invalidChars" },
);
assert.deepEqual(
renameSnippetPackage(["ops", "db"], [], "ops", "DB"),
{ ok: false, error: "duplicate" },
);
});
test("renameSnippetPackage rejects collisions with inferred ancestor packages", () => {
assert.deepEqual(
renameSnippetPackage(["a", "b/x"], [], "a", "b"),
{ ok: false, error: "duplicate" },
);
assert.deepEqual(
renameSnippetPackage(["a", "B/x"], [], "a", "b"),
{ ok: false, error: "duplicate" },
);
});
test("renameSnippetPackage rejects collisions with snippet-implied packages", () => {
assert.deepEqual(
renameSnippetPackage(
["a"],
[snippet({ id: "s", package: "b/x" })],
"a",
"b",
),
{ ok: false, error: "duplicate" },
);
});
test("collectSnippetPackageTreePaths includes persisted and inferred ancestors", () => {
assert.deepEqual(
collectSnippetPackageTreePaths(["a", "b/x"], [snippet({ id: "s", package: "c/y" })]).sort(),
["a", "b", "b/x", "c", "c/y"],
);
});
test("renameSnippetPackage no-ops when the name is unchanged", () => {
const packages = ["ops"];
const snippets = [snippet({ id: "a", package: "ops" })];
const result = renameSnippetPackage(packages, snippets, "ops", "ops");
assert.equal(result.ok, true);
if (!result.ok) return;
assert.equal(result.newPath, "ops");
assert.equal(result.packages, packages);
assert.equal(result.snippets, snippets);
});
test("applySnippetPackagePathChange rewrites descendants and clears deleted paths", () => {
assert.equal(
applySnippetPackagePathChange("ops/linux", { from: "ops", to: "platform" }),
"platform/linux",
);
assert.equal(
applySnippetPackagePathChange("ops/linux", { from: "ops", to: null }),
"",
);
assert.equal(
applySnippetPackagePathChange("other", { from: "ops", to: "platform" }),
"other",
);
});