[tests] clean up some over-specific tests
This commit is contained in:
parent
06ed2ce54a
commit
e071bd89b0
4 changed files with 26 additions and 62 deletions
|
|
@ -245,54 +245,3 @@ def test_boolean_invalid_inputs_raise_pattern_error() -> None:
|
|||
for bad in (123, object(), [123]):
|
||||
with pytest.raises(PatternError, match='Unsupported type'):
|
||||
boolean([rect], bad, operation='intersection')
|
||||
|
||||
|
||||
def test_bridge_holes() -> None:
|
||||
from masque.utils.boolean import _bridge_holes
|
||||
|
||||
# Outer: 10x10 square
|
||||
outer = numpy.array([[0, 0], [10, 0], [10, 10], [0, 10]])
|
||||
# Hole: 2x2 square in the middle
|
||||
hole = numpy.array([[4, 4], [6, 4], [6, 6], [4, 6]])
|
||||
|
||||
bridged = _bridge_holes(outer, [hole])
|
||||
|
||||
# We expect more vertices than outer + hole
|
||||
# Original outer has 4, hole has 4. Bridge adds 2 (to hole) and 2 (back to outer) + 1 to close hole loop?
|
||||
# Our implementation:
|
||||
# 1. outer up to bridge edge (best_edge_idx)
|
||||
# 2. bridge point on outer
|
||||
# 3. hole reordered starting at max X
|
||||
# 4. close hole loop (repeat max X)
|
||||
# 5. bridge point on outer again
|
||||
# 6. rest of outer
|
||||
|
||||
# max X of hole is 6 at (6,4) or (6,6). argmax will pick first one.
|
||||
# hole vertices: [4,4], [6,4], [6,6], [4,6]. argmax(x) is index 1: (6,4)
|
||||
# roll hole to start at (6,4): [6,4], [6,6], [4,6], [4,4]
|
||||
|
||||
# intersection of ray from (6,4) to right:
|
||||
# edges of outer: (0,0)-(10,0), (10,0)-(10,10), (10,10)-(0,10), (0,10)-(0,0)
|
||||
# edge (10,0)-(10,10) spans y=4.
|
||||
# intersection at (10,4). best_edge_idx = 1 (edge from index 1 to 2)
|
||||
|
||||
# vertices added:
|
||||
# outer[0:2]: (0,0), (10,0)
|
||||
# bridge pt: (10,4)
|
||||
# hole: (6,4), (6,6), (4,6), (4,4)
|
||||
# hole close: (6,4)
|
||||
# bridge pt back: (10,4)
|
||||
# outer[2:]: (10,10), (0,10)
|
||||
|
||||
expected_len = 11
|
||||
assert len(bridged) == expected_len
|
||||
|
||||
# verify it wraps around the hole and back
|
||||
# index 2 is bridge_pt
|
||||
assert_allclose(bridged[2], [10, 4])
|
||||
# index 3 is hole reordered max X
|
||||
assert_allclose(bridged[3], [6, 4])
|
||||
# index 7 is hole closed at max X
|
||||
assert_allclose(bridged[7], [6, 4])
|
||||
# index 8 is bridge_pt back
|
||||
assert_allclose(bridged[8], [10, 4])
|
||||
|
|
|
|||
|
|
@ -10,6 +10,18 @@ from ..shapes import Path as MPath, Polygon
|
|||
from ..repetition import Grid
|
||||
from ..file import dxf
|
||||
|
||||
|
||||
def _matches_open_path(actual: numpy.ndarray, expected: numpy.ndarray) -> bool:
|
||||
return bool(
|
||||
numpy.allclose(actual, expected)
|
||||
or numpy.allclose(actual, expected[::-1])
|
||||
)
|
||||
|
||||
|
||||
def _matches_closed_vertices(actual: numpy.ndarray, expected: numpy.ndarray) -> bool:
|
||||
return {tuple(row) for row in actual.tolist()} == {tuple(row) for row in expected.tolist()}
|
||||
|
||||
|
||||
def test_dxf_roundtrip(tmp_path: Path):
|
||||
lib = Library()
|
||||
pat = Pattern()
|
||||
|
|
@ -47,21 +59,20 @@ def test_dxf_roundtrip(tmp_path: Path):
|
|||
polys = [s for s in top_pat.shapes["1"] if isinstance(s, Polygon)]
|
||||
assert len(polys) >= 1
|
||||
poly_read = polys[0]
|
||||
# DXF polyline might be shifted or vertices reordered, but here they should be simple
|
||||
assert_allclose(poly_read.vertices, poly_verts)
|
||||
assert _matches_closed_vertices(poly_read.vertices, poly_verts)
|
||||
|
||||
# Verify 3-point Path
|
||||
paths = [s for s in top_pat.shapes["2"] if isinstance(s, MPath)]
|
||||
assert len(paths) >= 1
|
||||
path_read = paths[0]
|
||||
assert_allclose(path_read.vertices, path_verts)
|
||||
assert _matches_open_path(path_read.vertices, path_verts)
|
||||
assert path_read.width == 2
|
||||
|
||||
# Verify 2-point Path
|
||||
paths2 = [s for s in top_pat.shapes["3"] if isinstance(s, MPath)]
|
||||
assert len(paths2) >= 1
|
||||
path2_read = paths2[0]
|
||||
assert_allclose(path2_read.vertices, path2_verts)
|
||||
assert _matches_open_path(path2_read.vertices, path2_verts)
|
||||
assert path2_read.width == 0
|
||||
|
||||
# Verify Ref with Grid
|
||||
|
|
@ -158,4 +169,4 @@ def test_dxf_read_legacy_polyline() -> None:
|
|||
|
||||
polys = [shape for shape in top_pat.shapes["legacy"] if isinstance(shape, Polygon)]
|
||||
assert len(polys) == 1
|
||||
assert_allclose(polys[0].vertices, [[0, 0], [10, 0], [10, 10]])
|
||||
assert _matches_closed_vertices(polys[0].vertices, numpy.array([[0, 0], [10, 0], [10, 10]]))
|
||||
|
|
|
|||
|
|
@ -364,7 +364,8 @@ def test_pather_place_treeview_resolves_once() -> None:
|
|||
|
||||
p.place(tree)
|
||||
|
||||
assert list(lib.keys()) == ['child']
|
||||
assert len(lib) == 1
|
||||
assert 'child' in lib
|
||||
assert 'child' in p.pattern.refs
|
||||
assert 'B' in p.pattern.ports
|
||||
|
||||
|
|
@ -379,7 +380,8 @@ def test_pather_plug_treeview_resolves_once() -> None:
|
|||
|
||||
p.plug(tree, {'A': 'B'})
|
||||
|
||||
assert list(lib.keys()) == ['child']
|
||||
assert len(lib) == 1
|
||||
assert 'child' in lib
|
||||
assert 'child' in p.pattern.refs
|
||||
assert 'A' not in p.pattern.ports
|
||||
|
||||
|
|
|
|||
|
|
@ -90,9 +90,11 @@ def test_svg_uses_unique_ids_for_colliding_mangled_names(tmp_path: Path) -> None
|
|||
|
||||
root = ET.fromstring(svg_path.read_text())
|
||||
ids = [group.attrib["id"] for group in root.iter(f"{SVG_NS}g")]
|
||||
hrefs = [use.attrib[XLINK_HREF] for use in root.iter(f"{SVG_NS}use")]
|
||||
top_group = next(group for group in root.iter(f"{SVG_NS}g") if group.attrib["id"] == "top")
|
||||
hrefs = [use.attrib[XLINK_HREF] for use in top_group.iter(f"{SVG_NS}use")]
|
||||
|
||||
assert ids.count("a_b") == 1
|
||||
assert len(set(ids)) == len(ids)
|
||||
assert "#a_b" in hrefs
|
||||
assert "#a_b_2" in hrefs
|
||||
assert len(hrefs) == 2
|
||||
assert len(set(hrefs)) == 2
|
||||
assert all(href.startswith("#") for href in hrefs)
|
||||
assert all(href[1:] in ids for href in hrefs)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue