"""횡단도(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}" )