AnasSarkiz/magnetic-shutter-remote-r8

A USB‑C rechargeable battery-powered ESP32‑C3 wireless controller with Li‑ion charging, protected 3.3‑V buck‑boost regulation, thermal/safety monitoring, status LEDs, buttons, programming UART, crystal clock, and 2.4‑GHz antenna matching network.

Version
0.4.0-prototype
License
unset
Stars
0

tests/cam/test_r9_declared_clearances.py

import importlib.util
from pathlib import Path
import sys
import unittest
from shapely.geometry import LineString, box

ROOT=Path(__file__).resolve().parents[2]
SPEC=importlib.util.spec_from_file_location('r9_declared_review',ROOT/'scripts/review-r9-declared-clearances.py')
REVIEW=importlib.util.module_from_spec(SPEC)
sys.modules[SPEC.name]=REVIEW
SPEC.loader.exec_module(REVIEW)
G=REVIEW.PROCESS.GEOMETRY
BOARD={'min_trace_to_pad_edge_clearance':.15,'min_via_edge_to_pad_edge_clearance':.35,
       'min_via_hole_edge_to_via_hole_edge_clearance':.5}


def via(name,x,net='a'):
    return G.Drill(name,'via',('top','bottom'),net,G.circle(x,0,.3),G.circle(x,0,.45))


class DeclaredClearanceTests(unittest.TestCase):
    def test_trace_gap_above_capability_but_below_board_rule_fails(self):
        traces=[G.Copper('a','track','top','a',LineString([(-1,0),(1,0)]).buffer(.075)),
                G.Copper('b','track','top','b',LineString([(-1,.28),(1,.28)]).buffer(.075))]
        rows=REVIEW.declared_measurements(traces,[],BOARD)
        self.assertEqual(len(rows),1)
        self.assertAlmostEqual(rows[0]['gap_mm'],.13)
        self.assertLess(rows[0]['gap_mm'],rows[0]['minimum_mm'])

    def test_same_net_is_not_a_via_to_smt_exemption(self):
        pad=G.Copper('land','smt','top','a',box(.5,-.2,.9,.2),'component')
        rows=REVIEW.declared_measurements([pad],[via('v',0)],BOARD)
        self.assertEqual(len(rows),1)
        self.assertAlmostEqual(rows[0]['gap_mm'],.275)
        self.assertEqual(rows[0]['minimum_mm'],.35)

    def test_drill_gap_is_checked_and_clear_pair_is_accepted(self):
        rows=REVIEW.declared_measurements([],[via('a',0),via('b',.72,'b')],BOARD)
        self.assertEqual(len(rows),1)
        self.assertAlmostEqual(rows[0]['gap_mm'],.42)
        self.assertEqual(rows[0]['minimum_mm'],.5)
        self.assertEqual(REVIEW.declared_measurements([],[via('a',0),via('b',.9,'b')],BOARD),[])

    def test_shared_barrel_requires_same_net(self):
        self.assertEqual(REVIEW.declared_measurements([],[via('a',0),via('b',0)],BOARD),[])
        rows=REVIEW.declared_measurements([],[via('a',0),via('b',0,'b')],BOARD)
        self.assertEqual(len(rows),1)
        self.assertEqual(rows[0]['gap_mm'],0)


if __name__=='__main__':unittest.main()