paperclip/scripts/test-line-shard.mjs

46 lines
2.1 KiB
JavaScript

import assert from "node:assert/strict";
import path from "node:path";
function validateTests(tests, file) {
assert.ok(Array.isArray(tests) && tests.length > 0, "Vitest must collect at least one test");
for (const test of tests) {
assert.equal(test.projectName, "@paperclipai/server", "unexpected test project");
assert.equal(path.resolve(test.file), path.resolve(file), "unexpected test file");
assert.ok(typeof test.name === "string" && test.name.length > 0, "missing test name");
assert.ok(Number.isSafeInteger(test.location?.line) && test.location.line > 0, "missing test source line");
}
}
// Keep all cases registered on one source line together, including it.each
// and loop-generated cases. Balance by collected case count, not line count.
export function partitionTestLines(tests, count, file) {
validateTests(tests, file);
assert.ok(Number.isSafeInteger(count) && count > 0, "invalid shard count");
const byLine = new Map();
for (const test of tests) {
const line = test.location.line;
if (!byLine.has(line)) byLine.set(line, []);
byLine.get(line).push(test);
}
assert.ok(byLine.size >= count, "each shard must contain a source line");
const groups = [...byLine].sort((a, b) => b[1].length - a[1].length || a[0] - b[0]);
const shards = Array.from({ length: count }, () => ({ lines: [], tests: [] }));
for (const [line, cases] of groups) {
const shard = shards.reduce((best, next) => next.tests.length < best.tests.length ? next : best);
shard.lines.push(line);
shard.tests.push(...cases);
}
for (const shard of shards) shard.lines.sort((a, b) => a - b);
return shards;
}
// Re-collect using the exact filters passed to the subsequent test run. A
// Vitest filtering change must fail here instead of silently dropping cases.
export function assertSelectedTests(expected, actual, file) {
validateTests(actual, file);
const identities = (tests) => tests.map((test) => JSON.stringify([
test.projectName, path.resolve(test.file), test.location.line, test.name,
])).sort();
assert.deepEqual(identities(actual), identities(expected), "Vitest filters must select exactly the assigned tests");
}