- 새 부품 파일: ui_template_card · empty · banner · stat · kv · toast · flow_legend(.ts) · 진행 막대 · 막대 · 원 그래프 덧붙임 - createCard · showToast · 로딩 가림막은 부품 파일로 옮기고 본체(ui_template_elements)가 다시 내보냄 — 부름 꼴 그대로 - 대시보드 emptyState = 빈 상태 부품을 씀(한 벌) · 선 카드 그림자 0 · 가림막 옛 보라 → --color-scrim - 부품 모음 화면 견본(밝음 · 어두움 · 상태) · 지킴 시험 test_552_3_* 열 - 전후 촬영: B01 여덟 화면 자리 · 화소 같음(실시간 CPU 값만 다름) · A01 · B08 카드 그림자만 다름 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
75 lines
3.1 KiB
Python
75 lines
3.1 KiB
Python
"""552-3 부품 「카드」 지킴 시험 + 묶음 부품 공용 규칙(`check_part` — 552-3 시험 파일들이 가져다 씀).
|
|
|
|
공용 규칙 = 파일 머리(꼴 · 크기 · 상태 · 쓰는 법 · 대신하는) · 만들기 함수 · 클래스 이름 · 날 색 · `--b01-*` · `--draw-*` 없음
|
|
· font-family 없음 · 마우스 · 눌림 = `:is(:hover, [data-state="hover"])` 꼴 · 부품 모음 줄(file · demo) · 700 줄.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
UI = ROOT / "ui_template"
|
|
RAW_COLOR = re.compile(r"#[0-9a-fA-F]{3,8}\b|rgba?\(|hsla?\(")
|
|
|
|
|
|
def _text(name: str) -> str:
|
|
return (UI / name).read_text(encoding="utf-8")
|
|
|
|
|
|
def kit_line(key: str) -> str:
|
|
"""부품 모음 목록의 그 부품 줄(이어지는 demo 줄까지)."""
|
|
src = _text("ui_template_ui_kit_parts.ts")
|
|
m = re.search(r' \{ key: "%s",[^\n]*\n(?: [^\n]*\n)*' % re.escape(key), src)
|
|
assert m, key
|
|
return m.group(0)
|
|
|
|
|
|
def check_part(key: str, ts: str, css: list[str], create: list[str], classes: list[str]) -> None:
|
|
head = _text(ts).split("*/", 1)[0]
|
|
for word in ("꼴", "크기", "상태", "쓰는 법", "대신하는"):
|
|
assert word in head, (ts, word)
|
|
body = _text(ts)
|
|
for fn in create:
|
|
assert re.search(rf"export function {fn}\b", body), fn
|
|
for cls in classes:
|
|
assert cls in body + "".join(_text(c) for c in css), cls
|
|
for name in [ts, *css]:
|
|
text = _text(name)
|
|
assert len(text.splitlines()) <= 700, name
|
|
# 옛 파일에 덧붙인 CSS 는 「(552-3)」 표 뒤만 · 주석(머리 설명 · 옛 변종 이름)은 빼고 봄
|
|
if name.endswith(".css") and "(552-3)" in text:
|
|
text = text[text.index("(552-3)") :]
|
|
code = re.sub(r"/\*[\s\S]*?\*/", "", text)
|
|
assert not RAW_COLOR.search(code), (name, RAW_COLOR.search(code))
|
|
assert "--b01-" not in code and "--draw-" not in code, name
|
|
if name.endswith(".css"):
|
|
assert "font-family" not in code, name
|
|
for m in re.finditer(r":(hover|active)\b", code):
|
|
around = code[max(0, m.start() - 4) : m.end() + 30]
|
|
assert f'[data-state="{m.group(1)}"]' in around, (name, around)
|
|
line = kit_line(key)
|
|
assert f'file: "{ts}"' in line and "demo:" in line, key
|
|
assert "legacy: true" not in line, key
|
|
|
|
|
|
def test_card():
|
|
check_part(
|
|
"card",
|
|
"ui_template_card.ts",
|
|
["ui_template_card.css"],
|
|
["createCard", "setCardSelected"],
|
|
["ui-card", "ui-card--raised", "ui-card__title", "ui-card__body", "ui-card--select"],
|
|
)
|
|
css = _text("ui_template_card.css")
|
|
assert '.ui-card[data-pad="12"]' in css and '.ui-card[data-pad="16"]' in css
|
|
assert '[aria-pressed="true"]' in css and ":disabled" in css
|
|
# 옛 부름 꼴 그대로 — 본체가 다시 내보냄 · 선 카드 그림자 0
|
|
elements = _text("ui_template_elements.ts")
|
|
assert (
|
|
'export { createCard, setCardSelected, type CardOptions } from "./ui_template_card"'
|
|
in elements
|
|
)
|
|
assert "box-shadow: none; /* 선 카드(552-3)" in _text("ui_template_elements_styles.ts")
|