Files
Aislo/resources/tester/test_52_structure_spec_pipe.py
T
eomsangdonandClaude Opus 5.5 209383ed17 feat(b05,b06,b07): 도수로/돌붙임 띠 = 낮은 쪽 끝단에서 · 원지반 닿으면 끝 · 길이 = 그 길이 · 모든 시설 같은 규칙과 길이 칸 (294-4)
- 공용 chuteRun(Wall_Hatch) — 길이 비움 = 원지반 닿으면 끝 · 넣음 = 사면 따라 그 길이 · 사면보다 길면 원지반 따라 이어 그 길이 · 끝단이 이미 원지반이면 안 그림
- 물넘이 — 띠 시작 = 늘인 노면 끝(294-3) · 아니면 유출 쪽 노견 끝 · 원지반 닿으면 끝(양측 절토 = 띠 없음)
- 배관 · 박스 · 세월교 — 띠 계산이 원지반(layout.ground)을 받아 같은 규칙 · 3D 띠도 같음 · 코리도 해시에 길이
- 명세 CHUTE_ITEMS 맨 아래 「길이 (m)」(chute_add_{n}_length_m · 그림 전용) · 물넘이는 공용 칸 그대로
- 면적 자동 = 물넘이 · 세월교만 월류 폭 × 길이(배관 · 박스 = 폭 정의 없어 손 입력 그대로 · 브레인 정함)
- 길이는 집계 열 · B08 수량(면적만)에 안 실림 · 마스터 정의 이름 표는 안 건드림(이름 표 대조 시험에서 이 칸만 밖)
- 시험 test_294_3 · 286_1 · 52 · 65 · 152_3 기대값

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TteK8mfYZetk5P3bEZkyVZ
2026-10-12 21:58:16 +09:00

113 lines
4.0 KiB
Python

# -*- coding: utf-8 -*-
"""구조물 명세 공용 틀 + 횡단배수 › 배관(표 01) — PLAN 52-1.
순수 규칙은 Node 헬퍼(`helper_52_structure_spec.cjs`)가 돌림 · 화면은 ORCA `ui_checks/52-1_배관_컨테이너.js`.
"""
import json
import os
import subprocess
import pytest
HERE = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(os.path.dirname(HERE))
def _node(*args):
proc = subprocess.run(
["node", os.path.join(HERE, "helper_52_structure_spec.cjs"), *args],
capture_output=True,
text=True,
encoding="utf-8",
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
@pytest.fixture(scope="module")
def out():
return _node()
def test_컨테이너_다섯_필수_셋_선택_둘(out):
assert out["containers"] == [
["pipe", "관", True],
["inlet", "관 보호공 (유입)", True],
["outlet", "관 보호공 (유출)", True],
["soil_add", "흙막이", False],
["chute_add", "도수로/돌붙임", False],
]
def test_형태_선택지는_구조를_따름(out):
assert out["formBasin"] == ["I형", "L형", "ㄷ형"]
assert out["formSoil"] == [
"돌 쌓기(찰)",
"돌 쌓기(메)",
"콘크리트",
"돌망태",
"통나무/목재틀",
"바자",
]
assert out["formNone"] is None # 구조 안 고름 = 형태 칸 가림
assert out["outletForms"] == out["formSoil"]
def test_옛_키로_읽고_같은_키로_씀_옛_칸은_안_씀(out):
back = out["back"]
assert back["pipe_diameter_mm"] == 1000
# 집수정 = 길이 · 전 · 후 칸 없음(54-1) — 폼이 안 적음(병합이 옛 값을 지킴)
assert back["inlet_structure"] == "L" and "inlet_basin_length_m" not in back
assert back["outlet_revet_height_m"] == 2.5
# 표 01 에 없는 옛 칸은 폼이 안 적음(병합이 이어 붙임 = 지난 정의 값)
assert "pipe_kind" not in back and "wing_wall_type" not in back
def test_선택_컨테이너는_인스턴스마다_차례대로_다시_매김(out):
# 흙막이 상자 = 구조 고르기 없음(54-30) — 옛 구조 키만 든 상자도 자리는 지킴
assert [i["form"] for i in out["state"]["soil_add"]] == ["바자", ""]
assert out["back"]["soil_add_1_form"] == "바자"
assert out["back"]["soil_add_2_form"] == "" # 빈 상자 자리 표식 = 첫 칸(형태) 빈 글
assert out["back"]["chute_add_1_structure"] == "도수로"
def test_흙막이로_바꾸면_기슭막이_키와_revet(out):
s = out["soilOut"]
assert s["inlet_type"] == "기슭막이" and s["inlet_structure"] == "revet"
assert s["inlet_revet_form"] == "콘크리트" and s["inlet_revet_length_m"] == 6
assert "inlet_basin_length_m" not in s
def test_길이_전_후_맞물림_마지막에_고친_둘을_지킴(out):
sp = out["split"]
assert sp["lengthFromSides"]["length"] == "7"
assert sp["beforeFromLength"]["before"] == "6"
assert sp["defaultKeepsLength"]["after"] == "7"
assert sp["blankKept"]["length"] == "" # 지킬 칸이 비면 안 셈
assert sp["clamp"]["before"] == "0"
def test_잇기_키와_이름_바꿈(out):
assert out["links"] == ["grv6lny", "gnbf9m9", "g9lq9uk", "gsoiladd2", "gchuteadd2"]
assert out["names"] == {
"renamed": "모양",
"title": "그룹 이름",
"titleOwn": "유입 보호",
"choice": "ㄷ형",
}
assert {"soil_add_", "chute_add_"} == set(out["keys"]["prefixes"])
def test_정의_파일에_이름_표가_올라_있음():
names = _node("names")
with open(
os.path.join(ROOT, "resources", "master_template", "구조물정의.json"), encoding="utf-8"
) as f:
doc = json.load(f)
on_file = doc["종류"]["pipe"]["이름"]
# 그림 전용 길이 칸(294-4)은 마스터 정의 이름 표에 안 올림(마스터 손대지 않음) — 대조 밖
assert set(names) - {"chute_add.length_m"} == set(on_file)
assert on_file["inlet.structure=기슭막이"] == "흙막이"