Treat KiCad PNM as MPN and skip missing U* as INSUFFICIENT_EVIDENCE.

HubAudio CSV has no U13–U39 rows; those refs stay without an invented part number. IC Value fills MPN when PNM is blank. Progress no longer labels netlist-only ICs as “no MPN in BOM”.
This commit is contained in:
2026-09-21 00:53:06 +02:00
parent e31981c812
commit 82d185ccf4
7 changed files with 225 additions and 15 deletions
+47
View File
@@ -0,0 +1,47 @@
"""HubAudio KiCad BOM: PNM column, grouped refs, no invented U13…U39 MPNs."""
from pathlib import Path
from backend.periscopex.parsers import ic_mpn_skip_reason, parse_bom
FIXTURE = Path(__file__).parent / "fixtures" / "hubaudio_kicad_bom.csv"
SKIPPED = ("U13", "U15", "U25", "U28", "U34", "U35", "U36", "U39")
def test_hubaudio_header_is_pnm_not_mpn():
header = FIXTURE.read_text(encoding="utf-8-sig").splitlines()[0]
assert "PNM" in header
assert "Manufacturer Part Number" not in header
def test_hubaudio_pnm_and_value_fallback():
bom = parse_bom(FIXTURE, mpn_col="Manufacturer Part Number")
assert bom["U1"]["mpn"] == "TPS22965DSGR"
assert bom["U10"]["mpn"] == "W25Q128JVS"
assert bom["U11"]["mpn"] == "ESP32-S31-WROOM-3"
# PNM blank, Value is the orderable MPN; grouped Reference list.
assert bom["U2"]["mpn"] == "PCA9534ARGTR"
assert bom["U3"]["mpn"] == "PCA9534ARGTR"
assert bom["U2"]["value"] == "PCA9534ARGTR"
assert (bom["U4"]["mpn"] == "INA228AQDGSRQ1") and bom["U8"]["mpn"] == "INA228AQDGSRQ1"
assert bom["L4"]["mpn"] == "BLM21PG121SN1D"
assert bom["L4"]["value"] == "120 ohm"
def test_hubaudio_skipped_refs_absent_no_invented_mpn():
bom = parse_bom(FIXTURE, mpn_col="Manufacturer Part Number")
for ref in SKIPPED:
assert ref not in bom
reason = ic_mpn_skip_reason(
ref, mpn=None, value="", footprint="MIKILAB_TPD2E007DCKR:SOT65P210X110-3N",
in_bom=False,
)
assert reason and reason.startswith("INSUFFICIENT_EVIDENCE")
assert "not in BOM" in reason
def test_ic_skip_empty_pnm_quotes_value():
reason = ic_mpn_skip_reason(
"U99", mpn=None, value="", footprint="QFN", in_bom=True, bom_value="",
)
assert reason and "PNM/MPN empty" in reason