@react-native-harness/cache 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/dist/__tests__/boundary.test.d.ts +0 -2
- package/dist/__tests__/boundary.test.d.ts.map +0 -1
- package/dist/__tests__/boundary.test.js +0 -77
- package/dist/__tests__/domains/metro.test.d.ts +0 -2
- package/dist/__tests__/domains/metro.test.d.ts.map +0 -1
- package/dist/__tests__/domains/metro.test.js +0 -234
- package/dist/__tests__/index.test.d.ts +0 -2
- package/dist/__tests__/index.test.d.ts.map +0 -1
- package/dist/__tests__/index.test.js +0 -40
- package/dist/__tests__/paths.test.d.ts +0 -2
- package/dist/__tests__/paths.test.d.ts.map +0 -1
- package/dist/__tests__/paths.test.js +0 -12
- package/dist/__tests__/plan.test.d.ts +0 -2
- package/dist/__tests__/plan.test.d.ts.map +0 -1
- package/dist/__tests__/plan.test.js +0 -197
- package/dist/__tests__/warmth.test.d.ts +0 -2
- package/dist/__tests__/warmth.test.d.ts.map +0 -1
- package/dist/__tests__/warmth.test.js +0 -36
- package/dist/tsconfig.lib.tsbuildinfo +0 -1
- package/src/__tests__/boundary.test.ts +0 -95
- package/src/__tests__/domains/metro.test.ts +0 -298
- package/src/__tests__/index.test.ts +0 -54
- package/src/__tests__/paths.test.ts +0 -18
- package/src/__tests__/plan.test.ts +0 -330
- package/src/__tests__/warmth.test.ts +0 -47
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import os from 'node:os';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
-
import { createHarnessCachePaths } from '../paths.js';
|
|
6
|
-
import {
|
|
7
|
-
planRestore,
|
|
8
|
-
planSave,
|
|
9
|
-
snapshot,
|
|
10
|
-
writeKeysFile,
|
|
11
|
-
type CacheKeyInputs,
|
|
12
|
-
type CacheSnapshot,
|
|
13
|
-
} from '../plan.js';
|
|
14
|
-
|
|
15
|
-
describe('planRestore', () => {
|
|
16
|
-
let projectRoot: string;
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-cache-'));
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
fs.rmSync(projectRoot, { recursive: true, force: true });
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const inputs = (
|
|
27
|
-
staticInputs: Record<string, string>
|
|
28
|
-
): Record<'metro', CacheKeyInputs> => ({
|
|
29
|
-
metro: { os: 'linux', staticInputs },
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('produces the same restoreKey across independent calls given the same staticInputs', () => {
|
|
33
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
34
|
-
|
|
35
|
-
const first = planRestore(paths, inputs({ a: '1', b: '2' }));
|
|
36
|
-
const second = planRestore(paths, inputs({ a: '1', b: '2' }));
|
|
37
|
-
|
|
38
|
-
expect(first.domains.metro?.restoreKey).toBe(
|
|
39
|
-
second.domains.metro?.restoreKey
|
|
40
|
-
);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('produces the same restoreKey regardless of staticInputs key order', () => {
|
|
44
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
45
|
-
|
|
46
|
-
const first = planRestore(paths, inputs({ a: '1', b: '2' }));
|
|
47
|
-
const second = planRestore(paths, inputs({ b: '2', a: '1' }));
|
|
48
|
-
|
|
49
|
-
expect(first.domains.metro?.restoreKey).toBe(
|
|
50
|
-
second.domains.metro?.restoreKey
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('produces a different restoreKey for different staticInputs', () => {
|
|
55
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
56
|
-
|
|
57
|
-
const first = planRestore(paths, inputs({ a: '1' }));
|
|
58
|
-
const second = planRestore(paths, inputs({ a: '2' }));
|
|
59
|
-
|
|
60
|
-
expect(first.domains.metro?.restoreKey).not.toBe(
|
|
61
|
-
second.domains.metro?.restoreKey
|
|
62
|
-
);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('shapes restorePrefixes for the accretive metro domain as a single trailing-dash prefix', () => {
|
|
66
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
67
|
-
const plan = planRestore(paths, inputs({ a: '1' }));
|
|
68
|
-
const domain = plan.domains.metro;
|
|
69
|
-
|
|
70
|
-
expect(domain?.accretive).toBe(true);
|
|
71
|
-
expect(domain?.restorePrefixes).toEqual([`${domain?.restoreKey}-`]);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('only includes domains present in the inputs', () => {
|
|
75
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
76
|
-
const plan = planRestore(paths, {});
|
|
77
|
-
|
|
78
|
-
expect(plan.domains).toEqual({});
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('reports the domain cache directories as paths', () => {
|
|
82
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
83
|
-
const plan = planRestore(paths, inputs({ a: '1' }));
|
|
84
|
-
|
|
85
|
-
expect(plan.domains.metro?.paths).toEqual([
|
|
86
|
-
paths.metroTransform,
|
|
87
|
-
paths.metroFileMap,
|
|
88
|
-
]);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe('snapshot', () => {
|
|
93
|
-
let projectRoot: string;
|
|
94
|
-
|
|
95
|
-
beforeEach(() => {
|
|
96
|
-
projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-cache-'));
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
afterEach(() => {
|
|
100
|
-
fs.rmSync(projectRoot, { recursive: true, force: true });
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('is empty for a domain whose directories do not exist', () => {
|
|
104
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
105
|
-
|
|
106
|
-
expect(() => snapshot(paths)).not.toThrow();
|
|
107
|
-
expect(snapshot(paths).metro).toEqual([]);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('collects entries for files under the domain directories', () => {
|
|
111
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
112
|
-
fs.mkdirSync(path.join(paths.metroTransform, 'nested'), {
|
|
113
|
-
recursive: true,
|
|
114
|
-
});
|
|
115
|
-
fs.writeFileSync(path.join(paths.metroTransform, 'a.txt'), 'aaa');
|
|
116
|
-
fs.writeFileSync(
|
|
117
|
-
path.join(paths.metroTransform, 'nested', 'b.txt'),
|
|
118
|
-
'bb'
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
const result = snapshot(paths);
|
|
122
|
-
const entries = result.metro ?? [];
|
|
123
|
-
|
|
124
|
-
expect(entries).toHaveLength(2);
|
|
125
|
-
const aEntry = entries.find((entry) =>
|
|
126
|
-
entry.path.endsWith(path.join('metro', 'a.txt'))
|
|
127
|
-
);
|
|
128
|
-
const bEntry = entries.find((entry) =>
|
|
129
|
-
entry.path.endsWith(path.join('metro', 'nested', 'b.txt'))
|
|
130
|
-
);
|
|
131
|
-
expect(aEntry?.sizeBytes).toBe(3);
|
|
132
|
-
expect(bEntry?.sizeBytes).toBe(2);
|
|
133
|
-
expect(typeof aEntry?.mtimeMs).toBe('number');
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
describe('planSave', () => {
|
|
138
|
-
let projectRoot: string;
|
|
139
|
-
|
|
140
|
-
beforeEach(() => {
|
|
141
|
-
projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-cache-'));
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
afterEach(() => {
|
|
145
|
-
fs.rmSync(projectRoot, { recursive: true, force: true });
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
const inputs = (
|
|
149
|
-
staticInputs: Record<string, string> = { a: '1' }
|
|
150
|
-
): Record<'metro', CacheKeyInputs> => ({
|
|
151
|
-
metro: { os: 'linux', staticInputs },
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it('does not save when there is no change, regardless of policy', () => {
|
|
155
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
156
|
-
fs.mkdirSync(paths.metroTransform, { recursive: true });
|
|
157
|
-
fs.writeFileSync(path.join(paths.metroTransform, 'a.txt'), 'aaa');
|
|
158
|
-
|
|
159
|
-
const before = snapshot(paths);
|
|
160
|
-
const plan = planSave(
|
|
161
|
-
paths,
|
|
162
|
-
before,
|
|
163
|
-
{ mode: 'always', isDefaultBranch: true },
|
|
164
|
-
inputs()
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
expect(plan.domains.metro?.shouldSave).toBe(false);
|
|
168
|
-
expect(plan.domains.metro?.delta).toEqual({
|
|
169
|
-
addedEntries: 0,
|
|
170
|
-
removedEntries: 0,
|
|
171
|
-
addedBytes: 0,
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it('saves an added file only when policy allows it', () => {
|
|
176
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
177
|
-
fs.mkdirSync(paths.metroTransform, { recursive: true });
|
|
178
|
-
const before = snapshot(paths);
|
|
179
|
-
|
|
180
|
-
fs.writeFileSync(path.join(paths.metroTransform, 'a.txt'), 'aaa');
|
|
181
|
-
|
|
182
|
-
const disallowed = planSave(
|
|
183
|
-
paths,
|
|
184
|
-
before,
|
|
185
|
-
{ mode: 'default-branch', isDefaultBranch: false },
|
|
186
|
-
inputs()
|
|
187
|
-
);
|
|
188
|
-
expect(disallowed.domains.metro?.shouldSave).toBe(false);
|
|
189
|
-
expect(disallowed.domains.metro?.delta.addedEntries).toBe(1);
|
|
190
|
-
expect(disallowed.domains.metro?.delta.addedBytes).toBe(3);
|
|
191
|
-
|
|
192
|
-
const allowed = planSave(
|
|
193
|
-
paths,
|
|
194
|
-
before,
|
|
195
|
-
{ mode: 'default-branch', isDefaultBranch: true },
|
|
196
|
-
inputs()
|
|
197
|
-
);
|
|
198
|
-
expect(allowed.domains.metro?.shouldSave).toBe(true);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it('never saves when policy mode is "never"', () => {
|
|
202
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
203
|
-
fs.mkdirSync(paths.metroTransform, { recursive: true });
|
|
204
|
-
const before = snapshot(paths);
|
|
205
|
-
fs.writeFileSync(path.join(paths.metroTransform, 'a.txt'), 'aaa');
|
|
206
|
-
|
|
207
|
-
const plan = planSave(
|
|
208
|
-
paths,
|
|
209
|
-
before,
|
|
210
|
-
{ mode: 'never', isDefaultBranch: true },
|
|
211
|
-
inputs()
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
expect(plan.domains.metro?.shouldSave).toBe(false);
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
it('counts a removed file in the delta', () => {
|
|
218
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
219
|
-
fs.mkdirSync(paths.metroTransform, { recursive: true });
|
|
220
|
-
fs.writeFileSync(path.join(paths.metroTransform, 'a.txt'), 'aaa');
|
|
221
|
-
const before = snapshot(paths);
|
|
222
|
-
|
|
223
|
-
fs.rmSync(path.join(paths.metroTransform, 'a.txt'));
|
|
224
|
-
|
|
225
|
-
const plan = planSave(
|
|
226
|
-
paths,
|
|
227
|
-
before,
|
|
228
|
-
{ mode: 'always', isDefaultBranch: true },
|
|
229
|
-
inputs()
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
expect(plan.domains.metro?.delta.removedEntries).toBe(1);
|
|
233
|
-
expect(plan.domains.metro?.shouldSave).toBe(true);
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
it('does not treat an mtime-only change as an added entry or change the content hash', () => {
|
|
237
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
238
|
-
fs.mkdirSync(paths.metroTransform, { recursive: true });
|
|
239
|
-
const filePath = path.join(paths.metroTransform, 'a.txt');
|
|
240
|
-
fs.writeFileSync(filePath, 'aaa');
|
|
241
|
-
const before = snapshot(paths);
|
|
242
|
-
|
|
243
|
-
const beforeSave = planSave(
|
|
244
|
-
paths,
|
|
245
|
-
before,
|
|
246
|
-
{ mode: 'always', isDefaultBranch: true },
|
|
247
|
-
inputs()
|
|
248
|
-
);
|
|
249
|
-
|
|
250
|
-
// Touch the file's mtime without changing its size/content.
|
|
251
|
-
const future = new Date(Date.now() + 10_000);
|
|
252
|
-
fs.utimesSync(filePath, future, future);
|
|
253
|
-
|
|
254
|
-
const afterSave = planSave(
|
|
255
|
-
paths,
|
|
256
|
-
before,
|
|
257
|
-
{ mode: 'always', isDefaultBranch: true },
|
|
258
|
-
inputs()
|
|
259
|
-
);
|
|
260
|
-
|
|
261
|
-
expect(afterSave.domains.metro?.delta.addedEntries).toBe(0);
|
|
262
|
-
expect(afterSave.domains.metro?.shouldSave).toBe(false);
|
|
263
|
-
expect(afterSave.domains.metro?.saveKey).toBe(
|
|
264
|
-
beforeSave.domains.metro?.saveKey
|
|
265
|
-
);
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
it('produces a deterministic saveKey across independent planSave calls given the same on-disk state', () => {
|
|
269
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
270
|
-
fs.mkdirSync(paths.metroTransform, { recursive: true });
|
|
271
|
-
fs.writeFileSync(path.join(paths.metroTransform, 'a.txt'), 'aaa');
|
|
272
|
-
const before: CacheSnapshot = {};
|
|
273
|
-
|
|
274
|
-
const first = planSave(
|
|
275
|
-
paths,
|
|
276
|
-
before,
|
|
277
|
-
{ mode: 'always', isDefaultBranch: true },
|
|
278
|
-
inputs()
|
|
279
|
-
);
|
|
280
|
-
const second = planSave(
|
|
281
|
-
paths,
|
|
282
|
-
before,
|
|
283
|
-
{ mode: 'always', isDefaultBranch: true },
|
|
284
|
-
inputs()
|
|
285
|
-
);
|
|
286
|
-
|
|
287
|
-
expect(first.domains.metro?.saveKey).toBe(second.domains.metro?.saveKey);
|
|
288
|
-
});
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
describe('writeKeysFile', () => {
|
|
292
|
-
let projectRoot: string;
|
|
293
|
-
|
|
294
|
-
beforeEach(() => {
|
|
295
|
-
projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-cache-'));
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
afterEach(() => {
|
|
299
|
-
fs.rmSync(projectRoot, { recursive: true, force: true });
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
it('writes keys.json under the cache root, outside domain subdirectories', () => {
|
|
303
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
304
|
-
const plan = planRestore(paths, {
|
|
305
|
-
metro: { os: 'linux', staticInputs: { a: '1' } },
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
writeKeysFile(paths, plan);
|
|
309
|
-
|
|
310
|
-
const filePath = path.join(paths.root, 'keys.json');
|
|
311
|
-
expect(fs.existsSync(filePath)).toBe(true);
|
|
312
|
-
expect(filePath.startsWith(paths.metroTransform)).toBe(false);
|
|
313
|
-
expect(filePath.startsWith(paths.metroFileMap)).toBe(false);
|
|
314
|
-
|
|
315
|
-
const written = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
316
|
-
expect(written.version).toBe(1);
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
it('swallows errors instead of throwing when the cache root cannot be created', () => {
|
|
320
|
-
const blockedRoot = path.join(projectRoot, 'blocked-file', 'nested');
|
|
321
|
-
fs.writeFileSync(path.join(projectRoot, 'blocked-file'), 'not a directory');
|
|
322
|
-
const paths = createHarnessCachePaths(blockedRoot);
|
|
323
|
-
const plan = planRestore(paths, {
|
|
324
|
-
metro: { os: 'linux', staticInputs: { a: '1' } },
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
expect(() => writeKeysFile(paths, plan)).not.toThrow();
|
|
328
|
-
expect(fs.existsSync(path.join(paths.root, 'keys.json'))).toBe(false);
|
|
329
|
-
});
|
|
330
|
-
});
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import os from 'node:os';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
5
|
-
import { createHarnessCachePaths } from '../paths.js';
|
|
6
|
-
import { isDomainWarm } from '../warmth.js';
|
|
7
|
-
|
|
8
|
-
describe('isDomainWarm', () => {
|
|
9
|
-
let projectRoot: string;
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
projectRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-cache-'));
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
fs.rmSync(projectRoot, { recursive: true, force: true });
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('is false when the domain directory does not exist', () => {
|
|
20
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
21
|
-
|
|
22
|
-
expect(isDomainWarm('metro', paths)).toBe(false);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('is false when the domain directory exists but is empty', () => {
|
|
26
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
27
|
-
fs.mkdirSync(paths.metroTransform, { recursive: true });
|
|
28
|
-
|
|
29
|
-
expect(isDomainWarm('metro', paths)).toBe(false);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('is true when the domain directory exists and has entries', () => {
|
|
33
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
34
|
-
fs.mkdirSync(paths.metroTransform, { recursive: true });
|
|
35
|
-
fs.writeFileSync(path.join(paths.metroTransform, 'entry'), 'data');
|
|
36
|
-
|
|
37
|
-
expect(isDomainWarm('metro', paths)).toBe(true);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('is false when the path exists but is a file, not a directory', () => {
|
|
41
|
-
const paths = createHarnessCachePaths(projectRoot);
|
|
42
|
-
fs.mkdirSync(path.dirname(paths.metroTransform), { recursive: true });
|
|
43
|
-
fs.writeFileSync(paths.metroTransform, 'not a directory');
|
|
44
|
-
|
|
45
|
-
expect(isDomainWarm('metro', paths)).toBe(false);
|
|
46
|
-
});
|
|
47
|
-
});
|