"""일위대가 라이브러리 나무 자료(PLAN 27-2b · `Labor_Tree.ts`) — Node 로 TS 를 돌려 판정. 못박는 것 - 조합 → 나무 항목: 경로 = [구분, 상세구분, 이름](빈 칸 건너뜀) · 열 = 키. - 나무 고침 알림: 새 · 바뀐 · 옮긴 폴더 경로 · 조합 고침은 그 조합(열)을 고른 채 · 지우기는 고름 없음. """ import json import shutil import subprocess from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] SCRIPT = r""" const fs = require("fs"); const ts = require(process.argv[1] + "/config/node_modules/typescript"); const file = "/M02_MasterTemplete/M02_MasterTemplete_Labor_Tree.ts"; const src = fs.readFileSync(process.argv[1] + file, "utf8"); const js = ts.transpileModule(src, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 }, }).outputText; const box = { exports: {} }; new Function("exports", "module", "require", js)(box.exports, box, require); const m = box.exports; const row = (키, 이름, 구분, 상세구분) => ({ 키, 이름, 구분, 상세구분, 단위: "m" }); const list = { 판: "v1", 폴더: [["석축"], ["석축", "찰쌓기"], ["빈"]], 줄: [row("UP1-000001", "가", "석축", "찰쌓기"), row("UP1-000002", "나", "석축", null), row("UP1-000003", "다", null, "무시")], }; const view = m.toView(list); const notes = [ { op: "add-folder", 경로: ["석축"], 이름: "메쌓기" }, { op: "rename", 경로: ["석축", "찰쌓기"], 이름: "찰" }, { op: "move", 경로: ["석축", "찰쌓기"], 새경로: [] }, { op: "move", 경로: ["석축"], 키: "UP1-000002", 새경로: ["빈"] }, { op: "rename", 경로: ["석축"], 키: "UP1-000002", 이름: "나나" }, { op: "delete", 경로: ["석축"], 키: "UP1-000002" }, { op: "delete", 경로: ["빈"] }, ].map((e) => m.noteOf(e, e.op === "delete" ? ["UP1-000002"] : [])); console.log(JSON.stringify({ view, notes })); """ @pytest.fixture(scope="module") def got(): if shutil.which("node") is None: pytest.skip("node 가 없음") proc = subprocess.run( ["node", "-e", SCRIPT, str(ROOT)], capture_output=True, text=True, encoding="utf-8" ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def test_조합이_나무_항목으로(got): items = got["view"]["items"] assert [i["경로"] for i in items] == [["석축", "찰쌓기", "가"], ["석축", "나"], ["다"]] assert [i["열"] for i in items] == ["UP1-000001", "UP1-000002", "UP1-000003"] assert got["view"]["폴더"] == [["석축"], ["석축", "찰쌓기"], ["빈"]] assert "알림" not in got["view"] def test_나무_고침_알림(got): add, rename, move, move_item, rename_item, delete_item, delete_folder = got["notes"] assert add["경로"] == ["석축", "메쌓기"] and "열" not in add assert rename["경로"] == ["석축", "찰"] assert move["경로"] == ["찰쌓기"] assert move_item["열"] == "UP1-000002" and move_item["경로"][:-1] == ["빈"] assert rename_item["경로"] == ["석축", "나나"] assert "열" not in delete_item and delete_item["지운항목"] == ["UP1-000002"] assert "경로" not in delete_folder