char-slop/berry

multipurpose self-modifiable agentic harness

git clone https://git.t4t.associates/char-slop/berry

Charlotte Somadd diff extension806cc3c

main
2.5 KiB66 linesraw
1import { assertEquals } from "@std/assert";
2import { pairs, pieces, trailing, wordChanges } from "./model.ts";
3import type { FileDiff } from "./types.ts";
4
5const file = (hunks: FileDiff["hunks"]): FileDiff => ({
6  path: "f.ts",
7  from: null,
8  status: "modified",
9  modes: { old: null, new: null },
10  binary: false,
11  hunks,
12});
13
14const shape = (file: FileDiff, context?: number) =>
15  pieces(file, context).map((piece) =>
16    piece.kind === "gap"
17      ? `gap ${piece.count}`
18      : `${piece.kind} ${
19        piece.lines.map((l) => `${l.mark}${l.old ?? "_"}/${l.new ?? "_"}`).join(" ")
20      }`
21  );
22
23Deno.test("a whole file folds its long unchanged stretches, keeping context beside each change", () => {
24  const lines = Array.from({ length: 20 }, (_, i) => ` ${i + 1}`);
25  lines.splice(9, 1, "-10", "+ten");
26  assertEquals(shape(file([{ old: 1, new: 1, lines }]), 2), [
27    "fold  1/1  2/2  3/3  4/4  5/5  6/6  7/7",
28    "lines  8/8  9/9 -10/_ +_/10  11/11  12/12",
29    "fold  13/13  14/14  15/15  16/16  17/17  18/18  19/19  20/20",
30  ]);
31});
32
33Deno.test("short unchanged stretches stay open, and lines a patch leaves out are counted", () => {
34  const near = file([
35    { old: 3, new: 3, lines: [" 3", "-4", "+four", " 5", " 6", " 7", " 8", " 9", "+new", " 10"] },
36    { old: 20, new: 21, lines: [" 20", "-21", "\\ No newline at end of file"] },
37  ]);
38  assertEquals(shape(near, 3), [
39    "gap 2",
40    "lines  3/3 -4/_ +_/4  5/5  6/6  7/7  8/8  9/9 +_/10  10/11",
41    "gap 9",
42    "lines  20/21 -21/_",
43  ]);
44  const last = pieces(near).at(-1)!;
45  assertEquals(last.kind === "lines" && last.lines.at(-1)!.newline, false);
46});
47
48Deno.test("side by side, removals sit beside the additions that replace them", () => {
49  const [piece] = pieces(file([{ old: 1, new: 1, lines: [" a", "-b", "-c", "+B", " d", "+e"] }]));
50  const rows = pairs(piece.kind === "lines" ? piece.lines : []).map(({ old, new: neu }) =>
51    `${old?.text ?? "·"}|${neu?.text ?? "·"}`
52  );
53  assertEquals(rows, ["a|a", "b|B", "c|·", "d|d", "·|e"]);
54});
55
56Deno.test("within a changed line, only the words that changed are marked", () => {
57  assertEquals(wordChanges("const total = a + b;", "const sum = a + b;"), {
58    old: [[6, 11]],
59    new: [[6, 9]],
60  });
61  assertEquals(wordChanges("f(x)", "f(x, y)"), { old: [], new: [[3, 6]] });
62  // lines with little in common are just different lines
63  assertEquals(wordChanges("import { a } from 'b';", "return value * 2;"), null);
64  assertEquals(trailing("let x = 1;  \r"), [10, 12]);
65  assertEquals(trailing("let x = 1;"), null);
66});