Files
Aislo/resources/tester/test_b05_structures_form_summary.py
T
eomsangdonandClaude Opus 5.5 0292c8c722 perf(520-7): B05 배수유역 되돌리기 때 저장분 GET 세 번 → 한 번 · 이음매 대조 차이 0
- B05 Drainage_Saved 새 파일 — 저장분 받기를 패널 밖으로 뗌(Panel 700 → 688 줄) · 떠 있는 받기는 같이 씀 · 화면이 마지막 저장분 그대로면 초안 버림은 GET 없이 그 답을 다시 올림 · 뒤이어 온 reload 가 밀어내면 그 답을 기다림(낡음 남지 않음)
- 원인 — Ctrl+Z 한 번에 관 자리 되돌림(setPipeChainages) · 시설 따라감(reload) · 묶음 초안 버림(backToSaved) 셋이 저장분을 따로 받음
- 관 자리 되돌림 건너뜀 조건 — 요청 몸통만 견주던 것을 「화면이 저장분 답 그대로」까지 봄(지금 노선 [업데이트] 답이 오른 뒤엔 다시 받음)
- 지킴 시험 test_520_7 — 세 부름 = GET 한 번 · 초안 버림 먼저여도 올림 · 저장분 그대로면 GET 없음 · 세션 관 초안은 세부 유역 계산
- 낡은 시험 고침 — test_298 · test_472_d · test_b05_structures_form_summary 가 패널 원문에서 찾던 저장분 받기 줄이 새 파일로 옮겨짐
- 이음매 대조(tmp 일회) — primary-region 길 대 저장 노선 [업데이트] 길 네 프로젝트 도로로 오는 셀 · road_slot · 관별 면적 차이 0 · 초안 2.2~2.3 s · 저장 노선 2.1~2.6 s · Ctrl+Z GET 1 · 낡음 꺼짐 249~258 ms

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 08:57:37 +09:00

185 lines
7.8 KiB
Python

# -*- coding: utf-8 -*-
"""B05/B06 좌측 패널 「집계 항목」 회귀검증 — PLAN 21-4 (2026-09-29).
폼 옵션 보이기(`visible`) · [수정] 옵션 보존(안 그린 칸 · 상세 칸) · 집계 항목 줄(이름 ·
고르기 · 해제) · 관 계열 merge · 목록 줄 색(`.is-assigned`) + 툴팁을 본다.
화면 그릇은 Node 헬퍼가 흉내낸다(`helper_b05_structures_form_summary.cjs` —
TS 를 그 자리에서 트랜스파일).
실제 화면 조작은 ORCA(자체 확인)로 따로 본다.
"""
import json
import os
import subprocess
import pytest
HERE = os.path.dirname(os.path.abspath(__file__))
A_KEY = "SS000007"
@pytest.fixture(scope="module")
def out():
proc = subprocess.run(
["node", os.path.join(HERE, "helper_b05_structures_form_summary.cjs")],
capture_output=True,
text=True,
encoding="utf-8", # 한글 출력 — Windows 기본(cp949)으로 읽으면 깨짐
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
def test_visible_false_만_숨김(out):
assert out["visible"] == [True, True, False]
def test_visible_false_옵션은_폼에_안_그림_정의는_그대로(out):
# 숨긴 길이는 칸을 안 그리고 값만 쥠(54-26 · 범위 계산 · 저장이 옛 값을 이어 씀) · 상세는 B05 에 없음
assert out["drawB05"] == {
"keys": ["height_m", "length_m"],
"drawn": ["height_m"],
"hidden": False,
}
# B06 은 상세까지 · 숨김은 여기도 칸 없음
assert out["drawB06"]["drawn"] == ["height_m", "stone_kind"]
assert out["drawB06"]["keys"] == ["height_m", "stone_kind", "length_m"]
assert out["definitionKept"] == ["height_m", "length_m", "stone_kind", "back_len_cm"]
def test_수정은_안_그린_칸을_보존(out):
# 폼이 그린 H · stone_kind 는 갈아 끼우고, 안 그린 상세 칸 · 숨긴 칸은 옛 값 그대로
assert out["mergeSame"] == {"back_length_m": 0.6, "memo_only": "x", "H": 3}
def test_그린_칸을_비우면_지워짐(out):
assert out["mergeCleared"] == {"back_length_m": 0.6, "memo_only": "x"}
def test_종류를_바꾸면_통째로_새_값(out):
assert out["mergeTypeChange"] == {"H": 1}
assert out["mergeNoPrev"] == {"H": 9}
assert out["mergePrevNoOptions"] == {"H": 9}
def test_참조_모양_검사(out):
assert out["isItem"] == [True, False, False, False]
assert out["readItem"] == [A_KEY, None]
assert out["same"] == [True, False, True, False] # 이름만 바뀌면 같음
def test_키는_앞에_안_내세움_툴팁에만(out):
assert out["label"] == ["미지정", "돌기슭막이 메쌓기 1.2m"]
assert A_KEY not in out["label"][1]
assert A_KEY in out["tip"][1] and "개인용" in out["tip"][1]
assert out["rowSet"]["nameShowsKey"] is False
def test_집계_항목_줄(out):
empty = out["rowEmpty"]
assert (empty["name"], empty["assigned"], empty["clearDisabled"], empty["get"]) == (
"미지정",
False,
True,
None,
)
# 280-1 — [선택] 단추 없음(이름 칸이 고르기) · [해제] 그대로
assert (empty["label"], empty["buttons"], empty["clear"]) == ("구조물 조합", ["해제"], "해제")
row = out["rowSet"]
assert row["assigned"] is True and row["clearDisabled"] is False
assert row["name"] == "돌기슭막이 메쌓기 1.2m" and A_KEY in row["title"]
assert out["clicks"][:2] == ["pick", "clear"] # 이름 칸 누름 = 고르기
assert out["keyClicks"] == {
"clicks": ["pick", "pick"],
"prevented": ["prevent:Enter", "prevent: "],
}
assert out["rowCleared"] == {"name": "미지정", "clearDisabled": True}
def test_관_계열_merge_가_집계_항목을_잇고_지움(out):
assert out["pipeKeep"]["key"] == A_KEY # 다음 값에 칸이 없으면 옛 지정을 이음
assert out["pipeClear"] is None # 폼이 null 을 보내면 해제
assert out["pipeSet"] == "SS000004" # 다른 항목으로 바꿈
def test_목록_줄_색과_툴팁(out):
rows = out["list"] # 측점 순: 구조물(지정) · 구조물(미지정) · 관(지정) · 관(미지정)
assert [r["assigned"] for r in rows] == [True, False, True, False]
assert A_KEY in rows[0]["title"] and "SS000004" in rows[2]["title"]
assert rows[1]["title"] == "" and rows[3]["title"] == "" # 미지정은 지금 그대로
def test_저장_기록에_집계_항목이_실리고_해제하면_칸이_빠짐(out):
# 새 구조물(미지정) — 칸을 아예 안 실음(서버가 모르는 칸을 거절하는 동안에도 저장이 안 깨짐)
assert out["commitNew"] == {"hasKey": False, "options": {"H": 3}}
# 지정돼 있던 것을 해제 — 옛 지정이 살아오지 않음 · 안 그린 칸은 보존
assert out["commitCleared"]["hasKey"] is False
assert out["commitCleared"]["options"] == {"hidden_cost_key": "keep", "detail_only": 9, "H": 3}
# 지정 유지 · 바꿈
assert out["commitKept"] == {
"key": A_KEY,
"options": {"hidden_cost_key": "keep", "detail_only": 9, "H": 3},
}
assert out["commitSwapped"] == "SS000004"
def test_집계_항목만_바뀌면_폼_검증과_무관하게_기록에_반영(out):
# 흠 2 — 필수 옵션이 비어도 실시간 반영은 나감(54-12 · 막기는 [추가] · [저장])
assert out["formBlocks"] is False
# 집계 항목 전용 반영은 그 검증을 안 거침 · 옵션은 그대로
assert out["summaryOnlyAssign"] == {
"done": True,
"key": "SS000004",
"options": {"H": 2, "hidden_cost_key": "keep", "detail_only": 9},
}
assert out["summaryOnlyClear"] == {"done": True, "hasKey": False}
assert out["summaryOnlyNew"] is False
def test_배수유역_화면은_들어올_때_세션_초안_관을_먼저_씀():
# 흠 3 — B05→B06→B05 를 오가도 저장 전 지정 · 옵션이 옛값으로 안 돌아감
source = open(
os.path.join(HERE, "..", "..", "B05_Profile", "B05_Profile_UI_Drainage_Saved.ts"),
encoding="utf-8",
).read() # 저장분 받기 = 패널 밖(520-7)
body = source.split("const load =", 1)[1].split("const matches", 1)[0]
assert "readPendingPipes(" in body and "computeDetailBasins(" in body
assert body.index("readPendingPipes(") < body.index("fetchDetailPipePoints(")
def test_시설_폼_끈_옵션_가리기(out):
# 칸 표식 — 키 하나 · 여럿 · 없음
assert out["labelTag"] == ["pipe_kind", "inlet_type inlet_structure", None]
none = dict(kind=False, dia=False, rowA=False, inlet=False, free=False, rowB=False)
assert out["hideOne"] == {**none, "kind": True}
# 줄의 칸이 다 가려지면 줄째 · 표식 없는 칸은 그대로
assert out["hideRow"] == {**none, "kind": True, "dia": True, "rowA": True}
assert out["hideInletPartial"] == none
assert out["hideInlet"] == {**none, "inlet": True}
assert out["showAll"] == none # [모두 보임] 뒤 되돌아옴
def test_숨긴_칸은_옛_값_그대로_저장에_실림(out):
# 칸에서 읽은 값(VR관 · 제안)이 아니라 폼이 받은 옛 값 — 안 숨긴 칸은 칸 값
assert out["restored"] == {"pipe_kind": "흄관", "pipe_diameter_mm": 800, "other": 2}
# 옛 값이 없던 숨긴 칸은 값이 안 실림(칸의 제안값이 몰래 확정되지 않음)
assert out["restoredEmpty"] == {"pipe_diameter_mm": 800}
def test_끈_키를_폼_칸_키로_넓힘(out):
# 독립 기슭막이는 유입 · 유출 채널 키로 · 유입구 구조는 inlet_structure 까지
assert out["revetKeys"] == sorted(
[
"form",
"height_m",
"side",
"inlet_revet_form",
"outlet_revet_form",
"inlet_revet_height_m",
"outlet_revet_height_m",
]
)
assert out["pipeKeys"] == ["inlet_structure", "inlet_type"]
assert out["otherKeys"] == ["form"]