woodshop/tests/test_cutlist.py

59 lines
1.8 KiB
Python

"""Tests for the cut list / board-feet / shopping estimate."""
import pytest
from woodshop.cutlist import board_feet, cut_rows, nominal_dims, shopping
from woodshop.scene import Scene
def test_nominal_dims():
assert nominal_dims("2x4") == (2.0, 4.0)
assert nominal_dims("4x4") == (4.0, 4.0)
def test_board_feet_uses_nominal():
# 2x4 at 96in = (2*4*96)/144 = 5.333 bd-ft
assert board_feet("2x4", 96) == pytest.approx(5.3333, abs=1e-3)
def test_cut_rows_groups_and_counts():
s = Scene()
s.place("2x4", 48)
s.place("2x4", 48)
s.place("2x4", 29)
rows = cut_rows(s)
by_len = {r["length_in"]: r for r in rows}
assert by_len[48.0]["count"] == 2
assert by_len[29.0]["count"] == 1
assert by_len[48.0]["board_feet"] == pytest.approx(board_feet("2x4", 48) * 2)
def test_shopping_rounds_up_with_waste():
s = Scene()
s.place("2x4", 48)
s.place("2x4", 48) # 96in total -> with 10% waste = 105.6 -> 2 sticks of 96in
assert shopping(s) == {"2x4": 2}
def test_empty_shopping():
assert shopping(Scene()) == {}
def test_end_tenon_extends_cut_length():
from woodshop.cutlist import cut_length
s = Scene()
s.place("2x4", 24)
assert cut_length(s.get_part("p1")) == 24
s.add_feature("p1", "tenon", face="end_b", depth_in=1.5) # protrudes 1.5"
assert cut_length(s.get_part("p1")) == 25.5
# the cut row and board-feet reflect the longer piece
assert cut_rows(s)[0]["length_in"] == 25.5
assert cut_rows(s)[0]["board_feet"] == pytest.approx(board_feet("2x4", 25.5))
def test_cut_feature_does_not_change_cut_length():
from woodshop.cutlist import cut_length
s = Scene()
s.place("2x4", 24)
s.add_feature("p1", "mortise", face="top", width_in=1, height_in=1, depth_in=0.5)
assert cut_length(s.get_part("p1")) == 24 # cuts don't reduce stock you buy