mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
chore: fix apply-diff test and add ntc apply-diff test
This commit is contained in:
parent
a42387e0af
commit
218ebbd44c
4 changed files with 1308 additions and 61 deletions
50
.vscode/launch.json
vendored
50
.vscode/launch.json
vendored
|
|
@ -24,6 +24,56 @@
|
|||
"group": "tasks",
|
||||
"order": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Debug E2E Tests",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"${workspaceFolder}/apps/vscode-e2e/test-workspace",
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/src",
|
||||
"--extensionTestsPath=${workspaceFolder}/apps/vscode-e2e/out/suite/index"
|
||||
],
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceFolder}/src/dist/**/*.js", "${workspaceFolder}/apps/vscode-e2e/out/**/*.js"],
|
||||
"preLaunchTask": "build-e2e-tests",
|
||||
"envFile": "${workspaceFolder}/apps/vscode-e2e/.env.local",
|
||||
"env": {
|
||||
"NODE_ENV": "development",
|
||||
"VSCODE_DEBUG_MODE": "true"
|
||||
},
|
||||
"resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"],
|
||||
"presentation": {
|
||||
"hidden": false,
|
||||
"group": "tasks",
|
||||
"order": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Debug E2E Tests (Quick - extension pre-built)",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"${workspaceFolder}/apps/vscode-e2e/test-workspace",
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/src",
|
||||
"--extensionTestsPath=${workspaceFolder}/apps/vscode-e2e/out/suite/index"
|
||||
],
|
||||
"sourceMaps": true,
|
||||
"outFiles": ["${workspaceFolder}/src/dist/**/*.js", "${workspaceFolder}/apps/vscode-e2e/out/**/*.js"],
|
||||
"preLaunchTask": "compile-e2e-only",
|
||||
"envFile": "${workspaceFolder}/apps/vscode-e2e/.env.local",
|
||||
"env": {
|
||||
"NODE_ENV": "development",
|
||||
"VSCODE_DEBUG_MODE": "true"
|
||||
},
|
||||
"resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"],
|
||||
"presentation": {
|
||||
"hidden": false,
|
||||
"group": "tasks",
|
||||
"order": 4
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
57
.vscode/tasks.json
vendored
57
.vscode/tasks.json
vendored
|
|
@ -69,6 +69,63 @@
|
|||
"group": "watch",
|
||||
"reveal": "always"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build-e2e-tests",
|
||||
"dependsOn": ["build-e2e:bundle", "build-e2e:webview", "build-e2e:compile"],
|
||||
"dependsOrder": "sequence",
|
||||
"group": "build",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "build-e2e:bundle",
|
||||
"type": "shell",
|
||||
"command": "pnpm -w bundle",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build-e2e:webview",
|
||||
"type": "shell",
|
||||
"command": "pnpm --filter @roo-code/vscode-webview build",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "build-e2e:compile",
|
||||
"type": "shell",
|
||||
"command": "npx rimraf out; npx tsc -p tsconfig.json",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/apps/vscode-e2e"
|
||||
},
|
||||
"group": "build",
|
||||
"problemMatcher": "$tsc",
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "compile-e2e-only",
|
||||
"type": "shell",
|
||||
"command": "npx rimraf out; npx tsc -p tsconfig.json",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/apps/vscode-e2e"
|
||||
},
|
||||
"group": "build",
|
||||
"problemMatcher": "$tsc",
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
1107
apps/vscode-e2e/src/suite/tools/apply-diff-native.test.ts
Normal file
1107
apps/vscode-e2e/src/suite/tools/apply-diff-native.test.ts
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -8,7 +8,7 @@ import { RooCodeEventName, type ClineMessage } from "@roo-code/types"
|
|||
import { waitFor, sleep } from "../utils"
|
||||
import { setDefaultSuiteTimeout } from "../test-utils"
|
||||
|
||||
suite.skip("Roo Code apply_diff Tool", function () {
|
||||
suite("Roo Code apply_diff Tool", function () {
|
||||
setDefaultSuiteTimeout(this)
|
||||
|
||||
let workspaceDir: string
|
||||
|
|
@ -133,6 +133,20 @@ function validateInput(input) {
|
|||
// Task might not be running
|
||||
}
|
||||
|
||||
// Reset all test files to their original content before each test
|
||||
// This ensures each test starts with a known clean state, even if a previous
|
||||
// test or run modified the file content
|
||||
for (const [key, file] of Object.entries(testFiles)) {
|
||||
if (file.path) {
|
||||
try {
|
||||
await fs.writeFile(file.path, file.content)
|
||||
console.log(`Reset ${key} test file to original content`)
|
||||
} catch (error) {
|
||||
console.log(`Failed to reset ${key} test file:`, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Small delay to ensure clean state
|
||||
await sleep(100)
|
||||
})
|
||||
|
|
@ -173,23 +187,22 @@ function validateInput(input) {
|
|||
}
|
||||
if (message.type === "ask" && message.ask === "tool") {
|
||||
console.log("Tool request:", message.text?.substring(0, 200))
|
||||
// Check for appliedDiff tool execution
|
||||
try {
|
||||
const toolData = JSON.parse(message.text || "{}")
|
||||
if (toolData.tool === "appliedDiff") {
|
||||
applyDiffExecuted = true
|
||||
console.log("apply_diff tool executed!")
|
||||
}
|
||||
} catch (_e) {
|
||||
// Not JSON or parsing failed
|
||||
}
|
||||
}
|
||||
if (message.type === "say" && (message.say === "completion_result" || message.say === "text")) {
|
||||
console.log("AI response:", message.text?.substring(0, 200))
|
||||
}
|
||||
|
||||
// Check for tool execution
|
||||
if (message.type === "say" && message.say === "api_req_started" && message.text) {
|
||||
console.log("API request started:", message.text.substring(0, 200))
|
||||
try {
|
||||
const requestData = JSON.parse(message.text)
|
||||
if (requestData.request && requestData.request.includes("apply_diff")) {
|
||||
applyDiffExecuted = true
|
||||
console.log("apply_diff tool executed!")
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Failed to parse api_req_started message:", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
api.on(RooCodeEventName.Message, messageHandler)
|
||||
|
|
@ -286,23 +299,22 @@ ${testFile.content}\nAssume the file exists and you can modify it directly.`,
|
|||
messages.push(message)
|
||||
if (message.type === "ask" && message.ask === "tool") {
|
||||
console.log("Tool request:", message.text?.substring(0, 200))
|
||||
// Check for appliedDiff tool execution
|
||||
try {
|
||||
const toolData = JSON.parse(message.text || "{}")
|
||||
if (toolData.tool === "appliedDiff") {
|
||||
applyDiffExecuted = true
|
||||
console.log("apply_diff tool executed!")
|
||||
}
|
||||
} catch (_e) {
|
||||
// Not JSON or parsing failed
|
||||
}
|
||||
}
|
||||
if (message.type === "say" && message.text) {
|
||||
console.log("AI response:", message.text.substring(0, 200))
|
||||
}
|
||||
|
||||
// Check for tool execution
|
||||
if (message.type === "say" && message.say === "api_req_started" && message.text) {
|
||||
console.log("API request started:", message.text.substring(0, 200))
|
||||
try {
|
||||
const requestData = JSON.parse(message.text)
|
||||
if (requestData.request && requestData.request.includes("apply_diff")) {
|
||||
applyDiffExecuted = true
|
||||
console.log("apply_diff tool executed!")
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Failed to parse api_req_started message:", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
api.on(RooCodeEventName.Message, messageHandler)
|
||||
|
|
@ -408,21 +420,20 @@ function keepThis() {
|
|||
messages.push(message)
|
||||
if (message.type === "ask" && message.ask === "tool") {
|
||||
console.log("Tool request:", message.text?.substring(0, 200))
|
||||
}
|
||||
|
||||
// Check for tool execution
|
||||
if (message.type === "say" && message.say === "api_req_started" && message.text) {
|
||||
console.log("API request started:", message.text.substring(0, 200))
|
||||
// Check for appliedDiff tool execution
|
||||
try {
|
||||
const requestData = JSON.parse(message.text)
|
||||
if (requestData.request && requestData.request.includes("apply_diff")) {
|
||||
const toolData = JSON.parse(message.text || "{}")
|
||||
if (toolData.tool === "appliedDiff") {
|
||||
applyDiffExecuted = true
|
||||
console.log("apply_diff tool executed!")
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Failed to parse api_req_started message:", e)
|
||||
} catch (_e) {
|
||||
// Not JSON or parsing failed
|
||||
}
|
||||
}
|
||||
if (message.type === "say" && message.say === "api_req_started" && message.text) {
|
||||
console.log("API request started:", message.text.substring(0, 200))
|
||||
}
|
||||
}
|
||||
api.on(RooCodeEventName.Message, messageHandler)
|
||||
|
||||
|
|
@ -501,6 +512,7 @@ ${testFile.content}\nAssume the file exists and you can modify it directly.`,
|
|||
let taskCompleted = false
|
||||
let errorDetected = false
|
||||
let applyDiffAttempted = false
|
||||
let writeToFileUsed = false
|
||||
|
||||
// Listen for messages
|
||||
const messageHandler = ({ message }: { message: ClineMessage }) => {
|
||||
|
|
@ -512,25 +524,33 @@ ${testFile.content}\nAssume the file exists and you can modify it directly.`,
|
|||
console.log("Error detected:", message.text)
|
||||
}
|
||||
|
||||
// Check if AI mentions it couldn't find the content
|
||||
if (message.type === "say" && message.text?.toLowerCase().includes("could not find")) {
|
||||
errorDetected = true
|
||||
console.log("AI reported search failure:", message.text)
|
||||
}
|
||||
|
||||
// Check for tool execution attempt
|
||||
if (message.type === "say" && message.say === "api_req_started" && message.text) {
|
||||
console.log("API request started:", message.text.substring(0, 200))
|
||||
if (message.type === "ask" && message.ask === "tool") {
|
||||
console.log("Tool ASK request:", message.text?.substring(0, 500))
|
||||
try {
|
||||
const requestData = JSON.parse(message.text)
|
||||
if (requestData.request && requestData.request.includes("apply_diff")) {
|
||||
const toolData = JSON.parse(message.text || "{}")
|
||||
if (toolData.tool === "appliedDiff") {
|
||||
applyDiffAttempted = true
|
||||
console.log("apply_diff tool attempted!")
|
||||
console.log("apply_diff tool attempted via ASK!")
|
||||
}
|
||||
// Detect if write_to_file was used (shows as editedExistingFile or newFileCreated)
|
||||
if (toolData.tool === "editedExistingFile" || toolData.tool === "newFileCreated") {
|
||||
writeToFileUsed = true
|
||||
console.log("write_to_file tool used!")
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Failed to parse api_req_started message:", e)
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
// Check for diff_error which indicates apply_diff was attempted but failed
|
||||
if (message.type === "say" && message.say === "diff_error") {
|
||||
applyDiffAttempted = true
|
||||
}
|
||||
|
||||
if (message.type === "say" && message.say === "api_req_started" && message.text) {
|
||||
console.log("API request started:", message.text.substring(0, 200))
|
||||
}
|
||||
}
|
||||
api.on(RooCodeEventName.Message, messageHandler)
|
||||
|
||||
|
|
@ -552,6 +572,9 @@ ${testFile.content}\nAssume the file exists and you can modify it directly.`,
|
|||
let taskId: string
|
||||
try {
|
||||
// Start task with invalid search content - file already exists
|
||||
// NOTE: We ask the AI to search for a pattern that doesn't exist, without telling it
|
||||
// what the replacement should be. This prevents the AI from working around by
|
||||
// replacing the actual content with the desired replacement.
|
||||
taskId = await api.startNewTask({
|
||||
configuration: {
|
||||
mode: "code",
|
||||
|
|
@ -560,14 +583,18 @@ ${testFile.content}\nAssume the file exists and you can modify it directly.`,
|
|||
alwaysAllowReadOnly: true,
|
||||
alwaysAllowReadOnlyOutsideWorkspace: true,
|
||||
},
|
||||
text: `Use apply_diff on the file ${testFile.name} to replace "This content does not exist" with "New content".
|
||||
text: `Use apply_diff on the file ${testFile.name} to find and replace the text "PATTERN_THAT_DOES_NOT_EXIST_xyz123" with "REPLACEMENT_xyz123".
|
||||
|
||||
The file already exists with this content:
|
||||
${testFile.content}
|
||||
|
||||
IMPORTANT: The search pattern "This content does not exist" is NOT in the file. When apply_diff cannot find the search pattern, it should fail gracefully and the file content should remain unchanged. Do NOT try to use write_to_file or any other tool to modify the file. Only use apply_diff, and if the search pattern is not found, report that it could not be found.
|
||||
|
||||
Assume the file exists and you can modify it directly.`,
|
||||
CRITICAL INSTRUCTIONS:
|
||||
1. You MUST attempt the apply_diff with EXACTLY the search pattern "PATTERN_THAT_DOES_NOT_EXIST_xyz123"
|
||||
2. If apply_diff cannot find this exact search pattern, report that the pattern was not found
|
||||
3. Do NOT use write_to_file under any circumstances
|
||||
4. Do NOT use a different search pattern - use EXACTLY "PATTERN_THAT_DOES_NOT_EXIST_xyz123"
|
||||
5. Do NOT modify the file in any other way
|
||||
6. Simply report that the replacement could not be made because the search text was not found`,
|
||||
})
|
||||
|
||||
console.log("Task ID:", taskId)
|
||||
|
|
@ -581,13 +608,20 @@ Assume the file exists and you can modify it directly.`,
|
|||
// Give time for any final operations
|
||||
await sleep(2000)
|
||||
|
||||
// The file content should remain unchanged since the search pattern wasn't found
|
||||
// Read the file content
|
||||
const actualContent = await fs.readFile(testFile.path, "utf-8")
|
||||
console.log("File content after task:", actualContent)
|
||||
|
||||
// The AI should have attempted to use apply_diff
|
||||
assert.strictEqual(applyDiffAttempted, true, "apply_diff tool should have been attempted")
|
||||
|
||||
// The AI should NOT have used write_to_file as a fallback
|
||||
assert.strictEqual(
|
||||
writeToFileUsed,
|
||||
false,
|
||||
"write_to_file should NOT be used when apply_diff fails - the AI should report the error instead",
|
||||
)
|
||||
|
||||
// The content should remain unchanged since the search pattern wasn't found
|
||||
assert.strictEqual(
|
||||
actualContent.trim(),
|
||||
|
|
@ -643,25 +677,24 @@ function checkInput(input) {
|
|||
}
|
||||
if (message.type === "ask" && message.ask === "tool") {
|
||||
console.log("Tool request:", message.text?.substring(0, 200))
|
||||
}
|
||||
if (message.type === "say" && (message.say === "completion_result" || message.say === "text")) {
|
||||
console.log("AI response:", message.text?.substring(0, 200))
|
||||
}
|
||||
|
||||
// Check for tool execution
|
||||
if (message.type === "say" && message.say === "api_req_started" && message.text) {
|
||||
console.log("API request started:", message.text.substring(0, 200))
|
||||
// Check for appliedDiff tool execution
|
||||
try {
|
||||
const requestData = JSON.parse(message.text)
|
||||
if (requestData.request && requestData.request.includes("apply_diff")) {
|
||||
const toolData = JSON.parse(message.text || "{}")
|
||||
if (toolData.tool === "appliedDiff") {
|
||||
applyDiffExecuted = true
|
||||
applyDiffCount++
|
||||
console.log(`apply_diff tool executed! (count: ${applyDiffCount})`)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Failed to parse api_req_started message:", e)
|
||||
} catch (_e) {
|
||||
// Not JSON or parsing failed
|
||||
}
|
||||
}
|
||||
if (message.type === "say" && (message.say === "completion_result" || message.say === "text")) {
|
||||
console.log("AI response:", message.text?.substring(0, 200))
|
||||
}
|
||||
if (message.type === "say" && message.say === "api_req_started" && message.text) {
|
||||
console.log("API request started:", message.text.substring(0, 200))
|
||||
}
|
||||
}
|
||||
api.on(RooCodeEventName.Message, messageHandler)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue