Initial release
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import { TaskState } from "../src/state.ts";
|
||||
import { registerTaskTools } from "../src/tools.ts";
|
||||
|
||||
function registeredTools(state = new TaskState()) {
|
||||
const tools = new Map<string, any>();
|
||||
let changes = 0;
|
||||
const pi = {
|
||||
registerTool(tool: any) {
|
||||
tools.set(tool.name, tool);
|
||||
},
|
||||
};
|
||||
registerTaskTools(pi as never, state, () => {
|
||||
changes += 1;
|
||||
});
|
||||
return { tools, state, changes: () => changes };
|
||||
}
|
||||
|
||||
async function execute(tool: any, params: unknown) {
|
||||
return tool.execute("call", params, undefined, undefined, {});
|
||||
}
|
||||
|
||||
test("registers the five requested tools with minimal top-level parameters", () => {
|
||||
const { tools } = registeredTools();
|
||||
assert.deepEqual([...tools.keys()], ["add_task", "update_task", "rm_task", "list_task", "get_task"]);
|
||||
assert.deepEqual(Object.keys(tools.get("add_task").parameters.properties), ["tasks"]);
|
||||
assert.deepEqual(Object.keys(tools.get("update_task").parameters.properties), ["tasks"]);
|
||||
assert.deepEqual(Object.keys(tools.get("rm_task").parameters.properties), ["ids"]);
|
||||
assert.deepEqual(Object.keys(tools.get("list_task").parameters.properties), []);
|
||||
assert.deepEqual(Object.keys(tools.get("get_task").parameters.properties), ["ids"]);
|
||||
});
|
||||
|
||||
test("mutations return compact content and complete persistence snapshots", async () => {
|
||||
const harness = registeredTools();
|
||||
const result = await execute(harness.tools.get("add_task"), {
|
||||
tasks: [{ name: "Parent", description: "Parent", children: [{ name: "Child", description: "Child" }] }],
|
||||
});
|
||||
|
||||
assert.equal(result.content[0].text, "Added 2 tasks: 1, 2. 0/2 done.");
|
||||
assert.equal(result.details.snapshot.tasks.length, 2);
|
||||
assert.equal(result.details.snapshot.nextId, 3);
|
||||
assert.equal(harness.changes(), 1);
|
||||
});
|
||||
|
||||
test("tool validation errors are summarized while preserving atomic state", async () => {
|
||||
const harness = registeredTools();
|
||||
await execute(harness.tools.get("add_task"), {
|
||||
tasks: [{ name: "Parent", description: "Parent", children: [{ name: "Child", description: "Child" }] }],
|
||||
});
|
||||
const before = harness.state.snapshot();
|
||||
|
||||
await assert.rejects(
|
||||
execute(harness.tools.get("update_task"), { tasks: [{ id: 1, parentId: 2 }] }),
|
||||
/Update failed · 1 validation error\n- task [12]: parentId creates a cycle/,
|
||||
);
|
||||
assert.deepEqual(harness.state.snapshot(), before);
|
||||
assert.equal(harness.changes(), 1);
|
||||
});
|
||||
|
||||
test("list is compact and get returns full JSON for multiple IDs", async () => {
|
||||
const harness = registeredTools();
|
||||
await execute(harness.tools.get("add_task"), {
|
||||
tasks: [{ name: "Parent", description: "Detailed", children: [{ name: "Child", description: "Child detail" }] }],
|
||||
});
|
||||
|
||||
const list = await execute(harness.tools.get("list_task"), {});
|
||||
assert.equal(list.content[0].text, "1 [pending] Parent\n└─ 2 [pending] Child");
|
||||
|
||||
const get = await execute(harness.tools.get("get_task"), { ids: [1, 2] });
|
||||
const parsed = JSON.parse(get.content[0].text);
|
||||
assert.equal(parsed[0].description, "Detailed");
|
||||
assert.deepEqual(parsed[0].childrenIds, [2]);
|
||||
assert.equal(parsed[1].parentId, 1);
|
||||
});
|
||||
Reference in New Issue
Block a user