Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions crates/konnect-core/src/tools/design_review.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ async fn handle_audit_decoupling(
None => continue,
};

let pins = extract_lib_pins(lib_sym);
let pins = extract_lib_pins_for_unit(lib_sym, inst.unit);
let is_passive = inst.lib_id.contains("R_")
|| inst.lib_id.contains("C_")
|| inst.lib_id.contains("L_")
Expand Down Expand Up @@ -268,7 +268,7 @@ async fn handle_audit_connections(
None => continue,
};

let pins = extract_lib_pins(lib_sym);
let pins = extract_lib_pins_for_unit(lib_sym, inst.unit);

// Check for I2C pull-ups
if has_i2c_pins(&pins) {
Expand Down Expand Up @@ -714,20 +714,14 @@ fn inspect_schematic_coverage(
};
coverage.resolved_symbols += 1;

// The design-review call sites tracked by #182 still use the
// unit-agnostic extractor. Until that issue lands, surface every such
// component as partial coverage rather than pretending it was audited.
// Deliberately compare the complete definition with the selected unit
// here: this is classification, not pin placement. Every audit below
// resolves the selected unit before transforming its pins (#182).
if extract_lib_pins(lib_symbol).len()
> extract_lib_pins_for_unit(lib_symbol, instance.unit).len()
&& multi_unit_references.insert(instance.reference.clone())
{
coverage.multi_unit_symbols += 1;
diagnostics.push(json!({
"code": "multi_unit_review_incomplete",
"source": path.display().to_string(),
"reference": instance.reference,
"message": "design-review pin analysis is not unit-aware yet; tracked by issue #182"
}));
}
}
}
Expand Down Expand Up @@ -1146,7 +1140,7 @@ fn collect_capacitor_nets(
}
let lib_sym = find_lib_symbol(lib_syms, inst);
if let Some(sym) = lib_sym {
let pins = extract_lib_pins(sym);
let pins = extract_lib_pins_for_unit(sym, inst.unit);
for pin in &pins {
let (px, py) = pin_endpoint(pin, inst.pin_transform());
if let Some(net) = find_net_at_point(content, px, py) {
Expand Down Expand Up @@ -1188,7 +1182,7 @@ fn collect_bulk_cap_nets(

let lib_sym = find_lib_symbol(lib_syms, inst);
if let Some(sym) = lib_sym {
let pins = extract_lib_pins(sym);
let pins = extract_lib_pins_for_unit(sym, inst.unit);
for pin in &pins {
let (px, py) = pin_endpoint(pin, inst.pin_transform());
if let Some(net) = find_net_at_point(content, px, py) {
Expand Down Expand Up @@ -1302,7 +1296,7 @@ fn has_pull_up_on_net(
}
let lib_sym = find_lib_symbol(lib_syms, inst);
if let Some(sym) = lib_sym {
let pins = extract_lib_pins(sym);
let pins = extract_lib_pins_for_unit(sym, inst.unit);
let pin_nets: Vec<Option<String>> = pins
.iter()
.map(|p| {
Expand Down Expand Up @@ -1536,7 +1530,7 @@ mod review_completion_tests {
(pin input line (at 0 0 0) (length 2.54) (name "A") (number "1"))
)
(symbol "DUAL_2_1"
(pin output line (at 0 0 0) (length 2.54) (name "Y") (number "2"))
(pin power_in line (at 0 0 0) (length 2.54) (name "VCC") (number "2"))
)
)
)
Expand Down Expand Up @@ -1702,20 +1696,28 @@ mod review_completion_tests {
}

#[tokio::test]
async fn multi_unit_symbol_is_partial_until_issue_182_lands() {
async fn multi_unit_symbol_is_fully_reviewed() {
let tmp = TempDir::new().unwrap();
let root = tmp.path().join("multi.kicad_sch");
std::fs::write(&root, multi_unit_schematic()).unwrap();

let result = review(&root, None).await;
let report = &result["design_review"];
assert_eq!(report["status"], "partial");
assert_eq!(report["status"], "complete");
assert_eq!(report["coverage"]["schematic"]["multi_unit_symbols"], 1);
assert!(report["diagnostics"]
assert!(!report["diagnostics"]
.as_array()
.unwrap()
.iter()
.any(|item| item["code"] == "multi_unit_review_incomplete"));
assert!(
!report["findings"]
.as_array()
.unwrap()
.iter()
.any(|finding| finding.to_string().contains("'VCC'")),
"the unplaced unit-2 pin must not be audited at unit 1's position: {report}"
);
}

#[tokio::test]
Expand Down
Loading
Loading