59 lines
1.8 KiB
Python
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
|