Files
oh-my-pi/packages/coding-agent/test/cursor-exec.test.ts
T
oldschoola a2854ba768 fix: migrate coding-agent tests from fs.rm to removeWithRetries
Migrate 203 test files (356 call sites) from fs.rm/fs.rmSync to
removeWithRetries/removeSyncWithRetries to reduce EBUSY test failures
on Windows. removeWithRetries is now exported from @oh-my-pi/pi-utils.

The migration uses a regex-based approach that:
- Replaces fs.rm(path, { recursive, force }) → removeWithRetries(path)
- Replaces fs.rmSync(path, { recursive, force }) → removeSyncWithRetries(path)
- Replaces fs.rm(path) → removeWithRetries(path) (no options)
- Skips fs.rm/fs.rmSync inside template literals (bun --eval scripts)
- Adds imports to existing @oh-my-pi/pi-utils import or creates new one
- Removes unused fs imports where fs.rm was the only fs usage (4 files)
2026-06-23 15:28:05 -07:00

68 lines
2.3 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it } from "bun:test";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
import { CursorExecHandlers } from "@oh-my-pi/pi-coding-agent/cursor";
import { SearchTool, type ToolSession } from "@oh-my-pi/pi-coding-agent/tools";
import { removeWithRetries } from "@oh-my-pi/pi-utils";
function createTestSession(cwd: string, overrides: Partial<ToolSession> = {}): ToolSession {
return {
cwd,
hasUI: false,
getSessionFile: () => null,
getSessionSpawns: () => "*",
settings: Settings.isolated(),
...overrides,
};
}
describe("CursorExecHandlers.grep bridge", () => {
let cwd: string;
let searchTool: SearchTool;
let handlers: CursorExecHandlers;
beforeEach(async () => {
cwd = await fs.mkdtemp(path.join(os.tmpdir(), "cursor-exec-test-"));
await Bun.write(path.join(cwd, "sample.txt"), "Hello World\nhello world\n");
searchTool = new SearchTool(createTestSession(cwd));
handlers = new CursorExecHandlers({
cwd,
tools: new Map([["search", searchTool as any]]),
});
});
afterEach(async () => {
await removeWithRetries(cwd);
});
it("maps caseInsensitive parameter correctly through the grep bridge", async () => {
// 1. By default/omitted caseInsensitive, should be case-sensitive (match count 1 for "hello")
const defaultResult = await handlers.grep({
toolCallId: "call-1",
path: cwd,
pattern: "hello",
} as any);
expect((defaultResult.details as { matchCount?: number } | undefined)?.matchCount).toBe(1);
// 2. If caseInsensitive: true, should be case-insensitive (match count 2 for "hello")
const insensitiveResult = await handlers.grep({
toolCallId: "call-2",
path: cwd,
pattern: "hello",
caseInsensitive: true,
} as any);
expect((insensitiveResult.details as { matchCount?: number } | undefined)?.matchCount).toBe(2);
// 3. If caseInsensitive: false, should be case-sensitive (match count 1 for "hello")
const sensitiveResult = await handlers.grep({
toolCallId: "call-3",
path: cwd,
pattern: "hello",
caseInsensitive: false,
} as any);
expect((sensitiveResult.details as { matchCount?: number } | undefined)?.matchCount).toBe(1);
});
});