130 lines
4.0 KiB
TypeScript
130 lines
4.0 KiB
TypeScript
// src/tools/file/read.test.ts
|
|
// Copyright (C) 2025 DTP Technologies, LLC
|
|
// All Rights Reserved
|
|
|
|
import { describe, it, expect, beforeEach } from "vitest";
|
|
import { FileReadTool } from "./read.js";
|
|
|
|
describe("FileReadTool", () => {
|
|
let tool: FileReadTool;
|
|
let mockSession: any;
|
|
|
|
beforeEach(() => {
|
|
tool = new FileReadTool();
|
|
mockSession = {
|
|
_id: "test-session-id",
|
|
user: "test-user-id",
|
|
};
|
|
});
|
|
|
|
describe("definition", () => {
|
|
it("should have correct tool name", () => {
|
|
expect(tool.definition.function.name).toBe("file_read");
|
|
});
|
|
|
|
it("should have correct definition structure for AI clients", () => {
|
|
const def = tool.definition;
|
|
expect(def.type).toBe("function");
|
|
expect(def.function).toBeDefined();
|
|
expect(def.function.name).toBe("file_read");
|
|
expect(def.function.description).toBeDefined();
|
|
expect(def.function.parameters).toBeDefined();
|
|
const params = def.function.parameters as any;
|
|
expect(params.type).toBe("object");
|
|
expect(params.properties).toBeDefined();
|
|
expect(params.properties.path).toBeDefined();
|
|
expect(params.required).toContain("path");
|
|
});
|
|
});
|
|
|
|
describe("execute", () => {
|
|
it("should return error for missing path", async () => {
|
|
const result = await tool.execute({ session: mockSession }, { path: "" });
|
|
|
|
expect(result).toContain("MISSING_PARAMETER");
|
|
expect(result).toContain("File path must not be empty");
|
|
});
|
|
|
|
it("should return error for non-existent file", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ path: "non/existent/file.txt" },
|
|
);
|
|
|
|
expect(result).toContain("NOT_FOUND");
|
|
expect(result).toContain("File not found");
|
|
});
|
|
|
|
it("should successfully read README.md", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ path: "README.md" },
|
|
);
|
|
|
|
// Result is now plain text with header metadata
|
|
expect(result).toContain("PATH: README.md");
|
|
expect(result).toContain("TOTAL LINES:");
|
|
expect(result).toContain("LINES SHOWN:");
|
|
expect(result).toContain("FILE OPERATION: read");
|
|
expect(result).toContain("Gadget Code");
|
|
});
|
|
|
|
it("should read file with line numbers", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ path: "README.md" },
|
|
);
|
|
|
|
// Result is plain text - content is after the "---" separator
|
|
expect(result).toContain("Gadget Code");
|
|
|
|
const lines = result.split("\n");
|
|
const firstContentLine = lines.find((l: string) =>
|
|
l.includes("Gadget Code"),
|
|
);
|
|
expect(firstContentLine).toBeDefined();
|
|
if (firstContentLine) {
|
|
expect(firstContentLine).toMatch(/^\d+:/);
|
|
}
|
|
});
|
|
|
|
it("should respect line range parameters", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ path: "README.md", startLine: 1, endLine: 3 },
|
|
);
|
|
|
|
// Result is plain text - check for line range in output
|
|
expect(result).toContain("lines 1-3");
|
|
const lines = result.split("\n").filter((l: string) => l.match(/^\d+: /));
|
|
expect(lines.length).toBeLessThanOrEqual(3);
|
|
});
|
|
});
|
|
|
|
describe("response format for AI clients", () => {
|
|
it("should return a string that can be used in message content", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ path: "README.md" },
|
|
);
|
|
|
|
expect(typeof result).toBe("string");
|
|
expect(result.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it("should return plain text with header metadata", async () => {
|
|
const result = await tool.execute(
|
|
{ session: mockSession },
|
|
{ path: "README.md" },
|
|
);
|
|
|
|
// Verify plain text format with header
|
|
expect(result).toMatch(/^PATH:/m);
|
|
expect(result).toContain("TOTAL LINES:");
|
|
expect(result).toContain("LINES SHOWN:");
|
|
expect(result).toContain("FILE OPERATION: read");
|
|
expect(result).toContain("---");
|
|
});
|
|
});
|
|
});
|