- D02 걷음 — 길 · 단계(PLAN 단계 둘 = 노선 분석 · 확정) · [>] · 대시보드 단계 점 · 서버 길 · 폴더 만들기 · 캐시 등록 · 글 · 가이드 폴더 - 등록 [등록] · 받은 예정노선 [보기] = D03 으로 곧바로 - D03 지점 = 긋기에 붙는 점 · 목록 칸(여섯 색 · 「지점 N」 · 🗑) · 핀 끌기 = 그 자리 노선 노드 같이 · [저장] 몸에 실음 · [초기화] = 선만 지우고 지점 남김 - 지도 우클릭 메뉴(부품 상자) — 여기서 긋기 시작(빈 땅 = 새 본선) · 갈래 시작 · 이어 긋기 · 지점 놓기 · 지점 지우기 · 긋기 끝 - 받기 — 처음 = 등록 기준점 둘레 ± 1 km(지점 · 선 없을 때) · 지점 · 선 · 지도 보기 가운데가 받은 범위 밖이면 조용히 이어 받음(단추 · 막는 창 걷음 · 실패만 [다시 받기]) - 좌표계 = 파일 머리 · 없으면 기준점 경도 TM 띠 - 시험: 529_3(D02 지점 API) 지움 → 591_2 로 갈음 · 280_2 · 528 · 530_2 · 547_1 · 548 · 553_4 · 556_2 · 560_4 · 401 · 54_2 = D02 단계 · 페이지 걷음에 맞춤 · 590_1 · 530_2_analyze = 사업연도 · 기준점 한 번에 읽음 · 591_1 D04 씨앗 시험 = 590-1 이 씨앗 줄 걷음에 맞춤 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
135 lines
5.2 KiB
Python
135 lines
5.2 KiB
Python
"""560-4 D 단계 이동 = 저장 뒤 이동 · 572-2 B 떠남 물음 지킴 시험 — 서버 · 화면 없이 소스만 본다.
|
|
단계 아이콘 · [<] [>] · 머리 메뉴 · 뒤로가 한 함수(beforeLeave)를 거치고 (D02 기준 지정은 591-2 에서 걷음 · 지점 = D03).
|
|
572-3 — D · E 페이지는 공용 가드에 {dirty, save} 를 둠(말없이 저장 없음) · 캐시 = 등록표 · 프로젝트 = currentProjectId."""
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def _src(path: str) -> str:
|
|
return (ROOT / path).read_text(encoding="utf-8")
|
|
|
|
|
|
def test_group_step_waits_before_leave():
|
|
ts = _src("A00_Common/group_workflow.ts")
|
|
assert "beforeLeave?: () => Promise<boolean>" in ts
|
|
assert "setLeaveGuard(" in ts # 머리 메뉴 · 뒤로
|
|
assert "leave().then((ok) => ok && navigateTo(" in ts # 단계 아이콘 · [<] [>]
|
|
|
|
|
|
# 572-2 B 페이지 떠남 물음 — 공용 가드에 {dirty, save} · 지금 프로젝트 = 탭마다(currentProjectId)
|
|
B_GUARDS = {
|
|
"B04_PreProcess/B04_PreProcess_UI_Page.ts": (
|
|
"mapViewer.drainageDirty",
|
|
"mapViewer.commitDrainage",
|
|
),
|
|
"B07_DesignDetail/B07_DesignDetail_UI_Page.ts": (
|
|
"cadDirty || tabs.anyDirty()",
|
|
"saveEditedDrawings(store)",
|
|
),
|
|
"B08_Quantity/B08_Quantity_UI_Page.ts": ("readState(name, projectId)", "save: saveShown"),
|
|
"B09_Estimation/B09_Estimation_UI_Shell.ts": (
|
|
'readState("b09-estimation", projectId)',
|
|
"save: saveChanged",
|
|
),
|
|
}
|
|
|
|
B_PROJECT_READS = [
|
|
"B02_ProjRegister/B02_ProjRegister_UI_Page.ts",
|
|
"B03_FileInput/B03_FileInput_UI_Page.ts",
|
|
"B03_FileInput/B03_FileInput_UI_Page_Flow.ts",
|
|
"B03_FileInput/B03_FileInput_UI_PlanImport.ts",
|
|
*B_GUARDS,
|
|
"B09_Estimation/B09_Estimation_UI_Tabs_Bill_Link.ts",
|
|
"B09_Estimation/B09_Estimation_UI_Tabs_Base_Quote.ts",
|
|
"B09_Estimation/B09_Estimation_UI_Haul_Modal.ts",
|
|
"B09_Estimation/draft/B09_Draft_Print_Page.ts",
|
|
"B11_Status/B11_Status_UI_Loading.ts",
|
|
]
|
|
|
|
|
|
def test_b_pages_guard_leave():
|
|
for path, (dirty, save) in B_GUARDS.items():
|
|
ts = _src(path)
|
|
at = ts.index("guardProjectLeave(layout.root, {")
|
|
block = ts[at : ts.index("});", at)]
|
|
assert dirty in block and save in block, path
|
|
b07 = _src("B07_DesignDetail/B07_DesignDetail_UI_Page.ts")
|
|
assert "discard: () => discardEditedRecovery(store)" in b07 # 폐기 = CAD 자동백업도
|
|
|
|
|
|
def test_b_pages_read_tab_project():
|
|
for path in B_PROJECT_READS:
|
|
ts = _src(path)
|
|
# 탭 공용 localStorage 직접 읽기 · 쓰기 없음
|
|
assert "CURRENT_PROJECT_ID_KEY" not in ts, path
|
|
assert "currentProjectId()" in ts or "setCurrentProject(" in ts, path
|
|
|
|
|
|
def test_b_pages_leave_other_project_cache_to_enter():
|
|
# 다른 프로젝트 보관함 지우기 = enterProject 한 곳(다른 탭 보관분을 지우지 않게)
|
|
for path in (
|
|
"B04_PreProcess/B04_PreProcess_UI_Page.ts",
|
|
"A00_Common/design/design_view_profile.ts",
|
|
"B11_Status/B11_Status_UI_Loading.ts",
|
|
):
|
|
assert "purgeOtherProjects" not in _src(path), path
|
|
|
|
|
|
# 572-3 D · E — 고침 판별 · 저장 · [폐기] 때 지울 등록표 칸(E03 = 별 저장 진행 중만 · 지울 칸 없음)
|
|
DE_GUARDED = {
|
|
"D03_PlanAnalysis/D03_PlanAnalysis_UI_Page.ts": "d03-plan",
|
|
"D04_PlanConfirm/D04_PlanConfirm_UI_Page.ts": "d04-assignees",
|
|
"E02_StabGround/E02_StabGround_UI_Page.ts": "e02-ground",
|
|
"E03_StabSection/E03_StabSection_UI_Page.ts": None,
|
|
"E05_StabReport/E05_StabReport_UI_Page.ts": "e05-report",
|
|
"E06_StabRock/E06_StabRock_UI_Page.ts": "e06-rock",
|
|
}
|
|
DE_PAGES = [
|
|
*DE_GUARDED,
|
|
"E03_StabSection/E03_StabSection_UI_Prob.ts",
|
|
"E04_Stab3D/E04_Stab3D_UI_Page.ts",
|
|
"E07_StabArea/E07_StabArea_UI_Page.ts",
|
|
]
|
|
DE_STATES = [
|
|
"e02-ground",
|
|
"e03-prob",
|
|
"e04-settings",
|
|
"e05-report",
|
|
"e06-rock",
|
|
"e07-settings",
|
|
]
|
|
|
|
|
|
def test_de_pages_guard_leave():
|
|
for path, name in DE_GUARDED.items():
|
|
ts = _src(path)
|
|
call = ts[ts.index("mountGroupStep(root") :]
|
|
call = call[: call.index("});")]
|
|
assert "dirty: () =>" in call and "save" in call, path
|
|
assert "beforeLeave" not in ts, path # 말없이 저장 없음 — 공용 셋 물음
|
|
if name:
|
|
assert f'discard: () => clearState("{name}", projectId)' in call, path
|
|
# D03 — 못 읽은 채(프로젝트 없음 · 불러오기 실패) 떠나면 고침 없음
|
|
assert "let savedJson = JSON.stringify({ network, points });" in _src(
|
|
"D03_PlanAnalysis/D03_PlanAnalysis_UI_Page.ts"
|
|
)
|
|
e03 = _src("E03_StabSection/E03_StabSection_UI_Page.ts")
|
|
assert "dirty: () => repPending > 0" in e03 and "repPending -= 1" in e03
|
|
|
|
|
|
def test_de_pages_shared_project_and_registry():
|
|
for path in DE_PAGES:
|
|
ts = _src(path)
|
|
assert "CURRENT_PROJECT_ID_KEY" not in ts and "localStorage" not in ts, path
|
|
assert "sessionStorage" not in ts, path
|
|
if path.endswith("_UI_Page.ts"):
|
|
assert "const projectId = currentProjectId();" in ts, path
|
|
registry = _src("A00_Common/b_page_state.ts")
|
|
for name in DE_STATES:
|
|
assert re.search(rf'"{name}": \{{[^}}]*bucket: "draft",[^}}]*scope: "project"', registry), (
|
|
name
|
|
)
|