Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
104 lines
4.7 KiB
JavaScript
104 lines
4.7 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Property-based tests for file-overlap-partitioner.cjs (#3674)
|
|
*
|
|
* Module: msd-core/bin/lib/file-overlap-partitioner.cjs
|
|
* Exported: partitionByFileOverlap(items: { id: string; files: string[] }[]) -> string[][]
|
|
*
|
|
* Properties tested (test matrix rows 9-11):
|
|
* (a) determinism — two runs on the same input produce an identical partition
|
|
* (b) totality — every input item appears in exactly one output stage,
|
|
* never lost or duplicated
|
|
* (c) the core invariant — no two items in the same stage share a file
|
|
*
|
|
* Duplicate `id`s are a real, intentionally-supported input shape (see
|
|
* `partitionByFileOverlap`'s doc comment) and properties (a) and (b) verify
|
|
* it correctly — (a) needs no per-item identity at all, and (b) only compares
|
|
* the sorted id multiset, so it never needs to pick out *which* physical item
|
|
* a given output id refers to. Property (c) is different: checking "do these
|
|
* two co-staged items' file sets overlap" requires reconstructing which
|
|
* physical item (files included) produced each id in the output, and under
|
|
* duplicate ids that reconstruction is ambiguous — a stage's "p208" could be
|
|
* either physical p208 occurrence, and picking the wrong one produces a false
|
|
* failure (see #3674 regression: `p0(f1)`, `p208(f1)`, `p208([])` staged
|
|
* correctly as `[[p0,p208#2],[p208#1]]`, misread as `[[p0,p208#1],...]` by an
|
|
* id-order reconstruction). So (c) alone constrains its generated items to
|
|
* unique ids, where the reconstruction is unambiguous by construction.
|
|
*/
|
|
|
|
const { describe, test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fc = require('./helpers/fast-check-setup.cjs');
|
|
|
|
const { partitionByFileOverlap } = require('../msd-core/bin/lib/file-overlap-partitioner.cjs');
|
|
|
|
/** A single overlap item: a small id plus a small set of file tokens (some shared, some not). */
|
|
const itemArb = fc.record({
|
|
id: fc.integer({ min: 0, max: 999 }).map((n) => 'p' + n),
|
|
files: fc.array(fc.constantFrom('f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7'), { maxLength: 4 }),
|
|
});
|
|
|
|
describe('partitionByFileOverlap: properties', () => {
|
|
|
|
test('property: repeated runs on the same input are deterministic', () => {
|
|
fc.assert(fc.property(
|
|
fc.array(itemArb, { minLength: 0, maxLength: 60 }),
|
|
(items) => {
|
|
const a = partitionByFileOverlap(items);
|
|
const b = partitionByFileOverlap(items);
|
|
assert.deepStrictEqual(a, b);
|
|
},
|
|
));
|
|
});
|
|
|
|
test('property: every input plan appears in exactly one output stage', () => {
|
|
fc.assert(fc.property(
|
|
fc.array(itemArb, { minLength: 0, maxLength: 60 }),
|
|
(items) => {
|
|
const stages = partitionByFileOverlap(items);
|
|
const flat = stages.flatMap((s) => s);
|
|
assert.strictEqual(flat.length, items.length, 'no item lost or duplicated across stages');
|
|
// Positional identity: nth occurrence in flattened output must match
|
|
// input order's ids, one-to-one (id alone is not unique under
|
|
// duplicates, so compare the full multiset via sorted copies).
|
|
assert.deepStrictEqual(flat.slice().sort(), items.map((i) => i.id).sort());
|
|
},
|
|
));
|
|
});
|
|
|
|
test('property: no two plans in the same stage share a modified file', () => {
|
|
fc.assert(fc.property(
|
|
// Unique ids only: this property reconstructs which physical item
|
|
// produced each output id, and that reconstruction is ambiguous when
|
|
// ids duplicate (see the module doc comment above). Properties (a)
|
|
// and (b) still fuzz duplicate ids via the shared `itemArb`.
|
|
fc.uniqueArray(itemArb, { minLength: 0, maxLength: 60, selector: (it) => it.id }),
|
|
(items) => {
|
|
const stages = partitionByFileOverlap(items);
|
|
// Positional lookup (not strictly required once ids are unique, but
|
|
// kept for symmetry with the reconstruction shape and to tolerate
|
|
// any future relaxation of the uniqueness constraint above).
|
|
const remaining = items.map((i) => ({ id: i.id, files: new Set(i.files) }));
|
|
for (const stageIds of stages) {
|
|
const stageItems = stageIds.map((id) => {
|
|
const idx = remaining.findIndex((r) => r.id === id);
|
|
const found = remaining[idx];
|
|
remaining.splice(idx, 1);
|
|
return found;
|
|
});
|
|
for (let i = 0; i < stageItems.length; i++) {
|
|
for (let j = i + 1; j < stageItems.length; j++) {
|
|
const a = stageItems[i].files;
|
|
const b = stageItems[j].files;
|
|
let overlap = false;
|
|
for (const f of a) if (b.has(f)) { overlap = true; break; }
|
|
assert.ok(!overlap, `stage-mates ${stageItems[i].id} and ${stageItems[j].id} must not share a file`);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
));
|
|
});
|
|
});
|