from pathlib import Path import importlib.util import math import pytest HERE = Path(__file__).resolve().parent spec = importlib.util.spec_from_file_location("concrete_beam_calc", HERE / "calc.py") assert spec is not None and spec.loader is not None calc_module = importlib.util.module_from_spec(spec) spec.loader.exec_module(calc_module) compute = calc_module.compute def _load(name: str, filename: str): spec = importlib.util.spec_from_file_location(name, HERE / filename) assert spec is not None and spec.loader is not None module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module @pytest.fixture def result(): import yaml with (HERE / "input.yaml").open(encoding="utf-8") as handle: return compute(yaml.safe_load(handle)) def test_example_demands(result): v = result["values"] assert v["self_weight"] == pytest.approx(0.1) assert v["wu"] == pytest.approx(0.7325) assert v["Mu"] == pytest.approx(23.44) assert v["Vu"] == pytest.approx(5.86) def test_example_flexure(result): v = result["values"] assert v["a"] == pytest.approx(1.823529, rel=1e-5) assert v["et"] == pytest.approx(0.010283, rel=1e-3) assert v["phi"] == pytest.approx(0.9) assert v["phiMn"] == pytest.approx(23.961176, rel=1e-5) assert result["checks"]["flexure"]["ok"] is True def test_example_min_steel_and_shear(result): v = result["values"] assert v["As_min"] == pytest.approx(0.253333, rel=1e-4) assert v["phiVc"] == pytest.approx(6.244016, rel=1e-4) assert result["checks"]["minimum_steel"]["ok"] is True assert result["checks"]["shear"]["ok"] is True def test_reinforcement_geometry(result): v = result["values"] assert v["cover"] == pytest.approx(1.5) assert v["stirrup_size"] == 3 assert v["stirrup_db"] == pytest.approx(0.375) assert v["stirrup_spacing"] == pytest.approx(6.0) assert v["bar_size"] == 5 assert v["n_bars"] == 2 assert v["bar_db"] == pytest.approx(0.625) assert v["top_bar_size"] == 4 assert v["n_top_bars"] == 2 assert v["top_bar_db"] == pytest.approx(0.5) assert v["As_bars"] == pytest.approx(2 * math.pi * 0.625**2 / 4.0, rel=1e-6) def test_rejects_depth_without_room_for_bars(): import yaml with (HERE / "input.yaml").open(encoding="utf-8") as handle: inp = yaml.safe_load(handle) inp["d"] = "11.9 in" with pytest.raises(ValueError): compute(inp) def test_section_fragment_is_current(result): module = _load("beam_section", "beam_section.py") expected = module.render(result["values"]) actual = (HERE / "assets" / "beam-section.typ").read_text(encoding="utf-8") assert actual == expected