// The AGENTS.md editor's diff builder. Run by `npm test`, which Node runs with // its built-in test runner and type stripping, so the `.ts` module is // imported as it is. The expected strings are what `git diff` writes for the // same two texts, and `git apply` reads back. import assert from "node:assert/strict"; import { test } from "node:test"; import { unifiedDiff } from "../src/agent/detail/unified-diff.ts"; test("the same text has no diff", () => { assert.equal(unifiedDiff("a\nb\n", "a\nb\n"), ""); assert.equal(unifiedDiff("", ""), ""); }); test("a changed middle line carries three lines of context", () => { const before = "1\n2\n3\n4\n5\n6\n7\n8\n9\n"; const after = "1\n2\n3\n4\nfive\n6\n7\n8\n9\n"; assert.equal( unifiedDiff(before, after), "--- a/AGENTS.md\n+++ b/AGENTS.md\n" + "@@ -2,7 +2,7 @@\n 2\n 3\n 4\n-5\n+five\n 6\n 7\n 8\n", ); }); test("two far apart changes make two hunks, near ones merge", () => { const lines = Array.from({ length: 20 }, (_, i) => `l${i + 1}`); const far = [...lines]; far[1] = "X"; far[17] = "Y"; const farDiff = unifiedDiff(lines.join("\n") + "\n", far.join("\n") + "\n"); assert.equal(farDiff.match(/^@@/gm)?.length, 2); const near = [...lines]; near[1] = "X"; near[6] = "Y"; const nearDiff = unifiedDiff(lines.join("\n") + "\n", near.join("\n") + "\n"); assert.equal(nearDiff.match(/^@@/gm)?.length, 1); }); test("writing into an empty file adds every line", () => { assert.equal( unifiedDiff("", "hello\nworld\n"), "--- a/AGENTS.md\n+++ b/AGENTS.md\n@@ -0,0 +1,2 @@\n+hello\n+world\n", ); }); test("emptying a file removes every line", () => { assert.equal( unifiedDiff("hello\n", ""), "--- a/AGENTS.md\n+++ b/AGENTS.md\n@@ -1 +0,0 @@\n-hello\n", ); }); test("a missing final newline is marked as git marks it", () => { assert.equal( unifiedDiff("a\nb", "a\nb\n"), "--- a/AGENTS.md\n+++ b/AGENTS.md\n@@ -1,2 +1,2 @@\n a\n" + "-b\n\\ No newline at end of file\n+b\n", ); assert.equal( unifiedDiff("a\nb\n", "a\nc"), "--- a/AGENTS.md\n+++ b/AGENTS.md\n@@ -1,2 +1,2 @@\n a\n" + "-b\n+c\n\\ No newline at end of file\n", ); }); test("a pure insertion keeps the lines around it as context", () => { assert.equal( unifiedDiff("a\nc\n", "a\nb\nc\n"), "--- a/AGENTS.md\n+++ b/AGENTS.md\n@@ -1,2 +1,3 @@\n a\n+b\n c\n", ); }); test("the file name is the one asked for", () => { assert.ok( unifiedDiff("a\n", "b\n", "CLAUDE.md").startsWith( "--- a/CLAUDE.md\n+++ b/CLAUDE.md\n", ), ); });