fix: EditTool can clobber human edits to the same file. (#3043)

Co-authored-by: Colt McAnlis <colton@google.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Colt McAnlis
2025-07-07 10:28:56 -07:00
committed by GitHub
parent 229ae03631
commit 8f4046c71a
7 changed files with 249 additions and 21 deletions

View File

@@ -84,20 +84,22 @@ describe('EditTool', () => {
// Reset mocks and set default implementation for ensureCorrectEdit
mockEnsureCorrectEdit.mockReset();
mockEnsureCorrectEdit.mockImplementation(async (currentContent, params) => {
let occurrences = 0;
if (params.old_string && currentContent) {
// Simple string counting for the mock
let index = currentContent.indexOf(params.old_string);
while (index !== -1) {
occurrences++;
index = currentContent.indexOf(params.old_string, index + 1);
mockEnsureCorrectEdit.mockImplementation(
async (_, currentContent, params) => {
let occurrences = 0;
if (params.old_string && currentContent) {
// Simple string counting for the mock
let index = currentContent.indexOf(params.old_string);
while (index !== -1) {
occurrences++;
index = currentContent.indexOf(params.old_string, index + 1);
}
} else if (params.old_string === '') {
occurrences = 0; // Creating a new file
}
} else if (params.old_string === '') {
occurrences = 0; // Creating a new file
}
return Promise.resolve({ params, occurrences });
});
return Promise.resolve({ params, occurrences });
},
);
// Default mock for generateJson to return the snippet unchanged
mockGenerateJson.mockReset();
@@ -333,7 +335,7 @@ describe('EditTool', () => {
// Set a specific mock for this test case
let mockCalled = false;
mockEnsureCorrectEdit.mockImplementationOnce(
async (content, p, client) => {
async (_, content, p, client) => {
mockCalled = true;
expect(content).toBe(originalContent);
expect(p).toBe(params);
@@ -383,7 +385,7 @@ describe('EditTool', () => {
beforeEach(() => {
filePath = path.join(rootDir, testFile);
// Default for execute tests, can be overridden
mockEnsureCorrectEdit.mockImplementation(async (content, params) => {
mockEnsureCorrectEdit.mockImplementation(async (_, content, params) => {
let occurrences = 0;
if (params.old_string && content) {
let index = content.indexOf(params.old_string);