diff --git a/src/footprinter.ts b/src/footprinter.ts
index 09c1cd8a..e6096d11 100644
--- a/src/footprinter.ts
+++ b/src/footprinter.ts
@@ -405,12 +405,17 @@ export const footprinter = (): Footprinter & {
} else {
target[prop] = true
target.fn = prop
- if (prop === "res" || prop === "cap") {
+ if (
+ prop === "res" ||
+ prop === "cap" ||
+ prop === "led" ||
+ prop === "diode"
+ ) {
if (v) {
if (typeof v === "string" && v.includes("_metric")) {
target.metric = v.split("_metric")[0]
} else {
- target.imperial = v // e.g., res0402, cap0603 etc.
+ target.imperial = v // e.g., res0402, cap0603, led0805 etc.
}
}
} else {
diff --git a/tests/__snapshots__/diode0402_string.snap.svg b/tests/__snapshots__/diode0402_string.snap.svg
new file mode 100644
index 00000000..8d67bac1
--- /dev/null
+++ b/tests/__snapshots__/diode0402_string.snap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/__snapshots__/diode0805_string.snap.svg b/tests/__snapshots__/diode0805_string.snap.svg
new file mode 100644
index 00000000..ff53e38d
--- /dev/null
+++ b/tests/__snapshots__/diode0805_string.snap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/__snapshots__/diode1206_string.snap.svg b/tests/__snapshots__/diode1206_string.snap.svg
new file mode 100644
index 00000000..a4a85de7
--- /dev/null
+++ b/tests/__snapshots__/diode1206_string.snap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/__snapshots__/led0402_string.snap.svg b/tests/__snapshots__/led0402_string.snap.svg
new file mode 100644
index 00000000..8d67bac1
--- /dev/null
+++ b/tests/__snapshots__/led0402_string.snap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/__snapshots__/led0805_string.snap.svg b/tests/__snapshots__/led0805_string.snap.svg
new file mode 100644
index 00000000..ff53e38d
--- /dev/null
+++ b/tests/__snapshots__/led0805_string.snap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/__snapshots__/led1206_string.snap.svg b/tests/__snapshots__/led1206_string.snap.svg
new file mode 100644
index 00000000..a4a85de7
--- /dev/null
+++ b/tests/__snapshots__/led1206_string.snap.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/diode-string-parsing.test.ts b/tests/diode-string-parsing.test.ts
new file mode 100644
index 00000000..ef2260ff
--- /dev/null
+++ b/tests/diode-string-parsing.test.ts
@@ -0,0 +1,17 @@
+import { expect, test } from "bun:test"
+import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
+import { fp } from "../src/footprinter"
+
+test("diode0402 string produces 2 SMT pads with correct imperial size", () => {
+ const soup = fp.string("diode0402").circuitJson()
+ const pads = soup.filter((e: any) => e.type === "pcb_smtpad")
+ expect(pads).toHaveLength(2)
+
+ const pad1 = pads.find((p: any) => p.port_hints?.includes("1"))
+ expect(pad1).toBeDefined()
+ expect(pad1!.width).toBeCloseTo(0.54, 1)
+ expect(pad1!.height).toBeCloseTo(0.64, 1)
+
+ const svgContent = convertCircuitJsonToPcbSvg(soup)
+ expect(svgContent).toMatchSvgSnapshot(import.meta.path, "diode0402_string")
+})
diff --git a/tests/diode-string-parsing2.test.ts b/tests/diode-string-parsing2.test.ts
new file mode 100644
index 00000000..33756776
--- /dev/null
+++ b/tests/diode-string-parsing2.test.ts
@@ -0,0 +1,16 @@
+import { expect, test } from "bun:test"
+import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
+import { fp } from "../src/footprinter"
+
+test("diode0805 string produces 2 SMT pads with correct imperial size", () => {
+ const soup = fp.string("diode0805").circuitJson()
+ const pads = soup.filter((e: any) => e.type === "pcb_smtpad")
+ expect(pads).toHaveLength(2)
+
+ const pad1 = pads.find((p: any) => p.port_hints?.includes("1"))
+ expect(pad1!.width).toBeCloseTo(1.025, 2)
+ expect(pad1!.height).toBeCloseTo(1.4, 1)
+
+ const svgContent = convertCircuitJsonToPcbSvg(soup)
+ expect(svgContent).toMatchSvgSnapshot(import.meta.path, "diode0805_string")
+})
diff --git a/tests/diode-string-parsing3.test.ts b/tests/diode-string-parsing3.test.ts
new file mode 100644
index 00000000..55d19ae0
--- /dev/null
+++ b/tests/diode-string-parsing3.test.ts
@@ -0,0 +1,12 @@
+import { expect, test } from "bun:test"
+import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
+import { fp } from "../src/footprinter"
+
+test("diode1206 string produces 2 SMT pads", () => {
+ const soup = fp.string("diode1206").circuitJson()
+ const pads = soup.filter((e: any) => e.type === "pcb_smtpad")
+ expect(pads).toHaveLength(2)
+
+ const svgContent = convertCircuitJsonToPcbSvg(soup)
+ expect(svgContent).toMatchSvgSnapshot(import.meta.path, "diode1206_string")
+})
diff --git a/tests/diode-string-parsing4.test.ts b/tests/diode-string-parsing4.test.ts
new file mode 100644
index 00000000..64cec5aa
--- /dev/null
+++ b/tests/diode-string-parsing4.test.ts
@@ -0,0 +1,19 @@
+import { expect, test } from "bun:test"
+import { fp } from "../src/footprinter"
+
+test("diode string matches diode builder API output", () => {
+ const fromString = fp.string("diode0603").circuitJson()
+ const fromBuilder = fp().diode().imperial("0603").circuitJson()
+
+ const stringPads = fromString.filter((e: any) => e.type === "pcb_smtpad")
+ const builderPads = fromBuilder.filter((e: any) => e.type === "pcb_smtpad")
+
+ expect(stringPads).toHaveLength(builderPads.length)
+
+ for (let i = 0; i < stringPads.length; i++) {
+ expect(stringPads[i].x).toBeCloseTo(builderPads[i].x, 5)
+ expect(stringPads[i].y).toBeCloseTo(builderPads[i].y, 5)
+ expect(stringPads[i].width).toBeCloseTo(builderPads[i].width, 5)
+ expect(stringPads[i].height).toBeCloseTo(builderPads[i].height, 5)
+ }
+})
diff --git a/tests/diode-string-parsing5.test.ts b/tests/diode-string-parsing5.test.ts
new file mode 100644
index 00000000..ce96f7e0
--- /dev/null
+++ b/tests/diode-string-parsing5.test.ts
@@ -0,0 +1,8 @@
+import { expect, test } from "bun:test"
+import { fp } from "../src/footprinter"
+
+test("diode0402_metric string uses metric lookup", () => {
+ const params = fp.string("diode1005_metric").params()
+ expect(params.metric).toBe("1005")
+ expect(params.fn).toBe("diode")
+})
diff --git a/tests/diode-string-parsing6.test.ts b/tests/diode-string-parsing6.test.ts
new file mode 100644
index 00000000..0c1f8f99
--- /dev/null
+++ b/tests/diode-string-parsing6.test.ts
@@ -0,0 +1,8 @@
+import { expect, test } from "bun:test"
+import { fp } from "../src/footprinter"
+
+test("diode0603_tht string produces through-hole pads", () => {
+ const soup = fp.string("diode0603_tht").circuitJson()
+ const holes = soup.filter((e: any) => e.type === "pcb_plated_hole")
+ expect(holes).toHaveLength(2)
+})
diff --git a/tests/led-string-parsing.test.ts b/tests/led-string-parsing.test.ts
new file mode 100644
index 00000000..fe87159f
--- /dev/null
+++ b/tests/led-string-parsing.test.ts
@@ -0,0 +1,19 @@
+import { expect, test } from "bun:test"
+import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
+import { fp } from "../src/footprinter"
+
+test("led0402 string produces 2 SMT pads with correct imperial size", () => {
+ const soup = fp.string("led0402").circuitJson()
+ const pads = soup.filter((e: any) => e.type === "pcb_smtpad")
+ expect(pads).toHaveLength(2)
+
+ const pad1 = pads.find((p: any) => p.port_hints?.includes("1"))
+ const pad2 = pads.find((p: any) => p.port_hints?.includes("2"))
+ expect(pad1).toBeDefined()
+ expect(pad2).toBeDefined()
+ expect(pad1!.width).toBeCloseTo(0.54, 1)
+ expect(pad1!.height).toBeCloseTo(0.64, 1)
+
+ const svgContent = convertCircuitJsonToPcbSvg(soup)
+ expect(svgContent).toMatchSvgSnapshot(import.meta.path, "led0402_string")
+})
diff --git a/tests/led-string-parsing2.test.ts b/tests/led-string-parsing2.test.ts
new file mode 100644
index 00000000..09977549
--- /dev/null
+++ b/tests/led-string-parsing2.test.ts
@@ -0,0 +1,16 @@
+import { expect, test } from "bun:test"
+import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
+import { fp } from "../src/footprinter"
+
+test("led0805 string produces 2 SMT pads with correct imperial size", () => {
+ const soup = fp.string("led0805").circuitJson()
+ const pads = soup.filter((e: any) => e.type === "pcb_smtpad")
+ expect(pads).toHaveLength(2)
+
+ const pad1 = pads.find((p: any) => p.port_hints?.includes("1"))
+ expect(pad1!.width).toBeCloseTo(1.025, 2)
+ expect(pad1!.height).toBeCloseTo(1.4, 1)
+
+ const svgContent = convertCircuitJsonToPcbSvg(soup)
+ expect(svgContent).toMatchSvgSnapshot(import.meta.path, "led0805_string")
+})
diff --git a/tests/led-string-parsing3.test.ts b/tests/led-string-parsing3.test.ts
new file mode 100644
index 00000000..7c3d4d48
--- /dev/null
+++ b/tests/led-string-parsing3.test.ts
@@ -0,0 +1,12 @@
+import { expect, test } from "bun:test"
+import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
+import { fp } from "../src/footprinter"
+
+test("led1206 string produces 2 SMT pads", () => {
+ const soup = fp.string("led1206").circuitJson()
+ const pads = soup.filter((e: any) => e.type === "pcb_smtpad")
+ expect(pads).toHaveLength(2)
+
+ const svgContent = convertCircuitJsonToPcbSvg(soup)
+ expect(svgContent).toMatchSvgSnapshot(import.meta.path, "led1206_string")
+})
diff --git a/tests/led-string-parsing4.test.ts b/tests/led-string-parsing4.test.ts
new file mode 100644
index 00000000..17d465ef
--- /dev/null
+++ b/tests/led-string-parsing4.test.ts
@@ -0,0 +1,19 @@
+import { expect, test } from "bun:test"
+import { fp } from "../src/footprinter"
+
+test("led string matches led builder API output", () => {
+ const fromString = fp.string("led0603").circuitJson()
+ const fromBuilder = fp().led().imperial("0603").circuitJson()
+
+ const stringPads = fromString.filter((e: any) => e.type === "pcb_smtpad")
+ const builderPads = fromBuilder.filter((e: any) => e.type === "pcb_smtpad")
+
+ expect(stringPads).toHaveLength(builderPads.length)
+
+ for (let i = 0; i < stringPads.length; i++) {
+ expect(stringPads[i].x).toBeCloseTo(builderPads[i].x, 5)
+ expect(stringPads[i].y).toBeCloseTo(builderPads[i].y, 5)
+ expect(stringPads[i].width).toBeCloseTo(builderPads[i].width, 5)
+ expect(stringPads[i].height).toBeCloseTo(builderPads[i].height, 5)
+ }
+})
diff --git a/tests/led-string-parsing5.test.ts b/tests/led-string-parsing5.test.ts
new file mode 100644
index 00000000..04c04b6e
--- /dev/null
+++ b/tests/led-string-parsing5.test.ts
@@ -0,0 +1,8 @@
+import { expect, test } from "bun:test"
+import { fp } from "../src/footprinter"
+
+test("led0402_metric string uses metric lookup", () => {
+ const params = fp.string("led1005_metric").params()
+ expect(params.metric).toBe("1005")
+ expect(params.fn).toBe("led")
+})