"""rebar_calc 테스트 (Rhino 없이 실행됩니다). 기준값 출처: docs/design_rules.md """ import pytest import rebar_calc as rc # ---- 철근 이름 -> 공칭 직경 ---- @pytest.mark.parametrize("name, expected", [ ("H13", 12.7), ("H16", 15.9), ("H19", 19.1), ("H22", 22.2), ("H25", 25.4), ("H29", 28.6), ]) def test_nominal_diameter(name, expected): assert rc.nominal_diameter(name) == expected def test_nominal_diameter_accepts_d_prefix_and_lowercase(): assert rc.nominal_diameter("D25") == 25.4 assert rc.nominal_diameter("h25") == 25.4 def test_nominal_diameter_unknown_bar_raises(): with pytest.raises(ValueError): rc.nominal_diameter("H99") # ---- 구부림 반지름 (프로젝트 적용값, 건축기준 기반) ---- def test_bend_radius_h25_is_3db(): # 두부보 H25 주철근: R = 76.2mm assert rc.bend_radius("H25") == pytest.approx(76.2) def test_bend_radius_h29_is_4db(): # 두부보 H29: R = 114.4mm assert rc.bend_radius("H29") == pytest.approx(114.4) def test_bend_radius_h38_is_5db(): assert rc.bend_radius("H38") == pytest.approx(5 * 38.1) def test_bend_radius_stirrup_d16_or_less_is_2db(): assert rc.bend_radius("H16", is_stirrup=True) == pytest.approx(2 * 15.9) assert rc.bend_radius("H13", is_stirrup=True) == pytest.approx(2 * 12.7) def test_bend_radius_stirrup_d19_or_more_uses_general_table(): assert rc.bend_radius("H19", is_stirrup=True) == pytest.approx(3 * 19.1) def test_bend_radius_main_bar_h16_is_3db_not_stirrup_rule(): assert rc.bend_radius("H16") == pytest.approx(3 * 15.9) # ---- KDS 24 14 21 최소 내면 지름 ---- def test_kds_min_inner_diameter_d16_or_less_is_2db(): assert rc.kds_min_inner_diameter("H16") == pytest.approx(2 * 15.9) def test_kds_min_inner_diameter_d19_or_more_is_3_5db(): assert rc.kds_min_inner_diameter("H25") == pytest.approx(3.5 * 25.4) def test_project_radius_satisfies_kds_for_all_bars(): # 프로젝트 R(반지름)의 2배 = 내면 지름이 KDS 최소값 이상이어야 합니다. for name in ["H13", "H16", "H19", "H22", "H25", "H29"]: assert rc.satisfies_kds_bend(name, rc.bend_radius(name)) assert rc.satisfies_kds_bend(name, rc.bend_radius(name, is_stirrup=True)) def test_too_small_radius_fails_kds(): # H25는 내면 지름 88.9mm 이상이 필요 -> 반지름 40mm(지름 80mm)는 부족 assert not rc.satisfies_kds_bend("H25", 40.0) # ---- 갈고리 연장 길이 ---- def test_hook_extension_90_is_12db(): assert rc.hook_extension("H25", 90) == pytest.approx(12 * 25.4) def test_hook_extension_135_is_6db(): assert rc.hook_extension("H25", 135) == pytest.approx(6 * 25.4) def test_hook_extension_180_is_4db(): assert rc.hook_extension("H25", 180) == pytest.approx(4 * 25.4) def test_hook_extension_180_has_60mm_minimum(): # H13: 4db = 50.8mm < 60mm 이므로 60mm assert rc.hook_extension("H13", 180) == pytest.approx(60.0) def test_hook_extension_unsupported_angle_raises(): with pytest.raises(ValueError): rc.hook_extension("H25", 45) def test_kds_min_hook_extension_is_5db_for_90_to_150(): assert rc.kds_min_hook_extension("H25", 90) == pytest.approx(5 * 25.4) assert rc.kds_min_hook_extension("H25", 135) == pytest.approx(5 * 25.4) def test_project_hook_extension_satisfies_kds_for_90_and_135(): for name in ["H13", "H16", "H19", "H22", "H25", "H29"]: for angle in (90, 135): assert rc.hook_extension(name, angle) >= rc.kds_min_hook_extension(name, angle)