diff --git a/src/fn/bga.ts b/src/fn/bga.ts index 8a712184..f354e890 100644 --- a/src/fn/bga.ts +++ b/src/fn/bga.ts @@ -55,7 +55,7 @@ export const bga_def = base_def const m = s.match(/([A-Z]+)(\d+)/) if (!m) return s const Y = ALPHABET.indexOf(m[1]!) - const X = Number.parseInt(m[2]!) - 1 + const X = Number.parseInt(m[2]!, 10) - 1 return Y * a.grid!.x + X + 1 }) } diff --git a/src/fn/sot23.ts b/src/fn/sot23.ts index d8852d98..9cdf1c21 100644 --- a/src/fn/sot23.ts +++ b/src/fn/sot23.ts @@ -106,7 +106,7 @@ export const sot23_3 = (parameters: z.infer) => { } const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, - Number.parseInt(parameters.h), + Number.parseFloat(parameters.h), 0.3, ) diff --git a/src/fn/sot23w.ts b/src/fn/sot23w.ts index 042aad3b..595d3c50 100644 --- a/src/fn/sot23w.ts +++ b/src/fn/sot23w.ts @@ -23,7 +23,7 @@ export const sot23w = ( raw_params: z.input, ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const match = raw_params.string?.match(/^sot23w_(\d+)/) - const numPins = match ? Number.parseInt(match[1]!, 3) : 3 + const numPins = match ? Number.parseInt(match[1]!, 10) : 3 const parameters = sot23w_def.parse({ ...raw_params, @@ -85,7 +85,7 @@ export const sot23w_3 = (parameters: z.infer) => { const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, - Number.parseInt(parameters.h) / 2 + 1, + Number.parseFloat(parameters.h) / 2 + 1, 0.3, ) diff --git a/src/fn/sot323.ts b/src/fn/sot323.ts index 07dd32d8..d5cb833a 100644 --- a/src/fn/sot323.ts +++ b/src/fn/sot323.ts @@ -23,7 +23,7 @@ export const sot323 = ( raw_params: z.input, ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const match = raw_params.string?.match(/^sot323_(\d+)/) - const numPins = match ? Number.parseInt(match[1]!, 3) : 3 + const numPins = match ? Number.parseInt(match[1]!, 10) : 3 const parameters = sot323_def.parse({ ...raw_params, @@ -85,7 +85,7 @@ export const sot323_3 = (parameters: z.infer) => { const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, - Number.parseInt(parameters.h) / 2 + 1, + Number.parseFloat(parameters.h) / 2 + 1, 0.3, ) diff --git a/src/fn/sot343.ts b/src/fn/sot343.ts index b151f300..9e0754b8 100644 --- a/src/fn/sot343.ts +++ b/src/fn/sot343.ts @@ -23,7 +23,7 @@ export const sot343 = ( raw_params: z.input, ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const match = raw_params.string?.match(/^sot343_(\d+)/) - const numPins = match ? Number.parseInt(match[1]!, 4) : 4 + const numPins = match ? Number.parseInt(match[1]!, 10) : 4 const parameters = sot343_def.parse({ ...raw_params, diff --git a/src/fn/to220.ts b/src/fn/to220.ts index 8c2c4f5e..338802a1 100644 --- a/src/fn/to220.ts +++ b/src/fn/to220.ts @@ -30,7 +30,7 @@ export const to220 = ( const numPins = parameters.num_pins ?? - Number.parseInt(string?.match(/^to220(?:_|-)(\d+)/i)?.[1] ?? "3") + Number.parseInt(string?.match(/^to220(?:_|-)(\d+)/i)?.[1] ?? "3", 10) const holeY = -1 const halfWidth = w / 2 diff --git a/src/fn/to220f.ts b/src/fn/to220f.ts index 67320ea4..06c79372 100644 --- a/src/fn/to220f.ts +++ b/src/fn/to220f.ts @@ -33,6 +33,7 @@ export const to220f = ( parameters.num_pins ?? Number.parseInt( parameters.string?.match(/^to220f(?:_|-)(\d+)/i)?.[1] ?? "3", + 10, ) // Get silkscreen and other non-hole elements from to220 diff --git a/tests/__snapshots__/sot23.snap.svg b/tests/__snapshots__/sot23.snap.svg index cf519eb8..38dc48ce 100644 --- a/tests/__snapshots__/sot23.snap.svg +++ b/tests/__snapshots__/sot23.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sot23_3.snap.svg b/tests/__snapshots__/sot23_3.snap.svg index cf519eb8..38dc48ce 100644 --- a/tests/__snapshots__/sot23_3.snap.svg +++ b/tests/__snapshots__/sot23_3.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sot23_w3_h1.5_p0.95mm.snap.svg b/tests/__snapshots__/sot23_w3_h1.5_p0.95mm.snap.svg index 2a0692ed..e0e0c7ec 100644 --- a/tests/__snapshots__/sot23_w3_h1.5_p0.95mm.snap.svg +++ b/tests/__snapshots__/sot23_w3_h1.5_p0.95mm.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sot23w.snap.svg b/tests/__snapshots__/sot23w.snap.svg index 3f1547d5..373a8786 100644 --- a/tests/__snapshots__/sot23w.snap.svg +++ b/tests/__snapshots__/sot23w.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sot23w_p2_w5.1_h5.2.snap.svg b/tests/__snapshots__/sot23w_p2_w5.1_h5.2.snap.svg index 9f215345..403c53ce 100644 --- a/tests/__snapshots__/sot23w_p2_w5.1_h5.2.snap.svg +++ b/tests/__snapshots__/sot23w_p2_w5.1_h5.2.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sot25.snap.svg b/tests/__snapshots__/sot25.snap.svg new file mode 100644 index 00000000..623423fc --- /dev/null +++ b/tests/__snapshots__/sot25.snap.svg @@ -0,0 +1 @@ +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sot323.snap.svg b/tests/__snapshots__/sot323.snap.svg index 7090a4d3..cb526a6c 100644 --- a/tests/__snapshots__/sot323.snap.svg +++ b/tests/__snapshots__/sot323.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sot23.snap.svg b/tests/kicad-parity/__snapshots__/sot23.snap.svg index 1b83478b..937ba2d4 100644 --- a/tests/kicad-parity/__snapshots__/sot23.snap.svg +++ b/tests/kicad-parity/__snapshots__/sot23.snap.svg @@ -1 +1 @@ -{REF}Diff: 0.00% \ No newline at end of file +{REF}Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sot323.snap.svg b/tests/kicad-parity/__snapshots__/sot323.snap.svg index b6c17777..d14eb63f 100644 --- a/tests/kicad-parity/__snapshots__/sot323.snap.svg +++ b/tests/kicad-parity/__snapshots__/sot323.snap.svg @@ -1 +1 @@ -{REF}Diff: 0.27% \ No newline at end of file +{REF}Diff: 0.27% \ No newline at end of file diff --git a/tests/parseint-radix.test.ts b/tests/parseint-radix.test.ts new file mode 100644 index 00000000..900de3c4 --- /dev/null +++ b/tests/parseint-radix.test.ts @@ -0,0 +1,41 @@ +import { test, expect } from "bun:test" +import { fp } from "src/footprinter" + +test("sot323 string parsing correctly reads num_pins", () => { + // Before fix: parseInt(match[1]!, 3) used base-3 radix, + // so digit "3" and above returned NaN + const params = fp.string("sot323").params() + expect(params.fn).toBe("sot323") +}) + +test("sot343 string parsing correctly reads num_pins", () => { + // Before fix: parseInt(match[1]!, 4) used base-4 radix, + // so digit "4" and above returned NaN + const params = fp.string("sot343").params() + expect(params.fn).toBe("sot343") + const circuitJson = fp.string("sot343").circuitJson() + const smtpads = circuitJson.filter((e) => e.type === "pcb_smtpad") + expect(smtpads.length).toBe(4) +}) + +test("sot23w generates 3 pads by default", () => { + const circuitJson = fp.string("sot23w").circuitJson() + const smtpads = circuitJson.filter((e) => e.type === "pcb_smtpad") + expect(smtpads.length).toBe(3) +}) + +test("sot23 silkscreen ref uses parseFloat for height positioning", () => { + // Before fix: parseInt("2.50mm") returned 2, truncating the decimal + // After fix: parseFloat("2.50mm") returns 2.5 + const circuitJson = fp.string("sot23").circuitJson() + const silkscreenText = circuitJson.find( + (e) => e.type === "pcb_silkscreen_text", + ) + expect(silkscreenText).toBeDefined() + // With parseFloat, the Y position should use the full decimal value + // not just the integer part + if (silkscreenText && "anchor_position" in silkscreenText) { + // Y should be based on parseFloat("2.50mm") = 2.5, not parseInt("2.50mm") = 2 + expect(silkscreenText.anchor_position.y).not.toBe(2) + } +})