- 위험 채움 토큰 밝음 #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>
117 lines
4.7 KiB
Python
117 lines
4.7 KiB
Python
"""247-1 B08 구조물 집계표 — 시설이 모두 조합에 이은 측점 줄 = 초록 램프.
|
|
|
|
- 칸 class: 화면 소스의 `missing` · `linked` · `cellClass` 를 떼어 공용 표로 그림(Node)
|
|
모두 연결 = 초록 · 하나라도 빈 칸 = 노랑 · 시설 없음 · 합계 줄 = 램프 없음
|
|
- 호버 글: 초록 = 「모두 연결됨」
|
|
- CSS: 초록 = 성공 토큰(밝음 · 어두움)
|
|
"""
|
|
|
|
import json
|
|
import re
|
|
|
|
from test_198_1_b08_summary_lamp import PRELUDE, ROOT, UI, _lamp_class, _node
|
|
|
|
DATA = (ROOT / "B08_Quantity" / "B08_Quantity_Summary_Data.ts").read_text(encoding="utf-8")
|
|
|
|
|
|
def _fac(fid: str, at: float, *linked: bool) -> dict:
|
|
slots = [
|
|
{"copy": f"{fid}{i}", "group": "칸", "item": None, "linked": v}
|
|
for i, v in enumerate(linked)
|
|
]
|
|
return {
|
|
"id": fid,
|
|
"type_id": "box",
|
|
"name": "BOX",
|
|
"facility": None,
|
|
"chainage_m": at,
|
|
"slots": slots,
|
|
}
|
|
|
|
|
|
def test_모두_연결_초록_빈_칸_노랑_없음_없음():
|
|
grab = lambda pat: re.search(pat, UI, re.S).group(1) # noqa: E731
|
|
missing = grab(r"(const missing = stations\.map\(.*?\);\n)")
|
|
linked = grab(r"(const linked = stations\.map\(.*?\);\n)")
|
|
cell = grab(r"cellClass: (\(i, key\) =>.*?),\n\s*frozen")
|
|
line = re.search(r"(const LINKED_CLASS = .*?;)", UI).group(1)
|
|
facilities = [_fac("a", 0, True, True), _fac("b", 20, True, False), _fac("c", 20, True)]
|
|
unlinked = [f for f in facilities if not all(s["linked"] for s in f["slots"])]
|
|
table = json.dumps(str(ROOT / "ui_template" / "ui_template_data_table.ts"))
|
|
# 두 함수만 떼어 씀(모듈 import 없이)
|
|
data = json.dumps(
|
|
"".join(
|
|
re.search(rf"export (const {name} = .*?;\n)\n", DATA, re.S).group(1)
|
|
for name in ("unlinkedAt", "unassignedText")
|
|
)
|
|
)
|
|
got = _node(
|
|
PRELUDE
|
|
+ f"""
|
|
const load = (src) => {{
|
|
const box = {{ exports: {{}} }};
|
|
new Function("exports", "module", "require", js(src))(
|
|
box.exports, box, (p) => (p.endsWith(".css") ? {{}} : require(p)));
|
|
return box.exports;
|
|
}};
|
|
const t = load(fs.readFileSync({table}, "utf8"));
|
|
const {{ unlinkedAt, unassignedText }} = new Function(
|
|
js({data}) + "; return {{ unlinkedAt, unassignedText }};")();
|
|
const L = (k) => k;
|
|
const LAMP_CLASS = {json.dumps(_lamp_class())};
|
|
{line}
|
|
const stations = [0, 20, 40];
|
|
const unlinked = {json.dumps(unlinked, ensure_ascii=False)};
|
|
const pipe = {{ facilities: {json.dumps(facilities, ensure_ascii=False)} }};
|
|
{missing}{linked}const cellClass = {cell};
|
|
const html = t.renderDataTableHtml({{
|
|
columns: [{{ key: "station", label: "측점" }}, {{ key: "c1", label: "조합" }}],
|
|
rows: stations.map((s) => ({{ station: String(s) }})),
|
|
total: {{ station: "계", c1: 1 }},
|
|
frozen: 1, empty: "", cellClass }});
|
|
const rows = html.split("<tbody>")[1].split("</tr>");
|
|
console.log(JSON.stringify({{ rows: rows.slice(0, 3), tail: html.split("</tbody>")[1] ?? "", lamps: html.split(LAMP_CLASS).length - 1 }}));
|
|
"""
|
|
)
|
|
lamp = _lamp_class()
|
|
assert (
|
|
f'class="is-frozen is-edge ui-data-table__lamp {lamp} is-linked"' in got["rows"][0]
|
|
) # 0 = 모두 연결
|
|
assert (
|
|
f'class="is-frozen is-edge ui-data-table__lamp {lamp}"' in got["rows"][1]
|
|
) # 20 = 빈 칸 하나 = 노랑
|
|
assert lamp not in got["rows"][2] # 40 = 시설 없음
|
|
assert got["lamps"] == 2 # 합계 줄 없음
|
|
|
|
|
|
def test_초록_호버_모두_연결됨():
|
|
hover = re.search(
|
|
r"attachHoverInfo\(\n\s*table\.root,\n\s*(\(cell\) => \{.*?\n\s*\}),\n", UI, re.S
|
|
)
|
|
got = _node(
|
|
PRELUDE
|
|
+ f"""
|
|
const L = (k) => ({{ B08_Quantity_Summary_LampTip: "구조물 조합 미연결", B08_Quantity_Summary_LampOk: "모두 연결됨" }})[k];
|
|
const missing = ["", "BOX: 칸"];
|
|
const text = eval(js("(" + {json.dumps(hover.group(1))} + ")"));
|
|
const cell = (i) => ({{ closest: () => ({{ dataset: {{ i: String(i) }} }}) }});
|
|
console.log(JSON.stringify([text(cell(0)), text(cell(1))]));
|
|
"""
|
|
)
|
|
assert got == ["모두 연결됨", "구조물 조합 미연결 — BOX: 칸"]
|
|
locale = (ROOT / "ui_template" / "ui_template_locale_b4.ts").read_text(encoding="utf-8")
|
|
assert 'B08_Quantity_Summary_LampOk: ["모두 연결됨",' in locale
|
|
|
|
|
|
def test_초록_성공_토큰():
|
|
# 꼴 = 표 부품 칸 램프(557-2)
|
|
css = (ROOT / "ui_template" / "ui_template_data_table.css").read_text(encoding="utf-8")
|
|
m = re.search(r"td\.ui-data-table__lamp\.is-linked::before\s*\{([^}]*)\}", css)
|
|
assert (
|
|
m
|
|
and re.search(r"color:\s*var\(--color-success\)", m.group(1))
|
|
and 'content: "✓"' in m.group(1)
|
|
)
|
|
theme = (ROOT / "ui_template" / "ui_template_theme.css").read_text(encoding="utf-8")
|
|
assert len(re.findall(r"--color-success:\s*#", theme)) >= 2 # 밝음 · 어두움
|