feat(ui): 고르기 모달 나무 M02 나무 꼴 — 층 단추 셋 · 잎 = 마지막 이름 · 폴더 먼저 · 왼쪽 폭 320px(173-2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018jonfdxn1Xit9bdkNJpE4G
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""PLAN 173-2 — 고르기 모달 왼쪽 나무 = M02 마스터 나무 꼴.
|
||||
|
||||
자료 쪽(잎 글 · 폴더 먼저 · 툴팁)은 Node 시험(`ui/item-picker-data.test.ts`)으로,
|
||||
층 단추 셋 · 뿌리 줄 없음 · 빈 자리 메뉴 · 폭 320px 은 소스로 본다.
|
||||
"""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
UI = os.path.join(ROOT, "ui_template")
|
||||
|
||||
|
||||
def _text(name: str) -> str:
|
||||
return open(os.path.join(UI, name), encoding="utf-8").read()
|
||||
|
||||
|
||||
def test_자료_시험_통과_잎_글_폴더_먼저():
|
||||
proc = subprocess.run(
|
||||
[
|
||||
"node",
|
||||
"--experimental-strip-types",
|
||||
os.path.join(ROOT, "resources", "tester", "ui", "item-picker-data.test.ts"),
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
timeout=60,
|
||||
)
|
||||
assert proc.returncode == 0, proc.stderr
|
||||
assert "통과" in proc.stdout
|
||||
|
||||
|
||||
def test_층_단추_셋_뿌리_줄_없음():
|
||||
ts = _text("ui_template_item_picker.ts")
|
||||
assert "children: [search.root, layerBar, treeHost]" in ts
|
||||
assert "...PICKER_LAYERS.map((one) =>" in ts
|
||||
assert 'variant: one === layer ? "filled" : "ghost"' in ts
|
||||
# 고른 층의 자식부터 그림(뿌리 줄 없음)
|
||||
assert "groups.find((group) => group.id === layer)?.children ?? []" in ts
|
||||
# 처음 층 = 지금 항목 층 · 없으면 개인 · 없으면 마스터
|
||||
assert "layer = layerOf(start);" in ts
|
||||
# 공용 줄 부품 그대로
|
||||
assert "createTreeRow(node, caret, depth" in ts
|
||||
|
||||
|
||||
def test_개인_맨_위_새_항목은_빈_자리_오른쪽_클릭():
|
||||
ts = _text("ui_template_item_picker.ts")
|
||||
assert 'treeHost.addEventListener("contextmenu"' in ts
|
||||
assert 'closest(".ui-tree__row")' in ts
|
||||
assert "folder: { layer, path: [] }" in ts
|
||||
|
||||
|
||||
def test_왼쪽_칸_폭_320_테두리_없음():
|
||||
css = _text("ui_template_item_picker.css")
|
||||
assert "grid-template-columns: var(--wf-left-panel-width) minmax(320px, 1fr);" in css
|
||||
tree = css[css.index(".ui-item-picker__tree {") :]
|
||||
tree = tree[: tree.index("}")]
|
||||
assert "border" not in tree
|
||||
theme = _text("ui_template_theme.css")
|
||||
assert "--wf-left-panel-width: 320px;" in theme
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
folderLines,
|
||||
isCurrent,
|
||||
itemName,
|
||||
leafLabel,
|
||||
pathIds,
|
||||
pathOf,
|
||||
rowId,
|
||||
@@ -120,14 +121,14 @@ assert.equal(size?.label, "1.2m");
|
||||
assert.deepEqual(size?.folder, { layer: "system", path: ["돌기슭막이", "메쌓기", "1.2m"] });
|
||||
assert.deepEqual(tree[2].folder, { layer: "personal", path: [] }); // 그룹 줄 = 빈 경로
|
||||
const leaf = size?.children?.[0];
|
||||
assert.equal(leaf?.label, "돌기슭막이 메쌓기 1.2m 기초유");
|
||||
assert.equal(leaf?.tip, "마스터 · SS000001"); // 툴팁 = 층 이름 + 키
|
||||
assert.equal(leaf?.label, "기초유"); // 잎 글 = 경로 마지막 이름(M02 나무 꼴 · 173-2)
|
||||
assert.equal(leaf?.tip, "돌기슭막이 메쌓기 1.2m 기초유 · 마스터 · SS000001"); // 툴팁 = 전체 이름 · 층 · 키
|
||||
assert.equal(leaf?.count, null);
|
||||
assert.ok(leaf?.row);
|
||||
|
||||
// 경로가 짧은 항목은 얕은 폴더에(옹벽 H=2m = 폴더 옹벽 · 잎 「옹벽 H=2m」)
|
||||
// 경로가 짧은 항목은 얕은 폴더에(옹벽 H=2m = 폴더 옹벽 · 잎 「H=2m」)
|
||||
assert.equal(tree[1].children?.[1].label, "옹벽");
|
||||
assert.equal(tree[1].children?.[1].children?.[0].label, "옹벽 H=2m");
|
||||
assert.equal(tree[1].children?.[1].children?.[0].label, "H=2m");
|
||||
assert.equal(tree[1].children?.[1].children?.[0].folder, undefined); // 잎에는 folder 없음
|
||||
|
||||
// 서버가 준 `경로` 가 종류 · 분류보다 앞 — 이름 = 경로 이음 · 자리표는 뺌
|
||||
@@ -148,6 +149,31 @@ const deepTree = buildTree([deep], labels)[2];
|
||||
assert.equal(deepTree.children?.[0].children?.[0].children?.[0].children?.[0].label, "라");
|
||||
assert.equal(deepTree.count, 1);
|
||||
|
||||
// 잎 글 = 마지막 이름 · 비면 열 id · 키
|
||||
assert.equal(leafLabel(rows[6]), "H=2m");
|
||||
assert.equal(leafLabel(fresh), "n1");
|
||||
assert.equal(leafLabel({ key: "SS000009", 열: "" }), "SS000009");
|
||||
|
||||
// 폴더 먼저 · 잎 뒤 — 같은 갈래 안은 서버 차례 그대로(173-2)
|
||||
const mixed = buildTree(
|
||||
[
|
||||
row("SS000501", "m1", "잎하나", ["", "", ""], "personal"),
|
||||
row("SS000502", "m2", "가폴더", ["잎", "", ""], "personal"),
|
||||
row("SS000503", "m3", "잎둘", ["", "", ""], "personal"),
|
||||
row("SS000504", "m4", "나폴더", ["잎", "", ""], "personal"),
|
||||
],
|
||||
labels,
|
||||
)[2];
|
||||
assert.deepEqual(
|
||||
mixed.children?.map((k) => [k.label, !!k.row]),
|
||||
[
|
||||
["가폴더", false],
|
||||
["나폴더", false],
|
||||
["잎하나", true],
|
||||
["잎둘", true],
|
||||
],
|
||||
);
|
||||
|
||||
// 빈 그룹도 한 줄은 남음(회사 없는 사람의 회사 · 개인 그룹)
|
||||
const onlySystem = buildTree(
|
||||
rows.filter((r) => r.layer === "system"),
|
||||
|
||||
Reference in New Issue
Block a user