061926b86a
- Auto-fix string concatenation → template literals - Remove unused imports - Prefix unused function with underscore - Format fixes across multiple files
122 lines
3.6 KiB
TypeScript
122 lines
3.6 KiB
TypeScript
import { afterAll, describe, expect, test } from "bun:test";
|
|
import { randomBytes } from "node:crypto";
|
|
import { mkdirSync, readFileSync, unlinkSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { patchFileTool, readFileTool, shellExecTool, writeFileTool } from "../src/tools/index.js";
|
|
|
|
const TMP_DIR = join(tmpdir(), `tools-test-${randomBytes(4).toString("hex")}`);
|
|
mkdirSync(TMP_DIR, { recursive: true });
|
|
|
|
const tmpFile = (name: string) => join(TMP_DIR, name);
|
|
|
|
const cleanupFiles: string[] = [];
|
|
|
|
afterAll(() => {
|
|
for (const f of cleanupFiles) {
|
|
try {
|
|
unlinkSync(f);
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
try {
|
|
unlinkSync(TMP_DIR);
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
});
|
|
|
|
describe("read_file", () => {
|
|
test("reads file with line numbers", async () => {
|
|
const p = tmpFile("read-test.txt");
|
|
cleanupFiles.push(p);
|
|
const content = "line1\nline2\nline3\n";
|
|
require("node:fs").writeFileSync(p, content);
|
|
|
|
const result = await readFileTool.handler(
|
|
JSON.stringify({ path: p, offset: null, limit: null }),
|
|
);
|
|
expect(result).toContain("1|line1");
|
|
expect(result).toContain("2|line2");
|
|
expect(result).toContain("3|line3");
|
|
});
|
|
|
|
test("reads with offset and limit", async () => {
|
|
const p = tmpFile("read-test2.txt");
|
|
cleanupFiles.push(p);
|
|
require("node:fs").writeFileSync(p, "a\nb\nc\nd\ne\n");
|
|
|
|
const result = await readFileTool.handler(JSON.stringify({ path: p, offset: 2, limit: 2 }));
|
|
expect(result).toBe("2|b\n3|c");
|
|
});
|
|
|
|
test("returns error for missing file", async () => {
|
|
const result = await readFileTool.handler(
|
|
JSON.stringify({ path: "/nonexistent/file.txt", offset: null, limit: null }),
|
|
);
|
|
expect(result).toContain("Error:");
|
|
});
|
|
});
|
|
|
|
describe("write_file", () => {
|
|
test("writes file and creates dirs", async () => {
|
|
const p = tmpFile("sub/write-test.txt");
|
|
cleanupFiles.push(p);
|
|
|
|
const result = await writeFileTool.handler(JSON.stringify({ path: p, content: "hello world" }));
|
|
expect(result).toContain("11 bytes");
|
|
expect(readFileSync(p, "utf-8")).toBe("hello world");
|
|
});
|
|
});
|
|
|
|
describe("patch_file", () => {
|
|
test("patches file content", async () => {
|
|
const p = tmpFile("patch-test.txt");
|
|
cleanupFiles.push(p);
|
|
require("node:fs").writeFileSync(p, "foo bar baz");
|
|
|
|
const result = await patchFileTool.handler(
|
|
JSON.stringify({ path: p, old_string: "bar", new_string: "qux" }),
|
|
);
|
|
expect(result).toContain("Successfully");
|
|
expect(readFileSync(p, "utf-8")).toBe("foo qux baz");
|
|
});
|
|
|
|
test("errors on not found", async () => {
|
|
const p = tmpFile("patch-test2.txt");
|
|
cleanupFiles.push(p);
|
|
require("node:fs").writeFileSync(p, "foo");
|
|
|
|
const result = await patchFileTool.handler(
|
|
JSON.stringify({ path: p, old_string: "xyz", new_string: "abc" }),
|
|
);
|
|
expect(result).toContain("not found");
|
|
});
|
|
|
|
test("errors on non-unique match", async () => {
|
|
const p = tmpFile("patch-test3.txt");
|
|
cleanupFiles.push(p);
|
|
require("node:fs").writeFileSync(p, "aaa bbb aaa");
|
|
|
|
const result = await patchFileTool.handler(
|
|
JSON.stringify({ path: p, old_string: "aaa", new_string: "ccc" }),
|
|
);
|
|
expect(result).toContain("not unique");
|
|
});
|
|
});
|
|
|
|
describe("shell_exec", () => {
|
|
test("runs echo", async () => {
|
|
const result = await shellExecTool.handler(
|
|
JSON.stringify({ command: "echo hello", timeout: null }),
|
|
);
|
|
expect(result.trim()).toBe("hello");
|
|
});
|
|
|
|
test("handles timeout", async () => {
|
|
const result = await shellExecTool.handler(JSON.stringify({ command: "sleep 10", timeout: 1 }));
|
|
expect(result).toContain("timed out");
|
|
});
|
|
});
|