app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Drive your own KiCad from an AI, in the background: open every editor, read the whole board as data (the EDA Bridge Standard board model), stack-up, part heights, netlists, place, route, pour, DRC and exports.
master
Colby Knox
Fix #133 (outline box from arcs and circles; ring courtyards: 2-degree sampling, interior probes), #130 (KICAD10_3RD_PA…
f7d1e2b
15d ago
//! Wiki #131: pin connection points, checked against KiCad's own demo sheets: every no-connect flag
//! KiCad placed sits on a pin the bridge computes (rotated and mirrored symbols included).
use kicad_core::schematic::Schematic;
use std::path::PathBuf;
#[test]
fn every_demo_no_connect_flag_lands_on_a_computed_pin() {
let dir = PathBuf::from(std::env::var("KICAD_DEMO_SCH").unwrap_or_else(|_| format!("{}/../../../../fixtures/sch", env!("CARGO_MANIFEST_DIR"))));
let Ok(rd) = std::fs::read_dir(&dir) else { eprintln!("no demo sheets at {}; skipped", dir.display()); return };
let (mut flags, mut hit) = (0, 0);
let mut misses = Vec::new();
for e in rd.flatten().filter(|e| e.path().extension().map_or(false, |x| x == "kicad_sch")) {
let text = std::fs::read_to_string(e.path()).unwrap();
let sch = Schematic::parse(&text).unwrap();
let refs: std::collections::BTreeSet<String> = sch.symbols().into_iter().map(|s| s.reference).collect();
let mut pins = Vec::new();
for r in &refs {
if let Ok(p) = sch.pin_points(r) {
pins.extend(p.into_iter().map(|(n, at)| (r.clone(), n, at)));
}
}
for line in text.lines().collect::<Vec<_>>().windows(2) {
if line[0].trim() == "(no_connect" {
let nums: Vec<f64> = line[1].trim().trim_start_matches("(at").trim_end_matches(')').split_whitespace().filter_map(|t| t.parse().ok()).collect();
if nums.len() < 2 { continue }
flags += 1;
if pins.iter().any(|(_, _, (x, y))| (x - nums[0]).abs() < 1e-3 && (y - nums[1]).abs() < 1e-3) {
hit += 1;
} else {
misses.push(format!("{}: ({}, {})", e.file_name().to_string_lossy(), nums[0], nums[1]));
}
}
}
}
eprintln!("{hit} of {flags} no-connect flags on a computed pin");
assert!(flags == 0 || hit == flags, "{} missed: {:?}", misses.len(), &misses[..misses.len().min(8)]);
}
#[test]
fn a_flag_lands_on_a_named_pin_of_the_fixture_sheet() {
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../../tour-pack-rp2040/template/rp2040-breakout.kicad_sch");
let mut sch = Schematic::parse(&std::fs::read_to_string(&path).unwrap()).unwrap();
let pins = sch.pin_points("U1").unwrap();
let (_, at) = pins.iter().find(|(n, _)| n == "1").expect("U1 pin 1");
let uuid = sch.add_no_connect(*at).unwrap();
let text = sch.to_text();
let again = Schematic::parse(&text).unwrap();
assert!(text.contains(&format!("(uuid \"{uuid}\")")));
assert!(again.pin_points("U1").unwrap().iter().any(|(_, p)| p == at));
assert!(text.contains("(no_connect"));
}