Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STqEqztUthVFBmEP18wBSz
78 lines
4.2 KiB
Python
78 lines
4.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""163 B08 구조물도 모달 — 연결 칩 · 접기(163-1) · 사본 고침(163-3) · [업데이트](163-4) · 콘크리트소요 줄(163-5).
|
|
|
|
화면 글 판정 — 서버 · 짝 계산(Material_Calc)은 안 고침 · 고르기 모달 편집 화면은 재사용만.
|
|
"""
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
LINK = (ROOT / "B08_Quantity/B08_Quantity_UI_Link.ts").read_text(encoding="utf-8")
|
|
DRAWING = (ROOT / "B08_Quantity/B08_Quantity_UI_Drawing.ts").read_text(encoding="utf-8")
|
|
CSS = (ROOT / "B08_Quantity/B08_Quantity_UI_Drawing.css").read_text(encoding="utf-8")
|
|
MATERIAL = (ROOT / "B08_Quantity/B08_Quantity_UI_Material.ts").read_text(encoding="utf-8")
|
|
LOCALE = (ROOT / "ui_template/ui_template_locale_b4.ts").read_text(encoding="utf-8")
|
|
|
|
|
|
def test_163_1_칩_한_줄_공용_접기():
|
|
assert 'line.className = "b08-link__row"' in LINK # 시설마다 한 줄
|
|
assert '"b08-link__chip is-linked"' in LINK and "chip.dataset.b08LinkSlot = slot.copy" in LINK
|
|
# 모두 연결이면 접힘 · 미연결 있으면 펼침
|
|
assert 'ui-collapsible${missing ? "" : " is-collapsed"}' in LINK
|
|
assert "ui-collapsible__title" in LINK and "attachCollapsible(section)" in LINK
|
|
assert "state.title = state.textContent" in LINK # 긴 이름 = 툴팁
|
|
assert re.search(r"\.b08-link__row \{[^}]*flex-wrap: wrap", CSS)
|
|
assert ".b08-link__slot" not in CSS + LINK # 옛 줄 꼴 없음
|
|
|
|
|
|
def test_163_3_수정_사본_편집_화면():
|
|
assert "editable: () => true" in DRAWING
|
|
assert "onEdit: (kind) => openEdit(copy, name, kind, load)" in DRAWING
|
|
assert 'labor: () => openEdit(copy, name, "inputs", load)' in DRAWING
|
|
assert 'import("@ui/ui_template_item_picker_edit")' in DRAWING
|
|
assert "createEditView(" in DRAWING and "items: projectItems(request.projectId)" in DRAWING
|
|
assert "info: { 폴더: copy.폴더, 원본: copy.항목 }" in DRAWING
|
|
# [뒤로] = 몸통 되돌림 · 저장했으면 카드 다시 읽음 · 닫을 때 집계표 다시 셈
|
|
assert "body.replaceChildren(...kept)" in DRAWING and "if (saved) reload()" in DRAWING
|
|
assert "if (edited) request.onLinked()" in DRAWING
|
|
assert "if (editView && !(await editView.leave())) return false" in DRAWING
|
|
assert 'kind === "inputs" ? [note(L("B08_Quantity_Sheets_InputsOnly"))]' in DRAWING
|
|
assert "saveTemplate" not in DRAWING # 층 쓰기 없음 — 사본 PUT 만(편집 화면 `items.write`)
|
|
|
|
|
|
def test_163_4_배지_업데이트():
|
|
assert ".list(folder)" in LINK and "structureFolder(slot.copy)" in LINK
|
|
for key in ("Edited", "Gone", "Changed"):
|
|
assert f'badge("B08_Quantity_Link_{key}"' in LINK, key
|
|
assert "button.disabled = !info.마스터바뀜 || !!info.원본없음" in LINK
|
|
assert "updateButton.disabled = true" in LINK # 대조 받기 전 꺼짐
|
|
assert "projectItems(projectId).reapply(info)" in LINK
|
|
assert 'showConfirmDialog(ask, L("B08_Quantity_Link_Update"))' in LINK
|
|
assert 'info.고침 ? ` ${L("B08_Quantity_Link_UpdateEdited")}`' in LINK
|
|
# 저장 뒤 = [선택]과 같은 흐름(onLinked)
|
|
assert "saved\n ? onLinked()" in LINK
|
|
|
|
|
|
def test_163_5_콘크리트_5줄_늘_까닭():
|
|
table = MATERIAL[
|
|
MATERIAL.index("function concreteTable") : MATERIAL.index("function totalTable")
|
|
]
|
|
assert "const keep = rows.map((_row, i) => i)" in table
|
|
assert 'editable: (_i, key) => key.startsWith("per:")' in table # 배합 늘 고침
|
|
assert "function concreteWhy(" in MATERIAL
|
|
assert "matched(m.name, m.spec, m.unit)" in MATERIAL # 짝 계산 맞춤 그대로
|
|
assert "source.snapshot?.units?.[row.id]" in MATERIAL
|
|
assert "concreteNote.textContent = concreteWhy(sheets, payload.source)" in MATERIAL
|
|
assert "Material_Calc" in MATERIAL and "concreteWhy" not in (
|
|
ROOT / "B08_Quantity/B08_Quantity_Material_Calc.ts"
|
|
).read_text(encoding="utf-8")
|
|
|
|
|
|
def test_locale_keys_exist():
|
|
for text in (LINK, DRAWING):
|
|
for key in set(re.findall(r'L\("([A-Za-z0-9_]+)"\)', text)) | set(
|
|
re.findall(r'badge\("([A-Za-z0-9_]+)"', text)
|
|
):
|
|
assert f"{key}:" in LOCALE or key.startswith(("B08_Quantity_Summary_", "Common_")), key
|