- DetailNav 지금 상세 단추 hidden · size sm 지움 · 눌림 CSS 지움 - 머리 [?] 만 ui-btn--sm 뺌 · 카드 [?] 는 작게 그대로 - test_m02_detail_nav 기대 고침 · test_m02_layer_screen 머리 줄 정규식에 nav.root Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W4uKaV4ZBhsJN4GHG7yRj4
152 lines
6.4 KiB
Python
152 lines
6.4 KiB
Python
"""상세 이동 단추 · 도면 상세 → 면적산출(PLAN 105-2 · 105-4) — Node 로 판정 · 화면은 ORCA.
|
|
|
|
못박는 것
|
|
- 머리 제목과 [?] 사이 [도면][일위대가][면적산출](`ui-btn-group` · 보통 크기) · 지금 상세 단추 = 숨김(113-2) ·
|
|
그 열 문서(번호)가 없으면 그 단추 꺼짐 · 프로젝트 층 · 남의 층은 번호를 안 읽고 다 켬 · 상세 아니면 숨김.
|
|
- 보임 조건 = 뒤로 단추와 같음 · 누름 = confirmLeave → open({...sel, kind}) · 지금 것 누름 = 그대로.
|
|
- 도면 상세 머리 [면적산출로 보내기] = CAD 요청 · 받은 표(TOAREA 도 같은 길) → 같은 열 면적 상세로 옮겨 가
|
|
넣을 자리 창(`importDrawingTable`) · 읽기 · 프로젝트 층은 단추 없음 · 떠나면 듣기를 뗌.
|
|
"""
|
|
|
|
import json
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
M02 = ROOT / "M02_MasterTemplete"
|
|
SCRIPT = r"""
|
|
const fs = require("fs");
|
|
const ts = require(process.argv[1] + "/config/node_modules/typescript");
|
|
const src = fs.readFileSync(process.argv[1] + "/M02_MasterTemplete/M02_MasterTemplete_DetailNav.ts", "utf8");
|
|
const js = ts.transpileModule(src, {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
|
}).outputText;
|
|
let fetched = 0;
|
|
let numbers = {};
|
|
const button = (o) => {
|
|
const b = { label: o.label, size: o.size, dataset: {}, attrs: {}, disabled: false, hidden: false, title: "", onClick: o.onClick };
|
|
b.setAttribute = (k, v) => (b.attrs[k] = v);
|
|
return b;
|
|
};
|
|
const stubs = {
|
|
"@ui/ui_template_elements": {
|
|
createButton: button,
|
|
el: (tag, o) => ({ tag, className: o.className, attrs: o.attrs, children: o.children, hidden: false }),
|
|
},
|
|
"./M02_MasterTemplete_Api_Fetch": {
|
|
fetchStructureNumbers: async () => (fetched++, numbers),
|
|
getActiveLayer: () => "system",
|
|
},
|
|
};
|
|
const box = { exports: {} };
|
|
new Function("exports", "module", "require", js)(box.exports, box, (n) => stubs[n] ?? require(n));
|
|
const gone = [];
|
|
const nav = box.exports.createDetailNav((kind) => gone.push(kind));
|
|
const view = () => ({
|
|
hidden: nav.root.hidden,
|
|
shown: nav.root.children.map((b) => !b.hidden),
|
|
disabled: nav.root.children.map((b) => b.disabled),
|
|
});
|
|
const tick = () => new Promise((r) => setTimeout(r, 0));
|
|
(async () => {
|
|
const out = {
|
|
className: nav.root.className,
|
|
labels: nav.root.children.map((b) => b.label),
|
|
sizes: nav.root.children.map((b) => b.size ?? null),
|
|
};
|
|
numbers = { c1: { 도번: "SD-000001", 일위대가번: "", 면적번: "SA-000001" } };
|
|
nav.update({ layer: "system", kind: "area", name: "c1" });
|
|
out.before = view();
|
|
await tick();
|
|
out.area = view();
|
|
nav.update({ layer: "project", kind: "structure", name: "c1" });
|
|
await tick();
|
|
out.project = view();
|
|
nav.update({ layer: "company", kind: "labor", name: "c1" }); // 남의 층(지금 층 아님)
|
|
await tick();
|
|
out.other = view();
|
|
out.fetched = fetched;
|
|
nav.update(null);
|
|
out.none = view();
|
|
nav.root.children[1].onClick();
|
|
out.gone = gone;
|
|
console.log(JSON.stringify(out));
|
|
})();
|
|
"""
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def run():
|
|
node = shutil.which("node")
|
|
if not node:
|
|
pytest.skip("node 없음")
|
|
done = subprocess.run(
|
|
[node, "-e", SCRIPT, str(ROOT)],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
check=True,
|
|
)
|
|
return json.loads(done.stdout)
|
|
|
|
|
|
def _text(name: str) -> str:
|
|
return (M02 / name).read_text(encoding="utf-8")
|
|
|
|
|
|
def test_단추_셋_묶음(run):
|
|
assert run["labels"] == ["도면", "일위대가", "면적산출"]
|
|
assert "ui-btn-group" in run["className"]
|
|
assert run["sizes"] == [None, None, None] # 113-2 — [다시 열기]와 같은 보통 크기
|
|
|
|
|
|
def test_지금_것_숨김_없는_문서_꺼짐(run):
|
|
assert run["before"]["shown"] == [True, True, False] # 113-2 — 지금 상세 단추 숨김
|
|
assert run["before"]["disabled"] == [False, False, False] # 번호 받기 전엔 켬
|
|
assert run["area"]["disabled"] == [False, True, False] # 일위대가번 없음 = 꺼짐
|
|
assert run["area"]["hidden"] is False
|
|
|
|
|
|
def test_프로젝트_남의_층은_안_읽음(run):
|
|
assert run["project"]["shown"] == [False, True, True]
|
|
assert run["project"]["disabled"] == [False, False, False]
|
|
assert run["other"]["disabled"] == [False, False, False]
|
|
assert run["fetched"] == 1
|
|
|
|
|
|
def test_상세_아니면_숨김_누름은_옮겨_감(run):
|
|
assert run["none"]["hidden"] is True
|
|
assert run["gone"] == ["labor"]
|
|
|
|
|
|
def test_머리_줄_자리와_보임_조건():
|
|
main = _text("M02_MasterTemplete_UI_Main.ts")
|
|
assert " title,\n nav.root,\n helpSlot," in main # 제목과 ? 사이
|
|
assert "nav.update(back.hidden ? null : sel); // 보임 조건 = 뒤로 단추와 같음" in main
|
|
assert "if (!at || at.kind === kind || !(await confirmLeave())) return;" in main
|
|
assert "void open({ ...at, kind });" in main
|
|
css = (M02 / "M02_MasterTemplete_UI_Style.css").read_text(encoding="utf-8")
|
|
assert "aria-pressed" not in css # 113-2 — 눌림 대신 숨김
|
|
# 머리 [?] 만 보통 크기 · 카드 [?] 는 작게 그대로(`helpParts` sm)
|
|
assert 'help?.button.classList.remove("ui-btn--sm");' in main
|
|
shell = _text("M02_MasterTemplete_CardShell.ts")
|
|
assert 'createButton({ label: CARD_TEXT.help, variant: "ghost", size: "sm" })' in shell
|
|
|
|
|
|
def test_도면_상세에서_면적으로_보내기():
|
|
main = _text("M02_MasterTemplete_UI_Main.ts")
|
|
block = main.split("const off = attachDrawingToArea(")[1].split("return;\n }\n empty(")[0]
|
|
assert 'readOnly || at.layer === "project"' in block # 읽기 · 프로젝트 층 막음
|
|
assert "if (!(await confirmLeave())) return;" in block # 미저장 도면이면 물음
|
|
assert 'await open({ ...at, kind: "area" });' in block
|
|
assert "void importDrawingTable(sheetHandle, table);" in block # 넣을 자리 창 · 저장은 사용자
|
|
assert "editor = { ...made, destroy: () => (off(), made.destroy()) };" in block # 떠나면 뗌
|
|
to_area = _text("M02_MasterTemplete_DrawingToArea.ts")
|
|
assert "postMessage({ type: EXPORT_TABLE_REQUEST }, window.location.origin)" in to_area
|
|
assert "if (data?.type !== EXPORT_TABLE || !data.table) return;" in to_area
|
|
assert "if (onTable) slot.append(send);" in to_area
|
|
assert "event.source !== win" in to_area # 다른 iframe(면적 도면 패널) 메시지는 안 받음
|