/ test / unit / dispatch / shape.py
shape.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 geometry as _geo
 6  from pdkmaster.dispatch.shape import ShapeDispatcher
 7  
 8  
 9  # Simple dispatcher that just returns the type of the shape
10  class MyDispatcher(ShapeDispatcher):
11      def _Shape(self, shape: _geo._Shape):
12          return type(shape)
13  
14  
15  class IsRectangularDispatcher(ShapeDispatcher):
16      def _Shape(self, shape: _geo._Shape):
17          return False
18  
19      def _Rectangular(self, shape: _geo._Rectangular, *args, **kwargs):
20          return True
21  
22  
23  class ShapeDispatchTest(unittest.TestCase):
24      def test_notimplemented(self):
25          with self.assertRaises(NotImplementedError):
26              # Call ShapeDispatched._Shape() method
27              ShapeDispatcher()(_geo.origin)
28  
29      def test_dispatch(self):
30          disp = MyDispatcher()
31  
32          with self.assertRaises(RuntimeError):
33              disp("error")
34  
35          line = _geo.Line(point1=_geo.origin, point2=_geo.Point(x=0.0, y=1.0))
36          rect = _geo.Rect.from_size(width=2.0, height=2.0)
37          polygon = _geo.Polygon.from_floats(points=(
38              (0.0, 0.0),
39              (0.0, 1.0),
40              (1.0, 1.0),
41              (1.0, 0.0),
42              (0.0, 0.0),
43          ))
44          multipath = _geo.MultiPath(
45              _geo.Start(point=_geo.origin, width=1.0),
46              _geo.GoLeft(dist=2.0),
47              _geo.GoUp(3.0),
48          )
49          ring = _geo.Ring(
50              outer_bound=_geo.Rect.from_size(width=2.0, height=2.0),
51              ring_width=0.5,
52          )
53          rectring = _geo.RectRing(
54              outer_bound=rect, rect_width=0.4, min_rect_space=0.4,
55          )
56          label = _geo.Label(origin=_geo.origin, text="label")
57          multishape = _geo.MultiShape(shapes=(rect, polygon))
58          repeatedshape = _geo.RepeatedShape(
59              shape=rect, offset0=_geo.origin, n=2, n_dxy=_geo.Point(x=0.0, y=4.0)
60          )
61          arrayshape = _geo.ArrayShape(
62              shape=rect, offset0=_geo.origin, rows=2, columns=2, pitch_y=4.0, pitch_x=3.0,
63          )
64  
65          part1 = _geo.Rect(left=0.0, bottom=0.0, right=1.0, top=1.0)
66          part2 = _geo.Rect(left=1.0, bottom=0.0, right=2.0, top=1.0)
67          part12 = _geo.Rect(left=0.0, bottom=0.0, right=2.0, top=1.0)
68          multipartshape = _geo.MultiPartShape(fullshape=part12, parts=(part1, part2))
69  
70          # Currently only code coerage is done
71          self.assertIs(disp(_geo.origin), _geo.Point)
72          self.assertIs(disp(line), _geo.Line)
73          self.assertIs(disp(polygon), _geo.Polygon)
74          self.assertIs(disp(rect), _geo.Rect)
75          self.assertIs(disp(multipath), _geo.MultiPath)
76          self.assertIs(disp(ring), _geo.Ring)
77          self.assertIs(disp(rectring), _geo.RectRing)
78          self.assertIs(disp(label), _geo.Label)
79          self.assertIs(disp(multishape), _geo.MultiShape)
80          self.assertIs(disp(multipartshape), _geo.MultiPartShape)
81          self.assertIs(disp(multipartshape.parts[0]), _geo.Rect)
82          self.assertIs(disp(repeatedshape), _geo.RepeatedShape)
83          self.assertIs(disp(arrayshape), _geo.ArrayShape)
84  
85      def test_hier(self):
86          disp = IsRectangularDispatcher()
87  
88          rect = _geo.Rect.from_size(width=2.0, height=2.0)
89          polygon = _geo.Polygon.from_floats(points=(
90              (0.0, 0.0),
91              (0.0, 1.0),
92              (1.0, 1.0),
93              (1.0, 0.0),
94              (0.0, 0.0),
95          ))
96  
97          self.assertTrue(disp(rect))
98          self.assertFalse(disp(polygon))