Repository navigation
Expand file tree
/
Copy pathcheck-patches.test.ts
More file actions
134 lines (113 loc) · 4.66 KB
/
Copy pathcheck-patches.test.ts
File metadata and controls
134 lines (113 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// This file contains two categories of tests:
// 1. Real-repo test: runs checkPatches against the actual repo state.
// 2. Isolated fixture tests: spin up temp directories to exercise specific
// failure modes without touching the real repo.
import { test, expect, describe, afterEach } from "bun:test";
import { resolve } from "node:path";
import { mkdtempSync, rmSync, mkdirSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { checkPatches } from "./check-patches.ts";
const repoRoot = resolve(import.meta.dir, "..");
// Real-repo happy path: verifies the current repo state end-to-end.
test("checkPatches: real repo state has zero failures", async () => {
const result = await checkPatches({ repoRoot });
expect(result.failures).toEqual([]);
expect(result.patchesChecked).toBeGreaterThan(0);
});
// Isolated fixture tests: construct a temp repoRoot with fake package.json,
// patches/, and node_modules/ trees, then assert specific failure modes.
describe("isolated fixture tests", () => {
const tempDirs: string[] = [];
afterEach(() => {
for (const dir of tempDirs) {
rmSync(dir, { recursive: true, force: true });
}
tempDirs.length = 0;
});
function makeTempRepo(): string {
const dir = mkdtempSync(resolve(tmpdir(), "check-patches-"));
tempDirs.push(dir);
return dir;
}
test("reports drift when declared version mismatches installed version", async () => {
const root = makeTempRepo();
writeFileSync(
resolve(root, "package.json"),
JSON.stringify({
name: "fixture",
patchedDependencies: {
"fake-pkg@1.0.0": "patches/fake-pkg@1.0.0.patch",
},
}),
);
mkdirSync(resolve(root, "patches"));
writeFileSync(resolve(root, "patches", "fake-pkg@1.0.0.patch"), "");
mkdirSync(resolve(root, "node_modules", "fake-pkg"), { recursive: true });
writeFileSync(
resolve(root, "node_modules", "fake-pkg", "package.json"),
JSON.stringify({ name: "fake-pkg", version: "1.0.1" }),
);
const result = await checkPatches({ repoRoot: root });
expect(result.failures).toHaveLength(1);
expect(result.failures[0]).toContain("fake-pkg");
expect(result.failures[0]).toContain("1.0.0");
expect(result.failures[0]).toContain("1.0.1");
// A failed check does not count as a verified patch, so patchesChecked is 0.
expect(result.patchesChecked).toBe(0);
});
test("reports orphan when patches/*.patch is not referenced", async () => {
const root = makeTempRepo();
// No patchedDependencies declared
writeFileSync(
resolve(root, "package.json"),
JSON.stringify({ name: "fixture", patchedDependencies: {} }),
);
// Stale orphan patch file on disk
mkdirSync(resolve(root, "patches"));
writeFileSync(resolve(root, "patches", "stale.patch"), "");
const result = await checkPatches({ repoRoot: root });
expect(result.failures).toHaveLength(1);
expect(result.failures[0]).toContain("stale.patch");
expect(result.failures[0]).toContain("orphaned");
expect(result.patchesChecked).toBe(0);
});
test("reports failure when patch hunks are not currently applied", async () => {
const root = makeTempRepo();
// A minimal real unified diff: one hunk, one file, single-line change.
// The patch transforms "old line\n" into "new line\n".
// We will populate node_modules/fake-pkg/foo.txt with "old line\n",
// which means the patch is NOT currently applied. Check 4 should fire.
const patchContents = [
"diff --git a/foo.txt b/foo.txt",
"--- a/foo.txt",
"+++ b/foo.txt",
"@@ -1 +1 @@",
"-old line",
"+new line",
"",
].join("\n");
writeFileSync(
resolve(root, "package.json"),
JSON.stringify({
name: "fixture",
patchedDependencies: {
"fake-pkg@1.0.0": "patches/fake-pkg@1.0.0.patch",
},
}),
);
mkdirSync(resolve(root, "patches"));
writeFileSync(resolve(root, "patches", "fake-pkg@1.0.0.patch"), patchContents);
mkdirSync(resolve(root, "node_modules", "fake-pkg"), { recursive: true });
writeFileSync(
resolve(root, "node_modules", "fake-pkg", "package.json"),
JSON.stringify({ name: "fake-pkg", version: "1.0.0" }),
);
// foo.txt is in the unpatched state, so the patch is not currently applied.
writeFileSync(resolve(root, "node_modules", "fake-pkg", "foo.txt"), "old line\n");
const result = await checkPatches({ repoRoot: root });
expect(result.failures).toHaveLength(1);
expect(result.failures[0]).toContain("fake-pkg");
expect(result.failures[0]).toContain("not currently applied");
expect(result.patchesChecked).toBe(0);
});
});