Skip to content

Commit 3e9eb2c

Browse files
test: fix stale PluginHookContract assertions for v1.4.2 plugin shape
The v1.4.2 migration (f9ea81e) changed plugins/ix-plugin.ts to export a named `server` Plugin function that returns a registration object (a `tool` map keyed by tool name + hook handlers like `tool.execute.after`). The PluginHookContract test block was not updated in that commit and still asserted the old default-export `{ name, tools[], hooks[] }` shape, so it failed: `import(...).default` is undefined and there is no 5-hook array. Update the three assertions to the actual contract: assert the `server` named export is a function, invoke it (the ix-unavailable startup probe is swallowed by its try/catch), and check the returned `tool` map has the 17 expected tools and a `tool.execute.after` hook handler. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 7630d86 commit 3e9eb2c

1 file changed

Lines changed: 28 additions & 12 deletions

File tree

tests/tools.test.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,22 +145,38 @@ describe("RuntimeUnavailableFallback", () => {
145145
// ─── Hook contract (structural) ──────────────────────────────────────────────
146146

147147
describe("PluginHookContract", () => {
148-
test("plugin module exports a default plugin object", async () => {
149-
const plugin = (await import("../plugins/ix-plugin")).default;
150-
expect(plugin).toBeDefined();
151-
expect(typeof plugin).toBe("object");
152-
expect(typeof (plugin as { name: string }).name).toBe("string");
153-
expect(Array.isArray((plugin as { tools: unknown[] }).tools)).toBe(true);
154-
expect(Array.isArray((plugin as { hooks: unknown[] }).hooks)).toBe(true);
148+
// The v1.4.2 plugin format (migrated in f9ea81e) exports a named `server`
149+
// Plugin function. Invoking it yields the registration object: a `tool` map
150+
// plus hook handlers keyed by event name (e.g. "tool.execute.after"). `ix` is
151+
// unavailable here, so the startup probe inside `server` falls through its
152+
// try/catch and the function still resolves.
153+
const PLUGIN_CTX = {
154+
directory: DEAD_CTX.directory,
155+
worktree: DEAD_CTX.directory,
156+
};
157+
158+
async function loadRegistration(): Promise<Record<string, unknown>> {
159+
const mod = await import("../plugins/ix-plugin");
160+
expect(typeof mod.server).toBe("function");
161+
return (await mod.server(PLUGIN_CTX as never)) as Record<string, unknown>;
162+
}
163+
164+
test("plugin module exports a server Plugin function", async () => {
165+
const reg = await loadRegistration();
166+
expect(reg).toBeDefined();
167+
expect(typeof reg).toBe("object");
155168
});
156169

157170
test("plugin registers 17 tools", async () => {
158-
const plugin = (await import("../plugins/ix-plugin")).default;
159-
expect((plugin as { tools: unknown[] }).tools).toHaveLength(17);
171+
const reg = await loadRegistration();
172+
const tools = reg.tool as Record<string, unknown>;
173+
expect(typeof tools).toBe("object");
174+
expect(Object.keys(tools)).toHaveLength(17);
175+
expect(Object.keys(tools).sort()).toEqual([...EXPECTED_TOOL_NAMES].sort());
160176
});
161177

162-
test("plugin registers 5 hooks", async () => {
163-
const plugin = (await import("../plugins/ix-plugin")).default;
164-
expect((plugin as { hooks: unknown[] }).hooks).toHaveLength(5);
178+
test("plugin registers the tool.execute.after hook", async () => {
179+
const reg = await loadRegistration();
180+
expect(typeof reg["tool.execute.after"]).toBe("function");
165181
});
166182
});

0 commit comments

Comments
 (0)