MustafaMulla29/rp2040-bldc-motor-controller-new

73×72 mm 4-layer USB‑C PD (5/9/15/20 V) RP2040 controller PCB with protected power switching, MCT8329A sensorless BLDC three-phase MOSFET bridge, USB data/programming, onboard controls, and three motor outputs feeding a 2212 motor through rigid bullet adapters.

Version
0.3.100
License
unset
Stars
0

scripts/test-order-review.py

"""Regression cases for the actual generated USB geometry and current budget."""
import copy,importlib.util,json,unittest
from pathlib import Path
ROOT=Path(__file__).resolve().parent.parent

def module(name,path):
 s=importlib.util.spec_from_file_location(name,ROOT/path);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m
usb=module('usb','scripts/pcb-audit/audit-usb.py');budget=module('budget','scripts/check-current-budget.py')
class ReviewRegressionTests(unittest.TestCase):
 @classmethod
 def setUpClass(cls):
  cls.c=json.loads((ROOT/'dist/index/circuit.json').read_text());cls.spec=json.loads((ROOT/'manufacturing/current-budget.json').read_text())
 def test_current_generated_usb_passes(self):self.assertFalse(usb.analyze(self.c)['failures'])
 def test_returning_a_segment_to_bottom_is_rejected(self):
  c=copy.deepcopy(self.c);r=next(r for r in c if r.get('pcb_trace_id')=='usb_dp_connector' and r['type']=='pcb_trace')
  r['route'][0]['layer']='bottom'
  self.assertTrue(any(f['issue']=='USB not entirely on top' for f in usb.analyze(c)['failures']))
 def test_missing_reference_plane_is_rejected(self):
  c=[r for r in self.c if not (r['type']=='pcb_copper_pour' and r['layer']=='inner1')]
  self.assertTrue(any(f['issue']=='L2 ground reference gap' for f in usb.analyze(c)['failures']))
 def test_oversized_usb_width_is_rejected(self):
  c=copy.deepcopy(self.c);r=next(r for r in c if r.get('pcb_trace_id')=='usb_dp_connector' and r['type']=='pcb_trace');r['route'][0]['width']=.4
  self.assertTrue(any(f['issue']=='USB width changed' for f in usb.analyze(c)['failures']))
 def test_current_budget_passes(self):self.assertFalse(budget.review(self.c,self.spec)['failures'])
 def test_old_resistor_exceeds_allocated_total(self):
  c=copy.deepcopy(self.c);next(r for r in c if r['type']=='source_component' and r['name']=='R142')['resistance']=1500
  self.assertIn('Input allocation exceeds PD contract',budget.review(c,self.spec)['failures'])
 def test_excess_logic_load_is_rejected(self):
  s=copy.deepcopy(self.spec);s['logicOutputAllocationMa']['9000']=1000
  self.assertIn('Input allocation exceeds PD contract',budget.review(self.c,s)['failures'])
if __name__=='__main__':unittest.main()