import { test } from "node:test";
import assert from "node:assert/strict";

import { diffLines, keyValueDiffLines } from "./diff-view.js";

test("diffLines tags add/remove/hunk/file/context lines", () => {
  const text = "--- a/x.py\n+++ b/x.py\n@@ -1,1 +1,1 @@\n-old\n+new\n unchanged\n";
  const lines = diffLines(text);
  assert.equal(lines[0].kind, "file");
  assert.equal(lines[1].kind, "file");
  assert.equal(lines[2].kind, "hunk");
  assert.equal(lines[3].kind, "remove");
  assert.equal(lines[4].kind, "add");
  assert.equal(lines[5].kind, "context");
});

test("diffLines drops exactly one trailing newline, not trailing blank lines", () => {
  const lines = diffLines("a\nb\n");
  assert.equal(lines.length, 2);
  assert.equal(lines[1].text, "b");
});

test("diffLines on empty text returns one empty context line, not a crash", () => {
  const lines = diffLines("");
  assert.equal(lines.length, 1);
  assert.equal(lines[0].text, "");
});

test("keyValueDiffLines only emits changed keys", () => {
  const lines = keyValueDiffLines({ a: 1, b: 2 }, { a: 1, b: 3 }, ["a", "b"]);
  assert.equal(lines.length, 2);
  assert.match(lines[0].text, /^- b: 2$/);
  assert.match(lines[1].text, /^\+ b: 3$/);
});

test("keyValueDiffLines handles a null before (brand-new object)", () => {
  const lines = keyValueDiffLines(null, { title: "New" }, ["title"]);
  assert.equal(lines.length, 1);
  assert.equal(lines[0].kind, "add");
  assert.match(lines[0].text, /title: "New"/);
});

test("keyValueDiffLines emits nothing when nothing changed", () => {
  assert.deepEqual(keyValueDiffLines({ a: 1 }, { a: 1 }, ["a"]), []);
});
