Files
Aislo/resources/tester/test_b08_stone_kind.py
T
eomsangdonandClaude Opus 5 d7cb14f416 test(B08): tmp/tests 중 tester 에 없던 47 개를 resources/tester 로 옮김
tmp/ 가 창끼리 안 건너가는 것이 확정돼(랩탑이 시간 두고 두 번 확인) 시험·예외가
저절로 건너가도록 git 안으로 옮김. 사용자 확정.

- 내용은 하나도 안 고침 — 자리만 옮김. tmp/tests 는 남겨 둠.
- 같은 이름이 이미 있던 64 개는 랩탑 것을 그대로 두고 건너뜀.
- helper_b05_*.js 둘은 랩탑이 .cjs 로 이미 올린 것과 **줄바꿈만 다른 같은 내용**이라
  복사본을 도로 뺌(시험이 .cjs 를 부름).
- resources/tester/ 에서 전체 1176 통과 · 29 건너뜀 · 실패 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 17:15:57 +09:00

123 lines
6.2 KiB
Python

"""돌 종류 축 — 계수 셋이 그 축으로 갈리는지 (2026-09-08).
⚠ 겨누는 것 다섯
① 안 고르면 **종전 값 그대로**인가 (저장된 프로젝트가 안 흔들리게)
② 고르면 산림품셈 계수로 바뀌는가
③ ⚠ 뒤채움 몫을 **뒤집어 쓰지 않는가** — 표는 「뒤채움」, 우리 식은 「빼는 몫」
④ 표에 없는 칸(「-」)을 **지어내지 않는가**
⑤ 모르는 종류를 조용히 넘기지 않는가
"""
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
load_stone_kind_table,
stone_masonry,
)
#: 고치기 전 값 — 이 셋이 바뀌면 이미 저장된 프로젝트의 수량이 흔들린 것이다.
#: ⚠ 막자갈이 두 번 갈렸다 — 15.130 → 12.630(2026-09-08 확정 ② 벽 두께 실무 구조물도 식)
#: → **9.375**(2026-09-09 확정 5차 작은 것 3, 랩탑 보조). 지금은 「입적 − 몸통」이 아니라
#: **뒷채움 사다리꼴**(정본 상 0.30 · 하 0.45)이라 **돌 종류·뒷길이를 아예 안 본다.**
#: 고임돌·채움콘크리트는 여전히 비탈면적 × 종류별 계수다.
BEFORE = {"고임돌": 3.915, "채움콘크리트": 5.220, "막자갈": 9.375}
def 성분(options: dict) -> dict:
components, notes = stone_masonry(
2.5, 10.0, {"height_m": 2.5, "length_m": 10.0, **options}, wet=True
)
return {c.name: round(c.amount, 3) for c in components}, notes
def test_안_고르면_종전_값_그대로() -> None:
"""⚠ 값을 못 낸다고 멈추면 이미 저장된 프로젝트가 통째로 빈다."""
got, notes = 성분({"back_len_cm": 45})
for name, before in BEFORE.items():
assert abs(got[name] - before) < 0.002, f"{name}{before}{got[name]} 로 바뀌었다"
assert any("돌 종류를 안 정해" in n for n in notes), "기본값으로 선 사실을 안 알린다"
def test_야면석을_고르면_계수가_바뀐다() -> None:
"""품셈 13-4-3 야면석 0.11 · 13-4-4 [주]① 야면석 0.15 (뒷길이 45)."""
got, notes = 성분({"back_len_cm": 45, "stone_kind": "야면석·호박돌"})
assert abs(got["고임돌"] - 26.101 * 0.11) < 0.01
assert abs(got["채움콘크리트"] - 26.101 * 0.15) < 0.01
# ⚠ 사유는 여러 갈래가 함께 뜬다(기초 유/무 등) — **돌 종류 사유만** 본다.
assert all("돌 종류를 안 정해" not in n for n in notes)
def test_깬돌은_종전과_같은_계수() -> None:
"""⚠ 종전 값이 「깬돌」 줄이었다 — 그것이 확인되면 지금까지 값의 성격이 밝혀진다."""
got, _ = 성분({"back_len_cm": 45, "stone_kind": "깬돌"})
assert abs(got["고임돌"] - BEFORE["고임돌"]) < 0.002
assert abs(got["채움콘크리트"] - BEFORE["채움콘크리트"]) < 0.002
def test_막자갈은_이제_돌_종류_축이_아니다() -> None:
"""⚠ 뒤집힌 시험이다 — 종전에는 「깬돌 막자갈 > 야면석 막자갈」을 겨눴다.
그 시험은 막자갈이 「입적 − 몸통」이던 시절 **뒤채움 몫을 뒤집어 쓰는 것**을 막으려던
것이었다(표는 뒤채움 몫, 우리 식은 빼는 몫 — 반대라 19.045 가 나온 적 있다).
2026-09-09 확정 5차로 막자갈이 **뒷채움 사다리꼴**로 갈리면서 그 축이 사라졌다 —
이제 뒤집어 쓸 몫 자체가 없다. 대신 **종류로 안 갈린다는 것**을 못 박는다.
"""
야면석, _ = 성분({"back_len_cm": 45, "stone_kind": "야면석·호박돌"})
깬돌, _ = 성분({"back_len_cm": 45, "stone_kind": "깬돌"})
assert 깬돌["막자갈"] == 야면석["막자갈"] == BEFORE["막자갈"]
# ⚠ 갈리는 줄은 그대로 갈려야 한다 — 축이 통째로 죽은 것이 아니다.
assert 깬돌["고임돌"] > 야면석["고임돌"]
def test_표에_없는_칸은_지어내지_않는다() -> None:
"""⚠ 견치돌은 뒷길이 25·30 이 원문에서 「-」다 — 그 규격에 그 돌을 안 쓴다는 뜻."""
table = load_stone_kind_table()
assert table["wedge_stone_m3_per_m2"]["견치돌"]["25"] is None
assert table["wedge_stone_m3_per_m2"]["야면석·호박돌"]["75"] is None
def test_모르는_종류는_조용히_넘어가지_않는다() -> None:
got, notes = 성분({"back_len_cm": 45, "stone_kind": "화강석"})
assert any("아는 돌 종류가 아니라" in n for n in notes)
# 값은 종전대로 서되 사유가 남는다 — 0 으로 때우지 않는다.
assert got["고임돌"] > 0
def test_산출_근거에_돌_종류가_적힌다() -> None:
"""⚠ 값만 바뀌고 근거가 그대로면 화면에서 왜 달라졌는지 못 짚는다."""
components, _ = stone_masonry(
2.5,
10.0,
{"height_m": 2.5, "length_m": 10.0, "back_len_cm": 45, "stone_kind": "깬돌"},
wet=True,
)
# ⚠ 막자갈은 이제 종류를 안 본다 — 계수가 종류로 갈리는 **두 줄**을 본다.
# 채움콘크리트는 값이 갈리는데 근거에 종류가 안 적히던 자리다(2026-09-09 맞춤).
for name in ("고임돌", "채움콘크리트"):
got = next(c for c in components if c.name == name)
assert "깬돌" in got.basis, name
def test_고른_종류의_빈_칸은_줄을_안_만든다() -> None:
"""⚠ 원문 「-」인 칸에 값이 서던 자리(만들다 잡음).
야면석 75㎝ 는 13-4-3 에 「-」다 — `None` 이라고 안 덮으면 종전 값(깬돌 0.25)이 남아
**원문에 없는 값이 조용히 선다.** 0 줄로 만들지도 않는다 — 0 은 「없음」과 구별이 안 된다.
"""
got, notes = 성분({"back_len_cm": 75, "stone_kind": "야면석·호박돌"})
assert "고임돌" not in got
assert any("「-」" in n or "칸이 비어" in n for n in notes)
def test_뒷길이_일곱_규격이_다_선다() -> None:
"""⚠ 앞서 네 칸만 들고 25·30·75 를 접고 있었다."""
for back in (25, 30, 35, 45, 55, 60, 75):
got, _ = 성분({"back_len_cm": back, "stone_kind": "깬잡석"})
assert got.get("채움콘크리트", 0) > 0, back