Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
7315b96d0This file is pinned to the selected release. Download the original to open it in your design tool.
"""Exercise the in-process CLI verbs end-to-end (exit codes + wiring). Complements test_cli.py
(which checks parsing). Standalone or pytest: python3 tests/test_cli_commands.py"""
import contextlib
import io
import json
import os
import sys
import tempfile
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from pcbflow import cli # noqa: E402
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
EX = os.path.join(REPO, "projects", "example-usb-c-3v3", "04_schematic", "netlist.enet")
def _run(argv):
buf = io.StringIO()
with contextlib.redirect_stdout(buf):
rc = cli.main(argv)
return rc, buf.getvalue()
def _tmp(obj, suffix):
p = tempfile.mktemp(suffix=suffix)
with open(p, "w") as f:
json.dump(obj, f)
return p
def test_ipc_and_engineering_verbs():
assert _run(["ipc", "10"])[0] == 0
assert _run(["stitch-pitch", "0.7"])[0] == 0
nets = _tmp([{"net": "VBUS", "i_peak_a": 2.0}, {"net": "GND", "i_peak_a": 5.0}], ".json")
assert _run(["widths", nets])[0] == 0
def test_spacing_and_congestion():
place = _tmp({"parts": [{"ref": "R1", "layer": "TOP", "bbox": [0, 0, 1, 1]},
{"ref": "R2", "layer": "TOP", "bbox": [1.2, 0, 2, 1]}], "min_gap": 0.5}, ".json")
rc, out = _run(["spacing", place])
assert rc == 1 and "violation" in out # 0.2mm gap < 0.5 -> flagged
cong = _tmp({"nets": [{"drc_class": "POWER_HC", "bbox": [0, 0, 4, 4]}], "w": 20, "h": 20}, ".json")
assert _run(["congestion", cong])[0] == 0
def test_enet_erc_dfm_verify_on_example():
if not os.path.exists(EX):
return
assert _run(["enet", EX])[0] == 0
assert _run(["erc", EX])[0] == 0
assert _run(["erc", EX, "--json"])[0] == 0
assert _run(["verify", EX])[0] == 0
board = _tmp({"board": {"layers": 2}, "tracks": [{"net": "SDA", "width": 0.10, "layer": "F"}]}, ".json")
assert _run(["dfm", board])[0] == 1 # sub-min track -> FAIL
assert _run(["dfm", board, "--json"])[0] == 1
def test_import_check_verb():
board = os.path.join(REPO, "projects", "example-usb-c-3v3", "10_kicad_export", "board.kicad_pcb")
if os.path.exists(EX) and os.path.exists(board):
assert _run(["import-check", EX, board])[0] == 0
def test_gate_and_export_verbs(tmp_path=None):
import pathlib
d = tempfile.mkdtemp()
sub = os.path.join(d, "04_schematic")
os.makedirs(sub)
with open(os.path.join(sub, "netlist.enet"), "w") as f:
json.dump({"version": "2.0.0", "components": {
"u": {"props": {"Designator": "U1"}, "pinInfoMap": {
"1": {"number": "1", "name": "1", "net": "VBUS"},
"2": {"number": "2", "name": "2", "net": "GND"}}},
"c": {"props": {"Designator": "C1"}, "pinInfoMap": {
"1": {"number": "1", "name": "1", "net": "VBUS"},
"2": {"number": "2", "name": "2", "net": "GND"}}}}}, f)
parent, name = pathlib.Path(d).parent, pathlib.Path(d).name
orig = cli.PROJECTS
cli.PROJECTS = parent
try:
assert _run(["gate", name, "5"])[0] == 0 # computes + records PASS
assert _run(["export", name])[0] == 1 # blocked: no approval
ap = _tmp({"approved_by": "x", "approved_at_utc": "t", "scope": "s"}, ".json")
assert _run(["export", name, "--approval", ap])[0] == 0 # cleared
finally:
cli.PROJECTS = orig
def _run_all():
for nm, fn in sorted(globals().items()):
if nm.startswith("test_") and callable(fn):
fn()
print("PASS — cli commands: ipc/widths/stitch, spacing/congestion, enet/erc/dfm/verify, "
"import-check, gate/export.")
if __name__ == "__main__":
_run_all()