- 「예상노선으로」를 「초기화」로 — 마지막에 적용한 초기값(처음엔 예상노선 추종)으로 편집값만 되돌림 · 즉시 재계산 없앰 - 옛 「초기화」(창을 연 상태로)는 「연 상태로」 - 로직 단추 토공 최소 · 기울기 순한 노선 · 비중 계산(예상 · 토공 · 기울기 슬라이더 · 합 100 자동 · 기본 50/25/25 · [계산]) - 누르면 서버 갈래(POST /route/initial)를 불러 받은 노드를 편집값에 싣고(되돌리기 한 걸음) 결과 캐시(routeedit-initial)에 새 초기값으로 적음 - 「현재 초기값: ○○」 · 결과 비교값(연장 · 최대/평균 기울기 · 절성토량 · 기준 초과 구간 · 이격) · 공통 제약 기준값은 서버 값만 보임(확정 표시 없으면 「후보 · 사용자 확정 대기」) - 다시 계산은 노선이 바뀐 뒤 [확인]에서만 — 그대로면 계산 없이 닫음 · [확인] 몸통에 초기값(initial) 실음 · [취소]는 이 창에서 바꾼 초기값도 되돌림 - 서버 길이 아직 없으면 알림만(고친 적 없는 노선의 [초기화]는 창을 연 노선으로) - 700줄 한도 — 노드 끼우기·빼기 배선은 _Input(bindNodeSplice), 셈은 _Initial_Model - 시험 test_b05_routeedit_initial.py (비중 합 100 · 서버 답 두 꼴 펴기 · 글 · 캐시 칸) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sCeZz8z8YnbovsKgn7HK7
99 lines
3.9 KiB
Python
99 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""계획노선 편집 창 — **초기노선 갈래**(계획서 20) 셈 회귀검증.
|
|
|
|
비중 슬라이더 셋은 합 100 을 지키고(하나를 옮기면 나머지가 비율대로), 서버 답은 노드 목록 꼴과
|
|
`/route/plan` 꼴(노드+곡선) 둘 다 편집값 한 벌로 펴야 한다. 비교값 · 기준값은 서버 값을 글로만
|
|
보이고, 확정 표시가 없으면 「사용자 확정 대기」를 붙인다. 마지막 초기값은 결과 통 프로젝트 칸.
|
|
|
|
Node 헬퍼(`helper_b05_routeedit_initial.cjs`)가 TS 를 트랜스파일해 돌리고, 여기서 값을 판정한다.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def results():
|
|
proc = subprocess.run(
|
|
["node", os.path.join(HERE, "helper_b05_routeedit_initial.cjs")],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=60,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
def test_비중은_늘_합_100_정수(results):
|
|
for weights in results["moves"]:
|
|
assert list(weights) == ["expected", "earthwork", "slope"]
|
|
assert sum(weights.values()) == 100
|
|
assert all(isinstance(v, int) and 0 <= v <= 100 for v in weights.values())
|
|
|
|
|
|
def test_비중은_나머지를_지금_비율대로_나눔(results):
|
|
moves = results["moves"]
|
|
assert moves[0] == {"expected": 70, "earthwork": 15, "slope": 15}
|
|
assert moves[1] == {"expected": 40, "earthwork": 40, "slope": 20}
|
|
# 나머지가 모두 0 이면 반씩.
|
|
assert moves[2] == {"expected": 60, "earthwork": 20, "slope": 20}
|
|
assert moves[3] == {"expected": 0, "earthwork": 0, "slope": 100}
|
|
assert moves[5]["slope"] == 0
|
|
|
|
|
|
def test_노드_목록_꼴을_편집값으로(results):
|
|
snap = results["plain"]["snapshot"]
|
|
assert snap["planned"] == [[0, 0], [50, 10], [100, 0]]
|
|
assert snap["curveOn"] == [True, True, False]
|
|
assert snap["curveRadius"] == [None, 30, None]
|
|
assert snap["curveLock"] == [None, None, None]
|
|
assert snap["apexLock"] == [False, False, False]
|
|
assert snap["picked"] == -1
|
|
|
|
|
|
def test_노선계획_꼴도_같은_규칙으로(results):
|
|
shape = results["planShape"]
|
|
snap = shape["snapshot"]
|
|
assert snap["planned"] == [[0, 0], [40, 30], [90, 30]]
|
|
assert snap["curveOn"] == [False, True, False]
|
|
assert snap["curveRadius"] == [None, 25, None]
|
|
assert shape["weights"] == {"expected": 60, "earthwork": 20, "slope": 20}
|
|
assert shape["metrics"] is None and shape["criteria"] is None
|
|
|
|
|
|
def test_노드가_모자라면_싣지_않음(results):
|
|
assert "모자랍니다" in results["tooShort"]
|
|
|
|
|
|
def test_비교값과_기준값_글(results):
|
|
labels = results["labels"]
|
|
assert labels["follow"] == "예상노선 추종"
|
|
assert labels["weighted"] == "비중 계산 60/20/20"
|
|
assert labels["metrics"] == (
|
|
"연장 1,234.6m · 기울기 최대 12.3% · 평균 6.1% · 절토 1,500㎥ · 성토 900㎥"
|
|
" · 기준 초과 2구간 · 이격 3.3m"
|
|
)
|
|
assert "로직을 누르면" in labels["metricsNone"]
|
|
assert labels["criteria"] == (
|
|
"공통 제약 종단기울기 ≤ 14.0% · 최소 R 12m · 계류 이격 ≥ 5.0m (후보 · 사용자 확정 대기)"
|
|
)
|
|
assert labels["criteriaConfirmed"].endswith("5.0m")
|
|
assert labels["criteriaFallback"] == (
|
|
"공통 제약 종단기울기 ≤ — · 최소 R 15m · 계류 이격 ≥ — (후보 · 사용자 확정 대기)"
|
|
)
|
|
|
|
|
|
def test_캐시는_결과_통_프로젝트_칸(results):
|
|
assert results["keys"] == ["aislo:result:routeedit-initial:p-1"]
|
|
assert results["readBack"]["logic"] == "earthwork"
|
|
assert results["readBack"]["snapshot"]["planned"] == [[0, 0], [50, 10], [100, 0]]
|
|
assert results["other"] is None
|
|
assert results["badLogic"] is None
|
|
assert results["cleared"] is None
|