feat(b09): 설계내역서 「연결 ▾」 칸 단추 · 우클릭과 같은 연결 메뉴 (182-2)
- 비고 앞 「연결」 칸 — 손 항목 줄만 「연결 ▾」 · 연결됨 = 호표 번호 ▾ · 누름 = 그 칸 아래 연결 메뉴 - 메뉴 = 일위대가 호표 · 단가산출 호표 · 단가산출 로직 + 로직 입력값 · 연결 풀기(166-2 고르기 창 재사용) - 단추 칸 = 이동 안 함 · 묶음 줄 · 자동 줄 = 안 엶 - 시험 test_182 연결 단추(칸 · 메뉴 · 고르기 창 → ref) · node 입력 = 표준입력(명령 줄 길이) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KYZ2HWWdUwZWYnn3tQz7X
This commit is contained in:
@@ -74,10 +74,11 @@ def _rows(sheets):
|
||||
|
||||
|
||||
def _node(source: str) -> str:
|
||||
# 표준입력으로 줌 — 「-e」 는 윈도 명령 줄 길이(32k)를 넘음
|
||||
result = subprocess.run(
|
||||
["node", "--experimental-strip-types", "--no-warnings",
|
||||
"--input-type=module-typescript", "-e", source],
|
||||
capture_output=True, text=True, encoding="utf-8", timeout=60,
|
||||
"--input-type=module-typescript"],
|
||||
input=source, capture_output=True, text=True, encoding="utf-8", timeout=60,
|
||||
) # fmt: skip
|
||||
assert result.returncode == 0, result.stderr
|
||||
return result.stdout
|
||||
@@ -228,3 +229,74 @@ def test_우클릭_레벨_메뉴_TS():
|
||||
user = {"bill": {"rows": [r if r["key"] != "hand:x" else out["indent"] for r in HAND]}}
|
||||
rows2 = _rows(compute_estimation(INPUTS, user, None, BOOKS))
|
||||
assert (rows2["hand:x"]["level"], rows2["hand:g1"]["sum"]) == (4, 12300 + 2460 + 1230)
|
||||
|
||||
|
||||
LINK_JS = """
|
||||
const opened = [];
|
||||
const picked = {};
|
||||
globalThis.createMapContextMenu = () => ({
|
||||
element: { isConnected: true, style: {} },
|
||||
open: (x, y, items) => opened.push({ x, y, items }),
|
||||
});
|
||||
globalThis.requestAnimationFrame = () => 0;
|
||||
globalThis.createFindList = () => ({
|
||||
search: { value: "", addEventListener() {}, focus() {} },
|
||||
hint: {},
|
||||
root: {},
|
||||
setRows: (rows) => (picked.rows = rows),
|
||||
});
|
||||
globalThis.openModal = (o) => {
|
||||
picked.title = o.title;
|
||||
o.mount({ append() {} }, () => (picked.closed = true));
|
||||
};
|
||||
let user = __USER__;
|
||||
const ctx = { sheets: { bill: __BILL__, daega: __DAEGA__ }, payload: {},
|
||||
get user() { return user; }, setUser: (u) => (user = u) };
|
||||
const listeners = {};
|
||||
const root = { addEventListener: (type, fn) => (listeners[type] = fn), contains: () => true };
|
||||
attachRowMenu(root, () => []);
|
||||
const cell = { getBoundingClientRect: () => ({ left: 10, bottom: 40 }) };
|
||||
listeners.click({ target: { closest: () => cell } });
|
||||
const table = buildBill(ctx);
|
||||
const at = (key) => table.rows.findIndex((r) => r.key === key);
|
||||
const name = (x) => (x === "-" ? "-" : x[0]);
|
||||
const out = {
|
||||
columns: table.columns.map((c) => c.key).slice(-2),
|
||||
connect: ["hand:a", "hand:c", "hand:g1", "earth:4"].map((k) => table.rows[at(k)].connect),
|
||||
link: [table.link(at("hand:a"), "connect"), table.link(at("hand:a"), "name")],
|
||||
cls: ["sec:1", "hand:g1", "hand:a", "earth:4"].map((k) => table.rowClass(at(k))),
|
||||
edit: [table.editable(at("hand:g1"), "name"), table.editable(at("hand:g1"), "qty")],
|
||||
};
|
||||
table.onCell(at("hand:a"), "connect");
|
||||
table.onCell(at("hand:g1"), "connect");
|
||||
table.onCell(at("earth:4"), "connect");
|
||||
table.onCell(at("hand:c"), "connect");
|
||||
out.menus = opened.map((m) => [m.x, m.y, m.items.map(name)]);
|
||||
opened[1].items[0][1](); // hand:c → 일위대가 호표 고르기 창
|
||||
picked.rows[0].onPick();
|
||||
out.picked = [picked.title, picked.closed, picked.rows.map((r) => r.tag)];
|
||||
out.ref = user.bill.rows.find((r) => r.key === "hand:c").ref;
|
||||
console.log(JSON.stringify(out));
|
||||
"""
|
||||
|
||||
|
||||
def test_연결_단추_칸_메뉴_고르기_창_TS():
|
||||
sheets = compute_estimation(INPUTS, USER, None, BOOKS)
|
||||
body = (
|
||||
LINK_JS.replace("__USER__", json.dumps(USER, ensure_ascii=False))
|
||||
.replace("__BILL__", json.dumps(sheets["bill"], ensure_ascii=False))
|
||||
.replace("__DAEGA__", json.dumps(BOOKS["daega"], ensure_ascii=False))
|
||||
)
|
||||
src = _ts(["UI_Tabs", "UI_Tabs_Bill_Edit", "UI_Tabs_Bill"])
|
||||
out = json.loads(_node(src + body))
|
||||
assert out["columns"] == ["connect", "note"] # 비고 앞 「연결」 칸
|
||||
assert out["connect"] == ["대가3 ▾", "연결 ▾", "", ""] # 손 항목 줄만 · 연결됨 = 호표 번호
|
||||
assert out["link"] == [None, {"tab": "dg", "key": "DG:a"}] # 단추 칸 = 이동 안 함
|
||||
assert out["cls"] == [
|
||||
"is-lv1 is-title", "is-lv3 is-group is-hand", "is-lv4 is-hand", "is-lv3"] # fmt: skip
|
||||
assert out["edit"] == [True, False] # 묶음 줄 = 이름만
|
||||
picks = ["일위대가 호표", "단가산출 호표", "단가산출 로직(M01 · 새 산근)"]
|
||||
# 누른 칸 아래(left · bottom) · 묶음 줄 · 자동 줄 = 안 엶 · 연결된 줄 = 연결 풀기 더함
|
||||
assert out["menus"] == [[10, 40, [*picks, "-", "연결 풀기"]], [10, 40, picks]]
|
||||
assert out["picked"] == ["일위대가 호표 고르기", True, ["대가3"]] # 166-2 고르기 창 재사용
|
||||
assert out["ref"] == DG
|
||||
|
||||
Reference in New Issue
Block a user