From b503c09b102627f21e6b818ac562af6a27b0941e Mon Sep 17 00:00:00 2001 From: ShiboSoftwareDev Date: Tue, 10 Mar 2026 00:47:53 +0200 Subject: [PATCH 1/2] Introduce checkNoPowerPinDefinedForChip --- README.md | 3 +- index.ts | 1 + lib/check-no-power-pin-defined-for-chip.ts | 63 ++++++++++++++ lib/run-all-checks.ts | 2 + ...heck-no-power-pin-defined-for-chip.test.ts | 87 +++++++++++++++++++ tests/lib/user-circuit-netlist.test.tsx | 5 +- 6 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 lib/check-no-power-pin-defined-for-chip.ts create mode 100644 tests/lib/check-no-power-pin-defined-for-chip.test.ts diff --git a/README.md b/README.md index 76c3ee8..1f3e409 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ and output an array of arrays for any issues found. | --- | --- | | [`checkConnectorAccessibleOrientation`](./lib/check-connector-accessible-orientation.ts) | Returns `pcb_accessibility_error` for connectors whose orientation makes them inaccessible. | | [`checkAllPinsInComponentAreUnderspecified`](./lib/check-all-pins-in-component-are-underspecified.ts) | Returns `source_component_pins_underspecified_warning` when every pin on a chip lacks pin attributes. | +| [`checkNoPowerPinDefinedForChip`](./lib/check-no-power-pin-defined-for-chip.ts) | Returns `source_chip_no_power_pin_defined_warning` when a chip has no pin with `requires_power=true`. | | [`checkDifferentNetViaSpacing`](./lib/check-different-net-via-spacing.ts) | Returns `pcb_via_clearance_error` if vias on different nets are too close together. | | [`checkEachPcbPortConnectedToPcbTraces`](./lib/check-each-pcb-port-connected-to-pcb-trace.ts) | Returns `pcb_trace_error` if any `source_port` is not connected to its corresponding PCB traces. | | [`checkEachPcbTraceNonOverlapping`](./lib/check-each-pcb-trace-non-overlapping/check-each-pcb-trace-non-overlapping.ts) | Returns `pcb_trace_error` when `pcb_trace` segments overlap incompatible geometry on the same layer. | @@ -28,7 +29,7 @@ and output an array of arrays for any issues found. | Function | Description | | --- | --- | | [`runAllPlacementChecks`](./lib/run-all-checks.ts) | Runs all placement checks (`checkViasOffBoard`, `checkPcbComponentsOutOfBoard`, `checkPcbComponentOverlap`, and `checkConnectorAccessibleOrientation`). | -| [`runAllNetlistChecks`](./lib/run-all-checks.ts) | Runs all netlist checks (e.g. `checkPinMustBeConnected`, `checkAllPinsInComponentAreUnderspecified`). | +| [`runAllNetlistChecks`](./lib/run-all-checks.ts) | Runs all netlist checks (e.g. `checkPinMustBeConnected`, `checkAllPinsInComponentAreUnderspecified`, `checkNoPowerPinDefinedForChip`). | | [`runAllRoutingChecks`](./lib/run-all-checks.ts) | Runs all routing checks currently enabled (`checkEachPcbPortConnectedToPcbTraces`, `checkSourceTracesHavePcbTraces`, `checkEachPcbTraceNonOverlapping`, same/different net via spacing, and `checkPcbTracesOutOfBoard`). | | [`runAllChecks`](./lib/run-all-checks.ts) | Runs all placement, netlist, and routing checks and returns a combined list of errors. | diff --git a/index.ts b/index.ts index e6f8f1d..5ab7b5c 100644 --- a/index.ts +++ b/index.ts @@ -10,6 +10,7 @@ export { checkPcbTracesOutOfBoard } from "./lib/check-trace-out-of-board/checkTr export { checkPcbComponentOverlap } from "./lib/check-pcb-components-overlap/checkPcbComponentOverlap" export { checkPinMustBeConnected } from "./lib/check-pin-must-be-connected" export { checkAllPinsInComponentAreUnderspecified } from "./lib/check-all-pins-in-component-are-underspecified" +export { checkNoPowerPinDefinedForChip } from "./lib/check-no-power-pin-defined-for-chip" export { runAllChecks, runAllNetlistChecks, diff --git a/lib/check-no-power-pin-defined-for-chip.ts b/lib/check-no-power-pin-defined-for-chip.ts new file mode 100644 index 0000000..b640254 --- /dev/null +++ b/lib/check-no-power-pin-defined-for-chip.ts @@ -0,0 +1,63 @@ +import { cju } from "@tscircuit/circuit-json-util" +import type { + AnyCircuitElement, + SourceComponentBase, + SourcePort, +} from "circuit-json" + +type SourceChipNoPowerPinDefinedWarning = { + type: "source_chip_no_power_pin_defined_warning" + source_chip_no_power_pin_defined_warning_id: string + warning_type: "source_chip_no_power_pin_defined_warning" + message: string + source_component_id: string + source_port_ids: string[] + subcircuit_id?: string +} + +/** + * Check that each chip has at least one pin marked as requires_power=true. + * Returns warnings for chips where no pin declares requires_power. + */ +export function checkNoPowerPinDefinedForChip( + circuitJson: AnyCircuitElement[], +): SourceChipNoPowerPinDefinedWarning[] { + const warnings: SourceChipNoPowerPinDefinedWarning[] = [] + const db = cju(circuitJson) + + const sourceComponents = db.source_component.list() as SourceComponentBase[] + const sourcePorts = db.source_port.list() as SourcePort[] + + const portsByComponent = new Map() + for (const port of sourcePorts) { + if (!port.source_component_id) continue + const existing = portsByComponent.get(port.source_component_id) ?? [] + existing.push(port) + portsByComponent.set(port.source_component_id, existing) + } + + for (const component of sourceComponents) { + if (component.ftype !== "simple_chip") continue + + const componentPorts = + portsByComponent.get(component.source_component_id) ?? [] + if (componentPorts.length === 0) continue + + const hasRequiredPowerPin = componentPorts.some( + (port) => port.requires_power === true, + ) + if (hasRequiredPowerPin) continue + + warnings.push({ + type: "source_chip_no_power_pin_defined_warning", + source_chip_no_power_pin_defined_warning_id: `source_chip_no_power_pin_defined_warning_${component.source_component_id}`, + warning_type: "source_chip_no_power_pin_defined_warning", + message: `${component.name} has no pin with requires_power=true`, + source_component_id: component.source_component_id, + source_port_ids: componentPorts.map((port) => port.source_port_id), + subcircuit_id: componentPorts[0]?.subcircuit_id, + }) + } + + return warnings +} diff --git a/lib/run-all-checks.ts b/lib/run-all-checks.ts index 7e2898b..a4734ec 100644 --- a/lib/run-all-checks.ts +++ b/lib/run-all-checks.ts @@ -8,6 +8,7 @@ import { checkViasOffBoard } from "./check-pcb-components-out-of-board/checkVias import { checkPcbComponentOverlap } from "./check-pcb-components-overlap/checkPcbComponentOverlap" import { checkConnectorAccessibleOrientation } from "./check-connector-accessible-orientation" import { checkPinMustBeConnected } from "./check-pin-must-be-connected" +import { checkNoPowerPinDefinedForChip } from "./check-no-power-pin-defined-for-chip" import { checkSameNetViaSpacing } from "./check-same-net-via-spacing" import { checkSourceTracesHavePcbTraces } from "./check-source-traces-have-pcb-traces" import { checkPcbTracesOutOfBoard } from "./check-trace-out-of-board/checkTraceOutOfBoard" @@ -26,6 +27,7 @@ export async function runAllNetlistChecks(circuitJson: AnyCircuitElement[]) { return [ ...checkPinMustBeConnected(circuitJson), ...checkAllPinsInComponentAreUnderspecified(circuitJson), + ...checkNoPowerPinDefinedForChip(circuitJson), ] } diff --git a/tests/lib/check-no-power-pin-defined-for-chip.test.ts b/tests/lib/check-no-power-pin-defined-for-chip.test.ts new file mode 100644 index 0000000..096c08b --- /dev/null +++ b/tests/lib/check-no-power-pin-defined-for-chip.test.ts @@ -0,0 +1,87 @@ +import { describe, expect, test } from "bun:test" +import type { AnyCircuitElement } from "circuit-json" +import { checkNoPowerPinDefinedForChip } from "lib/check-no-power-pin-defined-for-chip" + +describe("checkNoPowerPinDefinedForChip", () => { + test("returns warning when chip has no requires_power pin", () => { + const circuitJson: AnyCircuitElement[] = [ + { + type: "source_component", + source_component_id: "component_1", + name: "U1", + ftype: "simple_chip", + }, + { + type: "source_port", + source_port_id: "port_1", + source_component_id: "component_1", + name: "IO1", + }, + { + type: "source_port", + source_port_id: "port_2", + source_component_id: "component_1", + name: "IO2", + }, + ] + + const warnings = checkNoPowerPinDefinedForChip(circuitJson) + expect(warnings).toHaveLength(1) + expect(warnings[0].type).toBe("source_chip_no_power_pin_defined_warning") + expect(warnings[0].source_component_id).toBe("component_1") + }) + + test("returns no warning when at least one pin has requires_power=true", () => { + const circuitJson: AnyCircuitElement[] = [ + { + type: "source_component", + source_component_id: "component_1", + name: "U1", + ftype: "simple_chip", + }, + { + type: "source_port", + source_port_id: "port_1", + source_component_id: "component_1", + name: "VCC", + requires_power: true, + }, + { + type: "source_port", + source_port_id: "port_2", + source_component_id: "component_1", + name: "IO2", + }, + ] + + const warnings = checkNoPowerPinDefinedForChip(circuitJson) + expect(warnings).toHaveLength(0) + }) + + test("ignores non-chip components", () => { + const circuitJson: AnyCircuitElement[] = [ + { + type: "source_component", + source_component_id: "component_1", + name: "R1", + ftype: "simple_resistor", + resistance: 1000, + }, + { + type: "source_port", + source_port_id: "port_1", + source_component_id: "component_1", + name: "pos", + }, + { + type: "source_port", + source_port_id: "port_2", + source_component_id: "component_1", + name: "neg", + }, + ] + + const warnings = checkNoPowerPinDefinedForChip(circuitJson) + expect(warnings).toHaveLength(0) + }) +}) diff --git a/tests/lib/user-circuit-netlist.test.tsx b/tests/lib/user-circuit-netlist.test.tsx index 3716b5d..920cd69 100644 --- a/tests/lib/user-circuit-netlist.test.tsx +++ b/tests/lib/user-circuit-netlist.test.tsx @@ -65,6 +65,8 @@ test("test.tsx builds and has no netlist errors", async () => { name="USBC" pinAttributes={{ GND1: { mustBeConnected: false }, + VBUS1: { requiresPower: true }, + A4: { requiresPower: true }, }} connections={{ GND1: "net.GND", @@ -90,6 +92,7 @@ test("test.tsx builds and has no netlist errors", async () => { const circuitJson = circuit.getCircuitJson() - const netlistErrors = await runAllNetlistChecks(circuitJson as any) + const netlistIssues = await runAllNetlistChecks(circuitJson) + const netlistErrors = netlistIssues.filter((issue) => "error_type" in issue) expect(netlistErrors).toEqual([]) }) From 06c943e4eb9db0ade99f9f49ddacab7db101346b Mon Sep 17 00:00:00 2001 From: ShiboSoftwareDev Date: Tue, 10 Mar 2026 23:59:08 +0200 Subject: [PATCH 2/2] refactor --- README.md | 8 +- index.ts | 4 +- ...ll-pins-in-component-are-underspecified.ts | 11 +-- lib/check-no-ground-pin-defined.ts | 54 +++++++++++ ...-chip.ts => check-no-power-pin-defined.ts} | 23 ++--- lib/run-all-checks.ts | 14 ++- package.json | 2 +- tests/lib/check-no-ground-pin-defined.test.ts | 90 +++++++++++++++++++ ....ts => check-no-power-pin-defined.test.ts} | 13 +-- tests/lib/run-all-checks.test.ts | 5 +- 10 files changed, 183 insertions(+), 41 deletions(-) create mode 100644 lib/check-no-ground-pin-defined.ts rename lib/{check-no-power-pin-defined-for-chip.ts => check-no-power-pin-defined.ts} (67%) create mode 100644 tests/lib/check-no-ground-pin-defined.test.ts rename tests/lib/{check-no-power-pin-defined-for-chip.test.ts => check-no-power-pin-defined.test.ts} (82%) diff --git a/README.md b/README.md index 1f3e409..f3fafbb 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ and output an array of arrays for any issues found. | --- | --- | | [`checkConnectorAccessibleOrientation`](./lib/check-connector-accessible-orientation.ts) | Returns `pcb_accessibility_error` for connectors whose orientation makes them inaccessible. | | [`checkAllPinsInComponentAreUnderspecified`](./lib/check-all-pins-in-component-are-underspecified.ts) | Returns `source_component_pins_underspecified_warning` when every pin on a chip lacks pin attributes. | -| [`checkNoPowerPinDefinedForChip`](./lib/check-no-power-pin-defined-for-chip.ts) | Returns `source_chip_no_power_pin_defined_warning` when a chip has no pin with `requires_power=true`. | +| [`checkNoPowerPinDefined`](./lib/check-no-power-pin-defined.ts) | Returns `source_no_power_pin_defined_warning` when a chip has no pin with `requires_power=true`. | +| [`checkNoGroundPinDefined`](./lib/check-no-ground-pin-defined.ts) | Returns `source_no_ground_pin_defined_warning` when a chip has no pin with `requires_ground=true`. | | [`checkDifferentNetViaSpacing`](./lib/check-different-net-via-spacing.ts) | Returns `pcb_via_clearance_error` if vias on different nets are too close together. | | [`checkEachPcbPortConnectedToPcbTraces`](./lib/check-each-pcb-port-connected-to-pcb-trace.ts) | Returns `pcb_trace_error` if any `source_port` is not connected to its corresponding PCB traces. | | [`checkEachPcbTraceNonOverlapping`](./lib/check-each-pcb-trace-non-overlapping/check-each-pcb-trace-non-overlapping.ts) | Returns `pcb_trace_error` when `pcb_trace` segments overlap incompatible geometry on the same layer. | @@ -29,9 +30,10 @@ and output an array of arrays for any issues found. | Function | Description | | --- | --- | | [`runAllPlacementChecks`](./lib/run-all-checks.ts) | Runs all placement checks (`checkViasOffBoard`, `checkPcbComponentsOutOfBoard`, `checkPcbComponentOverlap`, and `checkConnectorAccessibleOrientation`). | -| [`runAllNetlistChecks`](./lib/run-all-checks.ts) | Runs all netlist checks (e.g. `checkPinMustBeConnected`, `checkAllPinsInComponentAreUnderspecified`, `checkNoPowerPinDefinedForChip`). | +| [`runAllNetlistChecks`](./lib/run-all-checks.ts) | Runs netlist connectivity checks (currently `checkPinMustBeConnected`). | +| [`runAllPinSpecificationChecks`](./lib/run-all-checks.ts) | Runs pin specification checks (e.g. `checkAllPinsInComponentAreUnderspecified`, `checkNoPowerPinDefined`, and `checkNoGroundPinDefined`). | | [`runAllRoutingChecks`](./lib/run-all-checks.ts) | Runs all routing checks currently enabled (`checkEachPcbPortConnectedToPcbTraces`, `checkSourceTracesHavePcbTraces`, `checkEachPcbTraceNonOverlapping`, same/different net via spacing, and `checkPcbTracesOutOfBoard`). | -| [`runAllChecks`](./lib/run-all-checks.ts) | Runs all placement, netlist, and routing checks and returns a combined list of errors. | +| [`runAllChecks`](./lib/run-all-checks.ts) | Runs placement, netlist, pin specification, and routing checks and returns a combined list of issues. | ## Implementation Details diff --git a/index.ts b/index.ts index 5ab7b5c..d616603 100644 --- a/index.ts +++ b/index.ts @@ -10,10 +10,12 @@ export { checkPcbTracesOutOfBoard } from "./lib/check-trace-out-of-board/checkTr export { checkPcbComponentOverlap } from "./lib/check-pcb-components-overlap/checkPcbComponentOverlap" export { checkPinMustBeConnected } from "./lib/check-pin-must-be-connected" export { checkAllPinsInComponentAreUnderspecified } from "./lib/check-all-pins-in-component-are-underspecified" -export { checkNoPowerPinDefinedForChip } from "./lib/check-no-power-pin-defined-for-chip" +export { checkNoPowerPinDefined } from "./lib/check-no-power-pin-defined" +export { checkNoGroundPinDefined } from "./lib/check-no-ground-pin-defined" export { runAllChecks, runAllNetlistChecks, + runAllPinSpecificationChecks, runAllPlacementChecks, runAllRoutingChecks, } from "./lib/run-all-checks" diff --git a/lib/check-all-pins-in-component-are-underspecified.ts b/lib/check-all-pins-in-component-are-underspecified.ts index 48e08c0..57e2f53 100644 --- a/lib/check-all-pins-in-component-are-underspecified.ts +++ b/lib/check-all-pins-in-component-are-underspecified.ts @@ -1,22 +1,13 @@ import { cju } from "@tscircuit/circuit-json-util" import type { AnyCircuitElement, + SourceComponentPinsUnderspecifiedWarning, SourcePinAttributes, SourcePort, SourceComponentBase, } from "circuit-json" import { source_pin_attributes } from "circuit-json" -type SourceComponentPinsUnderspecifiedWarning = { - type: "source_component_pins_underspecified_warning" - source_component_pins_underspecified_warning_id: string - warning_type: "source_component_pins_underspecified_warning" - message: string - source_component_id: string - source_port_ids: string[] - subcircuit_id?: string -} - const PIN_ATTRIBUTE_KEYS = Object.keys( source_pin_attributes.shape, ) as (keyof SourcePinAttributes)[] diff --git a/lib/check-no-ground-pin-defined.ts b/lib/check-no-ground-pin-defined.ts new file mode 100644 index 0000000..d57fb68 --- /dev/null +++ b/lib/check-no-ground-pin-defined.ts @@ -0,0 +1,54 @@ +import { cju } from "@tscircuit/circuit-json-util" +import type { + AnyCircuitElement, + SourceComponentBase, + SourceNoGroundPinDefinedWarning, + SourcePort, +} from "circuit-json" + +/** + * Check that each chip has at least one pin marked as requires_ground=true. + * Returns warnings for chips where no pin declares requires_ground. + */ +export function checkNoGroundPinDefined( + circuitJson: AnyCircuitElement[], +): SourceNoGroundPinDefinedWarning[] { + const warnings: SourceNoGroundPinDefinedWarning[] = [] + const db = cju(circuitJson) + + const sourceComponents = db.source_component.list() as SourceComponentBase[] + const sourcePorts = db.source_port.list() as SourcePort[] + + const portsByComponent = new Map() + for (const port of sourcePorts) { + if (!port.source_component_id) continue + const existing = portsByComponent.get(port.source_component_id) ?? [] + existing.push(port) + portsByComponent.set(port.source_component_id, existing) + } + + for (const component of sourceComponents) { + if (component.ftype !== "simple_chip") continue + + const componentPorts = + portsByComponent.get(component.source_component_id) ?? [] + if (componentPorts.length === 0) continue + + const hasRequiredGroundPin = componentPorts.some( + (port) => port.requires_ground === true, + ) + if (hasRequiredGroundPin) continue + + warnings.push({ + type: "source_no_ground_pin_defined_warning", + source_no_ground_pin_defined_warning_id: `source_no_ground_pin_defined_warning_${component.source_component_id}`, + warning_type: "source_no_ground_pin_defined_warning", + message: `${component.name} has no pin with requires_ground=true`, + source_component_id: component.source_component_id, + source_port_ids: componentPorts.map((port) => port.source_port_id), + subcircuit_id: componentPorts[0]?.subcircuit_id, + }) + } + + return warnings +} diff --git a/lib/check-no-power-pin-defined-for-chip.ts b/lib/check-no-power-pin-defined.ts similarity index 67% rename from lib/check-no-power-pin-defined-for-chip.ts rename to lib/check-no-power-pin-defined.ts index b640254..04e54ec 100644 --- a/lib/check-no-power-pin-defined-for-chip.ts +++ b/lib/check-no-power-pin-defined.ts @@ -2,27 +2,18 @@ import { cju } from "@tscircuit/circuit-json-util" import type { AnyCircuitElement, SourceComponentBase, + SourceNoPowerPinDefinedWarning, SourcePort, } from "circuit-json" -type SourceChipNoPowerPinDefinedWarning = { - type: "source_chip_no_power_pin_defined_warning" - source_chip_no_power_pin_defined_warning_id: string - warning_type: "source_chip_no_power_pin_defined_warning" - message: string - source_component_id: string - source_port_ids: string[] - subcircuit_id?: string -} - /** * Check that each chip has at least one pin marked as requires_power=true. * Returns warnings for chips where no pin declares requires_power. */ -export function checkNoPowerPinDefinedForChip( +export function checkNoPowerPinDefined( circuitJson: AnyCircuitElement[], -): SourceChipNoPowerPinDefinedWarning[] { - const warnings: SourceChipNoPowerPinDefinedWarning[] = [] +): SourceNoPowerPinDefinedWarning[] { + const warnings: SourceNoPowerPinDefinedWarning[] = [] const db = cju(circuitJson) const sourceComponents = db.source_component.list() as SourceComponentBase[] @@ -49,9 +40,9 @@ export function checkNoPowerPinDefinedForChip( if (hasRequiredPowerPin) continue warnings.push({ - type: "source_chip_no_power_pin_defined_warning", - source_chip_no_power_pin_defined_warning_id: `source_chip_no_power_pin_defined_warning_${component.source_component_id}`, - warning_type: "source_chip_no_power_pin_defined_warning", + type: "source_no_power_pin_defined_warning", + source_no_power_pin_defined_warning_id: `source_no_power_pin_defined_warning_${component.source_component_id}`, + warning_type: "source_no_power_pin_defined_warning", message: `${component.name} has no pin with requires_power=true`, source_component_id: component.source_component_id, source_port_ids: componentPorts.map((port) => port.source_port_id), diff --git a/lib/run-all-checks.ts b/lib/run-all-checks.ts index a4734ec..a1d0a14 100644 --- a/lib/run-all-checks.ts +++ b/lib/run-all-checks.ts @@ -8,7 +8,8 @@ import { checkViasOffBoard } from "./check-pcb-components-out-of-board/checkVias import { checkPcbComponentOverlap } from "./check-pcb-components-overlap/checkPcbComponentOverlap" import { checkConnectorAccessibleOrientation } from "./check-connector-accessible-orientation" import { checkPinMustBeConnected } from "./check-pin-must-be-connected" -import { checkNoPowerPinDefinedForChip } from "./check-no-power-pin-defined-for-chip" +import { checkNoGroundPinDefined } from "./check-no-ground-pin-defined" +import { checkNoPowerPinDefined } from "./check-no-power-pin-defined" import { checkSameNetViaSpacing } from "./check-same-net-via-spacing" import { checkSourceTracesHavePcbTraces } from "./check-source-traces-have-pcb-traces" import { checkPcbTracesOutOfBoard } from "./check-trace-out-of-board/checkTraceOutOfBoard" @@ -24,10 +25,16 @@ export async function runAllPlacementChecks(circuitJson: AnyCircuitElement[]) { } export async function runAllNetlistChecks(circuitJson: AnyCircuitElement[]) { + return [...checkPinMustBeConnected(circuitJson)] +} + +export async function runAllPinSpecificationChecks( + circuitJson: AnyCircuitElement[], +) { return [ - ...checkPinMustBeConnected(circuitJson), ...checkAllPinsInComponentAreUnderspecified(circuitJson), - ...checkNoPowerPinDefinedForChip(circuitJson), + ...checkNoPowerPinDefined(circuitJson), + ...checkNoGroundPinDefined(circuitJson), ] } @@ -47,6 +54,7 @@ export async function runAllChecks(circuitJson: AnyCircuitElement[]) { return [ ...(await runAllPlacementChecks(circuitJson)), ...(await runAllNetlistChecks(circuitJson)), + ...(await runAllPinSpecificationChecks(circuitJson)), ...(await runAllRoutingChecks(circuitJson)), ] } diff --git a/package.json b/package.json index 0af3cac..335907c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "@types/debug": "^4.1.12", "bun-match-svg": "^0.0.11", "circuit-to-svg": "^0.0.333", - "circuit-json": "^0.0.392", + "circuit-json": "^0.0.395", "debug": "^4.3.5", "tscircuit": "^0.0.1439", "zod": "^3.23.8", diff --git a/tests/lib/check-no-ground-pin-defined.test.ts b/tests/lib/check-no-ground-pin-defined.test.ts new file mode 100644 index 0000000..24f6a7c --- /dev/null +++ b/tests/lib/check-no-ground-pin-defined.test.ts @@ -0,0 +1,90 @@ +import { describe, expect, test } from "bun:test" +import type { AnyCircuitElement } from "circuit-json" +import { checkNoGroundPinDefined } from "lib/check-no-ground-pin-defined" + +describe("checkNoGroundPinDefined", () => { + test("returns warning when chip has no requires_ground pin", () => { + const circuitJson: AnyCircuitElement[] = [ + { + type: "source_component", + source_component_id: "component_1", + name: "U1", + ftype: "simple_chip", + }, + { + type: "source_port", + source_port_id: "port_1", + source_component_id: "component_1", + name: "IO1", + }, + { + type: "source_port", + source_port_id: "port_2", + source_component_id: "component_1", + name: "IO2", + }, + ] + + const warnings = checkNoGroundPinDefined(circuitJson) + expect(warnings).toHaveLength(1) + expect(warnings[0].type).toBe("source_no_ground_pin_defined_warning") + expect(warnings[0].warning_type).toBe( + "source_no_ground_pin_defined_warning", + ) + expect(warnings[0].source_component_id).toBe("component_1") + }) + + test("returns no warning when at least one pin has requires_ground=true", () => { + const circuitJson: AnyCircuitElement[] = [ + { + type: "source_component", + source_component_id: "component_1", + name: "U1", + ftype: "simple_chip", + }, + { + type: "source_port", + source_port_id: "port_1", + source_component_id: "component_1", + name: "GND", + requires_ground: true, + }, + { + type: "source_port", + source_port_id: "port_2", + source_component_id: "component_1", + name: "IO2", + }, + ] + + const warnings = checkNoGroundPinDefined(circuitJson) + expect(warnings).toHaveLength(0) + }) + + test("ignores non-chip components", () => { + const circuitJson: AnyCircuitElement[] = [ + { + type: "source_component", + source_component_id: "component_1", + name: "R1", + ftype: "simple_resistor", + resistance: 1000, + }, + { + type: "source_port", + source_port_id: "port_1", + source_component_id: "component_1", + name: "pos", + }, + { + type: "source_port", + source_port_id: "port_2", + source_component_id: "component_1", + name: "neg", + }, + ] + + const warnings = checkNoGroundPinDefined(circuitJson) + expect(warnings).toHaveLength(0) + }) +}) diff --git a/tests/lib/check-no-power-pin-defined-for-chip.test.ts b/tests/lib/check-no-power-pin-defined.test.ts similarity index 82% rename from tests/lib/check-no-power-pin-defined-for-chip.test.ts rename to tests/lib/check-no-power-pin-defined.test.ts index 096c08b..de50abb 100644 --- a/tests/lib/check-no-power-pin-defined-for-chip.test.ts +++ b/tests/lib/check-no-power-pin-defined.test.ts @@ -1,8 +1,8 @@ import { describe, expect, test } from "bun:test" import type { AnyCircuitElement } from "circuit-json" -import { checkNoPowerPinDefinedForChip } from "lib/check-no-power-pin-defined-for-chip" +import { checkNoPowerPinDefined } from "lib/check-no-power-pin-defined" -describe("checkNoPowerPinDefinedForChip", () => { +describe("checkNoPowerPinDefined", () => { test("returns warning when chip has no requires_power pin", () => { const circuitJson: AnyCircuitElement[] = [ { @@ -25,9 +25,10 @@ describe("checkNoPowerPinDefinedForChip", () => { }, ] - const warnings = checkNoPowerPinDefinedForChip(circuitJson) + const warnings = checkNoPowerPinDefined(circuitJson) expect(warnings).toHaveLength(1) - expect(warnings[0].type).toBe("source_chip_no_power_pin_defined_warning") + expect(warnings[0].type).toBe("source_no_power_pin_defined_warning") + expect(warnings[0].warning_type).toBe("source_no_power_pin_defined_warning") expect(warnings[0].source_component_id).toBe("component_1") }) @@ -54,7 +55,7 @@ describe("checkNoPowerPinDefinedForChip", () => { }, ] - const warnings = checkNoPowerPinDefinedForChip(circuitJson) + const warnings = checkNoPowerPinDefined(circuitJson) expect(warnings).toHaveLength(0) }) @@ -81,7 +82,7 @@ describe("checkNoPowerPinDefinedForChip", () => { }, ] - const warnings = checkNoPowerPinDefinedForChip(circuitJson) + const warnings = checkNoPowerPinDefined(circuitJson) expect(warnings).toHaveLength(0) }) }) diff --git a/tests/lib/run-all-checks.test.ts b/tests/lib/run-all-checks.test.ts index 7f9b2dc..233a8d6 100644 --- a/tests/lib/run-all-checks.test.ts +++ b/tests/lib/run-all-checks.test.ts @@ -2,6 +2,7 @@ import { expect, test } from "bun:test" import { runAllChecks, runAllNetlistChecks, + runAllPinSpecificationChecks, runAllPlacementChecks, runAllRoutingChecks, } from "../.." // index.ts when imported from root @@ -82,7 +83,7 @@ test("runAllNetlistChecks excludes routing-only pcb trace connectivity checks", expect(netlistErrors).toEqual([]) expect(routingErrors.length).toBeGreaterThan(0) }) -test("runAllChecks equals placement + netlist + routing checks", async () => { +test("runAllChecks equals placement + netlist + pin specification + routing checks", async () => { const circuitJson: AnyCircuitElement[] = [ { type: "pcb_board", @@ -158,11 +159,13 @@ test("runAllChecks equals placement + netlist + routing checks", async () => { const allChecksErrors = await runAllChecks(circuitJson) const placementErrors = await runAllPlacementChecks(circuitJson) const netlistErrors = await runAllNetlistChecks(circuitJson) + const pinSpecificationErrors = await runAllPinSpecificationChecks(circuitJson) const routingErrors = await runAllRoutingChecks(circuitJson) expect(allChecksErrors).toEqual([ ...placementErrors, ...netlistErrors, + ...pinSpecificationErrors, ...routingErrors, ]) })