diff --git a/src/fn/vson.ts b/src/fn/vson.ts index 699d5735..1e90a2a8 100644 --- a/src/fn/vson.ts +++ b/src/fn/vson.ts @@ -12,21 +12,29 @@ import { dim2d } from "src/helpers/zod/dim-2d" import { type SilkscreenRef, silkscreenRef } from "src/helpers/silkscreenRef" import { createRectUnionOutline } from "src/helpers/rect-union-outline" -// can't use defaults because there is not a lot of common dimensions. +// Defaults describe the canonical KiCad VSON-8-1EP 3x3mm 0.65mm-pitch part +// (Package_SON VSON-8-1EP_3x3mm_P0.65mm_EP1.65x2.4mm) so a bare `vsonN` renders +// instead of throwing a raw parse error; pass explicit dims to override for a +// specific part. The exposed pad is left at 0 so a bare `vson8` stays 8 pads; +// add `ep` for a part that needs the thermal pad. export const vson_def = base_def.extend({ fn: z.string(), num_pins: z.number().optional().default(8), - p: distance.describe("pitch (distance between center of each pin)"), - w: length.describe("width between vertical rows of pins"), - grid: dim2d.describe("width and height of the border of the footprint"), + p: distance + .default("0.65mm") + .describe("pitch (distance between center of each pin)"), + w: length.default("2.9mm").describe("width between vertical rows of pins"), + grid: dim2d + .default("3x3mm") + .describe("width and height of the border of the footprint"), ep: dim2d .default("0x0mm") .describe("width and height of the central exposed thermal pad"), epx: length .default("0mm") .describe("x offset of the center of the central exposed thermal pad"), - pinw: length.describe("width of the pin pads"), - pinh: length.describe("height of the pin pads"), + pinw: length.default("0.85mm").describe("width of the pin pads"), + pinh: length.default("0.35mm").describe("height of the pin pads"), }) export type VsonDefInput = z.input diff --git a/tests/__snapshots__/vson8.snap.svg b/tests/__snapshots__/vson8.snap.svg new file mode 100644 index 00000000..011d4a56 --- /dev/null +++ b/tests/__snapshots__/vson8.snap.svg @@ -0,0 +1 @@ +{REF} \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/vson8_default.snap.svg b/tests/kicad-parity/__snapshots__/vson8_default.snap.svg new file mode 100644 index 00000000..543232ae --- /dev/null +++ b/tests/kicad-parity/__snapshots__/vson8_default.snap.svg @@ -0,0 +1 @@ +{REF}REF**Diff: 45.41% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/vson8_default_boolean_difference.snap.svg b/tests/kicad-parity/__snapshots__/vson8_default_boolean_difference.snap.svg new file mode 100644 index 00000000..5a68f442 --- /dev/null +++ b/tests/kicad-parity/__snapshots__/vson8_default_boolean_difference.snap.svg @@ -0,0 +1 @@ +VSON-8-1EP_3x3mm_P0.65mm_EP1.65x2.4mm - Alignment Analysis (Footprinter vs KiCad)vson8KiCad: VSON-8-1EP_3x3mm_P0.65mm_EP1.65x2.4mmPerfect alignment = complete overlap \ No newline at end of file diff --git a/tests/kicad-parity/vson8_kicad_parity.test.ts b/tests/kicad-parity/vson8_kicad_parity.test.ts index 5911815b..a3582d66 100644 --- a/tests/kicad-parity/vson8_kicad_parity.test.ts +++ b/tests/kicad-parity/vson8_kicad_parity.test.ts @@ -26,3 +26,28 @@ test("parity/VSON8-1EP_grid3x3mm_P0.65mm_EP1.65x2.4mm_w2.9mm_pinw0.85mm_pinh0.35 "VSON-8-1EP_3x3mm_P0.65mm_EP1.65x2.4mm_boolean_difference", ) }) + +// Parity for the bare `vson8` name (the default dimensions added in this PR). +// The defaults describe the canonical KiCad VSON-8-1EP 3x3mm 0.65mm-pitch part, +// so a bare `vson8` should line up with that reference courtyard. +test("parity/vson8 (default dimensions)", async () => { + const { + avgRelDiff, + combinedFootprintElements, + booleanDifferenceSvg, + courtyardDiffPercent, + } = await compareFootprinterVsKicad( + "vson8", + "Package_SON.pretty/VSON-8-1EP_3x3mm_P0.65mm_EP1.65x2.4mm.circuit.json", + ) + + const svgContent = convertCircuitJsonToPcbSvg(combinedFootprintElements, { + showCourtyards: true, + }) + expect(courtyardDiffPercent).toBeLessThan(0.5) + expect(svgContent).toMatchSvgSnapshot(import.meta.path, "vson8_default") + expect(booleanDifferenceSvg).toMatchSvgSnapshot( + import.meta.path, + "vson8_default_boolean_difference", + ) +}) diff --git a/tests/vson8.test.ts b/tests/vson8.test.ts new file mode 100644 index 00000000..18dd5fe7 --- /dev/null +++ b/tests/vson8.test.ts @@ -0,0 +1,13 @@ +import { test, expect } from "bun:test" +import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" +import { fp } from "../src/footprinter" + +test("vson8 renders from a bare name", () => { + // vson is advertised by getFootprintNames() and its siblings son8/wson8 render + // from a bare name; vson8 used to throw a raw parse error for missing dims. + const soup = fp.string("vson8").circuitJson() + const pads = soup.filter((e) => e.type === "pcb_smtpad") + expect(pads.length).toBe(8) + const svgContent = convertCircuitJsonToPcbSvg(soup) + expect(svgContent).toMatchSvgSnapshot(import.meta.path, "vson8") +})