From 7696e756bffb0f48391cd12a5a7af2770596d118 Mon Sep 17 00:00:00 2001 From: TheoKremer Date: Sat, 30 May 2026 17:29:43 -0700 Subject: [PATCH] Fix readable labels for numbered pins --- lib/convertCircuitJsonToReadableNetlist.ts | 10 ++- lib/scorePhrase.ts | 15 ++-- tests/test4-pin-label-quality.test.tsx | 85 ++++++++++++++++++++++ 3 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 tests/test4-pin-label-quality.test.tsx diff --git a/lib/convertCircuitJsonToReadableNetlist.ts b/lib/convertCircuitJsonToReadableNetlist.ts index 0994dc9..c8fb12c 100644 --- a/lib/convertCircuitJsonToReadableNetlist.ts +++ b/lib/convertCircuitJsonToReadableNetlist.ts @@ -145,9 +145,15 @@ export const convertCircuitJsonToReadableNetlist = ( const footprint = cadComponent?.footprinter_string let header = component.name if (component.ftype === "simple_resistor") { - header = `${component.name} (${component.display_resistance} ${footprint})` + const details = [component.display_resistance, footprint] + .filter(Boolean) + .join(" ") + header = details ? `${component.name} (${details})` : component.name } else if (component.ftype === "simple_capacitor") { - header = `${component.name} (${component.display_capacitance} ${footprint})` + const details = [component.display_capacitance, footprint] + .filter(Boolean) + .join(" ") + header = details ? `${component.name} (${details})` : component.name } else if (component.manufacturer_part_number) { header = `${component.name} (${component.manufacturer_part_number})` } diff --git a/lib/scorePhrase.ts b/lib/scorePhrase.ts index 8c90244..5870fce 100644 --- a/lib/scorePhrase.ts +++ b/lib/scorePhrase.ts @@ -31,18 +31,19 @@ const wordQualityScore = { right: 0.3, } -const wordQualityScoreEntries = Object.entries(wordQualityScore).sort( - (a, b) => b[1] - a[1], -) +const wordQualityScoreEntries = Object.entries(wordQualityScore) + .map(([word, score]) => [word.toLowerCase(), score] as const) + .sort((a, b) => b[1] - a[1]) export const scorePhrase = (phrase: string) => { - if (phrase.match(/\d+/)) { - return 0.5 - } + const lowerPhrase = phrase.toLowerCase() for (const [word, score] of wordQualityScoreEntries) { - if (phrase.includes(word)) { + if (lowerPhrase.includes(word)) { return score } } + if (phrase.match(/\d+/)) { + return 0.5 + } return 1 } diff --git a/tests/test4-pin-label-quality.test.tsx b/tests/test4-pin-label-quality.test.tsx new file mode 100644 index 0000000..1bf96d2 --- /dev/null +++ b/tests/test4-pin-label-quality.test.tsx @@ -0,0 +1,85 @@ +import { expect, it } from "bun:test" +import { convertCircuitJsonToReadableNetlist } from "lib/convertCircuitJsonToReadableNetlist" +import { scorePhrase } from "lib/scorePhrase" +import { renderCircuit } from "tests/fixtures/render-circuit" + +declare module "bun:test" { + interface Matchers { + toMatchInlineSnapshot(snapshot?: string | null): Promise + } +} + +it("scores known digit-bearing pin labels above generic numbered labels", () => { + expect(scorePhrase("pin14")).toBe(0.5) + expect(scorePhrase("GPIO14")).toBeGreaterThan(scorePhrase("pin14")) + expect(scorePhrase("UART_TX1")).toBeGreaterThan(scorePhrase("pin14")) +}) + +it("keeps descriptive numbered chip pin hints in generated net names", () => { + const circuitJson = renderCircuit( + + + + + , + ) + + expect( + convertCircuitJsonToReadableNetlist(circuitJson), + ).toMatchInlineSnapshot(` + "COMPONENTS: + - U1: RP2040, soic16 + - R1: 1kΩ 0402 resistor + + NET: U1_UART_TX1 + - U1 GPIO14 (UART_TX1) + - R1 pin1 + + + COMPONENT_PINS: + U1 (RP2040) + - pin1: NOT_CONNECTED + - pin2: NOT_CONNECTED + - pin3: NOT_CONNECTED + - pin4: NOT_CONNECTED + - pin5: NOT_CONNECTED + - pin6: NOT_CONNECTED + - pin7: NOT_CONNECTED + - pin8: NOT_CONNECTED + - pin9: NOT_CONNECTED + - pin10: NOT_CONNECTED + - pin11: NOT_CONNECTED + - pin12: NOT_CONNECTED + - pin13: NOT_CONNECTED + - pin14(GPIO14, UART_TX1): NETS(U1_UART_TX1) + - pin15(GPIO15, UART_RX1): NOT_CONNECTED + - pin16: NOT_CONNECTED + + R1 (1kΩ 0402) + - pin1(anode, pos, left): NETS(U1_UART_TX1) + - pin2(cathode, neg, right): NOT_CONNECTED + " + `) +}) + +it("does not print undefined in passive pin headers when footprint data is missing", () => { + const circuitJson = renderCircuit( + + + + , + ) + + const netlist = convertCircuitJsonToReadableNetlist(circuitJson) + expect(netlist).not.toContain("undefined") + expect(netlist).toContain("R1 (1kΩ)") + expect(netlist).toContain("C1 (1nF)") +})