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:
@@ -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×(H−1)
|
||||
어느 쪽으로 맞출지는 아직 안 정함 — 그래서 `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}"
|
||||
)
|
||||
Reference in New Issue
Block a user