imrishabh18/pedometer
This code defines and assembles a simple radio receiver hardware circuit using specific imported capacitors, inductors, RF connectors, and oscillator components with precise footprints and schematic attributes.
- Version
- 1.1.3
- License
- unset
- Stars
- 0
tests/routing-cleanup.test.ts
import { expect, test } from "bun:test";
import { repairViaClearances } from "../via-clearance";
import { compareRoutingPreservation } from "../scripts/check-routing-preserved";
test("via legalization retains clean 45-degree bends instead of drawing arbitrary-angle shortcuts", () => {
const trace: any = { type: "pcb_trace", pcb_trace_id: "signal", connection_name: "signal", route: [
{ route_type: "wire", x: -3, y: -1, width: 0.1, layer: "top", start_pcb_port_id: "a" },
{ route_type: "wire", x: -1, y: 1, width: 0.1, layer: "top" },
{ route_type: "wire", x: 3, y: 1, width: 0.1, layer: "top", end_pcb_port_id: "b" },
] };
const original = structuredClone(trace);
const input: any = { layerCount: 4, minTraceWidth: 0.1, minViaPadDiameter: 0.3, minViaHoleDiameter: 0.15,
bounds: { minX: -5, minY: -5, maxX: 5, maxY: 5 }, obstacles: [],
connections: [{ name: "signal", pointsToConnect: [{ x: -3, y: -1, layer: "top" }, { x: 3, y: 1, layer: "top" }] }],
};
expect(repairViaClearances([trace], input)).toEqual([original]);
});
test("via legalization still moves a colliding through-via and preserves its attached copper", () => {
const trace: any = { type: "pcb_trace", pcb_trace_id: "signal", connection_name: "signal", route: [
{ route_type: "wire", x: -2, y: 0, width: 0.1, layer: "top", start_pcb_port_id: "a" },
{ route_type: "wire", x: 0, y: 0, width: 0.1, layer: "top" },
{ route_type: "via", x: 0, y: 0, via_diameter: 0.3, from_layer: "top", to_layer: "bottom" },
{ route_type: "wire", x: 0, y: 0, width: 0.1, layer: "bottom" },
{ route_type: "wire", x: 2, y: 0, width: 0.1, layer: "bottom", end_pcb_port_id: "b" },
] };
const original = structuredClone(trace);
const input: any = { layerCount: 4, minTraceWidth: 0.1, minViaPadDiameter: 0.3, minViaHoleDiameter: 0.15,
bounds: { minX: -5, minY: -5, maxX: 5, maxY: 5 },
obstacles: [{ type: "rect", center: { x: 0, y: 0 }, width: 0.2, height: 0.2, layers: ["top"], connectedTo: ["other"] }],
connections: [{ name: "signal", pointsToConnect: [{ x: -2, y: 0, layer: "top" }, { x: 2, y: 0, layer: "bottom" }] }],
};
repairViaClearances([trace], input);
const via = trace.route[2];
expect(Math.hypot(via.x, via.y)).toBeGreaterThan(0.3);
expect(trace.route[0]).toEqual(original.route[0]);
expect(trace.route[4]).toEqual(original.route[4]);
for (const index of [1, 3]) expect({ x: trace.route[index].x, y: trace.route[index].y }).toEqual({ x: via.x, y: via.y });
expect(via.via_diameter).toBe(0.3);
});
const fixture = (): any[] => [
{ type: "source_group", source_group_id: "source_group_0", is_subcircuit: true, subcircuit_id: "subcircuit_source_group_0" },
{ type: "source_board", source_board_id: "source_board_0", source_group_id: "source_group_0", title: "fixture" },
{ type: "source_component", source_component_id: "source_component_0", source_group_id: "source_group_0", name: "C1", capacitance: 1.5e-12 },
{ type: "source_port", source_port_id: "source_port_0", source_component_id: "source_component_0", pin_number: 1 },
{ type: "source_port", source_port_id: "source_port_1", source_component_id: "source_component_0", pin_number: 2 },
{ type: "source_net", source_net_id: "source_net_0", name: "SIGNAL" },
{ type: "source_net", source_net_id: "source_net_1", name: "GND", is_ground: true },
{ type: "source_trace", source_trace_id: "source_trace_0", connected_source_port_ids: ["source_port_0"], connected_source_net_ids: ["source_net_0"], max_via_count: 0 },
{ type: "source_trace", source_trace_id: "source_trace_1", connected_source_port_ids: ["source_port_1"], connected_source_net_ids: ["source_net_1"] },
{ type: "pcb_board", pcb_board_id: "pcb_board_0", source_board_id: "source_board_0", width: 40, height: 38, num_layers: 4, min_trace_to_pad_edge_clearance: 0.075 },
{ type: "pcb_component", pcb_component_id: "pcb_component_0", source_component_id: "source_component_0", center: { x: 1, y: 2 }, rotation: 90, layer: "top" },
{ type: "pcb_port", pcb_port_id: "pcb_port_0", pcb_component_id: "pcb_component_0", source_port_id: "source_port_0", x: 1, y: 2, layers: ["top"] },
{ type: "pcb_smtpad", pcb_smtpad_id: "pcb_smtpad_0", pcb_component_id: "pcb_component_0", pcb_port_id: "pcb_port_0", x: 1, y: 2, layer: "top", shape: "rect", width: 0.6, height: 0.25 },
{ type: "pcb_solder_paste", pcb_solder_paste_id: "pcb_solder_paste_0", pcb_smtpad_id: "pcb_smtpad_0", x: 1, y: 2, layer: "top", shape: "rect", width: 0.4, height: 0.2 },
];
test("preservation check tolerates regenerated IDs and changed route metadata", () => {
const baseline = fixture();
const changed = JSON.parse(JSON.stringify(baseline).replace(/(_\d+)(?=")/g, "$1new"));
changed.push({ type: "pcb_trace", pcb_trace_id: "new_route", route: [{ x: 0, y: 0 }] });
changed.push({ type: "source_project_metadata", source_filesystem_md5_hash: "changed-source" });
expect(compareRoutingPreservation(baseline, changed).result).toBe("PASS");
});
test("preservation check rejects pin reassignment, footprint movement, and relaxed clearance rules", () => {
const baseline = fixture();
for (const mutate of [
(c: any[]) => { c.find(e => e.type === "source_trace").connected_source_net_ids = ["source_net_1"]; },
(c: any[]) => { c.find(e => e.type === "pcb_component").center.x += 0.01; },
(c: any[]) => { c.find(e => e.type === "pcb_smtpad").width += 0.01; },
(c: any[]) => { c.find(e => e.type === "pcb_board").min_trace_to_pad_edge_clearance = 0.05; },
(c: any[]) => { c.find(e => e.type === "source_component").capacitance = 2.2e-12; },
(c: any[]) => { c.find(e => e.type === "source_trace").max_via_count = 1; },
]) {
const changed = structuredClone(baseline);
mutate(changed);
expect(compareRoutingPreservation(baseline, changed).result).toBe("FAIL");
}
});