test(b06,b08): 횡단도 벽 폭 ↔ 수량 벽 두께 대조 시험 — 지금 빨강(H2.0 메 · 윗폭 0.675/밑폭 1.375 ↔ 상부 0.75/하부 1.05) · 맞출 쪽 판정 전이라 xfail(strict)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
2026-09-14 14:28:07 +09:00
co-authored by Claude Opus 5
parent ce8339f34a
commit e9b8eacc90
@@ -0,0 +1,102 @@
"""횡단도(B06)가 그리는 돌쌓기 벽 폭과 수량(B08)이 세는 벽 두께가 **같은 값인가** — 대조 시험.
왜 (2026-09-14 브레인 차례 「두께 차이」) — 같은 다단 벽을 두 곳이 다른 두께로 봄:
B06 `REVET_THICKNESS_M` 0.45(울진 뒷길이 관측 · 표시용) → 윗폭 1.5×0.45 · 밑폭 윗폭 + 기울기×H
B08 `wall_thickness` 실무 구조물도 식 → 상부 뒷길이 + 0.30 · 하부 상부 + 0.30×(H1)
어느 쪽으로 맞출지는 아직 안 정함 — 그래서 `xfail(strict)`: 지금은 빨강이 **나야** 하고,
두 값이 맞춰지면 통과로 뒤집혀 이 표시를 걷으라고 알림.
실제 화면 코드를 컴파일해 Node 로 돌림(`test_b06_extra_shift_floor` 와 같은 방식).
"""
import json
import subprocess
import sys
from pathlib import Path
import pytest
PROJECT_ROOT = Path(__file__).resolve().parents[2]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from B08_Quantity.B08_Quantity_Engine_UnitQuantity_StoneSpec import ( # noqa: E402
_back_length,
wall_thickness,
)
TSC = PROJECT_ROOT / "config" / "node_modules" / "typescript" / "bin" / "tsc"
MODULE = PROJECT_ROOT / "B06_Section" / "B06_Section_UI_Cross_Culvert_Extra.ts"
FORM = "돌쌓기(메)"
LEAN = 0.35 # 품셈 13-4-4 [주]⑪ 메쌓기 성토 ~3m
_RUNNER = """
const { buildOutletExtras } = require(process.argv[3]);
const { writeFileSync } = require("node:fs");
const groundAt = (offset) => 95 - offset / 2;
const result = buildOutletExtras({
start: { offset: 0, elevation: 100 },
startBottomElevation: 100,
outward: 1,
groundAt,
limitOffset: 60,
adjusts: [{ x: 0, d: null, h: 2.0, m: "%(form)s" }],
leanFor: () => %(lean)s,
});
const wall = result.walls[0];
const [bottomBack, topBack, topFront, bottomFront] = wall.points;
writeFileSync(process.argv[2], JSON.stringify({
pureHeight: wall.height + 0.5,
top: Math.abs(topFront.offset - topBack.offset),
bottom: Math.abs(bottomFront.offset - bottomBack.offset),
}));
"""
def _drawn(tmp_path: Path) -> dict:
out = tmp_path / "out"
subprocess.run( # noqa: S603 — 고정 실행 파일
[
"node",
str(TSC),
"--ignoreConfig",
"--target",
"es2022",
"--module",
"commonjs",
"--skipLibCheck",
"--outDir",
str(out),
str(MODULE),
],
cwd=str(PROJECT_ROOT),
check=False,
capture_output=True,
)
compiled = next(out.rglob("B06_Section_UI_Cross_Culvert_Extra.js"), None)
assert compiled is not None, "화면 코드가 JS 로 안 나옴 — tsc 실패"
(out / "runner.cjs").write_text(_RUNNER % {"form": FORM, "lean": LEAN}, encoding="utf-8")
result = tmp_path / "result.json"
subprocess.run( # noqa: S603 — 고정 실행 파일
["node", str(out / "runner.cjs"), str(result), str(compiled)],
cwd=str(PROJECT_ROOT),
check=True,
capture_output=True,
)
return json.loads(result.read_text(encoding="utf-8"))
@pytest.mark.skipif(not TSC.is_file(), reason="프론트엔드 의존성 미설치")
@pytest.mark.xfail(strict=True, reason="B06 0.45 표시값 ↔ B08 구조물도 식 — 맞출 쪽 판정 대기")
def test_횡단도_벽_폭과_수량_벽_두께가_같다(tmp_path: Path) -> None:
drawn = _drawn(tmp_path)
height = drawn["pureHeight"]
options = {"form": FORM}
back_cm = _back_length(options, wet=False, height_m=height)
top, bottom, basis = wall_thickness(options, back_cm=back_cm, height_m=height)
assert (round(drawn["top"], 2), round(drawn["bottom"], 2)) == (
round(top, 2),
round(bottom, 2),
), (
f"H {height:.2f} — 횡단도 윗폭 {drawn['top']:.3f} · 밑폭 {drawn['bottom']:.3f}"
f" ↔ 수량 {basis}"
)