- A00_Common/design/design_store.ts — useDesignStore(projectId, routeId) get · set · subscribe
(structures · pipes · alignmentDraft · sectionDetail · selection) · 밑은 b_page_state 등록 키
(selection 등록 · alignmentDraft 는 옛 키 감쌈 — 브레인 판정 B)
- A00_Common/design/design_save.ts — saveDesign(ctx, {confirm}) 한 줄기:
관 → 구조물 → 계획고 → 암거 옵션 → 오르막 → 횡단 · B05 [임시저장] · B06 [저장] · [확정]이 같은 차례
- 계획고 초안 가게 노선마다 한 벌(B05 Profile_Edit 주인 · B06 Grade_Edit 는 useProfileEditStore)
- 관 목록 주인 = 가게 pipes(Pipes_Draft 창구)
- 시험: test_design_store_save 추가 · save_channels · save_recompute · save_roundtrip 새 차례로
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KmELpdXFDRZHhfbGuRhSmL
81 lines
2.8 KiB
Python
81 lines
2.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""설계 가게 한 곳 · 저장 한 줄기(계획서 24-2a) 회귀검증.
|
|
|
|
- 가게(`design_store`) — 밑은 등록 키 · 같은 칸이면 어느 가게든 같은 값 · 듣는 쪽.
|
|
- 계획고 가게 한 벌 — B05 종단 패널 · B06 계획선 편집이 같은 벌을 씀(옛 두 가게 덮어쓰기 흠).
|
|
- 저장 한 줄기(`saveDesign`) — 관 → 구조물 → 계획고 → 암거 옵션 → 오르막 → 횡단 · 관 · 구조물 ·
|
|
계획고는 실패해도 다음 차례로.
|
|
Node 헬퍼(`helper_design_store_save.cjs`)가 TS 를 트랜스파일해 돌린다.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
|
|
import pytest
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def out():
|
|
proc = subprocess.run(
|
|
["node", os.path.join(HERE, "helper_design_store_save.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["pipesShared"] == [{"chainage_m": 10, "source": "user"}]
|
|
assert out["pipesKey"] == ["aislo:draft:pipes:p1"]
|
|
assert out["heard"] == [1], "끊은 뒤에는 안 불려야 함"
|
|
assert out["otherProject"] is None
|
|
assert out["noRoute"] is None
|
|
assert out["selection"] == {"chainageM": 12.5, "structureId": "s-1"}
|
|
|
|
|
|
def test_계획고_가게_한_벌(out):
|
|
assert out["b05SeesB06"] == {"20.000": 0.5}
|
|
assert out["b05Dirty"] is True
|
|
assert out["afterBoth"] == {"20.000": 0.5, "60.000": -0.2}
|
|
assert out["draft"] == out["afterBoth"] == out["pending"]
|
|
assert out["rebuiltSeenByB06"] == {"20.000": 0.1}
|
|
|
|
|
|
def test_저장_차례(out):
|
|
assert out["order"] == ["pipes", "structures", "alignment", "culvertOptions", "uphill", "cross"]
|
|
assert out["saveOk"] is True
|
|
assert out["saveCalls"] == [
|
|
"overlay:on",
|
|
"prepare",
|
|
"pipes",
|
|
"pipes:screen",
|
|
"structures",
|
|
'alignment:7:{"20.000":0.1}',
|
|
"culvert:aislo:draft:culvertopt:p1:7",
|
|
"uphill",
|
|
"cross:false",
|
|
"done:false",
|
|
"overlay:off",
|
|
]
|
|
assert out["afterSave"] == {"dirty": False, "draft": None}
|
|
|
|
|
|
def test_구조물_실패는_알리고_넘어감_확정_노선없음(out):
|
|
calls = out["tolerant"]
|
|
assert "toast:error" in calls
|
|
assert calls.index("structures") < calls.index("toast:error") < calls.index("uphill:screen")
|
|
assert "uphill" not in calls, "보기 몫이 기본 창구를 갈음"
|
|
assert calls[-2:] == ["cross:true", "overlay:off"]
|
|
assert "failed" not in calls
|
|
assert out["noRouteSave"] is False and out["noRouteCalls"] == []
|
|
|
|
|
|
def test_초기화는_초안과_한_벌을_버림(out):
|
|
assert out["cleared"] == {"draft": None, "pending": None}
|