def test_picklers(self): data = [ BBox(1, 2, 3, 4), Point(1, 2), Vector(3, 4), ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6), 'sharp'), Pen('red', 1.5), Brush('blue'), PenBrush(Pen('green', 0.5), '#808080'), Transform((1.6, 2.5, 3.4, 4.3, 5.2, 6.1)), ElemRectangle('r1', PenBrush('red'), Point(1, 2), Point(-3, -4)), ] data_dict = {} for datum in data: name = type(datum).__name__ data_dict[name] = datum with self.subTest(name=name): self.assertMatch(datum, case=name) self.assertMatch(data, case='all as list') self.assertMatch(data_dict, case='all as dict') self.assertMatch([Point(1, 2), Point(3, 4)], case='point list') self.assertMatch([Point(1, 2), Vector(3, 4)], case='point-vector list') self.assertMatch(dict(p1=Point(1, 2), p2=Point(3, 4)), case='point dict') self.assertMatch([Point(1, 2), Vector(3, 4), '5,6', 7.8], case='point-vector-str-float list')
def test_repr_str(self): cp = ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)) self.assertEqual("(Point(1, 2), Vector(3, 4), Vector(5, 6), 'smooth')", str(cp)) self.assertEqual( "ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6), 'smooth')", repr(cp))
def test_restore(self): cp1 = ControlPoint(Point(11, 12), Vector(13, 4), Vector(15, 6), 'sharp') cp2 = ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)) cp1.restore(cp2) self.assertEqual(cp1, cp2) self.assertIsNot(cp1.c, cp2.c)
def test_init(self): cp = ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)) self.assertEqual(cp.c, Point(1, 2)) self.assertEqual(cp.dl, Vector(3, 4)) self.assertEqual(cp.dr, Vector(5, 6)) self.assertEqual(cp.kind, 'smooth') self.assertEqual(cp.l, Point(4, 6)) self.assertEqual(cp.r, Point(6, 8))
def test_path_translate(self): path = [Point(0, 0), Point(1, 2)] self.assertEqual([Point(1, 3), Point(2, 5)], path_translate(path, Vector(1, 3), as_pt=True)) self.assertEqual([(1, 3), (2, 5)], path_translate(path, Vector(1, 3))) self.assertEqual([Point(-1, -3), Point(0, -1)], path_translate(path, Point(-1, -3), as_pt=True)) self.assertEqual([(-1, -3), (0, -1)], path_translate(path, Point(-1, -3)))
def test_transform(self): cp = ControlPoint(Point(0, 0), Vector(1, 1), Vector(-1, -1), 'very-smooth') t = Transform().translate(1, 1).rotate(90).scale(2, 2) cpt = cp.transform(t) self.assertAlmostEqual(cpt.c, Point(2, -2)) self.assertAlmostEqual(cpt.dl, Vector(2, -2)) self.assertAlmostEqual(cpt.dr, Vector(-2, 2)) self.assertEqual(cpt.kind, 'very-smooth')
def test_vec(self): vec1 = Vector(1, 1) vec2 = Vector(1, 1) vec3 = Vector(1, 1.000000001) vec4 = Vector(-1, 1.01) self.assertEqual(vec1, vec2) self.assertNotEqual(vec1, vec3) self.assertAlmostEqual(vec1, vec3) # TODO-self.assertNotAlmostEqual(vec1, vec4) with self.assertRaisesRegex(AssertionError, 'Vector.* == Vector'): self.assertNotEqual(vec1, vec2) with self.assertRaisesRegex(AssertionError, 'Vector.* != Vector.*1.000000001'): self.assertEqual(vec1, vec3) with self.assertRaisesRegex(AssertionError, 'y: 1 != 1.01 within 7 places'): self.assertAlmostEqual(vec1, vec4)
def test_copy(self): cp = ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)) cp.c.restore(Point(0, 0)) self.assertEqual(ControlPoint(Point(0, 0), Vector(3, 4), Vector(5, 6)), cp) cp = ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)) cpc = cp.copy() cp.c.restore(Point(0, 0)) self.assertEqual(ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)), cpc)
def path_translate(path: PointList, dxy: Union[Point, Vector], as_pt=False) -> PointUnionList: """Rotate all points by angle (in degrees) about 0,0""" dxy = Vector(*dxy.xy()) if as_pt: return [p + dxy for p in path] else: return [(p + dxy).xy() for p in path]
def test_fixed(self): cp = ControlPoint(PointRelative(1, 2, Point(3, 4)), Vector(3, 4), Vector(5, 6)) self.assertNotEqual( cp, ControlPoint(Point(4, 6), Vector(3, 4), Vector(5, 6))) self.assertEqual(cp.fixed(), ControlPoint(Point(4, 6), Vector(3, 4), Vector(5, 6)))
def test_cp(self): cp1 = ControlPoint(Point(1, 1), Vector(1, 1), Vector(-1, 1)) cp2 = ControlPoint(Point(1, 1), Vector(1, 1), Vector(-1, 1)) cp3 = ControlPoint(Point(1, 1), Vector(1, 1), Vector(-1, 1.000000001)) cp4 = ControlPoint(Point(1, 1), Vector(1, 1), Vector(-1, 1.01)) self.assertEqual(cp1, cp2) self.assertNotEqual(cp1, cp3) self.assertAlmostEqual(cp1, cp3) # TODO-self.assertNotAlmostEqual(cp1, cp4) with self.assertRaisesRegex( AssertionError, 'ControlPoint.*Point.*Vector.*Vector.*== ControlPoint.*Point.*Vector.*Vector' ): self.assertNotEqual(cp1, cp2) with self.assertRaisesRegex( AssertionError, 'ControlPoint.*Point.*Vector.*Vector.*!= ControlPoint.*Point.*Vector.*Vector.*1.000000001' ): self.assertEqual(cp1, cp3) with self.assertRaisesRegex(AssertionError, 'y: 1 != 1.01 within 7 places'): self.assertAlmostEqual(cp1, cp4)
def plus(r, c=Point(0, 0)) -> XYList: """Generate a plus sign of radius r about c as a list of x,y pairs""" vx = Vector(r, 0) vy = Vector(0, r) return [p.xy() for p in [c - vx, c + vx, c, c - vy, c + vy]]
def test_bbox(self): cp = ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)) self.assertEqual(BBox(1, 2, 6, 8), cp.bbox()) cp = ControlPoint(Point(1, 2), Vector(-3, -4), Vector(5, 6)) self.assertEqual(BBox(-2, -2, 6, 8), cp.bbox())
def test_eq(self): cp = ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)) self.assertEqual(cp, ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6))) self.assertNotEqual(cp, "not even close") self.assertNotEqual( cp, ControlPoint(Point(1, 1), Vector(3, 4), Vector(5, 6))) self.assertNotEqual( cp, ControlPoint(Point(1, 2), Vector(1, 4), Vector(5, 6))) self.assertNotEqual( cp, ControlPoint(Point(1, 2), Vector(3, 4), Vector(1, 6))) self.assertNotEqual( cp, ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6), 'sharp'))
def test_assertAlmostEqual_vector_list(self): """Test that List[Vector] works with assertAlmostEqual.""" self.assertAlmostEqual([Vector(0, 0)], [Vector(0, 0)]) self.assertAlmostEqual([Vector(0, 0)], [Vector(1e-9, -1e-9)])
def test_reversed(self): cp = ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)) cr = cp.reversed() self.assertEqual(cp.c, cr.c) self.assertEqual(cp.l, cr.r) self.assertEqual(cp.r, cr.l)
def cross(r, c=Point(0, 0)) -> XYList: """Generate a cross of radius r about c as a list of x,y pairs""" r *= sqrt(2) / 2 vx = Vector(r, r) vy = Vector(-r, r) return [p.xy() for p in [c - vx, c + vx, c, c - vy, c + vy]]
def test_round(self): cp1 = ControlPoint(Point(1.123, 2.247), Vector(2.55, 4.499), Vector(5.3, 6.0)) cp2 = ControlPoint(Point(1, 2), Vector(3, 4), Vector(5, 6)) self.assertEqual(cp2, cp1.round(0))
def test_bez_self_intersect(self): # bez_split(cp1: 'ControlPoint', cp2: 'ControlPoint', t=0.5) -> Tuple[ForwardRef('ControlPoint'), ForwardRef('ControlPoint'), ForwardRef('ControlPoint')] curve = [ ControlPoint(Point(0, 0), Vector(0, 1), Vector(0, -1)), ControlPoint(Point(2, 0), Vector(0, -1), Vector(0, 1)), ] self.assertEqual([], bez_self_intersect(curve)) curve = [ ControlPoint(Point(0, 0), Vector(0, -1), Vector(0, 1)), ControlPoint(Point(2, 0), Vector(0, -1), Vector(0, 1)), ] expected = [[ ControlPoint(Point(1.0, 0.0), Vector(0.5, 0.25), Vector(0.5, -0.25), 'sharp'), ControlPoint(Point(2, 0), Vector(0.0, -0.5), Vector(0.0, 0.5), 'smooth') ], [ ControlPoint(Point(1.0, 0.0), Vector(-0.5, 0.25), Vector(-0.5, -0.25), 'sharp'), ControlPoint(Point(0, 0), Vector(0.0, -0.5), Vector(0.0, 0.5), 'smooth') ]] self.assertEqual(expected, bez_self_intersect(curve))