tests / tools.test.ts
tests / tools.test.ts
import { describe, it, expect } from "vitest";
import { registerShellTools } from "../src/tools/shell_tools";
import { registerFileTools } from "../src/tools/file_tools";
import { registerSystemTools } from "../src/tools/system_tools";
import { registerArchiveTools } from "../src/tools/archive_tools";
import { registerTextTools } from "../src/tools/text_tools";
import { toolsProvider } from "../src/toolsProvider";
describe("toolsProvider", () => {
it("should return all tools", async () => {
const tools = await toolsProvider();
expect(tools.length).toBeGreaterThanOrEqual(15);
});
});
describe("shell_tools", () => {
it("should register shell_exec and run_process", async () => {
const tools = await registerShellTools();
expect(tools).toHaveLength(2);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("shell_exec");
expect(names).toContain("run_process");
});
it("shell_exec should reject dangerous commands", async () => {
const tools = await registerShellTools();
const shellExec = tools.find((t: { name: string }) => t.name === "shell_exec") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; error?: string }>;
};
const result = await shellExec.implementation({ command: "rm -rf /" });
expect(result.success).toBe(false);
expect(result.error).toContain("dangerous");
});
it("shell_exec should run safe commands", async () => {
const tools = await registerShellTools();
const shellExec = tools.find((t: { name: string }) => t.name === "shell_exec") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; stdout?: string }>;
};
const result = await shellExec.implementation({ command: "echo hello" });
expect(result.success).toBe(true);
expect(result.stdout).toContain("hello");
});
it("run_process should execute direct commands", async () => {
const tools = await registerShellTools();
const runProcess = tools.find((t: { name: string }) => t.name === "run_process") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; stdout?: string }>;
};
const result = await runProcess.implementation({
command: process.execPath,
args: ["-e", "console.log('world')"],
});
expect(result.success).toBe(true);
expect(result.stdout).toContain("world");
});
});
describe("file_tools", () => {
it("should register all file tools", async () => {
const tools = await registerFileTools();
expect(tools.length).toBeGreaterThanOrEqual(8);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("file_write");
expect(names).toContain("read_file");
expect(names).toContain("file_diff");
expect(names).toContain("file_checksum");
expect(names).toContain("file_stats");
expect(names).toContain("list_directory");
expect(names).toContain("create_directory");
expect(names).toContain("delete_file");
});
it("file_write should write and read back", async () => {
const tools = await registerFileTools();
const fileWrite = tools.find((t: { name: string }) => t.name === "file_write") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; path?: string }>;
};
const readFile = tools.find((t: { name: string }) => t.name === "read_file") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; content?: string }>;
};
const writeResult = await fileWrite.implementation({
path: "test_output.txt",
content: "smoke test content",
});
expect(writeResult.success).toBe(true);
const readResult = await readFile.implementation({ path: "test_output.txt" });
expect(readResult.success).toBe(true);
expect(readResult.content).toBe("smoke test content");
});
it("file_write should reject path traversal", async () => {
const tools = await registerFileTools();
const fileWrite = tools.find((t: { name: string }) => t.name === "file_write") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; error?: string }>;
};
const result = await fileWrite.implementation({
path: "../../etc/passwd",
content: "hacked",
});
expect(result.success).toBe(false);
expect(result.error).toContain("traversal");
});
});
describe("system_tools", () => {
it("should register all system tools", async () => {
const tools = await registerSystemTools();
expect(tools.length).toBeGreaterThanOrEqual(6);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("system_info");
expect(names).toContain("list_processes");
expect(names).toContain("kill_process");
expect(names).toContain("check_network");
expect(names).toContain("get_network_info");
expect(names).toContain("get_disk_info");
});
it("system_info should return platform info", async () => {
const tools = await registerSystemTools();
const systemInfo = tools.find((t: { name: string }) => t.name === "system_info") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; output?: string }>;
};
const result = await systemInfo.implementation({});
expect(result.success).toBe(true);
expect(result.output).toContain("Platform:");
});
it("kill_process should reject invalid PID", async () => {
const tools = await registerSystemTools();
const killProcess = tools.find((t: { name: string }) => t.name === "kill_process") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; error?: string }>;
};
const result = await killProcess.implementation({ pid: -1 });
expect(result.success).toBe(false);
expect(result.error).toContain("Invalid PID");
});
});
describe("archive_tools", () => {
it("should register all archive tools", async () => {
const tools = await registerArchiveTools();
expect(tools).toHaveLength(3);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("zip_create");
expect(names).toContain("zip_extract");
expect(names).toContain("zip_list");
});
});
describe("text_tools", () => {
it("should register all text tools", async () => {
const tools = await registerTextTools();
expect(tools.length).toBeGreaterThanOrEqual(4);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("replace_text");
expect(names).toContain("count_text");
expect(names).toContain("insert_text");
expect(names).toContain("delete_lines");
});
it("replace_text should find and replace", async () => {
const tools = await registerFileTools();
const fileWrite = tools.find((t: { name: string }) => t.name === "file_write") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean }>;
};
await fileWrite.implementation({
path: "replace_test.txt",
content: "hello world\nfoo bar\n",
});
const textTools = await registerTextTools();
const replaceText = textTools.find((t: { name: string }) => t.name === "replace_text") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; replacements_made?: number }>;
};
const result = await replaceText.implementation({
file_path: "replace_test.txt",
find: "foo",
replace_with: "baz",
});
expect(result.success).toBe(true);
expect(result.replacements_made).toBe(1);
});
});
import { describe, it, expect } from "vitest";
import { registerShellTools } from "../src/tools/shell_tools";
import { registerFileTools } from "../src/tools/file_tools";
import { registerSystemTools } from "../src/tools/system_tools";
import { registerArchiveTools } from "../src/tools/archive_tools";
import { registerTextTools } from "../src/tools/text_tools";
import { toolsProvider } from "../src/toolsProvider";
describe("toolsProvider", () => {
it("should return all tools", async () => {
const tools = await toolsProvider();
expect(tools.length).toBeGreaterThanOrEqual(15);
});
});
describe("shell_tools", () => {
it("should register shell_exec and run_process", async () => {
const tools = await registerShellTools();
expect(tools).toHaveLength(2);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("shell_exec");
expect(names).toContain("run_process");
});
it("shell_exec should reject dangerous commands", async () => {
const tools = await registerShellTools();
const shellExec = tools.find((t: { name: string }) => t.name === "shell_exec") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; error?: string }>;
};
const result = await shellExec.implementation({ command: "rm -rf /" });
expect(result.success).toBe(false);
expect(result.error).toContain("dangerous");
});
it("shell_exec should run safe commands", async () => {
const tools = await registerShellTools();
const shellExec = tools.find((t: { name: string }) => t.name === "shell_exec") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; stdout?: string }>;
};
const result = await shellExec.implementation({ command: "echo hello" });
expect(result.success).toBe(true);
expect(result.stdout).toContain("hello");
});
it("run_process should execute direct commands", async () => {
const tools = await registerShellTools();
const runProcess = tools.find((t: { name: string }) => t.name === "run_process") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; stdout?: string }>;
};
const result = await runProcess.implementation({
command: process.execPath,
args: ["-e", "console.log('world')"],
});
expect(result.success).toBe(true);
expect(result.stdout).toContain("world");
});
});
describe("file_tools", () => {
it("should register all file tools", async () => {
const tools = await registerFileTools();
expect(tools.length).toBeGreaterThanOrEqual(8);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("file_write");
expect(names).toContain("read_file");
expect(names).toContain("file_diff");
expect(names).toContain("file_checksum");
expect(names).toContain("file_stats");
expect(names).toContain("list_directory");
expect(names).toContain("create_directory");
expect(names).toContain("delete_file");
});
it("file_write should write and read back", async () => {
const tools = await registerFileTools();
const fileWrite = tools.find((t: { name: string }) => t.name === "file_write") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; path?: string }>;
};
const readFile = tools.find((t: { name: string }) => t.name === "read_file") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; content?: string }>;
};
const writeResult = await fileWrite.implementation({
path: "test_output.txt",
content: "smoke test content",
});
expect(writeResult.success).toBe(true);
const readResult = await readFile.implementation({ path: "test_output.txt" });
expect(readResult.success).toBe(true);
expect(readResult.content).toBe("smoke test content");
});
it("file_write should reject path traversal", async () => {
const tools = await registerFileTools();
const fileWrite = tools.find((t: { name: string }) => t.name === "file_write") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; error?: string }>;
};
const result = await fileWrite.implementation({
path: "../../etc/passwd",
content: "hacked",
});
expect(result.success).toBe(false);
expect(result.error).toContain("traversal");
});
});
describe("system_tools", () => {
it("should register all system tools", async () => {
const tools = await registerSystemTools();
expect(tools.length).toBeGreaterThanOrEqual(6);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("system_info");
expect(names).toContain("list_processes");
expect(names).toContain("kill_process");
expect(names).toContain("check_network");
expect(names).toContain("get_network_info");
expect(names).toContain("get_disk_info");
});
it("system_info should return platform info", async () => {
const tools = await registerSystemTools();
const systemInfo = tools.find((t: { name: string }) => t.name === "system_info") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; output?: string }>;
};
const result = await systemInfo.implementation({});
expect(result.success).toBe(true);
expect(result.output).toContain("Platform:");
});
it("kill_process should reject invalid PID", async () => {
const tools = await registerSystemTools();
const killProcess = tools.find((t: { name: string }) => t.name === "kill_process") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; error?: string }>;
};
const result = await killProcess.implementation({ pid: -1 });
expect(result.success).toBe(false);
expect(result.error).toContain("Invalid PID");
});
});
describe("archive_tools", () => {
it("should register all archive tools", async () => {
const tools = await registerArchiveTools();
expect(tools).toHaveLength(3);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("zip_create");
expect(names).toContain("zip_extract");
expect(names).toContain("zip_list");
});
});
describe("text_tools", () => {
it("should register all text tools", async () => {
const tools = await registerTextTools();
expect(tools.length).toBeGreaterThanOrEqual(4);
const names = tools.map((t: { name: string }) => t.name);
expect(names).toContain("replace_text");
expect(names).toContain("count_text");
expect(names).toContain("insert_text");
expect(names).toContain("delete_lines");
});
it("replace_text should find and replace", async () => {
const tools = await registerFileTools();
const fileWrite = tools.find((t: { name: string }) => t.name === "file_write") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean }>;
};
await fileWrite.implementation({
path: "replace_test.txt",
content: "hello world\nfoo bar\n",
});
const textTools = await registerTextTools();
const replaceText = textTools.find((t: { name: string }) => t.name === "replace_text") as {
implementation: (params: Record<string, unknown>) => Promise<{ success: boolean; replacements_made?: number }>;
};
const result = await replaceText.implementation({
file_path: "replace_test.txt",
find: "foo",
replace_with: "baz",
});
expect(result.success).toBe(true);
expect(result.replacements_made).toBe(1);
});
});