Public: anyone can read this; the crew can change it.

A test pins `readConflictedFiles`: diff3 markers from a real two-sided change, one merge for many paths, and nothing for a clean or missing path #6704

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/6696-a-test-pins-readconflictedfiles-diff3-ma → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/6696-a-test-pins-readconflictedfiles-diff3-ma was merged into main as 5b58857.

Review

Sign in to review this change.
1 file changed +95 −0
test/conflict-file.test.ts added +95
@@ -0,0 +1,95 @@
1 /** `readConflictedFiles` against a real two-sided change in a temp repository. */
2
3 import { afterAll, beforeAll, expect, test } from "bun:test";
4 import { mkdtemp, rm, writeFile } from "node:fs/promises";
5 import { tmpdir } from "node:os";
6 import { join } from "node:path";
7 import { readConflictedFile, readConflictedFiles } from "../src/git/conflict-file.ts";
8 import { gitClientEnv } from "./helpers/git-client.ts";
9
10 const IDENTITY = {
11 GIT_AUTHOR_NAME: "Ada",
12 GIT_AUTHOR_EMAIL: "[email protected]",
13 GIT_COMMITTER_NAME: "Ada",
14 GIT_COMMITTER_EMAIL: "[email protected]",
15 };
16
17 async function sh(args: string[], cwd: string): Promise<string> {
18 const proc = Bun.spawn(["git", ...args], {
19 cwd,
20 env: gitClientEnv(IDENTITY),
21 stdout: "pipe",
22 stderr: "pipe",
23 });
24 const [out, err, code] = await Promise.all([
25 new Response(proc.stdout).text(),
26 new Response(proc.stderr).text(),
27 proc.exited,
28 ]);
29 if (code !== 0) throw new Error(`git ${args.join(" ")}: ${err}`);
30 return out.trim();
31 }
32
33 let root = "";
34 let ours = "";
35 let theirs = "";
36
37 async function commit(msg: string, files: Record<string, string>) {
38 for (const [name, text] of Object.entries(files)) await writeFile(join(root, name), text);
39 await sh(["add", "-A"], root);
40 await sh(["commit", "-m", msg], root);
41 return sh(["rev-parse", "HEAD"], root);
42 }
43
44 beforeAll(async () => {
45 root = await mkdtemp(join(tmpdir(), "conflict-file-"));
46 await sh(["init", "-q", "-b", "main"], root);
47 const base = await commit("base", {
48 "a.txt": "one\nshared\nthree\n",
49 "b.txt": "top\nmiddle\nbottom\n",
50 "big.txt": "x\n",
51 });
52 await sh(["checkout", "-q", "-b", "other", base], root);
53 theirs = await commit("theirs", {
54 "a.txt": "one\nTHEIRS\nthree\n",
55 "b.txt": "top\nmiddle\nbottom\nbottom2\n",
56 "big.txt": `${"y".repeat(1_000_001)}\n`,
57 });
58 await sh(["checkout", "-q", "main"], root);
59 ours = await commit("ours", { "a.txt": "one\nOURS\nthree\n" });
60 });
61
62 afterAll(async () => {
63 await rm(root, { recursive: true, force: true });
64 });
65
66 test("a file changed on both sides carries diff3 markers and both sides", async () => {
67 const text = await readConflictedFile(root, ours, theirs, "a.txt");
68 expect(text).toBeDefined();
69 for (const marker of ["<<<<<<<", "|||||||", "=======", ">>>>>>>"]) {
70 expect(text).toContain(marker);
71 }
72 expect(text).toContain("OURS");
73 expect(text).toContain("THEIRS");
74 expect(text).toContain("shared");
75 });
76
77 test("three paths are answered from one merge: clean merged, missing absent", async () => {

This test name claims one merge, but the assertions cannot tell one merge from three. Either count the merges or reword the name.

78 const got = await readConflictedFiles(root, ours, theirs, ["a.txt", "b.txt", "nope.txt"]);
79 expect(got.has("a.txt")).toBe(true);
80 expect(got.get("b.txt")).toBe("top\nmiddle\nbottom\nbottom2\n");
81 expect(got.has("nope.txt")).toBe(false);
82 expect(got.size).toBe(2);
83 });
84
85 test("a file over 1,000,000 bytes is absent, not cut", async () => {
86 const got = await readConflictedFiles(root, ours, theirs, ["a.txt", "big.txt"]);
87 expect(got.has("big.txt")).toBe(false);
88 expect(got.has("a.txt")).toBe(true);
89 });
90
91 test("the merge leaves no ref behind", async () => {
92 const before = await sh(["for-each-ref"], root);
93 await readConflictedFiles(root, ours, theirs, ["a.txt", "b.txt"]);
94 expect(await sh(["for-each-ref"], root)).toBe(before);
95 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs