woodshop/tests/test_miter.py

85 lines
2.6 KiB
Python

"""End miter / bevel angled cuts."""
import json
import pytest
from woodshop.scene import Scene
def test_add_miter_defaults_to_45_on_end():
s = Scene()
s.place("2x4", 24)
f = s.add_feature("p1", "miter") # no angle given
assert f.kind == "miter" and f.face == "end_b" and f.miter_deg == 45.0
def test_miter_forced_to_end_face():
s = Scene()
s.place("2x4", 24)
f = s.add_feature("p1", "miter", face="top", miter_deg=30) # top is invalid for miter
assert f.face == "end_b" and f.miter_deg == 30
def test_miter_roundtrips_through_json():
s = Scene()
s.place("2x4", 24)
s.add_feature("p1", "miter", miter_deg=45, bevel_deg=15)
s2 = Scene.from_dict(json.loads(json.dumps(s.to_dict())))
f = s2.get_part("p1").features[0]
assert f.kind == "miter" and f.miter_deg == 45 and f.bevel_deg == 15
def test_cutlist_notes_the_miter():
from woodshop.cutplan import build_cut_plan
s = Scene()
s.place("2x4", 24)
s.add_feature("p1", "miter", miter_deg=45)
note = build_cut_plan(s).items[0].note
assert "miter 45" in note
def test_instructions_describe_miter():
from woodshop.instructions import build_steps, format_steps
s = Scene()
s.place("2x4", 24)
s.add_feature("p1", "miter", miter_deg=45, bevel_deg=10)
text = format_steps(build_steps(s))
assert "miter 45" in text and "bevel 10" in text
def test_jigs_suggest_miter_sled_for_repeats():
from woodshop.jigs import suggest_jigs
s = Scene()
for _ in range(4):
s.place("2x4", 24)
for pid in ("p1", "p2", "p3", "p4"):
s.add_feature(pid, "miter", miter_deg=45)
kinds = [j.kind for j in suggest_jigs(s)]
assert "miter-sled" in kinds
def test_miter_geometry_removes_material():
pytest.importorskip("build123d")
from woodshop.geometry import part_solid
s = Scene()
s.place("2x4", 24)
square_vol = part_solid(s.get_part("p1")).volume
s.add_feature("p1", "miter", miter_deg=45)
mitered_vol = part_solid(s.get_part("p1")).volume
assert mitered_vol < square_vol # a wedge was cut off
def test_miter_preview_is_a_wedge_not_a_box():
pytest.importorskip("pyvista")
pytest.importorskip("build123d")
from woodshop.viewer import feature_preview_mesh
s = Scene()
s.place("2x4", 24)
feat = s.add_feature("p1", "miter", miter_deg=45)
mesh = feature_preview_mesh(s.get_part("p1"), feat)
assert mesh is not None and mesh.n_points > 0
# the wedge sits at the mitered end (x≈24), not a 1" box at the end centre
xmax = mesh.bounds[1]
assert xmax > 20 # spans out to the board end, like the real cut