From d07bd4c5861488dcc957c1398ce3f490ea08c5b6 Mon Sep 17 00:00:00 2001 From: mohan-bee Date: Fri, 24 Jul 2026 15:38:28 +0530 Subject: [PATCH] repro crystal circuit --- .../repro-crystal-load-capacitors.snap.svg | 56 +++++++++ .../repro-crystal-load-capacitors.input.json | 117 ++++++++++++++++++ .../repro-crystal-load-capacitors.test.ts | 29 +++++ 3 files changed, 202 insertions(+) create mode 100644 tests/repros/__snapshots__/repro-crystal-load-capacitors.snap.svg create mode 100644 tests/repros/assets/repro-crystal-load-capacitors.input.json create mode 100644 tests/repros/repro-crystal-load-capacitors.test.ts diff --git a/tests/repros/__snapshots__/repro-crystal-load-capacitors.snap.svg b/tests/repros/__snapshots__/repro-crystal-load-capacitors.snap.svg new file mode 100644 index 000000000..cc3451ff2 --- /dev/null +++ b/tests/repros/__snapshots__/repro-crystal-load-capacitors.snap.svg @@ -0,0 +1,56 @@ + \ No newline at end of file diff --git a/tests/repros/assets/repro-crystal-load-capacitors.input.json b/tests/repros/assets/repro-crystal-load-capacitors.input.json new file mode 100644 index 000000000..4b219e2e3 --- /dev/null +++ b/tests/repros/assets/repro-crystal-load-capacitors.input.json @@ -0,0 +1,117 @@ +{ + "chips": [ + { + "chipId": "schematic_component_0", + "center": { + "x": 0, + "y": 0 + }, + "width": 1.1, + "height": 0.54, + "pins": [ + { + "pinId": "Y1.1", + "x": -0.55, + "y": 0, + "_facingDirection": "x-" + }, + { + "pinId": "Y1.2", + "x": 0.55, + "y": 0, + "_facingDirection": "x+" + } + ] + }, + { + "chipId": "schematic_component_1", + "center": { + "x": -0.41500000000000004, + "y": -1.52 + }, + "width": 0.9199999999999999, + "height": 0.7599999999999998, + "pins": [ + { + "pinId": "C19.1", + "x": -0.55, + "y": -1.1400000000000001, + "_facingDirection": "y+" + }, + { + "pinId": "C19.2", + "x": -0.55, + "y": -1.9, + "_facingDirection": "y-" + } + ] + }, + { + "chipId": "schematic_component_2", + "center": { + "x": 0.685, + "y": -1.52 + }, + "width": 0.9199999999999999, + "height": 0.7599999999999998, + "pins": [ + { + "pinId": "C20.1", + "x": 0.55, + "y": -1.1400000000000001, + "_facingDirection": "y+" + }, + { + "pinId": "C20.2", + "x": 0.55, + "y": -1.9, + "_facingDirection": "y-" + } + ] + } + ], + "directConnections": [], + "netConnections": [ + { + "netId": "XIN", + "pinIds": [ + "Y1.1", + "C19.1" + ], + "netLabelWidth": 0.48 + }, + { + "netId": "XOUT", + "pinIds": [ + "Y1.2", + "C20.1" + ], + "netLabelWidth": 0.6 + }, + { + "netId": "GND", + "pinIds": [ + "C19.2", + "C20.2" + ], + "netLabelWidth": 0.42, + "netLabelHeight": 0.48 + } + ], + "textBoxes": [], + "availableNetLabelOrientations": { + "XIN": [ + "x-", + "x+" + ], + "XOUT": [ + "x-", + "x+" + ], + "GND": [ + "y-" + ] + }, + "maxMspPairDistance": 2.4, + "_hideRatsNet": false +} diff --git a/tests/repros/repro-crystal-load-capacitors.test.ts b/tests/repros/repro-crystal-load-capacitors.test.ts new file mode 100644 index 000000000..0740e8fde --- /dev/null +++ b/tests/repros/repro-crystal-load-capacitors.test.ts @@ -0,0 +1,29 @@ +import { expect, test } from "bun:test" +import { SchematicTracePipelineSolver } from "lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver" +import "tests/fixtures/matcher" +import inputProblem from "./assets/repro-crystal-load-capacitors.input.json" + +// InputProblem extracted from a tscircuit circuit: a 12MHz crystal (Y1) wired +// to two 22pF load capacitors (C19, C20) via the XIN and XOUT nets, with both +// capacitor bottom pins tied to GND. Generated by rendering the circuit in +// @tscircuit/core and capturing the "solver:started" event for +// SchematicTracePipelineSolver. +test("repro crystal with load capacitors routes XIN, XOUT, GND nets", () => { + const solver = new SchematicTracePipelineSolver(inputProblem as any) + + const getPin = (pinId: string) => + solver.inputProblem.chips + .flatMap((chip) => chip.pins) + .find((pin) => pin.pinId === pinId)! + + expect(getPin("Y1.1").x).toBeCloseTo(getPin("C19.1").x) + expect(getPin("Y1.2").x).toBeCloseTo(getPin("C20.1").x) + expect(getPin("C19.2").y).toBeCloseTo(getPin("C20.2").y) + + solver.solve() + + expect(solver.schematicTraceLinesSolver?.failedConnectionPairs).toHaveLength( + 0, + ) + expect(solver).toMatchSolverSnapshot(import.meta.path) +})