136 lines
6.1 KiB
Python
136 lines
6.1 KiB
Python
"""553-4 예정노선(D01~D04) · 안정성평가(E01~E07) 부품 옮김 지킴 시험 — 서버 · 화면 없이 소스만 본다.
|
|
옮긴 페이지는 날 `<input>` · `<progress>` · 날 색 · 안 쓰는 변종 CSS 가 다시 생기면 안 됨."""
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def _src(path: str) -> str:
|
|
return (ROOT / path).read_text(encoding="utf-8")
|
|
|
|
|
|
def _no_hex(path: str) -> None:
|
|
css = re.sub(r"/\*.*?\*/", "", _src(path), flags=re.S)
|
|
assert not re.search(r"#[0-9a-fA-F]{3,8}\b", css), f"{path}: 날 색"
|
|
|
|
|
|
def test_d01_station_label_is_text_part():
|
|
ts = _src("D01_PlanRegister/D01_PlanRegister_UI_Page.ts")
|
|
assert "style.cssText" not in ts
|
|
assert 'createText("", "muted")' in ts
|
|
assert 'dataset.station = ""' in ts # 시험 · 촬영이 잡음
|
|
|
|
|
|
def test_d02_parts():
|
|
ts = _src("D02_PlanBase/D02_PlanBase_UI_Page.ts")
|
|
css = _src("D02_PlanBase/D02_PlanBase_UI_Style.css")
|
|
assert 'el("input"' not in ts
|
|
assert 'createInputField({ type: "number"' in ts
|
|
assert 'classList.add("d02-info")' in ts # 촬영 장면이 `p.d02-info` 로 잡음
|
|
for dead in (".d02-info", "is-invalid", "font-size: var(--text-caption);\n}\n\n.d02-info"):
|
|
assert dead not in css
|
|
assert "data-axis" in ts or "dataset.axis" in ts
|
|
|
|
|
|
def test_d03_parts():
|
|
ts = _src("D03_PlanAnalysis/D03_PlanAnalysis_UI_Page.ts")
|
|
three = _src("D03_PlanAnalysis/D03_PlanAnalysis_UI_3D.ts")
|
|
css = _src("D03_PlanAnalysis/D03_PlanAnalysis_UI_Style.css")
|
|
assert 'createElement("progress")' not in ts and "createProgressBar()" in ts
|
|
assert "createCard({" in ts and "onSelect:" in ts
|
|
assert 'classList.toggle("is-picked"' in ts # 촬영 장면이 `.d03-plan__mode.is-picked` 로 잡음
|
|
assert "card.dataset.mode = mode" in ts
|
|
assert 'createElement("select")' not in three and "createSelectField" in three
|
|
assert 'createElement("input")' not in three and "createCheckbox" in three
|
|
for dead in (".d03-plan__bar", ".d03-plan__mode", "is-picked"):
|
|
assert dead not in css, dead
|
|
|
|
|
|
def test_d04_parts():
|
|
ts = _src("D04_PlanConfirm/D04_PlanConfirm_UI_Page.ts")
|
|
css = _src("D04_PlanConfirm/D04_PlanConfirm_UI_Style.css")
|
|
assert 'el("input"' not in ts
|
|
assert ts.count("createInputField(") == 2 and "createCheckbox(" in ts
|
|
assert 'createBanner({ tone: "warning"' in ts
|
|
assert "input:checked" in ts # [확정] 이 고른 연도를 읽는 길
|
|
assert "border:" not in css.split(".d04-confirm__input")[1].split("}")[0]
|
|
assert ".d04-confirm__dirty" not in css
|
|
assert 'el("table"' not in ts and "tableShell(columns)" in ts
|
|
assert "d04-confirm__table" not in css # 표 모양은 표 부품 · 이름은 촬영 장면용 걸이
|
|
|
|
|
|
def test_e01_missing_is_banner_part():
|
|
ts = _src("E01_StabRegister/E01_StabRegister_UI_Missing.ts")
|
|
assert "createBanner" in ts and '"details"' not in ts
|
|
assert 'dataset.role = "missing-stations"' in ts # 시험 · 촬영이 잡음
|
|
assert not (ROOT / "E01_StabRegister/E01_StabRegister_UI_Missing.css").exists()
|
|
|
|
|
|
def test_e02_parts():
|
|
tables = _src("E02_StabGround/E02_StabGround_UI_Tables.ts")
|
|
page = _src("E02_StabGround/E02_StabGround_UI_Page.ts")
|
|
css = _src("E02_StabGround/E02_StabGround_UI_Style.css")
|
|
assert 'el("input"' not in tables and 'el("select"' not in tables
|
|
assert "createInputField(" in tables and "createSelectField(" in tables
|
|
assert "createCard({ title" in tables
|
|
assert "is-invalid" not in page + css and "is-error" in page
|
|
for dead in (".e02-card__head", ".e02-card__title", ".e02-hint", ".e02-empty"):
|
|
assert dead not in css, dead
|
|
_no_hex("E02_StabGround/E02_StabGround_UI_Style.css")
|
|
assert "createTable(" in tables and "createTHead" not in tables
|
|
assert 'className: "ui-field e02-field"' in tables # 칸 이름 줄은 입력 부품의 ui-field
|
|
assert ".e02-field" not in css and "border-collapse" not in css
|
|
|
|
|
|
def test_e03_parts():
|
|
names = [
|
|
"List", "Page", "Plan", "Prob", "ProbChart", "Reinforce", "Result", "Section", "Support", "View3D",
|
|
] # fmt: skip
|
|
ts = {n: _src(f"E03_StabSection/E03_StabSection_UI_{n}.ts") for n in names}
|
|
css = _src("E03_StabSection/E03_StabSection_UI_Style.css")
|
|
for n, src in ts.items():
|
|
assert 'el("table"' not in src, n # 표 = 표 부품(`E03_StabSection_UI_Table.ts`)
|
|
assert 'el("input"' not in src and 'el("select"' not in src, n
|
|
assert "e03-legend__item" not in src and "e03-legend__swatch" not in src, n
|
|
assert "createTable(" in _src("E03_StabSection/E03_StabSection_UI_Table.ts")
|
|
assert "dataset.role = role" in _src("E03_StabSection/E03_StabSection_UI_Table.ts")
|
|
assert "createLegend(" in _src("E03_StabSection/E03_StabSection_UI_Parts.ts")
|
|
assert "openModal(" in ts["View3D"] and 'className: "e03-view3d"' not in ts["View3D"]
|
|
for key in ("station-list", "slice-table", "methods", "whatif-table", "support-table"):
|
|
assert f'"{key}"' in "".join(ts.values()), key # 촬영 장면 · 시험이 잡는 data-role
|
|
for dead in (
|
|
".e03-legend__item", ".e03-legend__swatch", ".e03-table", ".e03-verdict", ".e03-kpi",
|
|
".e03-view3d {", ".e03-swatch-none", ".e03-list table", ".e03-list th {",
|
|
): # fmt: skip
|
|
assert dead not in css, dead
|
|
|
|
|
|
def test_e04_parts():
|
|
page = _src("E04_Stab3D/E04_Stab3D_UI_Page.ts")
|
|
view = _src("E04_Stab3D/E04_Stab3D_UI_View3D.ts")
|
|
css = _src("E04_Stab3D/E04_Stab3D_UI_Style.css")
|
|
assert 'el("progress"' not in page and "createProgressBar()" in page
|
|
for part in (
|
|
"createSegment(",
|
|
"createListRow(",
|
|
"createKv(",
|
|
"createFloatPanel(",
|
|
"createBanner(",
|
|
):
|
|
assert part in page, part
|
|
assert 'el("input"' not in view and "createCheckbox(" in view
|
|
assert (
|
|
'classList.add("e04-toggle")' in page
|
|
) # 촬영 장면이 `.e04-toggle button[data-value]` 로 잡음
|
|
assert 'row.classList.add("e04-section")' in page
|
|
for dead in (
|
|
".e04-toggle .ui-btn",
|
|
".e04-legend__row",
|
|
".e04-legend__swatch",
|
|
".e04-result__list",
|
|
".e04-section:hover",
|
|
):
|
|
assert dead not in css, dead
|