- 280-1 이름 칸 = 고르기(누름 · Enter · Space · 손 커서 · 풍선 · 초점 테두리) · [선택] 단추 지움 · [해제] 그대로 · 본체 · 그룹 · 명세 잇기 같은 줄 부품 - 280-2 모달 제목 「구조물 조합 선택」 · 위 표 열 고름 → 나무 펼쳐 고름 · 카드 · 층 단추 → 위 표 = 그 층 표 · B08 연결 같은 모달 - 280-3 M02 구조물 조합 = 따로 짠 길로 두 고리 정상 · 고침 없음 - 시험 test_280_1_combo_label_pick 새로 · test_224_1 · test_b05_structures_form_summary 새 꼴에 맞춤 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
155 lines
5.4 KiB
Python
155 lines
5.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""PLAN 280 — B05 · B06 구조물조합 칸 · 「구조물 조합 선택」 모달.
|
|
|
|
280-1 이름 칸 = 고르기 단추 노릇(누름 · Enter · Space · 손 커서 · 풍선 · 초점 테두리) · [선택] 없음 · [해제] 그대로 ·
|
|
본체 집계 항목 · 그룹 상자 · 명세 컨테이너 잇기가 같은 줄 부품.
|
|
280-2 모달 제목 · 위 표 고름 → 나무(펼쳐 굴림) · 오른쪽 카드 · 층 단추 → 위 표 = 그 층(Node · 대역).
|
|
"""
|
|
|
|
import json
|
|
import re
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
ROOT = HERE.parents[1]
|
|
UI = ROOT / "ui_template"
|
|
B05 = ROOT / "B05_Profile"
|
|
|
|
|
|
def _text(path: Path) -> str:
|
|
return path.read_text(encoding="utf-8")
|
|
|
|
|
|
def _node(helper: str) -> dict:
|
|
proc = subprocess.run(
|
|
["node", str(HERE / helper)],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=60,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def row():
|
|
return _node("helper_b05_structures_form_summary.cjs")
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def picker():
|
|
return _node("helper_280_1_combo_pick.cjs")
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def table():
|
|
return _node("helper_224_1_picker_top_table.cjs")
|
|
|
|
|
|
# ── 280-1 ────────────────────────────────────────────────────────────────
|
|
|
|
|
|
def test_이름_칸_누름_Enter_Space_고르기_선택_단추_없음_해제_있음(row):
|
|
assert row["rowEmpty"]["buttons"] == ["해제"]
|
|
assert row["clicks"][:2] == ["pick", "clear"]
|
|
assert row["keyClicks"] == {
|
|
"clicks": ["pick", "pick"],
|
|
"prevented": ["prevent:Enter", "prevent: "],
|
|
}
|
|
# 고른 뒤 · 해제 뒤 이름 칸 글 바뀜 그대로
|
|
assert row["rowSet"]["name"] == "돌기슭막이 메쌓기 1.2m"
|
|
assert row["rowCleared"] == {"name": "미지정", "clearDisabled": True}
|
|
|
|
|
|
def test_이름_칸_풍선_초점_손_커서():
|
|
src = _text(B05 / "B05_Profile_UI_Structures_Summary_Row.ts")
|
|
assert 'const PICK_TIP = "눌러서 고르기";' in src
|
|
assert "name.title = `${summaryTooltip(item)} · ${PICK_TIP}`;" in src
|
|
assert "name.tabIndex = -1;" not in src # Tab 으로 초점이 감
|
|
assert '"선택"' not in src
|
|
css = _text(B05 / "B05_Profile_UI_Style_Structures.css")
|
|
base = re.search(r"\.b05-structure__summary-name \{([^}]*)\}", css).group(1)
|
|
assert "cursor: pointer;" in base
|
|
focus = re.search(r"\.b05-structure__summary-name:focus-visible \{([^}]*)\}", css).group(1)
|
|
assert "outline:" in focus
|
|
|
|
|
|
def test_같은_꼴_줄_모두_한_부품():
|
|
# 본체 집계 항목 · 그룹 상자 · 명세 컨테이너 잇기 = 같은 `buildSummaryRow`
|
|
for path in (
|
|
B05 / "B05_Profile_UI_Structures_Form.ts",
|
|
B05 / "B05_Profile_UI_Structures_Groups.ts",
|
|
ROOT / "A00_Common" / "design" / "design_structure_form.ts",
|
|
):
|
|
assert "buildSummaryRow()" in _text(path), path.name
|
|
|
|
|
|
# ── 280-2 ────────────────────────────────────────────────────────────────
|
|
|
|
|
|
def test_모달_제목():
|
|
locale = _text(UI / "ui_template_locale_m2.ts")
|
|
assert 'M02_PickerTitle: ["구조물 조합 선택", "Select structure combo"],' in locale
|
|
assert 'title: t("M02_PickerTitle"),' in _text(UI / "ui_template_item_picker.ts")
|
|
|
|
|
|
def test_처음_위_표_보이는_층_표(picker):
|
|
assert picker["start"] == {
|
|
"table": "personal|u1|",
|
|
"layer": ["M02_PickerPersonal"],
|
|
"detail": None,
|
|
}
|
|
|
|
|
|
def test_위_표_고름_나무_펼쳐_고름_오른쪽_카드(picker):
|
|
assert picker["tablePick"] == {
|
|
"active": "personal|u1|SP2",
|
|
"visible": True,
|
|
"scrolled": True,
|
|
"detail": "SP2",
|
|
"table": "personal|u1|rvP2",
|
|
}
|
|
# 같은 열 · 표에 없는 열 = 안 바뀜(표 → 나무 → 표 되돌이 없음)
|
|
assert picker["sameAgain"] == {"detail": 0, "table": 0}
|
|
# 접힌 폴더 속 항목도 펼쳐서 고름
|
|
assert picker["systemLeavesBefore"] == []
|
|
assert picker["systemPick"] == {
|
|
"active": "system||SS2",
|
|
"visible": True,
|
|
"detail": "SS2",
|
|
"table": "system||rvS2",
|
|
}
|
|
|
|
|
|
def test_층_단추_위_표_그_층(picker):
|
|
assert picker["layerSystem"] == {
|
|
"table": "system||",
|
|
"layer": ["M02_PickerSystem"],
|
|
"detail": "SP2", # 고른 항목은 그대로
|
|
}
|
|
assert picker["layerCompany"] == {"table": "company|c1|", "layer": ["M02_PickerCompany"]}
|
|
assert picker["layerBack"] == "personal|u1|rvP2" # 고른 항목 층으로 오면 그 열
|
|
|
|
|
|
def test_나무_고름_위_표_열_지금_길(picker):
|
|
assert picker["treePick"] == {
|
|
"active": "system||SS2",
|
|
"detail": "SS2",
|
|
"table": "system||rvS2",
|
|
}
|
|
|
|
|
|
def test_찾기에_가려진_항목_표에서_고르면_찾기_풂(picker):
|
|
assert picker["searchCleared"] == {"value": "", "active": "system||SS1"}
|
|
|
|
|
|
def test_위_표_열_고름은_부른_쪽에_층만_바꾸면_열_없이(table):
|
|
assert table["onColumn"] == ["rv2"]
|
|
assert table["layerOnly"]["reads"] == [
|
|
["readTemplate", "system", "table", "구조물집계표", None, None]
|
|
]
|