0hmX/dual-usb-peltier-assembly

A tscircuit package created by 0hmX.

Version
0.4.12
License
unset
Stars
0

tests/helpers/copper-associations.ts

import type { AnyCircuitElement } from "circuit-json"
import type { RoutedCopperData } from "../../src/board/routed-copper"
import { copperPortContacts, sourceConnectivity } from "./physical-copper"

/** PCB metadata cannot establish a net: use the original source graph only. */
export function assertCopperAssociations(json: AnyCircuitElement[], data: RoutedCopperData) {
  const source = sourceConnectivity(json)
  const ports = new Map(json.filter(e => e.type === "source_port").map(e => [e.source_port_id, e]))
  const components = new Map(json.filter(e => e.type === "source_component").map(e => [e.source_component_id, e]))
  const nets = json.filter(e => e.type === "source_net")
  const traces = json.filter(e => e.type === "source_trace")
  const originalPorts = new Map([...source.ports].map(([key, id]) => [id, key]))
  const contacts = copperPortContacts(json)
  const portName = (id: string) => {
    const port = ports.get(id)!
    return `${components.get(port.source_component_id!)!.name}.pin${port.pin_number ?? port.name}`
  }
  for (const [i, route] of data.routes.entries()) {
    const trace = traces.find(t => t.source_trace_id === route.sourceTraceId)
    const namedNets = nets.filter(n => n.name === route.net)
    if (!trace || namedNets.length !== 1 || !trace.connected_source_port_ids.length ||
      !trace.connected_source_port_ids.every(id => source.groups.some(group =>
        group.nets.includes(route.net) && group.ports.includes(originalPorts.get(id) ?? "")))) {
      throw new Error(`Route ${i} (${route.net}) has a stale/missing source association`)
    }
    const key = JSON.stringify([
      trace.connected_source_port_ids.map(portName).sort(),
      trace.connected_source_net_ids.map(id => nets.find(net => net.source_net_id === id)?.name).sort(),
      trace.max_length ?? null, trace.max_via_count ?? null,
    ])
    if (key !== route.sourceTraceKey) throw new Error(`Route ${i} (${route.net}) has stale pin/constraint metadata`)
    const endpointPorts = contacts([route.route[0], route.route[route.route.length - 1]].filter(point => !!point)
      .map(point => ({ x: point.x, y: point.y, layers: point.route_type === "wire" ? [point.layer] : [point.from_layer, point.to_layer] })))
    const { sourcePort } = route
    if (sourcePort && !trace.connected_source_port_ids.some(id => portName(id) === sourcePort && endpointPorts.has(id)))
      throw new Error(`Route ${i} (${route.net}) sourcePort ${sourcePort} does not own its endpoint`)
    if (trace.max_length !== undefined || trace.max_via_count !== undefined) {
      if (!trace.connected_source_port_ids.every(id => endpointPorts.has(id)))
        throw new Error(`Route ${i} (${route.net}) borrows a constraint from an unrelated branch`)
    }
  }
}