- 규격 판정(bodyOf): 가로 · 세로 중 손 값 하나라도 있으면 사용자 입력 + 빈 칸은 빈 채 - 둘 다 비면 표시 키 body_custom 만 저장 · 폼 칸 목록에 넣어 숫자 채우면 지워짐 - B06 폼→조정창 다리: 흙막이 · 날개벽 글을 있음/없음으로 바꿔 적던 것 → 글 그대로 - 시험: 52-2 헬퍼 한 칸 · 두 칸 빈 경우 · ui_checks 52-19 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W4uKaV4ZBhsJN4GHG7yRj4
109 lines
3.9 KiB
Python
109 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""횡단배수 › 박스암거(표 02 고친 판) 명세 — PLAN 52-2.
|
||
|
||
순수 규칙은 Node 헬퍼(`helper_52_structure_spec_box.cjs`)가 돌림 · 화면은 ORCA `ui_checks/52-2_박스암거_컨테이너.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_box.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"] == [
|
||
["body", "본체", True],
|
||
["inlet", "유입 구조", True],
|
||
["outlet", "유출 구조", True],
|
||
]
|
||
assert out["links"] == ["gboxbody", "gboxin", "gboxout"]
|
||
|
||
|
||
def test_선택지_표_02_그대로(out):
|
||
assert out["sizes"] == ["2.0×2.0", "3.0×3.0", "사용자 입력"]
|
||
assert out["structures"] == ["없음", "날개벽", "흙막이"]
|
||
|
||
|
||
def test_사용자_입력일_때만_가로_세로_칸(out):
|
||
assert out["customHidden"] is None
|
||
assert out["customShown"] == {"key": "body_width_m"}
|
||
|
||
|
||
def test_옛_값_읽기_규격_밖은_사용자_입력_있음은_날개벽(out):
|
||
st = out["old"]["state"]
|
||
assert st["body"][0] == {"size": "사용자 입력", "width": "3", "height": "2.5"}
|
||
assert st["inlet"][0]["structure"] == "날개벽"
|
||
back = out["old"]["out"]
|
||
assert back == {"body_width_m": 3, "body_height_m": 2.5, "wing_in": "날개벽"}
|
||
# 옛 날개벽 치수는 폼이 안 적음(병합이 이어 붙임 = 지난 정의 값)
|
||
assert "wing_in_length_m" not in back
|
||
assert "wing_in_length_m" in out["retired"]
|
||
|
||
|
||
def test_규격은_폭_높이_수로_저장_규격_칸은_저장_안_함(out):
|
||
assert out["preset"]["state"]["body"][0]["size"] == "2.0×2.0"
|
||
assert out["preset"]["out"] == {"body_width_m": 2, "body_height_m": 2, "wing_out": "없음"}
|
||
to = out["toPreset"]["out"]
|
||
assert to["body_width_m"] == 3 and to["body_height_m"] == 3
|
||
assert to["wing_out"] == "흙막이"
|
||
assert out["toCustom"]["out"] == {"body_width_m": 2.4, "body_height_m": 1.8}
|
||
assert "size" not in json.dumps(out["keys"])
|
||
|
||
|
||
def test_빈_값은_빈_채로(out):
|
||
assert out["blank"]["out"] == {}
|
||
assert out["blank"]["state"]["body"][0]["size"] == ""
|
||
|
||
|
||
def test_사용자_입력_빈_칸은_다시_열어도_사용자_입력(out):
|
||
# 52-19 — 가로만 비움: 세로 손 값이 남아 사용자 입력 + 빈 가로
|
||
assert out["oneBlank"]["state"]["body"][0] == {
|
||
"size": "사용자 입력",
|
||
"width": "",
|
||
"height": "2.5",
|
||
}
|
||
assert out["oneBlank"]["out"] == {"body_height_m": 2.5}
|
||
# 둘 다 비움: 표시 키만 적고 다시 열면 사용자 입력 + 빈 칸 둘
|
||
assert out["bothBlank"]["out"] == {"body_custom": "사용자 입력"}
|
||
assert out["bothBlankAgain"]["state"]["body"][0] == {
|
||
"size": "사용자 입력",
|
||
"width": "",
|
||
"height": "",
|
||
}
|
||
assert out["bothBlankAgain"]["out"] == {"body_custom": "사용자 입력"}
|
||
|
||
|
||
def test_정의_파일에_이름_표_그룹_선택지가_올라_있음():
|
||
names = _node("names")
|
||
with open(
|
||
os.path.join(ROOT, "resources", "master_template", "구조물정의.json"), encoding="utf-8"
|
||
) as f:
|
||
doc = json.load(f)
|
||
assert set(names) == set(doc["종류"]["box_culvert"]["이름"])
|
||
assert [g["id"] for g in doc["그룹"]["box_culvert"]] == ["gboxbody", "gboxin", "gboxout"]
|
||
box = next(t for t in doc["types"] if t["type_id"] == "box_culvert")
|
||
wing = {o["key"]: o for o in box["options"]}
|
||
for key in ("wing_in", "wing_out"):
|
||
assert wing[key]["choices"] == ["없음", "날개벽", "흙막이"]
|