"""Tests for the cost-estimate price book (deterministic math; no network).""" from woodshop import prices as P from woodshop.cutplan import ShopSettings, build_cut_plan from woodshop.scene import Scene def test_estimate_sums_sticks_and_applies_hst(): s = Scene() for _ in range(3): s.place("2x4", 40) # 3 × 40" -> 2 sticks plan = build_cut_plan(s) est = P.estimate(plan, {"2x4": 4.00}, hst=0.15) line = next(ln for ln in est.lines if ln.stock == "2x4") assert line.qty == 2 and line.unit_price == 4.00 and line.total == 8.00 assert est.subtotal == 8.00 assert est.tax == 1.20 assert est.total == 9.20 def test_plywood_priced_per_sheet(): s = Scene() s.place("ply-3/4", 40, width_in=20) s.place("ply-3/4", 40, width_in=20) # both fit one sheet plan = build_cut_plan(s) est = P.estimate(plan, {"ply-3/4": 63.98}, hst=0.0) line = next(ln for ln in est.lines if ln.stock == "ply-3/4") assert line.qty == 1 and line.unit_price == 63.98 and est.total == 63.98 def test_lumber_price_scales_with_stick_length(): s = Scene() s.place("2x4", 40) plan = build_cut_plan(s, settings=ShopSettings(stick_len_in=192)) # 16' sticks est = P.estimate(plan, {"2x4": 4.00}) # priced per 8' stick line = next(ln for ln in est.lines if ln.stock == "2x4") assert line.unit_price == 8.00 # 192/96 × $4 def test_missing_price_is_flagged_not_invented(): s = Scene() s.place("2x4", 40) plan = build_cut_plan(s) est = P.estimate(plan, {}) # empty book assert est.missing == ["2x4"] assert est.subtotal == 0.0 assert "No price on file" in P.format_estimate(est) def test_save_and_load_roundtrip(tmp_path, monkeypatch): monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path)) P.save_prices({"2x4": 3.49, "ply-3/4": 59.99}) loaded = P.load_prices() assert loaded["2x4"] == 3.49 and loaded["ply-3/4"] == 59.99 # untouched stocks still come from defaults assert loaded["2x6"] == P.DEFAULT_PRICES["2x6"] def test_corrupt_price_file_falls_back_to_defaults(tmp_path, monkeypatch): monkeypatch.setenv("XDG_CONFIG_HOME", str(tmp_path)) path = P._config_path() path.parent.mkdir(parents=True, exist_ok=True) path.write_text("{ not json") assert P.load_prices()["2x4"] == P.DEFAULT_PRICES["2x4"] def test_format_estimate_empty(): assert "nothing to buy" in P.format_estimate(P.estimate(build_cut_plan(Scene()))) def test_parse_price_reads_json_ld(): html = ('') assert P._parse_price(html) == 3.98 def test_parse_price_none_when_absent(): assert P._parse_price("no price here") is None