test(stammbaum): no two nodes overlap on the same row (#724)

O(n^2) sweep over canonical + synthetic: any two nodes sharing a y are at least
NODE_W + COL_GAP apart.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-04 13:37:20 +02:00
committed by marcel
parent a85b22efcf
commit 0cd4882ef4

View File

@@ -501,4 +501,42 @@ describe('buildLayout — ancestor centring invariant (#724)', () => {
forest.roots.forEach(walk);
}
});
it('no two nodes on the same row overlap (canonical + synthetic)', () => {
const cases: [string, PersonNodeDTO[], RelationshipDTO[]][] = [
['canonical', fixtureNodes, fixtureEdges],
[
'synthetic deep',
[
node('R', 'R', 0),
node('p1', 'p1', 1),
node('p2', 'p2', 1),
node('g1', 'g1', 2),
node('g2', 'g2', 2)
],
[
parentEdge('R', 'p1'),
parentEdge('R', 'p2'),
parentEdge('p1', 'g1'),
parentEdge('p1', 'g2')
]
]
];
for (const [label, nodes, edges] of cases) {
const layout = buildLayout(nodes, edges);
const entries = [...layout.positions.entries()];
for (let i = 0; i < entries.length; i++) {
for (let j = i + 1; j < entries.length; j++) {
const [, a] = entries[i];
const [, b] = entries[j];
if (a.y !== b.y) continue;
expect(
Math.abs(a.x - b.x),
`${label}: ${entries[i][0]} vs ${entries[j][0]} overlap on y=${a.y}`
).toBeGreaterThanOrEqual(NODE_W + COL_GAP);
}
}
}
});
});