- B05 · B06 [추가] = 그 측점 횡단(카드 · 측점선) 바로 + 세부유역 뒤에서 다시 나눔(세션 초안 · 저장 안 함 · 최신 응답만 · 지도 칸 표시만) — 있던 길 그대로 - 까닭 1: B06 [추가]는 높이 기다림을 판에 안 알려 새 세월교 · 물넘이 월류 높이(126-1)가 빈칸 — 기다림 표를 프로젝트마다 한 벌(fordWaitsOf)로 판 · B06 이 같이 씀 · 채운 높이를 B06 목록 · 폼이 받음(adoptFordHeights) - 까닭 2: B06 알림 글이 「세부 배수유역은 [저장]·[확정] 뒤 계산」 — 실제는 뒤에서 바로 다시 나눔 · 넣기 · 빼기 · 옮기기 글 고침 - 다시 나눔 실패 = 지도 칸 문구 + 토스트 한 줄(analyzeFailed) - 시험: test_298_add_reanalyze 새로 · test_126 · test_291_1 · helper_165 · helper_231_1 맞춤 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
110 lines
4.3 KiB
Python
110 lines
4.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""126-1 우클릭 세월교 · 물넘이포장도 바로 추가 · 월류 높이 실시간.
|
|
|
|
못박는 것
|
|
- 세월교 · 물넘이포장 = 바로 추가 + 그 측점 관을 고른 채 · 알림 한 줄(높이는 유량 뒤).
|
|
- 배수유역 재계산 응답에 유량이 오면 기다리던 항목의 빈 월류 높이 = 필요 수심(서버 `ford_height_m` 거울).
|
|
- 유량이 아직 없으면 빈칸으로 다음 응답까지 · 손 값은 안 덮음 · 기다리지 않는 옛 항목은 그대로.
|
|
- 세부유역 요청은 최신 응답만 채택 · 채운 뒤 세션 초안에 다시 담음.
|
|
|
|
Node 헬퍼 `helper_126_ford_fill.cjs` 가 판정 · 끝맺음 · 채움을 돌림. 화면은 사용자 확인.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
from B04_PreProcess import B04_PreProcess_Router_Basins as basins
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
ROOT = os.path.abspath(os.path.join(HERE, "..", ".."))
|
|
|
|
|
|
def _read(*parts: str) -> str:
|
|
with open(os.path.join(ROOT, *parts), encoding="utf-8") as f:
|
|
return f.read()
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def out():
|
|
proc = subprocess.run(
|
|
["node", os.path.join(HERE, "helper_126_ford_fill.cjs")],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=60,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
def test_우클릭_세월교_물넘이포장은_바로_추가(out):
|
|
assert out["once"] == {"fordBridge": True, "fordPavement": True, "pavement": False}
|
|
|
|
|
|
def test_추가_뒤_목록에_들고_그_관을_고른_채_알림_한_줄(out):
|
|
for key in ("bridge", "paveRc"):
|
|
r = out[key]
|
|
assert r["done"] is True and r["commits"] == 1
|
|
assert r["picked"] == [["pipe", 120]]
|
|
assert r["toasts"] == [out["notice"]]
|
|
assert out["pipe"]["toasts"] == [] # 배관은 알림 없음
|
|
|
|
|
|
def test_빈_높이만_기다림(out):
|
|
assert out["waits"] == {
|
|
"bridgeEmpty": True,
|
|
"paveEmpty": True,
|
|
"bridgeHand": False,
|
|
"pipe": False,
|
|
}
|
|
|
|
|
|
def test_유량_오기_전엔_빈칸_오면_그_항목에_채움(out):
|
|
assert out["noFlow"] == {"filled": False, "heights": [None], "pending": [120]}
|
|
assert out["withFlow"] == {"filled": True, "heights": [0.16], "pending": []}
|
|
|
|
|
|
def test_채운_높이는_서버_풀이와_같음(out):
|
|
assert out["need"]["w10"] == basins.ford_height_m(8.0, 10) == 0.16
|
|
assert out["need"]["w5"] == basins.ford_height_m(8.0, 5)
|
|
|
|
|
|
def test_손_값은_안_덮음(out):
|
|
assert out["hand"] == {"filled": False, "heights": [0.5], "pending": []}
|
|
|
|
|
|
def test_기다리지_않는_옛_항목은_그대로_폭_없으면_기본_폭(out):
|
|
assert out["other"]["heights"] == [0.16, None] # 물넘이 기본 폭 10 · 옛 세월교 빈칸 그대로
|
|
assert out["other"]["pending"] == []
|
|
|
|
|
|
def test_관이_사라지거나_종류가_바뀌면_그만_기다림(out):
|
|
assert out["gone"] == {"filled": False, "heights": [None], "pending": []}
|
|
|
|
|
|
def test_배수유역_패널_배선():
|
|
src = _read("B05_Profile", "B05_Profile_UI_Drainage_Panel.ts")
|
|
# 최신 응답만 채택
|
|
run = src[src.index("async function run(") : src.index("/** 지금 관 목록")]
|
|
assert "const seq = ++requestSeq;" in run
|
|
assert run.index("await request()") < run.index("if (seq !== requestSeq) return;")
|
|
assert run.index("if (seq !== requestSeq) return;") < run.index("apply(response)")
|
|
# 채움은 보관소가 응답을 받기 전에 · 채웠으면 세션 초안에 다시 담음
|
|
apply = src[src.index("function apply(") : src.index("async function run(")]
|
|
order = [
|
|
apply.index("fillFordHeights(response.pipe_points, response.basins, fordWaits())"),
|
|
apply.index("facilityStore.replaceFromResponse(response.pipe_points)"),
|
|
apply.index("if (fordFilled) rememberPipes()"),
|
|
apply.index("callbacks.onPipesChanged?.("),
|
|
]
|
|
assert order == sorted(order)
|
|
add = src[src.index(" addPipe(chainageM, attributes) {") : src.index(" removePipe(")]
|
|
assert "waitsFordHeight(attributes?.facility, attributes?.options)" in add
|
|
assert add.index("fordWaits().add(chainageM)") < add.index(
|
|
"pipeEditor.addAtChainage(chainageM)"
|
|
)
|
|
assert "if (fordWaits().delete(fromChainageM)) fordWaits().add(toChainageM);" in add
|