"""계수 갈래·채움콘 강도·돌 중량 근거 (2026-09-08 사용자 확정 2차 ⑤·⑨·⑩). ⚠ 겨누는 것 여섯 ① **빈 칸은 「안 정함」**이다 — 기본값은 등록부가 아니라 계산 쪽이 갖는다 ② ⑨ 기본은 **품셈 열**(야면석 고임돌 0.11 · 채움 0.15) ③ ⑨ 「실무 관행」으로 두면 건설품셈 참고자료 열(0.15 · 0.20)로 덮이고 사유가 뜬다 ④ ⑩ 강도 기본은 **210**, 180 을 고르면 그 값이 이긴다 ⑤ ⚠ 아는 값이 아니면 **조용히 넘어가지 않는다** ⑥ ⑤ 돌 중량은 값을 그대로 두되 **어디서 온 값인지**가 줄에 적힌다 """ from __future__ import annotations import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT)) from B08_Quantity.B08_Quantity_Engine_UnitQuantity import ( # noqa: E402 FILL_CONCRETE_MPA_DEFAULT, fill_concrete_mpa, stone_masonry, wants_practice_coefficients, ) def 성분(**options: object) -> tuple[dict, list[str]]: components, notes = stone_masonry( 2.5, 10.0, {"height_m": 2.5, "length_m": 10.0, "back_len_cm": 45, **options}, wet=True ) return {c.name: c for c in components}, notes def test_빈_칸은_안_정함이다() -> None: assert wants_practice_coefficients({}) is False assert fill_concrete_mpa({})[0] == FILL_CONCRETE_MPA_DEFAULT == "210" def test_기본은_품셈_열이다() -> None: """야면석을 고르면 품셈 계수(고임돌 0.11 · 채움 0.15)가 선다 — 확정 ⑨.""" got, _ = 성분(stone_kind="야면석·호박돌") 돌쌓기 = got["돌쌓기"].amount assert abs(got["고임돌"].amount - 돌쌓기 * 0.11) < 0.01 assert abs(got["채움콘크리트"].amount - 돌쌓기 * 0.15) < 0.01 def test_실무_관행으로_두면_덮이고_사유가_뜬다() -> None: """⚠ 값이 조용히 바뀌면 안 된다 — 덮어썼다는 사실이 사유로 나온다.""" got, notes = 성분(stone_kind="야면석·호박돌", stone_coeff_basis="실무 관행") 돌쌓기 = got["돌쌓기"].amount assert abs(got["고임돌"].amount - 돌쌓기 * 0.15) < 0.01 assert abs(got["채움콘크리트"].amount - 돌쌓기 * 0.20) < 0.01 assert any("실무 관행" in n for n in notes) def test_강도는_기본_210이고_고르면_그_값() -> None: 기본, _ = 성분() assert 기본["채움콘크리트"].spec == "210" assert "확정 ⑩" in 기본["채움콘크리트"].basis 고름, _ = 성분(fill_concrete_mpa="180") assert 고름["채움콘크리트"].spec == "180" assert "고른 값" in 고름["채움콘크리트"].basis def test_모르는_강도는_조용히_넘어가지_않는다() -> None: 강도, basis = fill_concrete_mpa({"fill_concrete_mpa": "240"}) assert 강도 == "210" assert "240" in basis def test_돌_중량은_값을_두고_근거를_남긴다() -> None: """⚠ 품셈·교본에 돌중량표가 없다 — 값은 그대로 두고 출처를 줄에 단다(확정 ⑤). ⚠ 2026-09-09 확정 5차 큰 것 7 로 **관측표를 보는 자리가 야면석 계열로 좁아졌다** — 종류를 안 고르면 계산식(뒷길이 × 0.77 × 2.65)으로 선다. 출처를 다는 못은 그대로이되 **어느 조건에서 다는지**가 달라졌으므로 조건을 명시한다. """ got, _ = 성분(stone_kind="야면석·호박돌") 야면석 = got["돌"] # 이름 「돌」 + 규격에 종류(명세 13장 Ⓒ) assert 야면석.spec == "야면석·호박돌" assert abs(야면석.amount - got["돌쌓기"].amount * 0.88) < 1e-9 assert "울진" in 야면석.basis and "품셈·교본에는 돌중량표가 없음" in 야면석.basis assert 야면석.source == "uljin_library" def test_안_고르면_계산식으로_서고_그_사실이_적힌다() -> None: """⚠ 값이 서는 것으로 끝나면 **관측값인지 계산값인지**를 화면에서 못 가른다.""" got, notes = 성분() 돌 = got["돌"] assert 돌.source == "" # 관측 출처가 아니다 assert "0.77" in 돌.basis and "2.65" in 돌.basis assert any("계산식" in n for n in notes) def test_두께_칸이_비면_식으로_돈다() -> None: """확정 2차 ② 후반 「사용자가 값을 바꿀 수 있게」 — 빈 칸은 「안 정함」이다.""" from B08_Quantity.B08_Quantity_Engine_UnitQuantity import wall_thickness top, bottom, basis = wall_thickness({}, back_cm=45, height_m=2.5) assert abs(top - 0.75) < 1e-9 # 뒷길이 0.45 + 0.30 assert abs(bottom - 1.20) < 1e-9 # 상부 + 0.30 × (2.5 − 1.0) assert "뒷길이" in basis and "사용자 입력" not in basis def test_넣은_두께가_식을_이긴다() -> None: from B08_Quantity.B08_Quantity_Engine_UnitQuantity import wall_thickness top, bottom, basis = wall_thickness( {"thickness_top_m": 0.6, "thickness_bottom_m": "1.0"}, back_cm=45, height_m=2.5 ) assert (top, bottom) == (0.6, 1.0) assert basis.count("사용자 입력") == 2 def test_상부만_넣으면_하부는_그_위에서_식을_잇는다() -> None: from B08_Quantity.B08_Quantity_Engine_UnitQuantity import wall_thickness top, bottom, _ = wall_thickness({"thickness_top_m": 0.6}, back_cm=45, height_m=2.5) assert (top, abs(bottom - 1.05) < 1e-9) == (0.6, True) # 0.6 + 0.30 × 1.5 def test_두께가_입적까지_닿는다() -> None: """칸만 만들고 계산이 안 읽으면 「값이 안 닿는」 옛 사고와 같아진다.""" 기본, _ = 성분() 두꺼움, _ = 성분(thickness_top_m=1.2, thickness_bottom_m=1.6) assert 두꺼움["입적"].amount > 기본["입적"].amount def test_이상한_값은_식으로_돌린다() -> None: from B08_Quantity.B08_Quantity_Engine_UnitQuantity import wall_thickness for bad in ("", None, "두꺼움", -1, 0): top, _, basis = wall_thickness({"thickness_top_m": bad}, back_cm=45, height_m=2.5) assert abs(top - 0.75) < 1e-9 and "사용자 입력" not in basis, bad