Files
Aislo/resources/tester/test_61_1_b08_summary_table.py
T
eomsangdonandClaude Opus 5.5 53d839cb1d feat(B08): 구조물 집계표를 공용 많은 자료 표로(70-2)
- 집계표 = createDataTable — 머리 두 줄(조합 구분 · 이름) · 측점 열 고정 · 칸은 빈칸 · 빠진 조합 빨강 · 풍선 글 그대로
- 공용 표 하위 호환 옵션 — empty(빈 값 글) · 열 title · className · 빠진 항목 머리 색 · 틀 폭은 표만큼

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
2026-10-06 23:15:42 +09:00

81 lines
3.4 KiB
Python

"""B08 1탭 구조물 집계표 줄 · 열 고르기 (PLAN 61-1).
`B08_Quantity_Summary_Data.ts` 를 `common_util_summary_item.ts` 와 이어 붙여 node 로 돌림.
줄 = 놓인 측점(같은 측점 한 줄 · 정렬) · 열 = 저장된 조합(본체 + 그룹 · 같은 키 한 열 · 구분 차례).
"""
import json
import re
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
IMPORTS = re.compile(r"^import[^;]*;\n", re.MULTILINE)
def _run(body: str):
sources = [
ROOT / "common_util" / "common_util_summary_item.ts",
ROOT / "B08_Quantity" / "B08_Quantity_Summary_Data.ts",
]
script = "\n".join(IMPORTS.sub("", p.read_text(encoding="utf-8")) for p in sources) + body
result = subprocess.run(
["node", "--experimental-strip-types", "--no-warnings",
"--input-type=module-typescript", "-e", script],
capture_output=True, text=True, encoding="utf-8", timeout=60,
) # fmt: skip
assert result.returncode == 0, result.stderr
return json.loads(result.stdout)
def _item(key: str, layer: str = "system", owner=None) -> dict:
return {"layer": layer, "owner": owner, "key": key, "name": f"저장 {key}"}
THINGS = [
{"chainage_m": 120.004, "summary_item": _item("SS2")},
{"chainage_m": 40.0, "summary_item": _item("SS1"), "group_items": {"g1": _item("SS3")}},
{"chainage_m": 120.0, "summary_item": _item("SS1")}, # 같은 측점 · 같은 조합
{"chainage_m": None, "start_m": 80.0}, # 구간형 옛 저장분 = 시점
{"chainage_m": 10.0, "summary_item": {"key": "깨짐"}}, # 모양 틀림 = 미지정
{"chainage_m": 60.0, "summary_item": _item("SS9", "company", "3")}, # M02 에 없음
]
M02 = {"SS1": ("기슭막이", "메쌓기"), "SS2": ("배수관", "파형관"), "SS3": ("기슭막이", "찰쌓기")}
def test_줄_열_머리():
out = _run(
f"\nconst things = {json.dumps(THINGS, ensure_ascii=False)};"
f"\nconst m02 = {json.dumps(M02, ensure_ascii=False)};"
"\nconst describe = (item) => item.layer === 'system' && m02[item.key]"
" ? { group: m02[item.key][0], name: m02[item.key][1] } : null;"
"\nconst columns = summaryColumns(things, describe);"
"\nconsole.log(JSON.stringify({ stations: summaryStations(things),"
" columns: columns.map((c) => [c.id, c.group, c.name, c.missing]),"
" spans: groupSpans(columns) }));"
)
assert out["stations"] == [10.0, 40.0, 60.0, 80.0, 120.0]
assert out["columns"] == [
["company|3|SS9", "", "저장 SS9", True],
["system||SS1", "기슭막이", "메쌓기", False],
["system||SS3", "기슭막이", "찰쌓기", False],
["system||SS2", "배수관", "파형관", False],
]
assert out["spans"] == [["", 1], ["기슭막이", 2], ["배수관", 1]]
def test_빈_목록():
out = _run(
"\nconsole.log(JSON.stringify([summaryStations([]),"
" summaryColumns([{ chainage_m: 5 }], () => null), groupSpans([])]));"
)
assert out == [[], [], []]
def test_집계표는_공용_표():
# PLAN 70-2 — 공용 많은 자료 표 · 측점 열 고정 · 칸은 빈칸(「—」 아님)
ui = (ROOT / "B08_Quantity" / "B08_Quantity_UI_Summary.ts").read_text(encoding="utf-8")
assert "createDataTable(" in ui and "@ui/ui_template_data_table" in ui
assert "frozen: 1" in ui and 'empty: ""' in ui
assert 'document.createElement("table")' not in ui