Files
Aislo/resources/tester/test_excavation_mirror.py
T
eomsangdonandClaude Opus 5.5 172ff8170b refactor(511-B B-6 정리): 운영 부름 0 파이썬 짝 걷음 · 남는 짝 머리에 남는 까닭 · 등록부 until 걷음 · 알려진 차 까닭 · 322_3 flow 빨강 고침
걷은 함수(운영 부름 0 · 전수 확인 = 화면 · 서버 · 체인 · 추천 엔진 · B07 · 시험)
- common_util/common_util_excavation.py 통째(126 줄 · pipe_trench_width_m · wall_trench_area_m2 · wall_trench_width_m · 서버 = Node excavation.trench)
- Engine_Grade_Carry.carry_edits(Node carry_seat 겉) · Route_Save_Parts.seat_route_moved(시험 헬퍼 helper_475_1_moved 로 옮김)
- Engine_Tilt.attach_underdrains · Engine_Structures_Wall.attach_wall_structures · load_wall_structures
- Engine_Grade_Alignment.tangent_elevation(부름 0) · station_key.dedupe_station_keys · loose_chainage
줄 수 전 → 후: excavation.py 126 → 0 · Grade_Carry 178 → 157 · Save_Parts 289 → 269 · Wall 221 → 197 · Tilt 115 → 112 · station_key 141 → 122 · Alignment 657 → 654

남는 짝(머리 「남는 까닭」 한 줄) — Grade · Grade_Profile · Alignment · CurveLaw(2~4 순위 폴백 · 추천) · NodeEdits · SampleExtend · Router_Design · Ranges · Engine_Design · Areas · cross_berm(DTM 아닌 지표면 · Node 못 부를 때 · B07 · 추천) · Tilt · Wall · Culvert(B04 B07 B08) · route_follow · structure_station · station_key · route_polyline(745 줄 · 까닭 = 등록부 R1 줄)

등록부 — until 칸 걷음(G1 = py 표본기 남김 · 까닭 note) · C6 pair = attach_underdrain_specs · F8 pair null
알려진 차 — golden KNOWN 셋 그대로 나타남(R7 표본 출처 · W0 저장 때 경고 · X2 입력 선 자릿수 · 까닭 고침) · underdrain 알려진 차 까닭 · 511_b5 KNOWN_ARC 그대로
계산 자리 창 — 45 줄 · 서버만 아닌 41(바꿀 수 있음 40 + F9) · 서버만 넷(G3 D1 D2 N1 줄마다 까닭) · 옛 까닭 「짝 모으는 중 · B-4」 글 걷음
test_322_3_flow 빨강 — 헬퍼가 @config/config_frontend 흉내(511-A design_calc_server import)
시험 기준 — 걷은 짝 거울 = 걷기 전 파이썬 값 고정(excavation · station_key) · Node carry_seat · attach_underdrain_specs · wall_specs_from

검증: 고친 대상 시험 97 파일 562 통과 · 21 건너뜀 · typecheck 0 · 700 줄 넘는 새 파일 없음 — 요구 320-4

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 16:34:08 +09:00

144 lines
5.2 KiB
Python

"""터파기 단면 — TS 한 벌(`common_util_excavation.ts`)이 법정 표 · 실무 정본 값을 냄 (2026-09-09).
화면(B06 횡단도)이 그리고 서버(B08 수량 · Node `excavation.trench`)가 세는 값.
파이썬 짝(`common_util_excavation.py`)은 운영 부름 0 이라 걷음(511-B B-6) — 기대값 = 걷기 전
파이썬 값 그대로.
⚠ 근거의 급이 다른 두 갈래를 함께 잠근다 —
관은 **법정 표**(KCS 44 40 10 그림 3.2-1), 벽은 **실무 정본 식**(구조도 기슭막이 xls).
"""
from __future__ import annotations
import json
import re
import subprocess
from pathlib import Path
import pytest
PROJECT_ROOT = Path(__file__).resolve().parents[2]
# 걷기 전 파이썬 짝 값(511-B B-6)
PIPE_TABLE = {
300: 700, 350: 800, 400: 900, 450: 1000, 500: 1100, 600: 1200, 700: 1400, 800: 1600,
900: 1700, 1000: 1800, 1100: 2000, 1200: 2100, 1300: 2200, 1400: 2400, 1500: 2500,
} # fmt: skip
WALL_FOUNDATION_DEPTH_M = 0.5
WALL_FOUNDATION_WIDTH_M = 0.9
WALL_TRENCH_CLEARANCE_M = 0.2
TSC = PROJECT_ROOT / "config" / "node_modules" / "typescript" / "bin" / "tsc"
_RUNNER = """
import { writeFileSync } from "node:fs";
import {
PIPE_TRENCH_WIDTH_MM,
WALL_FOUNDATION_DEPTH_M,
WALL_FOUNDATION_WIDTH_M,
WALL_TRENCH_CLEARANCE_M,
pipeTrenchWidthM,
wallTrenchAreaM2,
wallTrenchWidthM,
} from "./common_util_excavation.js";
const out = {
table: PIPE_TRENCH_WIDTH_MM,
pipe: [300, 800, 1000, 1200, 1500, 250, 1600].map((d) => pipeTrenchWidthM(d)),
wallWithFoundation: [1.0, 2.0, 3.0].map((h) => wallTrenchAreaM2(h, 0.7, true)),
wallBlindingOnly: [1.0, 2.0, 3.0].map((h) => wallTrenchAreaM2(h, 0.7, false)),
wallWidth: [0.7, 1.05, 0].map((t) => wallTrenchWidthM(t)),
nulls: [pipeTrenchWidthM(null), wallTrenchAreaM2(null, 0.7, true), wallTrenchAreaM2(1, null, true)],
practice: [1.0, 2.0, 3.0].map((h) => wallTrenchAreaM2(h, 0.83, true)),
consts: [WALL_FOUNDATION_DEPTH_M, WALL_FOUNDATION_WIDTH_M, WALL_TRENCH_CLEARANCE_M],
};
writeFileSync(process.argv[2], JSON.stringify(out));
"""
def _ts_values(tmp_path: Path) -> dict:
out = tmp_path / "js"
subprocess.run( # noqa: S603 — 고정 실행 파일
[
"node",
str(TSC),
str(PROJECT_ROOT / "common_util" / "common_util_excavation.ts"),
"--outDir",
str(out),
"--module",
"esnext",
"--target",
"es2022",
"--moduleResolution",
"bundler",
"--ignoreConfig",
],
cwd=str(PROJECT_ROOT),
check=True,
capture_output=True,
)
for emitted in out.glob("*.js"):
text = emitted.read_text(encoding="utf-8")
emitted.write_text(
re.sub(r'(from "\./[^"]+?)(")', lambda m: m.group(1) + ".js" + m.group(2), text),
encoding="utf-8",
)
(out / "runner.mjs").write_text(_RUNNER, encoding="utf-8")
result = tmp_path / "out.json"
subprocess.run( # noqa: S603
["node", str(out / "runner.mjs"), str(result)],
cwd=str(PROJECT_ROOT),
check=True,
capture_output=True,
)
return json.loads(result.read_text(encoding="utf-8"))
@pytest.fixture(scope="module")
def ts(tmp_path_factory) -> dict:
if not TSC.is_file():
pytest.skip("프론트엔드 의존성 미설치")
return _ts_values(tmp_path_factory.mktemp("excavation"))
def test_걷기_전_파이썬_값과_같다(ts: dict) -> None:
assert {int(k): v for k, v in ts["table"].items()} == PIPE_TABLE
assert ts["pipe"] == [0.7, 1.6, 1.8, 2.1, 2.5, None, None]
assert ts["wallWithFoundation"] == pytest.approx([1.35, 2.25, 3.15], abs=1e-12)
assert ts["wallBlindingOnly"] == pytest.approx([0.97, 1.87, 2.77], abs=1e-12)
assert ts["wallWidth"][:2] == pytest.approx([0.9, 1.25], abs=1e-12)
assert ts["wallWidth"][2] is None
assert ts["nulls"] == [None, None, None]
assert ts["consts"] == [
WALL_FOUNDATION_DEPTH_M,
WALL_FOUNDATION_WIDTH_M,
WALL_TRENCH_CLEARANCE_M,
]
def test_관은_표를_그대로_쓴다(ts: dict) -> None:
"""⚠ 관경 + 2b 로 계산하지 않는다 — 표가 관 두께·작업여유를 담고 있다(800 → 1.6)."""
width_800 = ts["pipe"][1]
assert width_800 == 1.6 and width_800 != 0.8 + 2 * 0.3
assert all(width is not None for width in ts["pipe"][1:5]) # 800 · 1000 · 1200 · 1500
def test_표에_없는_관경은_지어내지_않는다(ts: dict) -> None:
assert ts["pipe"][5:] == [None, None] # 250 · 1600
def test_실무_정본_수치와_맞는다(ts: dict) -> None:
"""xls 7탭: H=1.0 → 1.03+0.45 = 1.48 · H=2.0 → 2.51 · H=3.0 → 3.54 (평균두께 0.83)."""
for area, expected in zip(ts["practice"], (1.48, 2.51, 3.54), strict=True):
assert area == pytest.approx(expected, abs=0.01)
def test_기초_유무가_기초분을_가른다(ts: dict) -> None:
with_base, without = ts["wallWithFoundation"][1], ts["wallBlindingOnly"][1] # H 2.0 · 0.7
assert with_base - without == pytest.approx(
WALL_FOUNDATION_DEPTH_M * WALL_FOUNDATION_WIDTH_M - 0.1 * 0.7
)
def test_여유폭은_평균두께에_더한다(ts: dict) -> None:
assert ts["wallWidth"][0] == pytest.approx(0.7 + WALL_TRENCH_CLEARANCE_M)