"""553-5 M01 · M02 페이지 부품 옮김 지킴 시험 — 자체 변종이 부품으로 바뀐 자리 · 날 단추 · 손 모달 · 날 색 없음.""" import re from pathlib import Path ROOT = Path(__file__).resolve().parents[2] OLD_ALIAS = re.compile(r"--color-(royal-amethyst|deep-iris|mist-violet|plum-velvet|lavender-wash)") RAW_COLOR = re.compile(r"#[0-9a-fA-F]{3,8}\b|\brgba?\(") def _src(folder: str, suffix: str) -> dict[str, str]: return {p.name: p.read_text(encoding="utf-8") for p in (ROOT / folder).glob(f"*{suffix}")} def test_m01_no_raw_buttons_or_hand_modals(): for name, ts in _src("M01_MasterData", ".ts").items(): # 날 단추 — 왼쪽 목록 줄(공용 ui-sidebar-row) · 목록 줄 부품 꼴 단추만 남음 for m in re.finditer(r'el\("button", \{\s*className: "([^"]*)"', ts): assert "ui-sidebar-row" in m.group(1), f"{name}: 날 단추 {m.group(1)}" assert "document.body.append(" not in ts, f"{name}: 손 모달 — openModal 부품을 씀" def test_m01_parts_in_place(): ts = "".join(_src("M01_MasterData", ".ts").values()) for part in ( "openModal(", "createBanner", "createBadge(", "createText(", "createEmpty(", "createIconButton(", ): if part == "createBanner": assert ( "ui-banner ui-banner--danger m01-master__notice" in ts ) # 알림 띠 = 띠 알림 부품 꼴 assert "ui-banner ui-banner--danger m01-logic__reasons" in ts continue assert part in ts, f"M01 이 부품 {part} 를 안 씀" assert "ui-table m01-master__grid" in ts and "ui-table-wrap m01-master__grid-wrap" in ts for gone in ( "m01-logic__muted", "m01c__muted", "m01-master__muted", "m01-logic__tag", "m01-logic__bad", ): assert gone not in ts, f"옛 변종 {gone} 남음" def test_m01_css_common_values_only(): for name, css in _src("M01_MasterData", ".css").items(): assert not OLD_ALIAS.search(css), f"{name}: 옛 보라 별칭" body = re.sub(r"/\*.*?\*/", "", css, flags=re.S) assert not RAW_COLOR.search(body), f"{name}: 날 색" for gone in ( ".m01-procure {", ".m01-logic__backdrop {", ".m01-logic__tag", ".m01lab__pills", ): assert gone not in css, f"{name}: 죽은 · 옛 CSS {gone}" def test_m02_borrowed_m01_classes_follow_parts(): ts = "".join(_src("M02_MasterTemplete", ".ts").values()) assert "m01-logic__muted" not in ts and "m01-master__muted" not in ts.replace("ui-text", "") assert 'className: "m01-master__grid"' not in ts # 빌린 표도 표 부품 꼴 assert "ui-table m01-master__grid" in ts def _m02_src(suffix: str) -> dict[str, str]: out = {} for sub in ("", "DataFlow", "StructOptions"): out.update(_src(f"M02_MasterTemplete/{sub}".rstrip("/"), suffix)) return out def test_m02_parts_in_place(): ts = "".join(_m02_src(".ts").values()) for part in ("createEmpty(", "createText(", "createBadge(", "createTabs(", "createCheckbox("): assert part in ts, f"M02 이 부품 {part} 를 안 씀" for cls in ( "ui-banner ui-banner--", "ui-toolbar m02-", "ui-table ui-table--data", "ui-list-row", ): assert cls in ts, f"M02 부품 꼴 {cls} 없음" # 시험 · 가이드가 잡는 이름은 그대로 for keep in ("m02-layers__btn", "m02-side__lists", "m02-main__new", "data-sod-tab"): assert keep in ts, f"잡히는 이름 {keep} 사라짐" def test_m02_css_no_old_alias(): for name, css in _m02_src(".css").items(): assert not OLD_ALIAS.search(css), f"{name}: 옛 보라 별칭" def test_m02_dataflow_muted_spans_use_ui_text(): """553-8 ① — 흐린 글 span · div · p 는 보조 글 부품 꼴 · 옛 __muted 걷음.""" ts = "".join(_m02_src(".ts").values()) css = "".join(_m02_src(".css").values()) for gone in ("m02-dfip__muted", "m02-dfout__muted", "m02-dfver__muted"): assert gone not in ts and gone not in css, f"옛 변종 {gone} 남음" assert len(re.findall(r'"ui-text ui-text--muted",\s*attrs: \{ "data-text": "14" \}', ts)) >= 21