mask.py
1 # SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-or-later OR CERN-OHL-S-2.0+ OR Apache-2.0 2 # type: ignore 3 import unittest 4 5 from pdkmaster.technology import mask as _msk 6 7 8 class MaskTest(unittest.TestCase): 9 def test_error(self): 10 class WrongCond(_msk._MultiMaskCondition): 11 pass 12 13 with self.assertRaises(AttributeError): 14 WrongCond( 15 mask=_msk.DesignMask(name="MyMask"), 16 others=_msk.DesignMask(name="Other"), 17 ) 18 19 mask = _msk.DesignMask(name="mask") 20 21 with self.assertRaises(ValueError): 22 _msk.Spacing(mask1=mask, mask2=mask) 23 24 # No value given for .remove() 25 with self.assertRaises(ValueError): 26 mask.remove(()) 27 28 def test_mask(self): 29 # We use DesignMask object to also cover code for _Mask and other 30 # classes 31 mask = _msk.DesignMask(name="MyMask") 32 mask2 = _msk.DesignMask(name="MyMask2") 33 mask3 = _msk.DesignMask(name="MyMask3") 34 35 alias = mask.alias("Alias") 36 samenet = mask.same_net 37 38 cond = mask.width >= 1.0 39 cond2 = mask2.length <= 2.0 40 41 self.assertEqual(mask.width, _msk._MaskProperty(mask=mask, name="width")) 42 self.assertEqual( 43 str(alias), "MyMask.alias(Alias)", 44 ) 45 self.assertNotEqual(mask.width, mask.length) 46 self.assertEqual( 47 mask.extend_over(other=mask2), 48 _msk._DualMaskProperty( 49 mask1=mask, mask2=mask2, name="extend_over", commutative=False, 50 ), 51 ) 52 self.assertNotEqual( 53 mask.extend_over(other=mask2), 54 _msk._DualMaskProperty( 55 mask1=mask, mask2=mask3, name="extend_over", commutative=False, 56 ), 57 ) 58 self.assertEqual( 59 mask.enclosed_by(other=mask2), 60 _msk._DualMaskEnclosureProperty( 61 mask1=mask, mask2=mask2, name="enclosed_by", 62 ), 63 ) 64 self.assertEqual( 65 mask.is_inside(mask2, mask3), 66 _msk._InsideCondition(mask=mask, others=(mask3, mask2)), 67 ) 68 self.assertEqual( 69 mask.is_outside(mask2), 70 _msk._OutsideCondition(mask=mask, others=(mask2)), 71 ) 72 self.assertEqual( 73 mask.parts_with(cond), 74 _msk._PartsWith(mask=mask, condition=cond), 75 ) 76 with self.assertRaises(TypeError): 77 mask.parts_with(cond2) 78 self.assertEqual( 79 mask.remove(mask2), 80 _msk._MaskRemove(from_=mask, what=mask2), 81 ) 82 self.assertEqual( 83 mask.remove(mask2, mask3), 84 _msk._MaskRemove(from_=mask, what=_msk.Join(mask2, mask3)) 85 ) 86 self.assertEqual( 87 alias, _msk._MaskAlias(mask=mask, name="Alias"), 88 ) 89 self.assertEqual(samenet, _msk._SameNet(mask)) 90 91 self.assertNotEqual(alias, "") 92 self.assertNotEqual(samenet, "") 93 self.assertNotEqual(mask.extend_over(other=mask2), "") 94 self.assertNotEqual(mask.enclosed_by(other=mask2), "") 95 self.assertNotEqual(mask.is_inside(mask2, mask3), "") 96 self.assertNotEqual(mask.is_outside(mask2), "") 97 self.assertNotEqual(mask.parts_with(cond), "") 98 self.assertNotEqual(mask.remove(mask2), "") 99 self.assertNotEqual(_msk.Join((mask, mask2)), "") 100 self.assertNotEqual(_msk.Intersect((mask, mask3)), "") 101 102 self.assertEqual(tuple(mask.designmasks), (mask,)) 103 self.assertEqual(samenet.designmasks, (mask,)) 104 self.assertEqual(set(mask.parts_with(cond).designmasks), {mask}) 105 self.assertEqual(set(mask.remove(mask2).designmasks), {mask, mask2}) 106 self.assertEqual(set(_msk.Join((mask, mask2)).designmasks), {mask, mask2}) 107 self.assertEqual( 108 set(_msk.Intersect((mask, mask2, mask3)).designmasks), 109 {mask, mask2, mask3}, 110 ) 111 112 self.assertEqual(_msk.Join((mask, mask2)), _msk.Join((mask2, mask))) 113 self.assertEqual(_msk.Intersect((mask, mask2)), _msk.Intersect((mask2, mask))) 114 115 self.assertEqual( 116 mask.parts_with(cond).name, 117 f"{mask.name}.parts_with({cond})", 118 ) 119 self.assertEqual( 120 mask.remove(mask2).name, 121 f"{mask.name}.remove({mask2.name})", 122 ) 123 self.assertEqual( 124 _msk.Join((mask, mask2)).name, 125 f"join({mask.name},{mask2.name})" 126 ) 127 self.assertEqual( 128 _msk.Intersect((mask, mask2, mask3)).name, 129 f"intersect({mask.name},{mask2.name},{mask3.name})" 130 ) 131 132 self.assertEqual(hash(alias), hash(alias.name)) 133 self.assertEqual(hash(samenet), hash(samenet.name)) 134 self.assertEqual( 135 hash(mask.is_inside(mask2, mask3)), 136 hash(_msk._InsideCondition(mask=mask, others=(mask3, mask2))), 137 ) 138 self.assertEqual( 139 hash(mask.parts_with(cond)), 140 hash(f"{mask.name}.parts_with({cond})"), 141 ) 142 self.assertEqual( 143 hash(mask.remove(mask2)), 144 hash((mask, mask2)), 145 ) 146 self.assertEqual( 147 hash(mask.remove(_msk.Join((mask2, mask3)))), 148 hash(mask.remove(_msk.Join((mask3, mask2)))), 149 ) 150 self.assertEqual( 151 hash(_msk.Join((mask, mask2))), 152 hash(_msk.Join((mask2, mask))), 153 ) 154 self.assertEqual( 155 hash(_msk.Intersect((mask, mask2))), 156 hash(_msk.Intersect((mask2, mask))), 157 ) 158 159 self.assertEqual( 160 mask.parts_with(cond).name, 161 f"{mask.parts_with(cond)!r}", 162 ) 163 self.assertEqual( 164 f"{mask.is_inside(mask2)!r}", 165 f"{mask!r}.is_inside({mask2!r})", 166 ) 167 168 def test_connect(self): 169 mask = _msk.DesignMask(name="mask") 170 mask2 = _msk.DesignMask(name="mask2") 171 mask3 = _msk.DesignMask(name="mask3") 172 173 conn = _msk.Connect(mask, mask2) 174 conn2 = _msk.Connect(mask2, mask) 175 conn3 = _msk.Connect(mask, (mask2, mask3)) 176 conn4 = _msk.Connect((mask3, mask2), mask) 177 178 self.assertNotEqual(conn, False) 179 self.assertEqual(str(conn), "connect(mask,mask2)") 180 181 self.assertEqual(conn, conn2) 182 self.assertEqual(conn3, conn4) 183 184 self.assertEqual(hash(conn), hash(conn2)) 185 self.assertEqual(hash(conn3), hash(conn4))