krishnax12/watchy-eink-smartwatch
Unfinished prototype (not production-ready): 4 native DRC errors, 2 display-flex intersections, and missing antenna radiator copper remain
- Version
- 1.2.7
- License
- MIT
- Stars
- 1
scripts/native-copper.test.ts
import { expect, test } from "bun:test";
import type { AnyCircuitElement } from "circuit-json";
import { BOARD_COPPER_LAYERS } from "../pcb/board-stackup";
test("two-layer native copper remains masked and outside the antenna keepout", async () => {
const circuit: AnyCircuitElement[] = await Bun.file(
"dist/index/circuit.json",
).json();
const ground = circuit.find(
(element) => element.type === "source_net" && element.name === "GND",
);
if (!ground || ground.type !== "source_net")
throw new Error("Missing ground net");
const keepout = circuit.find((element) => element.type === "pcb_keepout");
if (!keepout || keepout.shape !== "rect")
throw new Error("Missing rectangular antenna keepout");
expect(keepout.layers).toEqual([...BOARD_COPPER_LAYERS]);
const board = circuit.find((element) => element.type === "pcb_board");
if (!board || board.type !== "pcb_board") throw new Error("Missing board");
expect(board.num_layers).toBe(2);
expect(board.thickness).toBe(1);
for (const trace of circuit.filter(
(element) => element.type === "pcb_trace",
)) {
for (const point of trace.route) {
if (point.route_type === "wire")
expect(["top", "bottom"]).toContain(point.layer);
}
}
for (const via of circuit.filter((element) => element.type === "pcb_via")) {
expect(
via.layers.every((layer) => layer === "top" || layer === "bottom"),
).toBe(true);
}
const copperSource = await Bun.file("pcb/BoardCopper.tsx").text();
expect(copperSource).not.toMatch(/\ballow(?:Traces|Placements)\b/);
const pours = circuit.filter((element) => element.type === "pcb_copper_pour");
expect(BOARD_COPPER_LAYERS).toEqual(["top", "bottom"]);
expect(
pours.every((pour) => pour.layer === "top" || pour.layer === "bottom"),
).toBe(true);
for (const layer of BOARD_COPPER_LAYERS) {
expect(pours.some((pour) => pour.layer === layer)).toBe(true);
}
for (const pour of pours) {
expect(pour.source_net_id).toBe(ground.source_net_id);
expect(pour.covered_with_solder_mask).toBe(true);
if (pour.shape !== "brep") throw new Error("Expected solved pour geometry");
for (const vertex of pour.brep_shape.outer_ring.vertices) {
expect(vertex.y).toBeLessThan(keepout.center.y - keepout.height / 2);
}
}
});