"""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