- ui_template_map_tools.ts · .css — 아이콘 단추 한 벌(차례 · 나눔선 · 켬끔 aria-pressed · [?] 안내 판) - 아이콘 더함 — ripple · tallymarks · percentage · magnet · satellite · droplet · borderAll · angle(Tabler MIT) - 부품 모음 틀 묶음에 「지도 도구줄」 견본 · 시험 test_568_1 · test_552_4 목록에 map-tools Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
107 lines
5.1 KiB
Python
107 lines
5.1 KiB
Python
"""552-4 틀 부품 아홉 지킴 시험 — 화면 확인은 부품 모음(`#/b01-account?view=ui-kit`) · ORCA.
|
|
|
|
부품마다(이름 · data-size · 상태 규칙 · 날 색 없음):
|
|
· 작업 화면 틀(overlay) · 일반 화면 틀(general_layout) · 공개 화면 틀(public_layout)
|
|
· 떠 있는 판 · 오른쪽 서랍(side_panels) · 도구줄 · 단계 줄(workflow_layout) · 패널 머리 · 목록 줄
|
|
· 부품 모음 목록 = 아홉 모두 `frame` 묶음 · 견본(demo) 있음 · 파일 이름 = 552-1 목록 그대로
|
|
· 옛 공용 이름(`ui-sidebar-actions` · `ui-sidebar-row` · `ui-workflow-layout__step` …)은 그대로 냄
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
UI = ROOT / "ui_template"
|
|
|
|
# 부품 열쇠 → (ts 파일, css 파일, 만들기 함수, 낼 클래스, 높이 단)
|
|
PARTS = {
|
|
"work-frame": ("ui_template_overlay", "createWorkflowOverlays", "ui-workflow-overlay", ()),
|
|
"page-frame": ("ui_template_general_layout", "createPageFrame", "ui-page-frame", ()),
|
|
"public-frame": ("ui_template_public_layout", "createPublicFrame", "ui-public-frame", ()),
|
|
"float-panel": ("ui_template_float_panel", "createFloatPanel", "ui-float-panel", (32,)),
|
|
"drawer": ("ui_template_side_panels", "createSidePanels", "ui-side-panels", ()),
|
|
"toolbar": ("ui_template_toolbar", "createToolbar", "ui-toolbar", (24, 28, 32)),
|
|
"map-tools": ("ui_template_map_tools", "createMapTools", "ui-map-tools", ()),
|
|
"steps": ("ui_template_workflow_layout", "createStepBar", "ui-workflow-layout__step", (28, 40)),
|
|
"panel-head": ("ui_template_panel_head", "createPanelHead", "ui-panel-head", (32,)),
|
|
"list-row": ("ui_template_list_row", "createListRow", "ui-list-row", (28, 32, 36)),
|
|
}
|
|
|
|
RAW_COLOR = re.compile(r"#[0-9a-fA-F]{3,8}\b|rgba?\(|hsla?\(|var\(--(?:b01|draw)-")
|
|
|
|
|
|
def _text(path: Path) -> str:
|
|
return path.read_text(encoding="utf-8")
|
|
|
|
|
|
def _strip_comments(css: str) -> str:
|
|
return re.sub(r"/\*[\s\S]*?\*/", "", css)
|
|
|
|
|
|
@pytest.mark.parametrize("key", PARTS)
|
|
def test_머리_이름_크기(key):
|
|
stem, maker, cls, sizes = PARTS[key]
|
|
ts = _text(UI / f"{stem}.ts")
|
|
head = ts.split("*/", 1)[0]
|
|
# 규칙 8 — 머리에 무엇 · 꼴 · 크기 · 상태 · 쓰는 법 · 대신하는 옛 변종
|
|
for word in ("꼴", "크기", "상태", "쓰는 법", "대신하는 옛 변종"):
|
|
assert word in head, f"{stem} 머리에 {word} 없음"
|
|
assert re.search(rf"export function {maker}\b", ts), maker
|
|
assert cls in ts
|
|
css = _strip_comments(_text(UI / f"{stem}.css"))
|
|
for size in sizes:
|
|
assert f'[data-size="{size}"]' in css or f"min-height: {size}px" in css, (stem, size)
|
|
assert len(ts.splitlines()) <= 700 and len(css.splitlines()) <= 700
|
|
|
|
|
|
@pytest.mark.parametrize("key", PARTS)
|
|
def test_날_색_없음(key):
|
|
stem = PARTS[key][0]
|
|
css = _strip_comments(_text(UI / f"{stem}.css"))
|
|
assert not RAW_COLOR.search(css), (stem, RAW_COLOR.search(css))
|
|
assert "font-family" not in css # 글꼴 = --font-ui 상속
|
|
|
|
|
|
def test_상태_규칙():
|
|
# 마우스 · 눌림을 data-state 로 굳혀 보일 수 있음
|
|
for stem in ("ui_template_list_row", "ui_template_workflow_layout", "ui_template_overlay"):
|
|
css = _text(UI / f"{stem}.css")
|
|
assert ':is(:hover, [data-state="hover"])' in css, stem
|
|
row = _text(UI / "ui_template_list_row.css")
|
|
assert ".ui-sidebar-row.is-active" in row and '[aria-disabled="true"]' in row
|
|
|
|
|
|
def test_작업_화면_틀_겉():
|
|
css = _strip_comments(_text(UI / "ui_template_overlay.css"))
|
|
title = re.search(r"\.ui-workflow-overlay__panel--title \{([^}]*)\}", css).group(1)
|
|
# 흰 판 + 1 px 선 · 그림자 없음(요구 375 정함 7)
|
|
assert "box-shadow: none" in title and "border-right-color: var(--color-border)" in title
|
|
# 손잡이는 강조색 그대로(2026-08-04 사용자 지시)
|
|
assert "border: 1px solid var(--panel-handle-border" in css
|
|
assert "background: var(--color-scrim)" in css
|
|
# 옛 이름 그대로 — 아래 단추 줄 · [?][<][>]
|
|
for name in (".ui-sidebar-actions", ".ui-workflow-overlay__handle--side"):
|
|
assert name in css
|
|
# 아래 단추 줄 — 다 안 들면 두 줄로 감음 · 글자 단추는 글보다 안 좁아짐(552-7 E03 「해석」 잘림)
|
|
row = re.search(r"\.ui-sidebar-actions \[data-help-row\] \{([^}]*)\}", css).group(1)
|
|
assert "flex-wrap: wrap" in row
|
|
btn = re.search(r"\[data-help-row\] > \.ui-btn:not\([^)]*\) \{([^}]*)\}", css).group(1)
|
|
assert "min-width: max-content" in btn
|
|
ts = _text(UI / "ui_template_overlay.ts")
|
|
assert 'import "./ui_template_list_row.css"' in ts # 옛 목록 줄 겉도 함께
|
|
|
|
|
|
def test_부품_모음_목록():
|
|
src = _text(UI / "ui_template_ui_kit_parts.ts")
|
|
rows = dict(re.findall(r'\{ key: "([^"]+)", name: "[^"]+", group: "(\w+)"', src))
|
|
lines = src.splitlines()
|
|
for key, (stem, *_rest) in PARTS.items():
|
|
assert rows.get(key) == "frame", key
|
|
i = next(i for i, x in enumerate(lines) if f'key: "{key}"' in x)
|
|
assert f'file: "{stem}.ts"' in lines[i], key
|
|
assert "demo:" in lines[i] + lines[i + 1], key
|