Files
Aislo/resources/tester/test_198_1_b08_summary_lamp.py
T
eomsangdonandClaude Opus 5.5 271c460641 fix(부품·테마): 위험 채움 대비 4.72 · 남은 옛 꼴 → 부품(계산 줄 · 칸 램프 · 넓은 중간 창 · 규칙 꼴 · 구역 머리 · 입력 칸 2열) (PLAN 557-2)
- 위험 채움 토큰 밝음 #e5484d → #d6363c(흰 글 3.91 → 4.72) · 어두움 5.6 · 위험 글 #c0392b 그대로
- 새 부품 계산 줄(ui_template_calc_row) — B08 수리집수면적표 b08-hydro__row · 식 칸 배치를 대신함
- 표 부품 칸 램프(ui-data-table__lamp · --only · ✓) — B08 집계표 · 거리이정표 · B09 설계내역 램프 CSS 세 벌을 걷음(표지 class 는 풍선 · 가이드용으로 남김)
- 모달 넓은 중간 창(wide + width 1100px · 1100 × 680) — B09 운반 창 손 인라인 크기를 걷음
- 값 목록 규칙 꼴(rule) — ☰ 설정 규칙 줄 ul/li 를 걷음
- 접이 구역 머리(createCollapsibleHead = 패널 머리 + 접는 제목) — B08 구조물도 「조합 연결」 제목(옛 b08-sheets__title)을 대신함
- 일반 화면 틀 좁은 폭 · 입력 칸 2열 · 끝 단추 줄 — D01 · E01 이 B02 CSS 를 빌리던 것을 끊음(가이드 장면 선택자 맞춤)
- 부품 모음 견본 · 지킴 시험 test_557_2 · 낡은 시험(198_1 · 247_1 · 251_1 · 257_1 · 276_1 · 551_1)은 부품 CSS · 새 class 로 맞춤

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 10:53:34 +09:00

119 lines
4.9 KiB
Python

"""198-1 B08 구조물 집계표 — 미연결 = 측점 칸 왼쪽 램프 하나 · 「미지정」 열 지움.
- 칸 class: 화면 소스의 `cellClass` 를 떼어 공용 표 `renderDataTableHtml` 로 그림(Node) — 미연결 줄 측점 칸만 램프
- 호버 글: 화면 소스의 호버 함수를 떼어 가짜 칸으로 부름 — 「구조물 조합 미연결 — 빈 칸 이름」 · 연결 줄은 없음
- CSS: 램프 = 경고 노랑 토큰(177-1) · 밝음 · 어두움 둘 다
- 줄 값 = 측점 + 서버 값뿐(「미지정」 · 「· 미연결」 글 없음 → 수량 · 합계 그대로)
"""
import json
import re
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
TS = ROOT / "config" / "node_modules" / "typescript"
UI = (ROOT / "B08_Quantity" / "B08_Quantity_UI_Summary.ts").read_text(encoding="utf-8") + (
ROOT / "B08_Quantity" / "B08_Quantity_Summary_Table.ts"
).read_text(encoding="utf-8")
PRELUDE = f"""
const fs = require("fs");
const ts = require({json.dumps(str(TS))});
const js = (code) => ts.transpileModule(code, {{
compilerOptions: {{ module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }},
}}).outputText;
"""
def _node(script: str):
out = subprocess.run(
["node", "-e", script], capture_output=True, text=True, encoding="utf-8", timeout=60
)
assert out.returncode == 0, out.stderr
return json.loads(out.stdout)
def _lamp_class() -> str:
m = re.search(r'const LAMP_CLASS = "([^"]+)";', UI)
assert m
return m.group(1)
def test_미연결_줄_측점_칸만_램프():
cell = re.search(r"cellClass: (\(i, key\) =>.*?),\n\s*frozen", UI, re.S)
assert cell
table = json.dumps(str(ROOT / "ui_template" / "ui_template_data_table.ts"))
got = _node(
PRELUDE
+ f"""
const box = {{ exports: {{}} }};
new Function("exports", "module", "require", js(fs.readFileSync({table}, "utf8")))(
box.exports, box, (p) => (p.endsWith(".css") ? {{}} : require(p)));
const LAMP_CLASS = {json.dumps(_lamp_class())};
const missing = ["", "BOX", ""];
const linked = [false, false, false];
const LINKED_CLASS = "ui-data-table__lamp " + LAMP_CLASS + " is-linked";
const cellClass = {cell.group(1)};
const html = box.exports.renderDataTableHtml({{
columns: [{{ key: "station", label: "측점" }}, {{ key: "c1", label: "조합" }}],
rows: [{{ station: "0+000" }}, {{ station: "0+020" }}, {{ station: "0+040", c1: 1 }}],
frozen: 1, empty: "", cellClass }});
const rows = html.split("<tbody>")[1].split("</tr>");
console.log(JSON.stringify({{
count: html.split(LAMP_CLASS).length - 1,
row1: rows[1],
row0: rows[0],
}}));
"""
)
assert got["count"] == 1
# 꼴 = 표 부품 칸 램프(557-2) · 표지 = 화면 class
assert (
f'<td class="is-frozen is-edge ui-data-table__lamp {_lamp_class()}"' in got["row1"]
) # 측점 칸(첫 칸)
assert _lamp_class() not in got["row0"]
def test_호버_글_까닭_한_줄():
hover = re.search(
r"attachHoverInfo\(\n\s*table\.root,\n\s*(\(cell\) => \{.*?\n\s*\}),\n", UI, re.S
)
assert hover
got = _node(
PRELUDE
+ f"""
const L = (k) => ({{ B08_Quantity_Summary_LampTip: "구조물 조합 미연결" }})[k];
const missing = ["", "배관: 본체 · 관 / 세월교: 유출 구조"];
const text = eval(js("(" + {json.dumps(hover.group(1))} + ")"));
const cell = (i) => ({{ closest: () => ({{ dataset: {{ i: String(i) }} }}) }});
console.log(JSON.stringify([text(cell(1)), text(cell(0)) || null]));
"""
)
assert got == ["구조물 조합 미연결 — 배관: 본체 · 관 / 세월교: 유출 구조", None]
assert 'import { attachHoverInfo } from "@ui/ui_template_hover_info";' in UI
assert "`td.${LAMP_CLASS}`," in UI # 램프 칸에만
locale = (ROOT / "ui_template" / "ui_template_locale_b4.ts").read_text(encoding="utf-8")
assert 'B08_Quantity_Summary_LampTip: ["구조물 조합 미연결",' in locale
def test_미지정_열_없음_줄_값_그대로():
assert 'key: "unassigned"' not in UI and "B08_Quantity_Summary_Unassigned" not in UI
assert 'L("B08_Quantity_Summary_Unlinked")' not in UI # 측점 「· 미연결」 글 지움
assert "frozen: 1," in UI
rows = re.search(r"rows: stations\.map\(\(station, i\) => \(\{(.*?)\}\)\),", UI, re.S)
assert rows and [s.strip() for s in rows.group(1).strip().split("\n")] == [
"station: labels[i],",
"...values.get(stationKey(station)),",
]
def test_램프_경고_노랑_토큰():
css = (ROOT / "ui_template" / "ui_template_data_table.css").read_text(encoding="utf-8")
m = re.search(r"td\.ui-data-table__lamp::before\s*\{([^}]*)\}", css) # 표 부품 칸 램프(557-2)
assert m
assert re.search(r"background:\s*var\(--color-warning\)", m.group(1))
assert "border-radius: 50%" in m.group(1)
theme = (ROOT / "ui_template" / "ui_template_theme.css").read_text(encoding="utf-8")
assert len(re.findall(r"--color-warning:\s*#", theme)) >= 2 # 밝음 · 어두움