import os import sys import pytest sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) import box_core # noqa: E402 from box_core import FEMALE, MALE, PLAIN # noqa: E402 def _is_orthogonal(points): n = len(points) for i in range(n): a, b = points[i], points[(i + 1) % n] if abs(a[0] - b[0]) > 1e-9 and abs(a[1] - b[1]) > 1e-9: return False return True def _size(panel): x0, y0, x1, y1 = panel.bbox() return round(x1 - x0, 6), round(y1 - y0, 6) def test_default_finger_is_three_times_thickness(): segs = box_core.edge_segments(100 + 6, 3, 9, MALE) widths = {round(e - s, 6) for s, e, _ in segs} assert len(widths) == 1 assert len(segs) % 2 == 1 # 0 = auto : même résultat qu'une largeur explicite de 3 × t auto = box_core.box_panels(100, 80, 50, 3, finger=0) explicit = box_core.box_panels(100, 80, 50, 3, finger=9) assert [p.points for p in auto] == [p.points for p in explicit] @pytest.mark.parametrize("middle,finger", [(94, 9), (50, 9), (10, 3), (200, 7)]) def test_finger_count_is_odd(middle, finger): n = box_core.finger_count(middle, finger) assert n % 2 == 1 and n >= 3 def test_male_and_female_edges_are_complementary(): male = box_core.edge_segments(106, 3, 9, MALE) female = box_core.edge_segments(106, 3, 9, FEMALE) assert len(male) == len(female) for (s1, e1, l1), (s2, e2, l2) in zip(male, female): assert (s1, e1) == (s2, e2) assert {l1, l2} == {0.0, 3.0} def test_closed_box_has_six_orthogonal_panels_with_exterior_size(): panels = box_core.box_panels(100, 80, 50, 3) assert [p.name for p in panels] == ["Avant", "Arrière", "Gauche", "Droite", "Fond", "Couvercle"] sizes = {p.name: _size(p) for p in panels} assert sizes["Avant"] == (100, 50) # Côtés et fond : coins en retrait, mais les créneaux atteignent le bord extérieur assert sizes["Gauche"] == (80, 50) assert sizes["Fond"] == (100, 80) for p in panels: assert _is_orthogonal(p.points) def test_interior_dimensions_add_thickness(): closed = box_core.box_panels(100, 80, 50, 3, interior=True, lid=True) assert _size(closed[0]) == (106, 56) opened = box_core.box_panels(100, 80, 50, 3, interior=True, lid=False) assert _size(opened[0]) == (106, 53) def test_open_box_has_five_panels_and_straight_top_edge(): panels = box_core.box_panels(100, 80, 50, 3, lid=False) assert len(panels) == 5 front = panels[0] top_points = [p for p in front.points if abs(p[1]) < 1e-9] assert sorted(top_points) == [(0.0, 0.0), (100.0, 0.0)] def test_kerf_offsets_outline_outward(): raw = box_core.box_panels(100, 80, 50, 3)[0] kerfed = box_core.offset_orthogonal(raw.points, 0.05) x0, y0, x1, y1 = box_core.Panel("k", kerfed).bbox() assert round(x1 - x0, 6) == 100.1 assert round(y1 - y0, 6) == 50.1 assert _is_orthogonal(kerfed) def test_layout_does_not_overlap(): panels = box_core.make_box(100, 80, 50, 3, gap=5) boxes = [p.bbox() for p in panels] for i, a in enumerate(boxes): for b in boxes[i + 1:]: overlap = a[0] < b[2] and b[0] < a[2] and a[1] < b[3] and b[1] < a[3] assert not overlap def test_too_small_dimension_raises(): with pytest.raises(ValueError): box_core.box_panels(10, 80, 50, 3) def test_plain_edge_is_single_segment(): assert box_core.edge_segments(100, 3, 9, PLAIN) == [(3, 97, 0.0)]