diff --git a/src/core/tools/__tests__/htmlEntityPreservation.spec.ts b/src/core/tools/__tests__/htmlEntityPreservation.spec.ts deleted file mode 100644 index 35a91a9efd..0000000000 --- a/src/core/tools/__tests__/htmlEntityPreservation.spec.ts +++ /dev/null @@ -1,345 +0,0 @@ -import { describe, it, expect, vi, beforeEach } from "vitest" -import * as fs from "fs/promises" -import { applyDiffToolLegacy } from "../applyDiffTool" -import { applyDiffTool } from "../multiApplyDiffTool" -import { writeToFileTool } from "../writeToFileTool" -import { searchAndReplaceTool } from "../searchAndReplaceTool" -import { ToolUse } from "../../../shared/tools" - -// Mock dependencies -vi.mock("fs/promises") -vi.mock("../../../utils/fs", () => ({ - fileExistsAtPath: vi.fn().mockResolvedValue(true), -})) -vi.mock("../../../utils/path", () => ({ - getReadablePath: vi.fn((cwd, path) => path), -})) -vi.mock("../../prompts/responses", () => ({ - formatResponse: { - toolError: vi.fn((msg) => `Error: ${msg}`), - rooIgnoreError: vi.fn((path) => `Access denied: ${path}`), - createPrettyPatch: vi.fn(() => "mock-diff"), - }, -})) -vi.mock("../../../integrations/editor/detect-omission", () => ({ - detectCodeOmission: vi.fn().mockReturnValue(false), -})) -vi.mock("../../../utils/pathUtils", () => ({ - isPathOutsideWorkspace: vi.fn().mockReturnValue(false), -})) -vi.mock("../../../integrations/misc/extract-text", () => ({ - everyLineHasLineNumbers: vi.fn().mockReturnValue(false), - stripLineNumbers: vi.fn((content) => content), -})) -vi.mock("delay", () => ({ - default: vi.fn(), -})) - -describe("HTML Entity Preservation", () => { - const testContent = ` -
This & that
- <important> -if (a < b && c > d) { return "test"; }
- This & that
-======= -This & that
->>>>>>> REPLACE`, - }, - partial: false, - } - - await applyDiffToolLegacy( - mockCline, - block, - mockAskApproval, - mockHandleError, - mockPushToolResult, - mockRemoveClosingTag, - ) - - // Verify that the diff content was passed to diffStrategy without modification - expect(mockCline.diffStrategy.applyDiff).toHaveBeenCalledWith( - testContent, - expect.stringContaining("&"), - expect.any(Number), - ) - }) - }) - - describe("multiApplyDiffTool", () => { - it("should preserve HTML entities in multi-file diff operations", async () => { - const block: ToolUse = { - type: "tool_use", - name: "apply_diff", - params: { - args: `if (a < b && c > d) { return "test"; }
-=======
-if (a < b && c > d) { return "test"; }
->>>>>>> REPLACE<Hello & "World">
' - const block: ToolUse = { - type: "tool_use", - name: "write_to_file", - params: { - path: "test.html", - content: htmlContent, - line_count: "1", - }, - partial: false, - } - - // Test with non-Claude model - mockCline.api.getModel.mockReturnValue({ id: "gpt-4" }) - await writeToFileTool( - mockCline, - block, - mockAskApproval, - mockHandleError, - mockPushToolResult, - mockRemoveClosingTag, - ) - expect(mockCline.diffViewProvider.update).toHaveBeenCalledWith(htmlContent, true) - - // Clear mocks and test with Claude model - vi.clearAllMocks() - mockCline.api.getModel.mockReturnValue({ id: "claude-3-opus" }) - await writeToFileTool( - mockCline, - block, - mockAskApproval, - mockHandleError, - mockPushToolResult, - mockRemoveClosingTag, - ) - expect(mockCline.diffViewProvider.update).toHaveBeenCalledWith(htmlContent, true) - }) - }) - - describe("searchAndReplaceTool", () => { - it("should preserve HTML entities in search and replace operations", async () => { - const block: ToolUse = { - type: "tool_use", - name: "search_and_replace", - params: { - path: "test.html", - search: "This & that", - replace: "This & that", - use_regex: "false", - ignore_case: "false", - }, - partial: false, - } - - await searchAndReplaceTool( - mockCline, - block, - mockAskApproval, - mockHandleError, - mockPushToolResult, - mockRemoveClosingTag, - ) - - // Verify that the search and replace preserved HTML entities - expect(mockCline.diffViewProvider.update).toHaveBeenCalled() - // The tool should have been called with the original search/replace values - expect(block.params.search).toBe("This & that") - expect(block.params.replace).toBe("This & that") - }) - }) - - describe("Integration test", () => { - it("should handle complex HTML with multiple entities correctly", async () => { - const complexHtml = ` - - - -Quote: "Hello, World!"
-Apostrophe: It's working!
-
- if (x < y && y > z) {
- console.log("Condition met");
- }
-
-
-
- `
-
- const block: ToolUse = {
- type: "tool_use",
- name: "write_to_file",
- params: {
- path: "complex.html",
- content: complexHtml,
- line_count: "18",
- },
- partial: false,
- }
-
- await writeToFileTool(
- mockCline,
- block,
- mockAskApproval,
- mockHandleError,
- mockPushToolResult,
- mockRemoveClosingTag,
- )
-
- // Verify all entities are preserved
- const calledContent = mockCline.diffViewProvider.update.mock.calls[0][0]
- expect(calledContent).toContain("&")
- expect(calledContent).toContain("<")
- expect(calledContent).toContain(">")
- expect(calledContent).toContain(""")
- expect(calledContent).toContain("'")
-
- // Ensure no unescaping happened
- expect(calledContent).not.toContain("&&")
- expect(calledContent).not.toContain("< 10 &&")
- expect(calledContent).not.toContain("> 5")
- })
- })
-})