v1.1.0: pooled runtime, 959 tests, production hardening (0 squash)

This commit is contained in:
John Dvorak
2025-08-15 10:00:00 -07:00
commit 92deb689cd
321 changed files with 79170 additions and 0 deletions
@@ -0,0 +1,439 @@
import { describe, it } from 'node:test';
import assert from 'node:assert';
import fc from 'fast-check';
import {
type GeometryWorld,
type ClauseDescriptor,
} from './registry.js';
import {
evaluateLeftOf,
evaluateRightOf,
evaluateAbove,
evaluateBelow,
evaluateOverlaps,
evaluateInside,
} from './relations.js';
import {
evaluateQuantifier,
type QuantifierClause,
} from './quantifiers.js';
import {
generateProof,
resetProofCounter,
} from './proofs.js';
// ---- Test Helpers ----
function makeWorldFromRects(
sLeft: number, sTop: number, sRight: number, sBottom: number,
rLeft: number, rTop: number, rRight: number, rBottom: number,
): GeometryWorld {
return {
sceneId: 'scene_1',
snapshotId: 'snap_1',
env: {
viewportWidth: 1280,
viewportHeight: 800,
deviceScaleFactor: 1,
colorScheme: 'light',
pointer: 'fine',
hover: false,
reducedMotion: false,
locale: 'en',
writingMode: 'horizontal-tb',
},
strings: { values: [] },
subjects: {
ids: [1, 2],
domNodeId: [10, 20],
subjectKind: [1, 1],
primaryBoxId: [100, 200],
firstFragmentId: [0, 0],
fragmentCount: [0, 0],
},
dom: {
nodeId: [10, 20],
parentNodeId: [0, 0],
childCount: [0, 0],
tagNameStringId: [0, 0],
},
boxes: {
boxId: [100, 200],
subjectId: [1, 2],
frameId: [1, 1],
borderLeft: [sLeft, rLeft],
borderTop: [sTop, rTop],
borderRight: [sRight, rRight],
borderBottom: [sBottom, rBottom],
paddingLeft: [0, 0],
paddingTop: [0, 0],
paddingRight: [0, 0],
paddingBottom: [0, 0],
contentLeft: [0, 0],
contentTop: [0, 0],
contentRight: [0, 0],
contentBottom: [0, 0],
},
visualBoxes: {
boxId: [], subjectId: [], frameId: [],
borderLeft: [], borderTop: [], borderRight: [], borderBottom: [],
paddingLeft: [], paddingTop: [], paddingRight: [], paddingBottom: [],
contentLeft: [], contentTop: [], contentRight: [], contentBottom: [],
},
transforms: {
transformId: [], subjectId: [], matrixStart: [], matrixLength: [],
originX: [], originY: [],
},
matrices: { values: [] },
rects: {
rectId: [],
left: [],
top: [],
right: [],
bottom: [],
},
topology: {
containingBlockOf: [0, 0],
nearestPositionedAncestorOf: [0, 0],
scrollContainerOf: [0, 0],
stackingContextOf: [0, 0],
formattingContextOf: [0, 0],
clippingRootOf: [0, 0],
paintOrderBucket: [0, 0],
paintOrderIndex: [0, 0],
},
scroll: {
containerId: [],
scrollLeft: [],
scrollTop: [],
scrollWidth: [],
scrollHeight: [],
clientWidth: [],
clientHeight: [],
},
clipping: {
clipNodeId: [],
subjectId: [],
clipKind: [],
clipLeft: [],
clipTop: [],
clipRight: [],
clipBottom: [],
parentClipNodeId: [],
},
visibility: {
subjectId: [],
isRendered: [],
isVisible: [],
visibleArea: [],
clippedArea: [],
},
};
}
function makeClause(kind: string, overrides?: Partial<ClauseDescriptor>): ClauseDescriptor {
return {
clauseId: 'clause_1',
clauseKind: kind,
version: 1,
subjectRef: 1,
referenceRef: 2,
...overrides,
};
}
// ---- Arbitraries ----
const coordArb = fc.integer({ min: 0, max: 500 });
const rectArb = fc
.tuple(coordArb, coordArb, coordArb, coordArb)
.filter(([l, t, r, b]) => l < r && t < b)
.map(([l, t, r, b]) => ({ left: l, top: t, right: r, bottom: b }));
const gapArb = fc.integer({ min: 0, max: 200 });
// ---- Property Tests ----
describe('solver property tests', () => {
it('property: leftOf and rightOf are inverse relations with same gap', () => {
fc.assert(
fc.property(
rectArb,
rectArb,
gapArb,
(subjectRect, referenceRect, gap) => {
// Place subject left of reference with exact gap
const sLeft = 0;
const sTop = 0;
const sRight = sLeft + (subjectRect.right - subjectRect.left);
const sBottom = sTop + (subjectRect.bottom - subjectRect.top);
const rLeft = sRight + gap;
const rTop = 0;
const rRight = rLeft + (referenceRect.right - referenceRect.left);
const rBottom = rTop + (referenceRect.bottom - referenceRect.top);
// World where subject is left of reference
const worldLR = makeWorldFromRects(sLeft, sTop, sRight, sBottom, rLeft, rTop, rRight, rBottom);
// World where subject is right of reference (swapped)
const worldRL = makeWorldFromRects(rLeft, rTop, rRight, rBottom, sLeft, sTop, sRight, sBottom);
const leftOfClause = makeClause('relation.leftOf', {
bounds: { minGap: gap, maxGap: gap },
});
const rightOfClause = makeClause('relation.rightOf', {
bounds: { minGap: gap, maxGap: gap },
});
const leftResult = evaluateLeftOf(worldLR, leftOfClause);
const rightResult = evaluateRightOf(worldRL, rightOfClause);
assert.strictEqual(leftResult.status, 'pass');
assert.strictEqual(rightResult.status, 'pass');
assert.strictEqual(leftResult.metrics?.observedGap, gap);
assert.strictEqual(rightResult.metrics?.observedGap, gap);
}
),
{ numRuns: 200, seed: 42 }
);
});
it('property: above and below are inverse relations', () => {
fc.assert(
fc.property(
rectArb,
rectArb,
gapArb,
(subjectRect, referenceRect, gap) => {
const sLeft = 0;
const sTop = 0;
const sRight = sLeft + (subjectRect.right - subjectRect.left);
const sBottom = sTop + (subjectRect.bottom - subjectRect.top);
const rLeft = 0;
const rTop = sBottom + gap;
const rRight = rLeft + (referenceRect.right - referenceRect.left);
const rBottom = rTop + (referenceRect.bottom - referenceRect.top);
// World where subject is above reference
const worldAB = makeWorldFromRects(sLeft, sTop, sRight, sBottom, rLeft, rTop, rRight, rBottom);
// World where subject is below reference (swapped)
const worldBA = makeWorldFromRects(rLeft, rTop, rRight, rBottom, sLeft, sTop, sRight, sBottom);
const aboveClause = makeClause('relation.above', {
bounds: { minGap: gap, maxGap: gap },
});
const belowClause = makeClause('relation.below', {
bounds: { minGap: gap, maxGap: gap },
});
const aboveResult = evaluateAbove(worldAB, aboveClause);
const belowResult = evaluateBelow(worldBA, belowClause);
assert.strictEqual(aboveResult.status, 'pass');
assert.strictEqual(belowResult.status, 'pass');
assert.strictEqual(aboveResult.metrics?.observedGap, gap);
assert.strictEqual(belowResult.metrics?.observedGap, gap);
}
),
{ numRuns: 200, seed: 123 }
);
});
it('property: if A is inside B, then B contains A', () => {
fc.assert(
fc.property(
rectArb,
fc.integer({ min: 0, max: 50 }),
(innerRect, padding) => {
const outerRect = {
left: innerRect.left - padding,
top: innerRect.top - padding,
right: innerRect.right + padding,
bottom: innerRect.bottom + padding,
};
if (outerRect.left >= outerRect.right || outerRect.top >= outerRect.bottom) {
return; // Skip invalid outer rect
}
// A inside B
const world1 = makeWorldFromRects(
innerRect.left, innerRect.top, innerRect.right, innerRect.bottom,
outerRect.left, outerRect.top, outerRect.right, outerRect.bottom
);
const insideClause = makeClause('relation.inside');
const insideResult = evaluateInside(world1, insideClause);
assert.strictEqual(insideResult.status, 'pass', 'A should be inside B');
// B contains A (swap subject/reference)
const world2 = makeWorldFromRects(
outerRect.left, outerRect.top, outerRect.right, outerRect.bottom,
innerRect.left, innerRect.top, innerRect.right, innerRect.bottom
);
// Use leftOf with a huge gap as a proxy for contains, or just verify the geometry relation
// Since there is no direct "contains" evaluator in relations.ts, we verify via inside logic:
// If A is inside B, then B's rect fully contains A's rect.
assert.ok(
innerRect.left >= outerRect.left &&
innerRect.top >= outerRect.top &&
innerRect.right <= outerRect.right &&
innerRect.bottom <= outerRect.bottom,
'Containment geometry should hold'
);
}
),
{ numRuns: 200, seed: 77 }
);
});
it('property: if A overlaps B, then B overlaps A', () => {
fc.assert(
fc.property(
rectArb,
rectArb,
(rectA, rectB) => {
const world = makeWorldFromRects(
rectA.left, rectA.top, rectA.right, rectA.bottom,
rectB.left, rectB.top, rectB.right, rectB.bottom
);
const overlapsClause = makeClause('relation.overlaps');
const resultAB = evaluateOverlaps(world, overlapsClause);
// Swap subject and reference by creating a new world with swapped boxes
const worldBA = makeWorldFromRects(
rectB.left, rectB.top, rectB.right, rectB.bottom,
rectA.left, rectA.top, rectA.right, rectA.bottom
);
const resultBA = evaluateOverlaps(worldBA, overlapsClause);
assert.strictEqual(resultAB.status, resultBA.status, 'Overlap should be symmetric');
}
),
{ numRuns: 300, seed: 88 }
);
});
it('property: all quantifier passes iff every sub-clause passes', () => {
fc.assert(
fc.property(
fc.array(fc.boolean(), { minLength: 1, maxLength: 20 }),
(passFlags) => {
const subResults = passFlags.map((pass, i) => ({
clauseId: `c${i}`,
status: pass ? 'pass' as const : 'fail' as const,
truth: 'determinate' as const,
}));
const clause: QuantifierClause = {
clauseId: 'q1',
clauseKind: 'quantifier.all',
version: 1,
quantifier: 'all',
subClauseIds: passFlags.map((_, i) => `c${i}`),
};
const result = evaluateQuantifier(subResults, clause);
const expected = passFlags.every(Boolean) ? 'pass' : 'fail';
assert.strictEqual(result.status, expected);
}
),
{ numRuns: 200, seed: 55 }
);
});
it('property: any quantifier passes iff at least one sub-clause passes', () => {
fc.assert(
fc.property(
fc.array(fc.boolean(), { minLength: 1, maxLength: 20 }),
(passFlags) => {
const subResults = passFlags.map((pass, i) => ({
clauseId: `c${i}`,
status: pass ? 'pass' as const : 'fail' as const,
truth: 'determinate' as const,
}));
const clause: QuantifierClause = {
clauseId: 'q1',
clauseKind: 'quantifier.any',
version: 1,
quantifier: 'any',
subClauseIds: passFlags.map((_, i) => `c${i}`),
};
const result = evaluateQuantifier(subResults, clause);
const expected = passFlags.some(Boolean) ? 'pass' : 'fail';
assert.strictEqual(result.status, expected);
}
),
{ numRuns: 200, seed: 66 }
);
});
it('property: none quantifier passes iff no sub-clause passes', () => {
fc.assert(
fc.property(
fc.array(fc.boolean(), { minLength: 1, maxLength: 20 }),
(passFlags) => {
const subResults = passFlags.map((pass, i) => ({
clauseId: `c${i}`,
status: pass ? 'pass' as const : 'fail' as const,
truth: 'determinate' as const,
}));
const clause: QuantifierClause = {
clauseId: 'q1',
clauseKind: 'quantifier.none',
version: 1,
quantifier: 'none',
subClauseIds: passFlags.map((_, i) => `c${i}`),
};
const result = evaluateQuantifier(subResults, clause);
const expected = !passFlags.some(Boolean) ? 'pass' : 'fail';
assert.strictEqual(result.status, expected);
}
),
{ numRuns: 200, seed: 33 }
);
});
it('property: proof generation preserves failure/success', () => {
fc.assert(
fc.property(
fc.tuple(coordArb, coordArb, coordArb, coordArb),
fc.tuple(coordArb, coordArb, coordArb, coordArb),
gapArb,
([sL, sT, sR, sB], [rL, rT, rR, rB], minGap) => {
if (sL >= sR || sT >= sB || rL >= rR || rT >= rB) return;
const world = makeWorldFromRects(sL, sT, sR, sB, rL, rT, rR, rB);
const clause = makeClause('relation.leftOf', {
bounds: { minGap },
});
resetProofCounter();
const evalResult = evaluateLeftOf(world, clause);
const proof = generateProof(evalResult, clause, world);
assert.strictEqual(proof.outcome, evalResult.status);
assert.strictEqual(proof.truth, evalResult.truth);
assert.strictEqual(proof.clauseId, clause.clauseId);
if (evalResult.status === 'fail') {
assert.ok(proof.failedPredicate, 'Failed proof should have failedPredicate');
} else {
assert.strictEqual(proof.failedPredicate, undefined);
}
}
),
{ numRuns: 300, seed: 99 }
);
});
});