AnasSarkiz/ble-pedometer

This code defines and configures various electronic hardware components such as surface-mount resistors, crystals, diodes, transistors, connectors, and switches with their physical footprints, schematic symbols, and 3D CAD models for PCB assembly.

Version
1.0.7
License
unset
Stars
0

tests/fabrication.test.ts

import { expect, test } from "bun:test"
import { pcb_via, pcb_board } from "circuit-json"
import { convertCircuitJsonToGerberFiles } from "circuit-json-to-gerber"
import { getFabricationBlockers } from "../lib/get-fabrication-blockers"

test("malformed geometry and emitted errors cannot pass the fabrication gate", () => {
  expect(getFabricationBlockers({})).toEqual(["Invalid Circuit JSON element array"])
  expect(getFabricationBlockers([{ type: "pcb_trace_error" }])).toContain("Unresolved pcb_trace_error")
  expect(getFabricationBlockers([{ type: "pcb_via", hole_diameter: "invalid" }]).some((blocker) => blocker.startsWith("Invalid via geometry:"))).toBe(true)
})

test("rejects the previous undersized via even when it lists every copper layer", () => {
  const via = pcb_via.parse({
    type: "pcb_via", x: 0, y: 0,
    pcb_via_id: "undersized",
    hole_diameter: 0.15, outer_diameter: 0.3,
    from_layer: "top", to_layer: "inner1",
    layers: ["top", "inner1", "inner2", "bottom"],
  })
  expect(getFabricationBlockers([via])).toContain("undersized: hole must be at least 0.30 mm")
  expect(getFabricationBlockers([via])).toContain("undersized: pad must be at least 0.45 mm")
  expect(getFabricationBlockers([{ ...via, layers: ["top", "inner1"] }])).toContain("undersized: not a full-stack through via")
})

test("accepts a 0.30/0.45 mm through via without hiding missing board/routing", () => {
  const via = pcb_via.parse({
    type: "pcb_via", x: 0, y: 0,
    pcb_via_id: "through",
    hole_diameter: 0.3, outer_diameter: 0.45,
    from_layer: "top", to_layer: "bottom",
    layers: ["top", "inner1", "inner2", "bottom"],
  })
  expect(getFabricationBlockers([via])).toEqual([
    "Expected the four-layer pedometer board",
    "No routed PCB traces: placement-only output is not fabrication-ready",
  ])
})

test("published exporter drills physical through layers despite legacy transition endpoints", () => {
  const board = pcb_board.parse({ type: "pcb_board", pcb_board_id: "board", num_layers: 4, center: { x: 0, y: 0 }, width: 10, height: 10 })
  const via = pcb_via.parse({
    type: "pcb_via", pcb_via_id: "physical-through", x: 1, y: 2,
    hole_diameter: 0.3, outer_diameter: 0.45,
    from_layer: "top", to_layer: "inner1",
    layers: ["bottom", "inner2", "top", "inner1"],
  })
  const circuitJson = [board, via, { ...via, pcb_via_id: "duplicate-physical-barrel" }]
  const originalCircuitJson = JSON.stringify(circuitJson)
  const files = convertCircuitJsonToGerberFiles(circuitJson)
  expect(Object.keys(files).filter(name => /^drill-L/.test(name))).toEqual(["drill-L1-L4.drl"])
  expect(files["drill-L1-L4.drl"]).toContain("TF.FileFunction,Plated,1,4,PTH")
  expect(files["drill-L1-L4.drl"]).toContain("C0.300000")
  expect(files["drill-L1-L4.drl"].split("\n").filter(line => line.startsWith("X"))).toHaveLength(1)
  expect(JSON.stringify(circuitJson)).toBe(originalCircuitJson)
  expect(getFabricationBlockers([board, { ...via, layers: ["top", "inner1"] }])).toContain("physical-through: not a full-stack through via")
})