120 lines
3.3 KiB
TypeScript
120 lines
3.3 KiB
TypeScript
import { assertEquals, assertRejects, assertThrows } from "jsr:@std/assert@1";
|
|
import { join } from "jsr:@std/path@1";
|
|
import {
|
|
loadSuperpowersReviewGuide,
|
|
parseBotType,
|
|
type SuperpowersFileSystem,
|
|
superpowersInstallCommands,
|
|
} from "./superpowers.ts";
|
|
|
|
function fakeFileSystem(files: Record<string, string>): SuperpowersFileSystem {
|
|
return {
|
|
readTextFile(path) {
|
|
const contents = files[path];
|
|
return contents === undefined
|
|
? Promise.reject(new Deno.errors.NotFound(path))
|
|
: Promise.resolve(contents);
|
|
},
|
|
async *readDir(directory) {
|
|
const prefix = `${directory}/`;
|
|
const children = new Map<string, boolean>();
|
|
for (const path of Object.keys(files)) {
|
|
if (!path.startsWith(prefix)) continue;
|
|
const [name, ...rest] = path.slice(prefix.length).split("/");
|
|
if (name !== "") children.set(name, rest.length > 0);
|
|
}
|
|
if (children.size === 0) throw new Deno.errors.NotFound(directory);
|
|
for (const [name, isDirectory] of children) {
|
|
yield {
|
|
name,
|
|
isDirectory,
|
|
isFile: !isDirectory,
|
|
isSymlink: false,
|
|
};
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
Deno.test("installs Superpowers from the Codex marketplace", () => {
|
|
assertEquals(superpowersInstallCommands("codex"), [{
|
|
command: "codex",
|
|
args: ["plugin", "add", "superpowers@openai-curated-remote"],
|
|
}]);
|
|
});
|
|
|
|
Deno.test("installs Superpowers from the Claude marketplace", () => {
|
|
assertEquals(superpowersInstallCommands("claude"), [
|
|
{
|
|
command: "claude",
|
|
args: [
|
|
"plugin",
|
|
"marketplace",
|
|
"add",
|
|
"obra/superpowers-marketplace",
|
|
],
|
|
},
|
|
{
|
|
command: "claude",
|
|
args: [
|
|
"plugin",
|
|
"install",
|
|
"-y",
|
|
"superpowers@superpowers-marketplace",
|
|
],
|
|
},
|
|
]);
|
|
});
|
|
|
|
Deno.test("rejects an unsupported bot type", () => {
|
|
assertThrows(
|
|
() => parseBotType("other"),
|
|
Error,
|
|
"unsupported bot type: other",
|
|
);
|
|
});
|
|
|
|
Deno.test("loads the newest installed Superpowers review guide", async () => {
|
|
const home = "/home/bot";
|
|
const older = join(
|
|
home,
|
|
".codex/plugins/cache/openai-curated-remote/superpowers/6.3.0/skills/requesting-code-review",
|
|
);
|
|
const newer = join(
|
|
home,
|
|
".codex/plugins/cache/openai-curated-remote/superpowers/6.10.0/skills/requesting-code-review",
|
|
);
|
|
const guide = await loadSuperpowersReviewGuide(
|
|
"codex",
|
|
home,
|
|
fakeFileSystem({
|
|
[join(older, "SKILL.md")]: "old",
|
|
[join(older, "code-reviewer.md")]: "old template",
|
|
[join(newer, "SKILL.md")]: "new",
|
|
[join(newer, "code-reviewer.md")]: "template",
|
|
}),
|
|
);
|
|
|
|
assertEquals(guide.version, "6.10.0");
|
|
assertEquals(guide.skill, "new");
|
|
assertEquals(guide.template, "template");
|
|
assertEquals(guide.skillPath, join(newer, "SKILL.md"));
|
|
});
|
|
|
|
Deno.test("fails when the installed review guide is incomplete", async () => {
|
|
const home = "/home/bot";
|
|
const directory = join(
|
|
home,
|
|
".claude/plugins/cache/superpowers-marketplace/superpowers/6.3.0/skills/requesting-code-review",
|
|
);
|
|
const fileSystem = fakeFileSystem({
|
|
[join(directory, "SKILL.md")]: "skill",
|
|
});
|
|
|
|
await assertRejects(
|
|
() => loadSuperpowersReviewGuide("claude", home, fileSystem),
|
|
Error,
|
|
"installed Superpowers requesting-code-review files not found",
|
|
);
|
|
});
|