pi-mono/packages/coding-agent/test/edit-tool-diff-before-write.test.ts
Petr Houška 991cb1ad24 fix(coding-agent): edit keeps line endings of untouched lines, diffs before writing
The edit tool wrote the whole file back with the first line ending it
found, so mixed CRLF/LF files and lone CRs were rewritten. Replacements
are now mapped from the LF-normalized text back to the original and
spliced in; new line breaks use the ending of the replaced line.

The diff and patch were computed after writing and diffed the whole
file, which ran out of memory on large files after the write. They are
now computed before writing, and files larger than 5 MB get a notice
instead of a diff (empty patch).

fixes #8544
2026-11-05 23:46:20 +01:00

30 lines
952 B
TypeScript

import { describe, expect, it, vi } from "vitest";
import { createEditTool } from "../src/core/tools/edit.ts";
vi.mock("../src/core/tools/edit-diff.ts", async (importOriginal) => {
const original = await importOriginal<typeof import("../src/core/tools/edit-diff.ts")>();
return {
...original,
generateUnifiedPatch: () => {
throw new Error("diff failed");
},
};
});
describe("edit tool diff before write", () => {
it("should compute the diff before writing, so a diff failure leaves the file unchanged", async () => {
const writeFile = vi.fn(async () => {});
const tool = createEditTool(process.cwd(), {
operations: {
access: async () => {},
readFile: async () => Buffer.from("a\nb\n"),
writeFile,
},
});
await expect(
tool.execute("test-diff-before-write", { path: "f.txt", edits: [{ oldText: "b", newText: "B" }] }),
).rejects.toThrow("diff failed");
expect(writeFile).not.toHaveBeenCalled();
});
});