Skip to content

Commit 8763031

Browse files
Prithvi-Webclaude
andcommitted
test(store): the Autopilot and shipped-packs differentials each show they fired, per kind of store, so a store spelling paths wrong cannot pass them by matching nothing on both sides (review F1.1)
Both tests compare the rewritten walk with the old one on the same store. A packed store that joins its paths with the wrong separator (the Windows runner's break) loses every location and stale-files match on both sides, and the comparison still held: the Autopilot test passed on Windows in run 38345032466 while the packed store picked none of them. - Autopilot: per kind of store, each policy must have picked, over the seeds, from every group it names - no more, no fewer. - Shipped packs: every path a group claims must be a path of the tree; and, over the seeds, the object store fired some shipped rule and every other kind fired exactly the same rules. Mutants (all RED for the right reason, files restored by SHA-256): the packed store joining with "\" on macOS (policy 2 guard; claimed-path check); the drive-less fuzz root under Windows path resolution, the CI shape (policy 2 guard); a catalog of only its stale-files rules (non-empty check); a packed store that leaves out hidden entries (cross-kind check). The guards hold under Linux rules and under Windows path resolution with a Windows home and the Windows pack. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 4149a5a commit 8763031

1 file changed

Lines changed: 35 additions & 3 deletions

File tree

‎tests/cleanupSlices.test.ts‎

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,11 @@ function folders(tree: FileNode): string[] {
193193
return out;
194194
}
195195

196+
/** Every path a tree holds, root included, in pre-order. */
197+
function everyPath(tree: FileNode): string[] {
198+
return [tree.path, ...(tree.children ?? []).flatMap(everyPath)];
199+
}
200+
196201
/* ───────────────────────────── the catalog ───────────────────────────── */
197202

198203
const ruleBase = (id: string, category: 'regenerable' | 'cache' | 'junk' = 'regenerable') => ({
@@ -327,8 +332,13 @@ test('the sliced walk and the drained walk give the pre-change answer, observer
327332

328333
test('the shipped rule packs give the pre-change answer through the rewritten walk', async () => {
329334
const home = path.dirname(loadRuleCatalog().staleFiles[0].withinPath); // {home}, as the packs expanded it
335+
// The shipped rules each kind of store fired, apart, and the paths it claimed: a packed store
336+
// joining with the wrong separator spells paths the tree does not hold and fires no location rule,
337+
// while both walks read the same store and agree (review F1.1).
338+
const fired = new Map<string, Set<string>>(STORES.map(([kind]) => [kind, new Set<string>()]));
330339
for (let seed = 1; seed <= 12; seed++) {
331340
const tree = fuzzTree(seed, home, 900, farFromThresholds(SEED_NOW));
341+
const held = new Set(everyPath(tree));
332342
for (const [kind, make] of STORES) {
333343
const want = recorder();
334344
const oracle = oracleCleanupSuggestions(make(tree), [], loadRuleCatalog(), want.observe, []);
@@ -337,8 +347,17 @@ test('the shipped rule packs give the pre-change answer through the rewritten wa
337347
assert.equal(JSON.stringify(sliced.groups), JSON.stringify(oracle), `seed ${seed}, ${kind}: the shipped packs answer as before`);
338348
assert.deepEqual(got.seen, want.seen, `seed ${seed}, ${kind}: observer order`);
339349
assert.equal(JSON.stringify(collectCleanupSuggestions(make(tree), [], loadRuleCatalog())), JSON.stringify(oracle), `seed ${seed}, ${kind}: drained`);
350+
for (const g of oracle) fired.get(kind)?.add(g.id);
351+
const strays = oracle.flatMap((g) => g.items.map((item) => item.path)).filter((p) => !held.has(p));
352+
assert.deepEqual(strays, [], `seed ${seed}, ${kind}: every path the shipped packs claim is a path of the tree`);
340353
}
341354
}
355+
// A differential that fires nothing proves nothing, and two kinds of store reading one tree fire the same rules.
356+
const [[, objectFired], ...others] = [...fired];
357+
assert.ok(objectFired.size > 0, 'the fuzz trees fired a shipped rule');
358+
for (const [kind, ids] of others) {
359+
assert.deepEqual([...ids].sort(), [...objectFired].sort(), `${kind}: fired every shipped rule the object store fired, and no other`);
360+
}
342361
});
343362

344363
test('a U+0130 location is found wherever case folds, and only there', async () => {
@@ -360,22 +379,35 @@ test('a U+0130 location is found wherever case folds, and only there', async ()
360379
});
361380

362381
test('the Autopilot selects through the rewritten matcher exactly what it selected through the old one', async () => {
363-
const matches: AutopilotMatch[] = [
382+
const matches: Array<Extract<AutopilotMatch, { kind: 'suggestion' }>> = [
364383
{ kind: 'suggestion', groupIds: ['p-node', 'd-build', 'f-junk'] },
365384
{ kind: 'suggestion', groupIds: ['s-old', 's-small', 'l-browser', 'l-dotted', 'p-rust', 'p-maven', 'p-web'] },
366385
];
386+
// The groups each kind of store had candidates picked from, per match, apart: a packed store
387+
// joining with the wrong separator (the Windows runner's break) picked no location or stale-files
388+
// candidate through either matcher, and the comparison below still held (review F1.1).
389+
const picked = new Map<string, Array<Set<string>>>(STORES.map(([kind]) => [kind, matches.map(() => new Set<string>())]));
367390
for (let seed = 1; seed <= 16; seed++) {
368391
const root = absRoot('ap', `root${seed}`);
369392
const catalog = testCatalog(root);
370393
const tree = fuzzTree(seed, root, 700, nearThresholds(T));
371394
for (const [kind, make] of STORES) {
372395
const old = oracleCleanupSuggestions(make(tree), [], catalog, undefined, [], T);
373396
const sliced = await collectCleanupSuggestionsAsync(make(tree), [], catalog, undefined, [], { now: () => T, sliceNodes: 11, yieldTurn: immediate });
374-
for (const match of matches) {
375-
assert.deepEqual(selectCandidates(sliced.groups, [], match), selectCandidates(old, [], match), `seed ${seed}, ${kind}: the same candidates in the same order`);
397+
const groupOf = new Map(old.flatMap((g) => g.items.map((item) => [item.path, g.id] as const)));
398+
for (let i = 0; i < matches.length; i++) {
399+
const candidates = selectCandidates(sliced.groups, [], matches[i]);
400+
assert.deepEqual(candidates, selectCandidates(old, [], matches[i]), `seed ${seed}, ${kind}: the same candidates in the same order`);
401+
for (const c of candidates) picked.get(kind)?.[i].add(groupOf.get(c.path) ?? c.path);
376402
}
377403
}
378404
}
405+
// A comparison that never picks from a group proves nothing about that group.
406+
for (const [kind, perMatch] of picked) {
407+
for (let i = 0; i < matches.length; i++) {
408+
assert.deepEqual([...perMatch[i]].sort(), [...matches[i].groupIds].sort(), `${kind}: policy ${i + 1} picked from every group it names, over the seeds`);
409+
}
410+
}
379411
});
380412

381413
/* ───────────────────────────── slices, counted ───────────────────────────── */

0 commit comments

Comments
 (0)