Преглед изворни кода

fix(action): handle edge case for add to context action (#2780)

Dicha Zelianivan Arkana пре 8 месеци
родитељ
комит
47230d5a5c
2 измењених фајлова са 132 додато и 11 уклоњено
  1. 117 0
      src/shared/__tests__/support-prompts.test.ts
  2. 15 11
      src/shared/support-prompt.ts

+ 117 - 0
src/shared/__tests__/support-prompts.test.ts

@@ -86,6 +86,123 @@ describe("Code Action Prompts", () => {
 		})
 	})
 
+	describe("ADD_TO_CONTEXT action", () => {
+		it("should format ADD_TO_CONTEXT prompt correctly with all parameters", () => {
+			const prompt = supportPrompt.create("ADD_TO_CONTEXT", {
+				name: "Roo",
+				place: "Workspace",
+				filePath: testFilePath,
+				selectedText: testCode,
+				startLine: "1",
+				endLine: "1",
+				diagnostics: [],
+			})
+			const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\``
+			expect(prompt).toBe(expected)
+		})
+
+		it("should format ADD_TO_CONTEXT prompt with diagnostics", () => {
+			const diagnostics = [{ message: "Error 1" }, { source: "Linter", message: "Warning 2" }]
+			const prompt = supportPrompt.create("ADD_TO_CONTEXT", {
+				filePath: testFilePath,
+				selectedText: testCode,
+				startLine: "10",
+				endLine: "20",
+				diagnostics,
+			})
+			const expected = `${testFilePath}:10-20\n\`\`\`\n${testCode}\n\`\`\``
+			expect(prompt).toBe(expected)
+		})
+
+		it("should not replace placeholders within parameter values", () => {
+			const prompt = supportPrompt.create("ADD_TO_CONTEXT", {
+				value1: "This is ${value2}",
+				value2: "Actual Value 2",
+				filePath: testFilePath,
+				selectedText: testCode,
+				startLine: "5",
+				endLine: "15",
+			})
+			const expected = `${testFilePath}:5-15\n\`\`\`\n${testCode}\n\`\`\``
+			expect(prompt).toBe(expected)
+		})
+
+		it("should replace remaining placeholders (not in params) with empty strings", () => {
+			const prompt = supportPrompt.create("ADD_TO_CONTEXT", {
+				name: "Roo",
+				filePath: testFilePath,
+				selectedText: testCode,
+				startLine: "1",
+				endLine: "1",
+			}) // 'status' is missing
+			const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\``
+			expect(prompt).toBe(expected)
+		})
+
+		it("should handle placeholders in values that are not in the template", () => {
+			const prompt = supportPrompt.create("ADD_TO_CONTEXT", {
+				data: "Some data with ${extraInfo}",
+				filePath: testFilePath,
+				selectedText: testCode,
+				startLine: "1",
+				endLine: "1",
+			})
+			const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\``
+			expect(prompt).toBe(expected)
+		})
+
+		it("should handle minimal params object", () => {
+			const prompt = supportPrompt.create("ADD_TO_CONTEXT", {
+				filePath: testFilePath,
+				selectedText: testCode,
+				startLine: "1",
+				endLine: "1",
+			})
+			const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\``
+			expect(prompt).toBe(expected)
+		})
+
+		it("should handle params with non-string values", () => {
+			const prompt = supportPrompt.create("ADD_TO_CONTEXT", {
+				count: "5",
+				isActive: "true",
+				filePath: testFilePath,
+				selectedText: testCode,
+				startLine: "1",
+				endLine: "1",
+			}) // Convert to strings
+			const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\``
+			expect(prompt).toBe(expected)
+		})
+
+		it("should handle keys with special regex characters", () => {
+			const prompt = supportPrompt.create("ADD_TO_CONTEXT", {
+				"key.with.dots": "Dotty",
+				value: "Simple",
+				filePath: testFilePath,
+				selectedText: testCode,
+				startLine: "1",
+				endLine: "1",
+			})
+			const expected = `${testFilePath}:1-1\n\`\`\`\n${testCode}\n\`\`\``
+			expect(prompt).toBe(expected)
+		})
+
+		it("should handle bash script selection", () => {
+			const bashText =
+				'if [ "${#usecase_deployments[@]}" -gt 0 ] && [ ${{ parameters.single_deployment_per_environment }} = true ]; then'
+			const prompt = supportPrompt.create("ADD_TO_CONTEXT", {
+				selectedText: bashText,
+				filePath: testFilePath,
+				startLine: "1",
+				endLine: "1",
+				diagnostics: [],
+			})
+			const expected = `${testFilePath}:1-1\n\`\`\`\n${bashText}\n\`\`\``
+			expect(prompt).toBe(expected)
+		})
+	})
+
 	describe("get template", () => {
 		it("should return default template when no custom prompts provided", () => {
 			const template = supportPrompt.get(undefined, "EXPLAIN")

+ 15 - 11
src/shared/support-prompt.ts

@@ -9,19 +9,23 @@ const generateDiagnosticText = (diagnostics?: any[]) => {
 }
 
 export const createPrompt = (template: string, params: PromptParams): string => {
-	let result = template
-	for (const [key, value] of Object.entries(params)) {
-		if (key === "diagnostics") {
-			result = result.replaceAll("${diagnosticText}", generateDiagnosticText(value as any[]))
+	return template.replace(/\${(.*?)}/g, (_, key) => {
+		if (key === "diagnosticText") {
+			return generateDiagnosticText(params["diagnostics"] as any[])
+		} else if (params.hasOwnProperty(key)) {
+			// Ensure the value is treated as a string for replacement
+			const value = params[key]
+			if (typeof value === "string") {
+				return value
+			} else {
+				// Convert non-string values to string for replacement
+				return String(value)
+			}
 		} else {
-			result = result.replaceAll(`\${${key}}`, value as string)
+			// If the placeholder key is not in params, replace with empty string
+			return ""
 		}
-	}
-
-	// Replace any remaining placeholders with empty strings
-	result = result.replaceAll(/\${[^}]*}/g, "")
-
-	return result
+	})
 }
 
 interface SupportPromptConfig {