Scope trace length checks to exact routed endpoints - #251
Merged
seveibar merged 1 commit intoAug 27, 2026
Conversation
Comment on lines
+129
to
+273
| test("ignores unrelated long MST branches when exact two-port traces are short", () => { | ||
| const cases = [ | ||
| { id: "charger_ground", maximum: 5, exact: 3.94, branch: 10.71 }, | ||
| { id: "vdd1_decoupling", maximum: 3, exact: 1.16, branch: 6.47 }, | ||
| { id: "regulator_output", maximum: 6, exact: 1.57, branch: 17.37 }, | ||
| ] | ||
| const multidropCircuitJson = cases.flatMap( | ||
| ({ id, maximum, exact, branch }): AnyCircuitElement[] => { | ||
| const sourceTraceId = `source_trace_${id}` | ||
| const startSourcePortId = `source_port_${id}_start` | ||
| const endSourcePortId = `source_port_${id}_end` | ||
| const branchSourcePortId = `source_port_${id}_branch` | ||
| const startPcbPortId = `pcb_port_${id}_start` | ||
| const endPcbPortId = `pcb_port_${id}_end` | ||
| const branchPcbPortId = `pcb_port_${id}_branch` | ||
|
|
||
| return [ | ||
| { | ||
| type: "source_trace", | ||
| source_trace_id: sourceTraceId, | ||
| connected_source_port_ids: [startSourcePortId, endSourcePortId], | ||
| connected_source_net_ids: [], | ||
| max_length: maximum, | ||
| }, | ||
| makePcbPort(startPcbPortId, startSourcePortId), | ||
| makePcbPort(endPcbPortId, endSourcePortId), | ||
| makePcbPort(branchPcbPortId, branchSourcePortId), | ||
| makeStraightPcbTrace({ | ||
| pcbTraceId: `pcb_trace_${id}_exact`, | ||
| sourceTraceId, | ||
| startPcbPortId, | ||
| endPcbPortId, | ||
| length: exact, | ||
| }), | ||
| makeStraightPcbTrace({ | ||
| pcbTraceId: `pcb_trace_${id}_unrelated_branch`, | ||
| sourceTraceId, | ||
| startPcbPortId, | ||
| endPcbPortId: branchPcbPortId, | ||
| length: branch, | ||
| }), | ||
| ] | ||
| }, | ||
| ) | ||
|
|
||
| expect(checkPcbTraceLengths(multidropCircuitJson)).toEqual([]) | ||
| }) | ||
|
|
||
| test("retains a violation on the exact two-port PCB trace", () => { | ||
| const exactViolationCircuitJson = [ | ||
| { | ||
| type: "source_trace", | ||
| source_trace_id: "source_trace_exact_violation", | ||
| connected_source_port_ids: ["source_port_a", "source_port_b"], | ||
| connected_source_net_ids: [], | ||
| max_length: 5, | ||
| }, | ||
| makePcbPort("pcb_port_a", "source_port_a"), | ||
| makePcbPort("pcb_port_b", "source_port_b"), | ||
| makePcbPort("pcb_port_branch", "source_port_branch"), | ||
| makeStraightPcbTrace({ | ||
| pcbTraceId: "pcb_trace_exact_violation", | ||
| sourceTraceId: "source_trace_exact_violation", | ||
| startPcbPortId: "pcb_port_a", | ||
| endPcbPortId: "pcb_port_b", | ||
| length: 7, | ||
| }), | ||
| makeStraightPcbTrace({ | ||
| pcbTraceId: "pcb_trace_unrelated_long_branch", | ||
| sourceTraceId: "source_trace_exact_violation", | ||
| startPcbPortId: "pcb_port_a", | ||
| endPcbPortId: "pcb_port_branch", | ||
| length: 12, | ||
| }), | ||
| ] as AnyCircuitElement[] | ||
|
|
||
| expect(checkPcbTraceLengths(exactViolationCircuitJson)).toEqual([ | ||
| expect.objectContaining({ | ||
| pcb_trace_id: "pcb_trace_exact_violation", | ||
| source_trace_id: "source_trace_exact_violation", | ||
| actual_trace_length: 7, | ||
| maximum_trace_length: 5, | ||
| }), | ||
| ]) | ||
| }) | ||
|
|
||
| test("retains one-port-to-net trace length warnings", () => { | ||
| const portToNetCircuitJson = [ | ||
| { | ||
| type: "source_trace", | ||
| source_trace_id: "source_trace_ground_drop", | ||
| connected_source_port_ids: ["source_port_c9_ground"], | ||
| connected_source_net_ids: ["source_net_ground"], | ||
| max_length: 5, | ||
| }, | ||
| makePcbPort("pcb_port_c9_ground", "source_port_c9_ground"), | ||
| makePcbPort("pcb_port_c3_ground", "source_port_c3_ground"), | ||
| makeStraightPcbTrace({ | ||
| pcbTraceId: "pcb_trace_c9_to_ground", | ||
| sourceTraceId: "source_trace_ground_drop", | ||
| startPcbPortId: "pcb_port_c9_ground", | ||
| endPcbPortId: "pcb_port_c3_ground", | ||
| length: 5.062790456754819, | ||
| }), | ||
| ] as AnyCircuitElement[] | ||
|
|
||
| expect(checkPcbTraceLengths(portToNetCircuitJson)).toEqual([ | ||
| expect.objectContaining({ | ||
| pcb_trace_id: "pcb_trace_c9_to_ground", | ||
| source_trace_id: "source_trace_ground_drop", | ||
| actual_trace_length: 5.062790456754819, | ||
| maximum_trace_length: 5, | ||
| }), | ||
| ]) | ||
| }) | ||
|
|
||
| test("keeps existing attribution when no exact endpoint route is exposed", () => { | ||
| const routeWithoutEndpointMetadata = [ | ||
| { | ||
| type: "source_trace", | ||
| source_trace_id: "source_trace_without_endpoint_metadata", | ||
| connected_source_port_ids: ["source_port_a", "source_port_b"], | ||
| connected_source_net_ids: [], | ||
| max_length: 5, | ||
| }, | ||
| makePcbPort("pcb_port_a", "source_port_a"), | ||
| makePcbPort("pcb_port_b", "source_port_b"), | ||
| { | ||
| type: "pcb_trace", | ||
| pcb_trace_id: "pcb_trace_without_endpoint_metadata", | ||
| source_trace_id: "source_trace_without_endpoint_metadata", | ||
| trace_length: 7, | ||
| route: [], | ||
| }, | ||
| ] as AnyCircuitElement[] | ||
|
|
||
| expect(checkPcbTraceLengths(routeWithoutEndpointMetadata)).toEqual([ | ||
| expect.objectContaining({ | ||
| pcb_trace_id: "pcb_trace_without_endpoint_metadata", | ||
| source_trace_id: "source_trace_without_endpoint_metadata", | ||
| actual_trace_length: 7, | ||
| maximum_trace_length: 5, | ||
| }), | ||
| ]) | ||
| }) |
Contributor
There was a problem hiding this comment.
A *.test.ts file may have AT MOST one test(...) call, but this file now contains at least 4 test(...) calls (at lines 129, 177, 215, and 245). The new tests added in this diff should be split into separate, numbered test files. For example: check-pcb-trace-lengths1.test.ts, check-pcb-trace-lengths2.test.ts, check-pcb-trace-lengths3.test.ts, check-pcb-trace-lengths4.test.ts, etc. Each file should contain exactly one test(...) call.
Suggested change
| test("ignores unrelated long MST branches when exact two-port traces are short", () => { | |
| const cases = [ | |
| { id: "charger_ground", maximum: 5, exact: 3.94, branch: 10.71 }, | |
| { id: "vdd1_decoupling", maximum: 3, exact: 1.16, branch: 6.47 }, | |
| { id: "regulator_output", maximum: 6, exact: 1.57, branch: 17.37 }, | |
| ] | |
| const multidropCircuitJson = cases.flatMap( | |
| ({ id, maximum, exact, branch }): AnyCircuitElement[] => { | |
| const sourceTraceId = `source_trace_${id}` | |
| const startSourcePortId = `source_port_${id}_start` | |
| const endSourcePortId = `source_port_${id}_end` | |
| const branchSourcePortId = `source_port_${id}_branch` | |
| const startPcbPortId = `pcb_port_${id}_start` | |
| const endPcbPortId = `pcb_port_${id}_end` | |
| const branchPcbPortId = `pcb_port_${id}_branch` | |
| return [ | |
| { | |
| type: "source_trace", | |
| source_trace_id: sourceTraceId, | |
| connected_source_port_ids: [startSourcePortId, endSourcePortId], | |
| connected_source_net_ids: [], | |
| max_length: maximum, | |
| }, | |
| makePcbPort(startPcbPortId, startSourcePortId), | |
| makePcbPort(endPcbPortId, endSourcePortId), | |
| makePcbPort(branchPcbPortId, branchSourcePortId), | |
| makeStraightPcbTrace({ | |
| pcbTraceId: `pcb_trace_${id}_exact`, | |
| sourceTraceId, | |
| startPcbPortId, | |
| endPcbPortId, | |
| length: exact, | |
| }), | |
| makeStraightPcbTrace({ | |
| pcbTraceId: `pcb_trace_${id}_unrelated_branch`, | |
| sourceTraceId, | |
| startPcbPortId, | |
| endPcbPortId: branchPcbPortId, | |
| length: branch, | |
| }), | |
| ] | |
| }, | |
| ) | |
| expect(checkPcbTraceLengths(multidropCircuitJson)).toEqual([]) | |
| }) | |
| test("retains a violation on the exact two-port PCB trace", () => { | |
| const exactViolationCircuitJson = [ | |
| { | |
| type: "source_trace", | |
| source_trace_id: "source_trace_exact_violation", | |
| connected_source_port_ids: ["source_port_a", "source_port_b"], | |
| connected_source_net_ids: [], | |
| max_length: 5, | |
| }, | |
| makePcbPort("pcb_port_a", "source_port_a"), | |
| makePcbPort("pcb_port_b", "source_port_b"), | |
| makePcbPort("pcb_port_branch", "source_port_branch"), | |
| makeStraightPcbTrace({ | |
| pcbTraceId: "pcb_trace_exact_violation", | |
| sourceTraceId: "source_trace_exact_violation", | |
| startPcbPortId: "pcb_port_a", | |
| endPcbPortId: "pcb_port_b", | |
| length: 7, | |
| }), | |
| makeStraightPcbTrace({ | |
| pcbTraceId: "pcb_trace_unrelated_long_branch", | |
| sourceTraceId: "source_trace_exact_violation", | |
| startPcbPortId: "pcb_port_a", | |
| endPcbPortId: "pcb_port_branch", | |
| length: 12, | |
| }), | |
| ] as AnyCircuitElement[] | |
| expect(checkPcbTraceLengths(exactViolationCircuitJson)).toEqual([ | |
| expect.objectContaining({ | |
| pcb_trace_id: "pcb_trace_exact_violation", | |
| source_trace_id: "source_trace_exact_violation", | |
| actual_trace_length: 7, | |
| maximum_trace_length: 5, | |
| }), | |
| ]) | |
| }) | |
| test("retains one-port-to-net trace length warnings", () => { | |
| const portToNetCircuitJson = [ | |
| { | |
| type: "source_trace", | |
| source_trace_id: "source_trace_ground_drop", | |
| connected_source_port_ids: ["source_port_c9_ground"], | |
| connected_source_net_ids: ["source_net_ground"], | |
| max_length: 5, | |
| }, | |
| makePcbPort("pcb_port_c9_ground", "source_port_c9_ground"), | |
| makePcbPort("pcb_port_c3_ground", "source_port_c3_ground"), | |
| makeStraightPcbTrace({ | |
| pcbTraceId: "pcb_trace_c9_to_ground", | |
| sourceTraceId: "source_trace_ground_drop", | |
| startPcbPortId: "pcb_port_c9_ground", | |
| endPcbPortId: "pcb_port_c3_ground", | |
| length: 5.062790456754819, | |
| }), | |
| ] as AnyCircuitElement[] | |
| expect(checkPcbTraceLengths(portToNetCircuitJson)).toEqual([ | |
| expect.objectContaining({ | |
| pcb_trace_id: "pcb_trace_c9_to_ground", | |
| source_trace_id: "source_trace_ground_drop", | |
| actual_trace_length: 5.062790456754819, | |
| maximum_trace_length: 5, | |
| }), | |
| ]) | |
| }) | |
| test("keeps existing attribution when no exact endpoint route is exposed", () => { | |
| const routeWithoutEndpointMetadata = [ | |
| { | |
| type: "source_trace", | |
| source_trace_id: "source_trace_without_endpoint_metadata", | |
| connected_source_port_ids: ["source_port_a", "source_port_b"], | |
| connected_source_net_ids: [], | |
| max_length: 5, | |
| }, | |
| makePcbPort("pcb_port_a", "source_port_a"), | |
| makePcbPort("pcb_port_b", "source_port_b"), | |
| { | |
| type: "pcb_trace", | |
| pcb_trace_id: "pcb_trace_without_endpoint_metadata", | |
| source_trace_id: "source_trace_without_endpoint_metadata", | |
| trace_length: 7, | |
| route: [], | |
| }, | |
| ] as AnyCircuitElement[] | |
| expect(checkPcbTraceLengths(routeWithoutEndpointMetadata)).toEqual([ | |
| expect.objectContaining({ | |
| pcb_trace_id: "pcb_trace_without_endpoint_metadata", | |
| source_trace_id: "source_trace_without_endpoint_metadata", | |
| actual_trace_length: 7, | |
| maximum_trace_length: 5, | |
| }), | |
| ]) | |
| }) | |
Spotted by Graphite (based on custom rule: Custom rule)
Is this helpful? React 👍 or 👎 to let us know.
Contributor
|
Thank you for your contribution! 🎉 PR Rating: ⭐⭐⭐ Track your contributions and see the leaderboard at: tscircuit Contribution Tracker |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Regression coverage
Validation
bun test tests/lib/check-pcb-trace-lengths.test.ts(6 passed)bun test(212 passed)bunx tsc --noEmitbun run buildbunx biome format lib/check-pcb-trace-lengths.ts tests/lib/check-pcb-trace-lengths.test.tsThe repository-wide format command still reports the existing Biome 1 MiB limit on three unchanged JSON fixtures; both changed files pass the formatter directly.