|
|
@@ -1,631 +0,0 @@
|
|
|
-import * as assert from "assert"
|
|
|
-import * as fs from "fs/promises"
|
|
|
-import * as path from "path"
|
|
|
-import * as vscode from "vscode"
|
|
|
-
|
|
|
-import { RooCodeEventName, type ClineMessage } from "@roo-code/types"
|
|
|
-
|
|
|
-import { waitFor, sleep } from "../utils"
|
|
|
-import { setDefaultSuiteTimeout } from "../test-utils"
|
|
|
-
|
|
|
-suite.skip("Roo Code search_and_replace Tool", function () {
|
|
|
- setDefaultSuiteTimeout(this)
|
|
|
-
|
|
|
- let workspaceDir: string
|
|
|
-
|
|
|
- // Pre-created test files that will be used across tests
|
|
|
- const testFiles = {
|
|
|
- simpleReplace: {
|
|
|
- name: `test-simple-replace-${Date.now()}.txt`,
|
|
|
- content: "Hello World\nThis is a test file\nWith multiple lines\nHello again",
|
|
|
- path: "",
|
|
|
- },
|
|
|
- regexReplace: {
|
|
|
- name: `test-regex-replace-${Date.now()}.js`,
|
|
|
- content: `function oldFunction() {
|
|
|
- console.log("old implementation")
|
|
|
- return "old result"
|
|
|
-}
|
|
|
-
|
|
|
-function anotherOldFunction() {
|
|
|
- console.log("another old implementation")
|
|
|
- return "another old result"
|
|
|
-}`,
|
|
|
- path: "",
|
|
|
- },
|
|
|
- caseInsensitive: {
|
|
|
- name: `test-case-insensitive-${Date.now()}.txt`,
|
|
|
- content: `Hello World
|
|
|
-HELLO UNIVERSE
|
|
|
-hello everyone
|
|
|
-HeLLo ThErE`,
|
|
|
- path: "",
|
|
|
- },
|
|
|
- multipleMatches: {
|
|
|
- name: `test-multiple-matches-${Date.now()}.txt`,
|
|
|
- content: `TODO: Fix this bug
|
|
|
-This is some content
|
|
|
-TODO: Add more tests
|
|
|
-Some more content
|
|
|
-TODO: Update documentation
|
|
|
-Final content`,
|
|
|
- path: "",
|
|
|
- },
|
|
|
- noMatches: {
|
|
|
- name: `test-no-matches-${Date.now()}.txt`,
|
|
|
- content: "This file has no matching patterns\nJust regular content\nNothing special here",
|
|
|
- path: "",
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- // Get the actual workspace directory that VSCode is using and create all test files
|
|
|
- suiteSetup(async function () {
|
|
|
- // Get the workspace folder from VSCode
|
|
|
- const workspaceFolders = vscode.workspace.workspaceFolders
|
|
|
- if (!workspaceFolders || workspaceFolders.length === 0) {
|
|
|
- throw new Error("No workspace folder found")
|
|
|
- }
|
|
|
- workspaceDir = workspaceFolders[0]!.uri.fsPath
|
|
|
- console.log("Using workspace directory:", workspaceDir)
|
|
|
-
|
|
|
- // Create all test files before any tests run
|
|
|
- console.log("Creating test files in workspace...")
|
|
|
- for (const [key, file] of Object.entries(testFiles)) {
|
|
|
- file.path = path.join(workspaceDir, file.name)
|
|
|
- await fs.writeFile(file.path, file.content)
|
|
|
- console.log(`Created ${key} test file at:`, file.path)
|
|
|
- }
|
|
|
-
|
|
|
- // Verify all files exist
|
|
|
- for (const [key, file] of Object.entries(testFiles)) {
|
|
|
- const exists = await fs
|
|
|
- .access(file.path)
|
|
|
- .then(() => true)
|
|
|
- .catch(() => false)
|
|
|
- if (!exists) {
|
|
|
- throw new Error(`Failed to create ${key} test file at ${file.path}`)
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- // Clean up after all tests
|
|
|
- suiteTeardown(async () => {
|
|
|
- // Cancel any running tasks before cleanup
|
|
|
- try {
|
|
|
- await globalThis.api.cancelCurrentTask()
|
|
|
- } catch {
|
|
|
- // Task might not be running
|
|
|
- }
|
|
|
-
|
|
|
- // Clean up all test files
|
|
|
- console.log("Cleaning up test files...")
|
|
|
- for (const [key, file] of Object.entries(testFiles)) {
|
|
|
- try {
|
|
|
- await fs.unlink(file.path)
|
|
|
- console.log(`Cleaned up ${key} test file`)
|
|
|
- } catch (error) {
|
|
|
- console.log(`Failed to clean up ${key} test file:`, error)
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- // Clean up before each test
|
|
|
- setup(async () => {
|
|
|
- // Cancel any previous task
|
|
|
- try {
|
|
|
- await globalThis.api.cancelCurrentTask()
|
|
|
- } catch {
|
|
|
- // Task might not be running
|
|
|
- }
|
|
|
-
|
|
|
- // Small delay to ensure clean state
|
|
|
- await sleep(100)
|
|
|
- })
|
|
|
-
|
|
|
- // Clean up after each test
|
|
|
- teardown(async () => {
|
|
|
- // Cancel the current task
|
|
|
- try {
|
|
|
- await globalThis.api.cancelCurrentTask()
|
|
|
- } catch {
|
|
|
- // Task might not be running
|
|
|
- }
|
|
|
-
|
|
|
- // Small delay to ensure clean state
|
|
|
- await sleep(100)
|
|
|
- })
|
|
|
-
|
|
|
- test("Should perform simple text replacement", async function () {
|
|
|
- const api = globalThis.api
|
|
|
- const messages: ClineMessage[] = []
|
|
|
- const testFile = testFiles.simpleReplace
|
|
|
- const expectedContent = "Hello Universe\nThis is a test file\nWith multiple lines\nHello again"
|
|
|
- let taskStarted = false
|
|
|
- let taskCompleted = false
|
|
|
- let errorOccurred: string | null = null
|
|
|
- let searchReplaceExecuted = false
|
|
|
-
|
|
|
- // Listen for messages
|
|
|
- const messageHandler = ({ message }: { message: ClineMessage }) => {
|
|
|
- messages.push(message)
|
|
|
-
|
|
|
- // Log important messages for debugging
|
|
|
- if (message.type === "say" && message.say === "error") {
|
|
|
- errorOccurred = message.text || "Unknown error"
|
|
|
- console.error("Error:", message.text)
|
|
|
- }
|
|
|
- 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))
|
|
|
- try {
|
|
|
- const requestData = JSON.parse(message.text)
|
|
|
- if (requestData.request && requestData.request.includes("search_and_replace")) {
|
|
|
- searchReplaceExecuted = true
|
|
|
- console.log("search_and_replace tool executed!")
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- console.log("Failed to parse api_req_started message:", e)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.Message, messageHandler)
|
|
|
-
|
|
|
- // Listen for task events
|
|
|
- const taskStartedHandler = (id: string) => {
|
|
|
- if (id === taskId) {
|
|
|
- taskStarted = true
|
|
|
- console.log("Task started:", id)
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.TaskStarted, taskStartedHandler)
|
|
|
-
|
|
|
- const taskCompletedHandler = (id: string) => {
|
|
|
- if (id === taskId) {
|
|
|
- taskCompleted = true
|
|
|
- console.log("Task completed:", id)
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.TaskCompleted, taskCompletedHandler)
|
|
|
-
|
|
|
- let taskId: string
|
|
|
- try {
|
|
|
- // Start task with search_and_replace instruction
|
|
|
- taskId = await api.startNewTask({
|
|
|
- configuration: {
|
|
|
- mode: "code",
|
|
|
- autoApprovalEnabled: true,
|
|
|
- alwaysAllowWrite: true,
|
|
|
- alwaysAllowReadOnly: true,
|
|
|
- alwaysAllowReadOnlyOutsideWorkspace: true,
|
|
|
- },
|
|
|
- text: `Use search_and_replace on the file ${testFile.name} to replace "Hello World" with "Hello Universe".
|
|
|
-
|
|
|
-The file is located at: ${testFile.path}
|
|
|
-
|
|
|
-The file already exists with this content:
|
|
|
-${testFile.content}
|
|
|
-
|
|
|
-Assume the file exists and you can modify it directly.`,
|
|
|
- })
|
|
|
-
|
|
|
- console.log("Task ID:", taskId)
|
|
|
- console.log("Test filename:", testFile.name)
|
|
|
-
|
|
|
- // Wait for task to start
|
|
|
- await waitFor(() => taskStarted, { timeout: 45_000 })
|
|
|
-
|
|
|
- // Check for early errors
|
|
|
- if (errorOccurred) {
|
|
|
- console.error("Early error detected:", errorOccurred)
|
|
|
- }
|
|
|
-
|
|
|
- // Wait for task completion
|
|
|
- await waitFor(() => taskCompleted, { timeout: 45_000 })
|
|
|
-
|
|
|
- // Give extra time for file system operations
|
|
|
- await sleep(2000)
|
|
|
-
|
|
|
- // Check if the file was modified correctly
|
|
|
- const actualContent = await fs.readFile(testFile.path, "utf-8")
|
|
|
- console.log("File content after modification:", actualContent)
|
|
|
-
|
|
|
- // Verify tool was executed
|
|
|
- assert.strictEqual(searchReplaceExecuted, true, "search_and_replace tool should have been executed")
|
|
|
-
|
|
|
- // Verify file content
|
|
|
- assert.strictEqual(
|
|
|
- actualContent.trim(),
|
|
|
- expectedContent.trim(),
|
|
|
- "File content should be modified correctly",
|
|
|
- )
|
|
|
-
|
|
|
- console.log("Test passed! search_and_replace tool executed and file modified successfully")
|
|
|
- } finally {
|
|
|
- // Clean up
|
|
|
- api.off(RooCodeEventName.Message, messageHandler)
|
|
|
- api.off(RooCodeEventName.TaskStarted, taskStartedHandler)
|
|
|
- api.off(RooCodeEventName.TaskCompleted, taskCompletedHandler)
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- test("Should perform regex pattern replacement", async function () {
|
|
|
- const api = globalThis.api
|
|
|
- const messages: ClineMessage[] = []
|
|
|
- const testFile = testFiles.regexReplace
|
|
|
- const expectedContent = `function newFunction() {
|
|
|
- console.log("new implementation")
|
|
|
- return "new result"
|
|
|
-}
|
|
|
-
|
|
|
-function anotherNewFunction() {
|
|
|
- console.log("another new implementation")
|
|
|
- return "another new result"
|
|
|
-}`
|
|
|
- let taskStarted = false
|
|
|
- let taskCompleted = false
|
|
|
- let errorOccurred: string | null = null
|
|
|
- let searchReplaceExecuted = false
|
|
|
-
|
|
|
- // Listen for messages
|
|
|
- const messageHandler = ({ message }: { message: ClineMessage }) => {
|
|
|
- messages.push(message)
|
|
|
-
|
|
|
- // Log important messages for debugging
|
|
|
- if (message.type === "say" && message.say === "error") {
|
|
|
- errorOccurred = message.text || "Unknown error"
|
|
|
- console.error("Error:", message.text)
|
|
|
- }
|
|
|
- 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))
|
|
|
- try {
|
|
|
- const requestData = JSON.parse(message.text)
|
|
|
- if (requestData.request && requestData.request.includes("search_and_replace")) {
|
|
|
- searchReplaceExecuted = true
|
|
|
- console.log("search_and_replace tool executed!")
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- console.log("Failed to parse api_req_started message:", e)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.Message, messageHandler)
|
|
|
-
|
|
|
- // Listen for task events
|
|
|
- const taskStartedHandler = (id: string) => {
|
|
|
- if (id === taskId) {
|
|
|
- taskStarted = true
|
|
|
- console.log("Task started:", id)
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.TaskStarted, taskStartedHandler)
|
|
|
-
|
|
|
- const taskCompletedHandler = (id: string) => {
|
|
|
- if (id === taskId) {
|
|
|
- taskCompleted = true
|
|
|
- console.log("Task completed:", id)
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.TaskCompleted, taskCompletedHandler)
|
|
|
-
|
|
|
- let taskId: string
|
|
|
- try {
|
|
|
- // Start task with search_and_replace instruction - simpler and more direct
|
|
|
- taskId = await api.startNewTask({
|
|
|
- configuration: {
|
|
|
- mode: "code",
|
|
|
- autoApprovalEnabled: true,
|
|
|
- alwaysAllowWrite: true,
|
|
|
- alwaysAllowReadOnly: true,
|
|
|
- alwaysAllowReadOnlyOutsideWorkspace: true,
|
|
|
- },
|
|
|
- text: `Use search_and_replace on the file ${testFile.name} to:
|
|
|
-1. First, replace "old" with "new" (use_regex: false)
|
|
|
-2. Then, replace "Old" with "New" (use_regex: false)
|
|
|
-
|
|
|
-The file is located at: ${testFile.path}
|
|
|
-
|
|
|
-Assume the file exists and you can modify it directly.
|
|
|
-
|
|
|
-Use the search_and_replace tool twice - once for each replacement.`,
|
|
|
- })
|
|
|
-
|
|
|
- console.log("Task ID:", taskId)
|
|
|
- console.log("Test filename:", testFile.name)
|
|
|
-
|
|
|
- // Wait for task to start
|
|
|
- await waitFor(() => taskStarted, { timeout: 90_000 })
|
|
|
-
|
|
|
- // Check for early errors
|
|
|
- if (errorOccurred) {
|
|
|
- console.error("Early error detected:", errorOccurred)
|
|
|
- }
|
|
|
-
|
|
|
- // Wait for task completion
|
|
|
- await waitFor(() => taskCompleted, { timeout: 90_000 })
|
|
|
-
|
|
|
- // Give extra time for file system operations
|
|
|
- await sleep(2000)
|
|
|
-
|
|
|
- // Check if the file was modified correctly
|
|
|
- const actualContent = await fs.readFile(testFile.path, "utf-8")
|
|
|
- console.log("File content after modification:", actualContent)
|
|
|
-
|
|
|
- // Verify tool was executed
|
|
|
- assert.strictEqual(searchReplaceExecuted, true, "search_and_replace tool should have been executed")
|
|
|
-
|
|
|
- // Verify file content
|
|
|
- assert.strictEqual(
|
|
|
- actualContent.trim(),
|
|
|
- expectedContent.trim(),
|
|
|
- "File content should be modified with regex replacement",
|
|
|
- )
|
|
|
-
|
|
|
- console.log("Test passed! search_and_replace tool executed with regex successfully")
|
|
|
- } finally {
|
|
|
- // Clean up
|
|
|
- api.off(RooCodeEventName.Message, messageHandler)
|
|
|
- api.off(RooCodeEventName.TaskStarted, taskStartedHandler)
|
|
|
- api.off(RooCodeEventName.TaskCompleted, taskCompletedHandler)
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- test("Should replace multiple matches in file", async function () {
|
|
|
- const api = globalThis.api
|
|
|
- const messages: ClineMessage[] = []
|
|
|
- const testFile = testFiles.multipleMatches
|
|
|
- const expectedContent = `DONE: Fix this bug
|
|
|
-This is some content
|
|
|
-DONE: Add more tests
|
|
|
-Some more content
|
|
|
-DONE: Update documentation
|
|
|
-Final content`
|
|
|
- let taskStarted = false
|
|
|
- let taskCompleted = false
|
|
|
- let errorOccurred: string | null = null
|
|
|
- let searchReplaceExecuted = false
|
|
|
-
|
|
|
- // Listen for messages
|
|
|
- const messageHandler = ({ message }: { message: ClineMessage }) => {
|
|
|
- messages.push(message)
|
|
|
-
|
|
|
- // Log important messages for debugging
|
|
|
- if (message.type === "say" && message.say === "error") {
|
|
|
- errorOccurred = message.text || "Unknown error"
|
|
|
- console.error("Error:", message.text)
|
|
|
- }
|
|
|
- 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))
|
|
|
- try {
|
|
|
- const requestData = JSON.parse(message.text)
|
|
|
- if (requestData.request && requestData.request.includes("search_and_replace")) {
|
|
|
- searchReplaceExecuted = true
|
|
|
- console.log("search_and_replace tool executed!")
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- console.log("Failed to parse api_req_started message:", e)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.Message, messageHandler)
|
|
|
-
|
|
|
- // Listen for task events
|
|
|
- const taskStartedHandler = (id: string) => {
|
|
|
- if (id === taskId) {
|
|
|
- taskStarted = true
|
|
|
- console.log("Task started:", id)
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.TaskStarted, taskStartedHandler)
|
|
|
-
|
|
|
- const taskCompletedHandler = (id: string) => {
|
|
|
- if (id === taskId) {
|
|
|
- taskCompleted = true
|
|
|
- console.log("Task completed:", id)
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.TaskCompleted, taskCompletedHandler)
|
|
|
-
|
|
|
- let taskId: string
|
|
|
- try {
|
|
|
- // Start task with search_and_replace instruction for multiple matches
|
|
|
- taskId = await api.startNewTask({
|
|
|
- configuration: {
|
|
|
- mode: "code",
|
|
|
- autoApprovalEnabled: true,
|
|
|
- alwaysAllowWrite: true,
|
|
|
- alwaysAllowReadOnly: true,
|
|
|
- alwaysAllowReadOnlyOutsideWorkspace: true,
|
|
|
- },
|
|
|
- text: `Use search_and_replace on the file ${testFile.name} to replace all occurrences of "TODO" with "DONE".
|
|
|
-
|
|
|
-The file is located at: ${testFile.path}
|
|
|
-
|
|
|
-The file already exists with this content:
|
|
|
-${testFile.content}
|
|
|
-
|
|
|
-Assume the file exists and you can modify it directly.`,
|
|
|
- })
|
|
|
-
|
|
|
- console.log("Task ID:", taskId)
|
|
|
- console.log("Test filename:", testFile.name)
|
|
|
-
|
|
|
- // Wait for task to start
|
|
|
- await waitFor(() => taskStarted, { timeout: 45_000 })
|
|
|
-
|
|
|
- // Check for early errors
|
|
|
- if (errorOccurred) {
|
|
|
- console.error("Early error detected:", errorOccurred)
|
|
|
- }
|
|
|
-
|
|
|
- // Wait for task completion
|
|
|
- await waitFor(() => taskCompleted, { timeout: 45_000 })
|
|
|
-
|
|
|
- // Give extra time for file system operations
|
|
|
- await sleep(2000)
|
|
|
-
|
|
|
- // Check if the file was modified correctly
|
|
|
- const actualContent = await fs.readFile(testFile.path, "utf-8")
|
|
|
- console.log("File content after modification:", actualContent)
|
|
|
-
|
|
|
- // Verify tool was executed
|
|
|
- assert.strictEqual(searchReplaceExecuted, true, "search_and_replace tool should have been executed")
|
|
|
-
|
|
|
- // Verify file content
|
|
|
- assert.strictEqual(
|
|
|
- actualContent.trim(),
|
|
|
- expectedContent.trim(),
|
|
|
- "All TODO occurrences should be replaced with DONE",
|
|
|
- )
|
|
|
-
|
|
|
- console.log("Test passed! search_and_replace tool executed and replaced multiple matches successfully")
|
|
|
- } finally {
|
|
|
- // Clean up
|
|
|
- api.off(RooCodeEventName.Message, messageHandler)
|
|
|
- api.off(RooCodeEventName.TaskStarted, taskStartedHandler)
|
|
|
- api.off(RooCodeEventName.TaskCompleted, taskCompletedHandler)
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- test("Should handle case when no matches are found", async function () {
|
|
|
- const api = globalThis.api
|
|
|
- const messages: ClineMessage[] = []
|
|
|
- const testFile = testFiles.noMatches
|
|
|
- const expectedContent = testFile.content // Should remain unchanged
|
|
|
- let taskStarted = false
|
|
|
- let taskCompleted = false
|
|
|
- let errorOccurred: string | null = null
|
|
|
- let searchReplaceExecuted = false
|
|
|
-
|
|
|
- // Listen for messages
|
|
|
- const messageHandler = ({ message }: { message: ClineMessage }) => {
|
|
|
- messages.push(message)
|
|
|
-
|
|
|
- // Log important messages for debugging
|
|
|
- if (message.type === "say" && message.say === "error") {
|
|
|
- errorOccurred = message.text || "Unknown error"
|
|
|
- console.error("Error:", message.text)
|
|
|
- }
|
|
|
- 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))
|
|
|
- try {
|
|
|
- const requestData = JSON.parse(message.text)
|
|
|
- if (requestData.request && requestData.request.includes("search_and_replace")) {
|
|
|
- searchReplaceExecuted = true
|
|
|
- console.log("search_and_replace tool executed!")
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- console.log("Failed to parse api_req_started message:", e)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.Message, messageHandler)
|
|
|
-
|
|
|
- // Listen for task events
|
|
|
- const taskStartedHandler = (id: string) => {
|
|
|
- if (id === taskId) {
|
|
|
- taskStarted = true
|
|
|
- console.log("Task started:", id)
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.TaskStarted, taskStartedHandler)
|
|
|
-
|
|
|
- const taskCompletedHandler = (id: string) => {
|
|
|
- if (id === taskId) {
|
|
|
- taskCompleted = true
|
|
|
- console.log("Task completed:", id)
|
|
|
- }
|
|
|
- }
|
|
|
- api.on(RooCodeEventName.TaskCompleted, taskCompletedHandler)
|
|
|
-
|
|
|
- let taskId: string
|
|
|
- try {
|
|
|
- // Start task with search_and_replace instruction for pattern that won't match
|
|
|
- taskId = await api.startNewTask({
|
|
|
- configuration: {
|
|
|
- mode: "code",
|
|
|
- autoApprovalEnabled: true,
|
|
|
- alwaysAllowWrite: true,
|
|
|
- alwaysAllowReadOnly: true,
|
|
|
- alwaysAllowReadOnlyOutsideWorkspace: true,
|
|
|
- },
|
|
|
- text: `Use search_and_replace on the file ${testFile.name} to replace "NONEXISTENT_PATTERN" with "REPLACEMENT". This pattern should not be found in the file.
|
|
|
-
|
|
|
-The file is located at: ${testFile.path}
|
|
|
-
|
|
|
-The file already exists with this content:
|
|
|
-${testFile.content}
|
|
|
-
|
|
|
-Assume the file exists and you can modify it directly.`,
|
|
|
- })
|
|
|
-
|
|
|
- console.log("Task ID:", taskId)
|
|
|
- console.log("Test filename:", testFile.name)
|
|
|
-
|
|
|
- // Wait for task to start
|
|
|
- await waitFor(() => taskStarted, { timeout: 45_000 })
|
|
|
-
|
|
|
- // Check for early errors
|
|
|
- if (errorOccurred) {
|
|
|
- console.error("Early error detected:", errorOccurred)
|
|
|
- }
|
|
|
-
|
|
|
- // Wait for task completion
|
|
|
- await waitFor(() => taskCompleted, { timeout: 45_000 })
|
|
|
-
|
|
|
- // Give extra time for file system operations
|
|
|
- await sleep(2000)
|
|
|
-
|
|
|
- // Check if the file remains unchanged
|
|
|
- const actualContent = await fs.readFile(testFile.path, "utf-8")
|
|
|
- console.log("File content after search (should be unchanged):", actualContent)
|
|
|
-
|
|
|
- // Verify tool was executed
|
|
|
- assert.strictEqual(searchReplaceExecuted, true, "search_and_replace tool should have been executed")
|
|
|
-
|
|
|
- // Verify file content remains unchanged
|
|
|
- assert.strictEqual(
|
|
|
- actualContent.trim(),
|
|
|
- expectedContent.trim(),
|
|
|
- "File content should remain unchanged when no matches are found",
|
|
|
- )
|
|
|
-
|
|
|
- console.log("Test passed! search_and_replace tool executed and handled no matches correctly")
|
|
|
- } finally {
|
|
|
- // Clean up
|
|
|
- api.off(RooCodeEventName.Message, messageHandler)
|
|
|
- api.off(RooCodeEventName.TaskStarted, taskStartedHandler)
|
|
|
- api.off(RooCodeEventName.TaskCompleted, taskCompletedHandler)
|
|
|
- }
|
|
|
- })
|
|
|
-})
|