Files
Aislo/resources/tester/test_52_1b_pipe_links.py
T
eomsangdonandClaude Opus 5.5 d7faee1cd2 feat(structure): 65-1~5 세월교 · 박스암거 유입 · 유출 흙막이 양식 공통 · 없음 = 램프 뺌 · 세월교 기본값 · 물넘이 월류 폭 · 높이
- 흙막이 양식 한 벌(design_structure_guard) — 배관 · 박스 · 세월교가 같은 칸(형태 · 길이 · 높이 · 측점 전후) · 추가 흙막이 · 도수로/돌붙임 상자
- 세월교 · 박스 유입 · 유출: 흙막이 고르면 흙막이 칸(키 {side}_revet_* · 기본 찰 10 · 1.5 · 5 · 5) · [연동][경사] 옵션 줄
- B06 측벽 높이 · 좌우 · 상하 · 바닥판 읽기 줄을 세월교 · 박스 유입 · 유출 칸에 안 옮김(강조만)
- 유입 · 유출 「없음」 = 목록 램프 · 구조물 조합 잇기 줄 없음(명세 none)
- 세월교: 수량(련) 관경 바로 뒤 · 련 기본 2 · 새 시설 빈 월류 높이 = 유량 오면 필요 수심 · 종류 바꿀 때 유량 넘김
- 물넘이 포장: 경사각 기본 3° · 월류 폭 · 높이 칸(세월교와 같은 키 ford_width_m · ford_height_m · 같은 계산)
- 구조물정의 판 18(판_17 이력) · 이름 표 · 집계표 선택 컨테이너 짝 · 저장 병합 키
- 시험: 세월교 · 박스 · 물넘이 명세 기대값 · 흙막이 짝 자리 옮김

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

128 lines
5.4 KiB
Python

# -*- coding: utf-8 -*-
"""배관 남은 연동 — PLAN 52-1b.
못박는 것
- 집계표: 선택 컨테이너(흙막이 추가 · 도수로/돌붙임)마다 한 건 — 잇기 `{link}{n}` 항목 ·
그 컨테이너 값.
- 짝: 서버 컨테이너 표(머리 · 잇기) = 배관 명세 TS.
"""
from __future__ import annotations
import json
import os
import re
from M02_MasterTemplete import M02_Table_Fill as fill
from M02_MasterTemplete.M02_Table_Fill_Spec import SPEC_CONTAINERS, container_rows
from resources.tester.test_structures_summary_snapshot import ( # noqa: F401 — world 고정물
MS,
PIPE,
RV,
_pipe,
_save,
world,
)
HERE = os.path.dirname(os.path.abspath(__file__))
ROOT = os.path.dirname(os.path.dirname(HERE))
SOIL = {
"soil_add_1_structure": "기슭막이",
"soil_add_1_form": "바자",
"soil_add_1_length": 6,
"soil_add_1_height": 2,
"soil_add_2_structure": "기슭막이",
"chute_add_1_structure": "돌붙임",
}
def test_컨테이너마다_한_건_잇기와_그_값():
item = {"type_id": "pipe", "options": {"pipe_diameter_mm": 1000, **SOIL}, "복사본": "pipe@40.0"}
rows = container_rows(item, {"gsoiladd1": RV, "gchuteadd1": MS})
assert [r["그룹"] for r in rows] == ["흙막이 1", "흙막이 2", "도수로/돌붙임 1"]
assert [r["복사본"] for r in rows] == [
"pipe@40.0__gsoiladd1",
"pipe@40.0__gsoiladd2",
"pipe@40.0__gchuteadd1",
]
assert [r["summary_item"] for r in rows] == [RV, None, MS]
first = rows[0]["options"]
assert first["length_m"] == first["inlet_revet_length_m"] == first["outlet_revet_length_m"] == 6
assert (
first["form"] == first["outlet_revet_form"] == "바자" and first["outlet_type"] == "기슭막이"
)
assert first["pipe_diameter_mm"] == 1000 # 구조물 옵션은 그대로
assert container_rows({"type_id": "masonry_dry", "options": SOIL, "복사본": "st0"}, {}) == []
# 옛 값 — 컨테이너 없는 옛 관 · 인스턴스 없는 잇기는 줄 없음
old = {"type_id": "pipe", "options": {"inlet_revet_length_m": 5}, "복사본": "pipe@9.0"}
assert container_rows(old, {"gsoiladd9": RV}) == []
def test_집계표_채움에_컨테이너_줄(world):
"""흙막이 추가 1 → 돌기슭막이 열(rv) 6 m · 관 본체 · 미지정 컨테이너는 표에 안 듦."""
root, system = world["root"], world["system"]
point = {**_pipe(PIPE), "group_items": {"gsoiladd1": RV}}
point["options"] = {**point["options"], **SOIL}
_save(root, [], [point])
table = json.loads((system / "table/구조물집계표.json").read_text("utf-8"))
doc = fill.fill_table(root, table)
values = [row["값"] for row in doc["줄"] if not row.get("고정")]
rv = [v for row in values for k, v in row.items() if k.split("|")[0] == "rv"]
assert rv == [6]
copies = [i["복사본"] for i in fill.collect_items(root)]
assert "pipe@40.0__gsoiladd1" in copies and "pipe@40.0__gchuteadd1" in copies
def test_서버_컨테이너_표는_배관_명세와_짝():
with open(
os.path.join(ROOT, "A00_Common/design/design_structure_guard.ts"), encoding="utf-8"
) as f:
text = f.read()
found = re.findall(
r'title: "([^"]+)",\s*required: false,\s*prefix: "(\w+)",\s*link: "(\w+)"', text
)
assert [(p, link, t) for t, p, link in found] == list(SPEC_CONTAINERS["pipe"])
# 박스 · 세월교 = 같은 흙막이 양식(65-2)
assert (
SPEC_CONTAINERS["box_culvert"] == SPEC_CONTAINERS["ford_bridge"] == SPEC_CONTAINERS["pipe"]
)
def test_54_11_흙막이는_선_단_수까지만():
"""단 수 2 → 1 = 흙막이 줄 2 → 1(값은 옵션에 그대로) · 다시 2 = 되살아남 · 모름 = 저장된 것 전부."""
from M02_MasterTemplete.M02_Table_Fill_Spec import soil_tiers_from_designs
item = {"type_id": "pipe", "options": SOIL, "복사본": "pipe@40.0"}
def soil(tiers):
rows = container_rows({**item, "흙막이단": tiers}, {})
return [r["그룹"] for r in rows if r["그룹"].startswith("흙막이")]
assert soil(2) == ["흙막이 1", "흙막이 2"]
assert soil(1) == ["흙막이 1"] and "soil_add_2_structure" in item["options"]
assert soil(0) == [] and soil(2) == ["흙막이 1", "흙막이 2"] and len(soil(None)) == 2
assert len(container_rows({**item, "흙막이단": 0}, {})) == 1 # 도수로/돌붙임은 그대로
walls = [{"side": "outlet"}, {"side": "basin"}, {"side": "outlet"}]
designs = [
{"chainage_m": 40.0, "design": {"extra_walls": walls}},
{"chainage_m": 60.0, "design": {"extra_walls": []}},
{"chainage_m": 80.0, "design": {"pipe_length_m": 9}},
]
assert soil_tiers_from_designs(designs) == {40.0: 2, 60.0: 0}
def test_54_11_집계표_미지정_알림도_선_단_수만(world):
root, system = world["root"], world["system"]
point = {**_pipe(PIPE), "group_items": {"gsoiladd1": RV}}
point["options"] = {**point["options"], **SOIL}
_save(root, [], [point])
table = json.loads((system / "table/구조물집계표.json").read_text("utf-8"))
def note(tiers):
found = fill.fill_table(root, table, None, tiers)["알림"]
return next((n for n in found if n.startswith("집계 항목 미지정")), "")
many, one = note(None), note({40.0: 1})
assert many != one # 숨은 흙막이 2 가 미지정 알림에서 빠짐
assert int(many.split()[3].rstrip("건")) - int(one.split()[3].rstrip("건")) == 1