From 313c8fd78be852627e28af6e1b744e66b8e00a59 Mon Sep 17 00:00:00 2001 From: ShiboSoftwareDev Date: Sun, 2 Aug 2026 05:43:53 +0200 Subject: [PATCH 1/2] test(pathing): visualize sample 4 port overcapacity --- ...sted-port-physical-capacity-repro.snap.svg | 44 +++++ ...ested-port-physical-capacity-repro.test.ts | 158 ++++++++++++++++++ 2 files changed, 202 insertions(+) create mode 100644 tests/solver/__snapshots__/duplicate-congested-port-physical-capacity-repro.snap.svg create mode 100644 tests/solver/duplicate-congested-port-physical-capacity-repro.test.ts diff --git a/tests/solver/__snapshots__/duplicate-congested-port-physical-capacity-repro.snap.svg b/tests/solver/__snapshots__/duplicate-congested-port-physical-capacity-repro.snap.svg new file mode 100644 index 0000000..621514e --- /dev/null +++ b/tests/solver/__snapshots__/duplicate-congested-port-physical-capacity-repro.snap.svg @@ -0,0 +1,44 @@ +Sample 4 opening: 7 lanes / 2 physical capacity \ No newline at end of file diff --git a/tests/solver/duplicate-congested-port-physical-capacity-repro.test.ts b/tests/solver/duplicate-congested-port-physical-capacity-repro.test.ts new file mode 100644 index 0000000..344ba13 --- /dev/null +++ b/tests/solver/duplicate-congested-port-physical-capacity-repro.test.ts @@ -0,0 +1,158 @@ +import "bun-match-svg" +import { expect, test } from "bun:test" +import type { SerializedHyperGraph } from "@tscircuit/hypergraph" +import { + getSvgFromGraphicsObject, + stackGraphicsVertically, + type GraphicsObject, +} from "graphics-debug" +import { DuplicateCongestedPortSolver } from "lib/index" + +const createRegion = ( + regionId: string, + center: { x: number; y: number }, + width: number, + height: number, + pointIds: string[], +): SerializedHyperGraph["regions"][number] => ({ + regionId, + pointIds, + d: { center, width, height }, +}) + +const createPort = ( + portId: string, + region1Id: string, + region2Id: string, + x: number, + y: number, +): SerializedHyperGraph["ports"][number] => ({ + portId, + region1Id, + region2Id, + d: { x, y, z: 0 }, +}) + +const createSample4BoundaryFixture = (): SerializedHyperGraph => { + const connections = Array.from({ length: 7 }, (_, index) => ({ + connectionId: `route-${index}`, + startRegionId: `start-${index}`, + endRegionId: `end-${index}`, + mutuallyConnectedNetworkId: `net-${index}`, + })) + const startPorts = connections.map((_, index) => + createPort(`start-port-${index}`, `start-${index}`, "left", -0.3, 0), + ) + const endPorts = connections.map((_, index) => + createPort(`end-port-${index}`, "right", `end-${index}`, 0.3, 0), + ) + + return { + regions: [ + ...connections.map((_, index) => + createRegion(`start-${index}`, { x: -0.4, y: 0 }, 0.1, 0.1, [ + `start-port-${index}`, + ]), + ), + // Exact sample 4 shared opening: 0.396 mm tall with a 0.05 mm gap. + createRegion("left", { x: -0.127, y: 0 }, 0.204, 0.396, [ + ...startPorts.map((port) => port.portId), + "sample4-opening", + ]), + createRegion("right", { x: 0.103, y: 0 }, 0.156, 0.396, [ + "sample4-opening", + ...endPorts.map((port) => port.portId), + ]), + ...connections.map((_, index) => + createRegion(`end-${index}`, { x: 0.4, y: 0 }, 0.1, 0.1, [ + `end-port-${index}`, + ]), + ), + ], + ports: [ + ...startPorts, + createPort("sample4-opening", "left", "right", 0, 0), + ...endPorts, + ], + connections, + } +} + +test("visualizes the physical capacity of a real sample 4 opening", () => { + const solver = new DuplicateCongestedPortSolver( + createSample4BoundaryFixture(), + { + duplicatePortProximity: 0.05, + // Older implementations ignore these options, which is the issue this + // snapshot reproduces. + minimumDuplicatePortSpacing: 0.2, + duplicatePortWidth: 0.1, + } as any, + ) + solver.solve() + + const output = solver.getOutput() + const lanes = output.ports + .filter( + (port) => + port.portId === "sample4-opening" || + port.d?.duplicatedFromPortId === "sample4-opening", + ) + .sort((a, b) => Number(a.d?.y) - Number(b.d?.y)) + const graphics: GraphicsObject = { + rects: [ + { + center: { x: -0.127, y: 0 }, + width: 0.204, + height: 0.396, + fill: "rgba(80, 140, 220, 0.16)", + stroke: "rgb(80, 140, 220)", + label: "left region", + }, + { + center: { x: 0.103, y: 0 }, + width: 0.156, + height: 0.396, + fill: "rgba(80, 140, 220, 0.16)", + stroke: "rgb(80, 140, 220)", + label: "right region", + }, + ], + lines: lanes.flatMap((port, index) => [ + { + points: [ + { x: -0.16, y: Number(port.d?.y) }, + { x: 0.16, y: Number(port.d?.y) }, + ], + strokeColor: "rgba(255, 120, 0, 0.2)", + strokeWidth: 0.2, + label: `lane ${index + 1}: 0.1 mm trace + 0.1 mm clearance`, + }, + { + points: [ + { x: -0.16, y: Number(port.d?.y) }, + { x: 0.16, y: Number(port.d?.y) }, + ], + strokeColor: "rgb(210, 45, 45)", + strokeWidth: 0.1, + label: `lane ${index + 1}: physical trace`, + }, + ]), + points: lanes.map((port, index) => ({ + x: Number(port.d?.x), + y: Number(port.d?.y), + color: "rgb(20, 20, 20)", + label: `lane ${index + 1}`, + })), + circles: [], + } + + const svg = getSvgFromGraphicsObject( + stackGraphicsVertically([graphics], { + titles: [ + `Sample 4 opening: ${lanes.length} lanes / 2 physical capacity`, + ], + }), + ) + expect(svg).toMatchSvgSnapshot(import.meta.path) +}) From bf3f044fa5196528854247659d25c1af37007336 Mon Sep 17 00:00:00 2001 From: ShiboSoftwareDev Date: Sun, 2 Aug 2026 06:08:09 +0200 Subject: [PATCH 2/2] style: format duplicate port reproduction --- .../duplicate-congested-port-physical-capacity-repro.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/solver/duplicate-congested-port-physical-capacity-repro.test.ts b/tests/solver/duplicate-congested-port-physical-capacity-repro.test.ts index 344ba13..bf28c4f 100644 --- a/tests/solver/duplicate-congested-port-physical-capacity-repro.test.ts +++ b/tests/solver/duplicate-congested-port-physical-capacity-repro.test.ts @@ -149,9 +149,7 @@ test("visualizes the physical capacity of a real sample 4 opening", () => { const svg = getSvgFromGraphicsObject( stackGraphicsVertically([graphics], { - titles: [ - `Sample 4 opening: ${lanes.length} lanes / 2 physical capacity`, - ], + titles: [`Sample 4 opening: ${lanes.length} lanes / 2 physical capacity`], }), ) expect(svg).toMatchSvgSnapshot(import.meta.path)