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”.
48 lines
1.8 KiB
Python
48 lines
1.8 KiB
Python
"""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
|