diff --git a/src/core/diff/strategies/new-unified/__tests__/edit-strategies.test.ts b/src/core/diff/strategies/new-unified/__tests__/edit-strategies.test.ts new file mode 100644 index 0000000..459445f --- /dev/null +++ b/src/core/diff/strategies/new-unified/__tests__/edit-strategies.test.ts @@ -0,0 +1,259 @@ +import { applyContextMatching, applyDMP } from "../edit-strategies" +import { Hunk } from "../types" + +const testCases = [ + { + name: "should return original content if no match is found", + hunk: { + changes: [ + { type: "context", content: "line1" }, + { type: "add", content: "line2" }, + ], + } as Hunk, + content: ["line1", "line3"], + matchPosition: -1, + expected: { + confidence: 0, + result: ["line1", "line3"], + }, + expectedResult: "line1\nline3", + strategies: ["context", "dmp"], + }, + { + name: "should apply a simple add change", + hunk: { + changes: [ + { type: "context", content: "line1" }, + { type: "add", content: "line2" }, + ], + } as Hunk, + content: ["line1", "line3"], + matchPosition: 0, + expected: { + confidence: 1, + result: ["line1", "line2", "line3"], + }, + expectedResult: "line1\nline2\nline3", + strategies: ["context", "dmp"], + }, + { + name: "should apply a simple remove change", + hunk: { + changes: [ + { type: "context", content: "line1" }, + { type: "remove", content: "line2" }, + ], + } as Hunk, + content: ["line1", "line2", "line3"], + matchPosition: 0, + expected: { + confidence: 1, + result: ["line1", "line3"], + }, + expectedResult: "line1\nline3", + strategies: ["context", "dmp"], + }, + { + name: "should apply a simple context change", + hunk: { + changes: [{ type: "context", content: "line1" }], + } as Hunk, + content: ["line1", "line2", "line3"], + matchPosition: 0, + expected: { + confidence: 1, + result: ["line1", "line2", "line3"], + }, + expectedResult: "line1\nline2\nline3", + strategies: ["context", "dmp"], + }, + { + name: "should apply a multi-line add change", + hunk: { + changes: [ + { type: "context", content: "line1" }, + { type: "add", content: "line2\nline3" }, + ], + } as Hunk, + content: ["line1", "line4"], + matchPosition: 0, + expected: { + confidence: 1, + result: ["line1", "line2\nline3", "line4"], + }, + expectedResult: "line1\nline2\nline3\nline4", + strategies: ["context", "dmp"], + }, + { + name: "should apply a multi-line remove change", + hunk: { + changes: [ + { type: "context", content: "line1" }, + { type: "remove", content: "line2\nline3" }, + ], + } as Hunk, + content: ["line1", "line2", "line3", "line4"], + matchPosition: 0, + expected: { + confidence: 1, + result: ["line1", "line4"], + }, + expectedResult: "line1\nline4", + strategies: ["context", "dmp"], + }, + { + name: "should apply a multi-line context change", + hunk: { + changes: [ + { type: "context", content: "line1" }, + { type: "context", content: "line2\nline3" }, + ], + } as Hunk, + content: ["line1", "line2", "line3", "line4"], + matchPosition: 0, + expected: { + confidence: 1, + result: ["line1", "line2\nline3", "line4"], + }, + expectedResult: "line1\nline2\nline3\nline4", + strategies: ["context", "dmp"], + }, + { + name: "should apply a change with indentation", + hunk: { + changes: [ + { type: "context", content: " line1" }, + { type: "add", content: " line2" }, + ], + } as Hunk, + content: [" line1", " line3"], + matchPosition: 0, + expected: { + confidence: 1, + result: [" line1", " line2", " line3"], + }, + expectedResult: " line1\n line2\n line3", + strategies: ["context", "dmp"], + }, + { + name: "should apply a change with mixed indentation", + hunk: { + changes: [ + { type: "context", content: "\tline1" }, + { type: "add", content: " line2" }, + ], + } as Hunk, + content: ["\tline1", " line3"], + matchPosition: 0, + expected: { + confidence: 1, + result: ["\tline1", " line2", " line3"], + }, + expectedResult: "\tline1\n line2\n line3", + strategies: ["context", "dmp"], + }, + { + name: "should apply a change with mixed indentation and multi-line", + hunk: { + changes: [ + { type: "context", content: " line1" }, + { type: "add", content: "\tline2\n line3" }, + ], + } as Hunk, + content: [" line1", " line4"], + matchPosition: 0, + expected: { + confidence: 1, + result: [" line1", "\tline2\n line3", " line4"], + }, + expectedResult: " line1\n\tline2\n line3\n line4", + strategies: ["context", "dmp"], + }, + { + name: "should apply a complex change with mixed indentation and multi-line", + hunk: { + changes: [ + { type: "context", content: " line1" }, + { type: "remove", content: " line2" }, + { type: "add", content: "\tline3\n line4" }, + { type: "context", content: " line5" }, + ], + } as Hunk, + content: [" line1", " line2", " line5", " line6"], + matchPosition: 0, + expected: { + confidence: 1, + result: [" line1", "\tline3\n line4", " line5", " line6"], + }, + expectedResult: " line1\n\tline3\n line4\n line5\n line6", + strategies: ["context", "dmp"], + }, + { + name: "should apply a complex change with mixed indentation and multi-line and context", + hunk: { + changes: [ + { type: "context", content: " line1" }, + { type: "remove", content: " line2" }, + { type: "add", content: "\tline3\n line4" }, + { type: "context", content: " line5" }, + { type: "context", content: " line6" }, + ], + } as Hunk, + content: [" line1", " line2", " line5", " line6", " line7"], + matchPosition: 0, + expected: { + confidence: 1, + result: [" line1", "\tline3\n line4", " line5", " line6", " line7"], + }, + expectedResult: " line1\n\tline3\n line4\n line5\n line6\n line7", + strategies: ["context", "dmp"], + }, + { + name: "should apply a complex change with mixed indentation and multi-line and context and a different match position", + hunk: { + changes: [ + { type: "context", content: " line1" }, + { type: "remove", content: " line2" }, + { type: "add", content: "\tline3\n line4" }, + { type: "context", content: " line5" }, + { type: "context", content: " line6" }, + ], + } as Hunk, + content: [" line0", " line1", " line2", " line5", " line6", " line7"], + matchPosition: 1, + expected: { + confidence: 1, + result: [" line0", " line1", "\tline3\n line4", " line5", " line6", " line7"], + }, + expectedResult: " line0\n line1\n\tline3\n line4\n line5\n line6\n line7", + strategies: ["context", "dmp"], + }, +] + +describe("applyContextMatching", () => { + testCases.forEach(({ name, hunk, content, matchPosition, expected, strategies, expectedResult }) => { + if (!strategies?.includes("context")) { + return + } + it(name, () => { + const result = applyContextMatching(hunk, content, matchPosition) + expect(result.result.join("\n")).toEqual(expectedResult) + expect(result.confidence).toBeGreaterThanOrEqual(expected.confidence) + expect(result.strategy).toBe("context") + }) + }) +}) + +describe("applyDMP", () => { + testCases.forEach(({ name, hunk, content, matchPosition, expected, strategies, expectedResult }) => { + if (!strategies?.includes("dmp")) { + return + } + it(name, () => { + const result = applyDMP(hunk, content, matchPosition) + expect(result.result.join("\n")).toEqual(expectedResult) + expect(result.confidence).toBeGreaterThanOrEqual(expected.confidence) + expect(result.strategy).toBe("dmp") + }) + }) +})