Files
Aislo/resources/tester/test_52_structure_spec_pipe.py
T
eomsangdonandClaude Opus 5.5 0a095c14b1 feat(design): 구조물 명세 공용 틀 + 횡단배수 배관(표 01) 컨테이너 폼
- 공용 틀(A00_Common/design/design_structure_*) — 명세(컨테이너 필수/선택 · 여러 개 · 항목 고르기/숫자/자동 · 상위 값에 따른 선택지 · 저장 키) · 그리기([추가]/[빼기]) · 길이 = 전 + 후 맞물림(마지막에 고친 둘을 지킴)
- 배관 명세 = 관 · 관 보호공(유입) · 관 보호공(유출) · 흙막이 추가 · 도수로/돌붙임 · 저장 키는 pipe_points 옛 키 그대로 · 옛 관종 · 날개벽 · 집수정 형식은 화면에서 빼고 지난 정의 값으로 남김
- 컨테이너 인스턴스마다 「구조물 조합」 잇기(group_items · 그룹 [고르기] 길 그대로) · 명세 종류는 그룹 상자 · 종류 단위 줄 가림 · 종류 단위 잇기 줄은 기준 측점 바로 아래
- 관 길이 자동 = 횡단 기하 computeStoredLayouts 값(서버 Node 와 같은 함수) · 높이 빈 칸 안내 = 관경 기준 최소 높이
- 정의 판 6 — 종류.pipe.이름 표(이름 바꿈 키) · 검사기가 이름 표 받음 · 판 5 이력 보관
- 시험 test_52_structure_spec_pipe · 병합 시험 기대값(빠진 옛 칸은 남음)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVPp2o6Mh2FZJr72yW3ofZ
2026-10-05 23:13:21 +09:00

110 lines
3.6 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
assert back["inlet_structure"] == "L" and back["inlet_basin_length_m"] == 2
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):
assert [i["structure"] for i in out["state"]["soil_add"]] == ["기슭막이", ""]
assert out["back"]["soil_add_1_form"] == "바자"
assert "soil_add_2_form" not in out["back"]
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"]["이름"]
assert set(names) == set(on_file)
assert on_file["inlet.structure=기슭막이"] == "흙막이"