Treat KiCad /net vs schematic net as one hierarchy finding.
Pad-net compare strips leading slash and nested sheet path so /ESP32_EN matches ESP32_EN. If every mismatch is only that prefix, emit PE-LAY-003 once instead of per-pad reconnect errors.
This commit is contained in:
@@ -62,6 +62,92 @@ def test_pad_net_mismatch_is_pe_lay_001():
|
||||
assert findings[0].rule_id == "PE-LAY-001"
|
||||
assert findings[0].status == "ERROR"
|
||||
assert findings[0].recommendation
|
||||
assert "Reconnect pad" in findings[0].recommendation
|
||||
|
||||
|
||||
def test_kicad_hierarchy_slash_is_one_sync_finding_not_per_pad():
|
||||
"""PCB /X vs schematic X (Emmaforo table) — one PE-LAY-003, pads treated as same net."""
|
||||
from backend.periscopex.pcb_net_match import kicad_nets_match
|
||||
|
||||
pairs = [
|
||||
("/ESP32_EN", "ESP32_EN"),
|
||||
("/ESP_32_BOOT", "ESP_32_BOOT"),
|
||||
("/REGN", "REGN"),
|
||||
("/LED_SDATA", "LED_SDATA"),
|
||||
("/power/REGN", "REGN"),
|
||||
]
|
||||
for pcb, sch in pairs:
|
||||
assert kicad_nets_match(pcb, sch), (pcb, sch)
|
||||
assert not kicad_nets_match("/sheet1/CLK", "/sheet2/CLK")
|
||||
assert not kicad_nets_match("/ESP32_EN", "ESP32_BOOT")
|
||||
|
||||
pins = {
|
||||
"1": "ESP32_EN",
|
||||
"2": "ESP_32_BOOT",
|
||||
"3": "REGN",
|
||||
"4": "LED_SDATA",
|
||||
}
|
||||
graph = DesignGraph(
|
||||
components={
|
||||
"U1": Component(
|
||||
reference="U1", value="", footprint="",
|
||||
component_type=ComponentType.IC, mpn="ESP",
|
||||
pins=pins,
|
||||
),
|
||||
},
|
||||
nets={n: Net(name=n, net_type=NetType.SIGNAL, pins=[]) for n in pins.values()},
|
||||
)
|
||||
layout = LayoutGraph(
|
||||
footprints={
|
||||
"U1": LayoutFootprint(
|
||||
reference="U1", x=0, y=0, layer="F.Cu",
|
||||
pads=[
|
||||
LayoutPad(number="1", x=0, y=0, net="/ESP32_EN"),
|
||||
LayoutPad(number="2", x=1, y=0, net="/ESP_32_BOOT"),
|
||||
LayoutPad(number="3", x=2, y=0, net="/REGN"),
|
||||
LayoutPad(number="4", x=3, y=0, net="/LED_SDATA"),
|
||||
],
|
||||
),
|
||||
},
|
||||
)
|
||||
findings = check_pcb_net_match(graph, layout)
|
||||
assert [f.rule_id for f in findings] == ["PE-LAY-003"]
|
||||
assert findings[0].status == "INFO"
|
||||
assert "individual pads" in findings[0].recommendation.lower() or "Do not retouch" in findings[0].recommendation
|
||||
assert "Won't fix" not in findings[0].recommendation
|
||||
assert "Reconnect pad" not in findings[0].recommendation
|
||||
|
||||
|
||||
def test_hierarchy_plus_real_mismatch_keeps_only_real_pe_lay_001():
|
||||
graph = DesignGraph(
|
||||
components={
|
||||
"U1": Component(
|
||||
reference="U1", value="", footprint="",
|
||||
component_type=ComponentType.IC, mpn="X",
|
||||
pins={"1": "ESP32_EN", "2": "GND"},
|
||||
),
|
||||
},
|
||||
nets={
|
||||
"ESP32_EN": Net(name="ESP32_EN", net_type=NetType.SIGNAL, pins=[]),
|
||||
"GND": Net(name="GND", net_type=NetType.GROUND, pins=[]),
|
||||
"+3V3": Net(name="+3V3", net_type=NetType.POWER, pins=[]),
|
||||
},
|
||||
)
|
||||
layout = LayoutGraph(
|
||||
footprints={
|
||||
"U1": LayoutFootprint(
|
||||
reference="U1", x=0, y=0, layer="F.Cu",
|
||||
pads=[
|
||||
LayoutPad(number="1", x=0, y=0, net="/ESP32_EN"),
|
||||
LayoutPad(number="2", x=1, y=0, net="+3V3"),
|
||||
],
|
||||
),
|
||||
},
|
||||
)
|
||||
findings = check_pcb_net_match(graph, layout)
|
||||
assert [f.rule_id for f in findings] == ["PE-LAY-001"]
|
||||
assert findings[0].pins == ["2"]
|
||||
assert "+3V3" in findings[0].finding
|
||||
|
||||
|
||||
def test_missing_footprint_is_pe_lay_002():
|
||||
|
||||
Reference in New Issue
Block a user