- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환 - Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용 - pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관) - worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md) - D:\Rhino-MCP 경로 참조를 새 위치로 치환 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
118 lines
3.5 KiB
Python
118 lines
3.5 KiB
Python
"""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)
|