[tests] Add machine-generated test suite
This commit is contained in:
parent
9bb0d5190d
commit
1de76bff47
24 changed files with 1703 additions and 0 deletions
134
masque/test/test_shape_advanced.py
Normal file
134
masque/test/test_shape_advanced.py
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
import pytest
|
||||
import numpy
|
||||
from numpy.testing import assert_equal, assert_allclose
|
||||
from numpy import pi
|
||||
import os
|
||||
|
||||
from ..shapes import Arc, Ellipse, Circle, Polygon, Path, Text, PolyCollection
|
||||
from ..error import PatternError
|
||||
|
||||
# 1. Text shape tests
|
||||
def test_text_to_polygons():
|
||||
font_path = "/usr/share/fonts/truetype/dejavu/DejaVuMathTeXGyre.ttf"
|
||||
if not os.path.exists(font_path):
|
||||
pytest.skip("Font file not found")
|
||||
|
||||
t = Text("Hi", height=10, font_path=font_path)
|
||||
polys = t.to_polygons()
|
||||
assert len(polys) > 0
|
||||
assert all(isinstance(p, Polygon) for p in polys)
|
||||
|
||||
# Check that it advances
|
||||
# Character 'H' and 'i' should have different vertices
|
||||
# Each character is a set of polygons. We check the mean x of vertices for each character.
|
||||
char_x_means = [p.vertices[:, 0].mean() for p in polys]
|
||||
assert len(set(char_x_means)) >= 2
|
||||
|
||||
# 2. Manhattanization tests
|
||||
def test_manhattanize():
|
||||
# Diamond shape
|
||||
poly = Polygon([[0, 5], [5, 10], [10, 5], [5, 0]])
|
||||
grid = numpy.arange(0, 11, 1)
|
||||
|
||||
manhattan_polys = poly.manhattanize(grid, grid)
|
||||
assert len(manhattan_polys) >= 1
|
||||
for mp in manhattan_polys:
|
||||
# Check that all edges are axis-aligned
|
||||
dv = numpy.diff(mp.vertices, axis=0)
|
||||
# For each segment, either dx or dy must be zero
|
||||
assert numpy.all((dv[:, 0] == 0) | (dv[:, 1] == 0))
|
||||
|
||||
# 3. Comparison and Sorting tests
|
||||
def test_shape_comparisons():
|
||||
c1 = Circle(radius=10)
|
||||
c2 = Circle(radius=20)
|
||||
assert c1 < c2
|
||||
assert not (c2 < c1)
|
||||
|
||||
p1 = Polygon([[0, 0], [10, 0], [10, 10]])
|
||||
p2 = Polygon([[0, 0], [10, 0], [10, 11]]) # Different vertex
|
||||
assert p1 < p2
|
||||
|
||||
# Different types
|
||||
assert c1 < p1 or p1 < c1
|
||||
assert (c1 < p1) != (p1 < c1)
|
||||
|
||||
# 4. Arc/Path Edge Cases
|
||||
def test_arc_edge_cases():
|
||||
# Wrapped arc (> 360 deg)
|
||||
a = Arc(radii=(10, 10), angles=(0, 3*pi), width=2)
|
||||
polys = a.to_polygons(num_vertices=64)
|
||||
# Should basically be a ring
|
||||
bounds = a.get_bounds_single()
|
||||
assert_allclose(bounds, [[-11, -11], [11, 11]], atol=1e-10)
|
||||
|
||||
def test_path_edge_cases():
|
||||
# Zero-length segments
|
||||
p = Path(vertices=[[0, 0], [0, 0], [10, 0]], width=2)
|
||||
polys = p.to_polygons()
|
||||
assert len(polys) == 1
|
||||
assert_equal(polys[0].get_bounds_single(), [[0, -1], [10, 1]])
|
||||
|
||||
# 5. PolyCollection with holes
|
||||
def test_poly_collection_holes():
|
||||
# Outer square, inner square hole
|
||||
# PolyCollection doesn't explicitly support holes, but its constituents (Polygons) do?
|
||||
# wait, Polygon in masque is just a boundary. Holes are usually handled by having multiple
|
||||
# polygons or using specific winding rules.
|
||||
# masque.shapes.Polygon doc says "specify an implicitly-closed boundary".
|
||||
# Pyclipper is used in connectivity.py for holes.
|
||||
|
||||
# Let's test PolyCollection with multiple polygons
|
||||
verts = [
|
||||
[0, 0], [10, 0], [10, 10], [0, 10], # Poly 1
|
||||
[2, 2], [2, 8], [8, 8], [8, 2] # Poly 2
|
||||
]
|
||||
offsets = [0, 4]
|
||||
pc = PolyCollection(verts, offsets)
|
||||
polys = pc.to_polygons()
|
||||
assert len(polys) == 2
|
||||
assert_equal(polys[0].vertices, [[0, 0], [10, 0], [10, 10], [0, 10]])
|
||||
assert_equal(polys[1].vertices, [[2, 2], [2, 8], [8, 8], [8, 2]])
|
||||
|
||||
def test_poly_collection_constituent_empty():
|
||||
# One real triangle, one "empty" polygon (0 vertices), one real square
|
||||
# Note: Polygon requires 3 vertices, so "empty" here might mean just some junk
|
||||
# that to_polygons should handle.
|
||||
# Actually PolyCollection doesn't check vertex count per polygon.
|
||||
verts = [
|
||||
[0, 0], [1, 0], [0, 1], # Tri
|
||||
# Empty space
|
||||
[10, 10], [11, 10], [11, 11], [10, 11] # Square
|
||||
]
|
||||
offsets = [0, 3, 3] # Index 3 is start of "empty", Index 3 is also start of Square?
|
||||
# No, offsets should be strictly increasing or handle 0-length slices.
|
||||
# vertex_slices uses zip(offsets, chain(offsets[1:], [len(verts)]))
|
||||
# if offsets = [0, 3, 3], slices are [0:3], [3:3], [3:7]
|
||||
offsets = [0, 3, 3]
|
||||
pc = PolyCollection(verts, offsets)
|
||||
# Polygon(vertices=[]) will fail because of the setter check.
|
||||
# Let's see if pc.to_polygons() handles it.
|
||||
# It calls Polygon(vertices=vv) for each slice.
|
||||
# slice [3:3] gives empty vv.
|
||||
with pytest.raises(PatternError):
|
||||
pc.to_polygons()
|
||||
|
||||
def test_poly_collection_valid():
|
||||
verts = [
|
||||
[0, 0], [1, 0], [0, 1],
|
||||
[10, 10], [11, 10], [11, 11], [10, 11]
|
||||
]
|
||||
offsets = [0, 3]
|
||||
pc = PolyCollection(verts, offsets)
|
||||
assert len(pc.to_polygons()) == 2
|
||||
shapes = [
|
||||
Circle(radius=20),
|
||||
Circle(radius=10),
|
||||
Polygon([[0, 0], [10, 0], [10, 10]]),
|
||||
Ellipse(radii=(5, 5))
|
||||
]
|
||||
sorted_shapes = sorted(shapes)
|
||||
assert len(sorted_shapes) == 4
|
||||
# Just verify it doesn't crash and is stable
|
||||
assert sorted(sorted_shapes) == sorted_shapes
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue