Files
Aislo/resources/tester/test_m02_labor_rowdrag.py
T
eomsangdonandClaude Opus 5.5 4e41e76d49 feat(m02): 일위대가 상세 손잡이 맨 왼쪽 · ▲▼ 위아래 · 옵션 · 삭제 2행 높이 · 줄 통째 끌기 · 구분 열 품셈 글(102-1~3)
- 손잡이 = 차례 칸 앞 · 단추 칸 = [▲ · ▼ 세로][옵션|수정][삭제] · 클래스 이름 그대로
- 줄 통째 끌기 = 6px 문턱 · 끈 뒤 누름 한 번 삼킴 · 열린 줄 하위 줄째 · 단추 · 입력칸 · 수량 칸 제외 · 끄는 동안 다시 그림 미룸(Labor_RowDrag)
- 구분 칸 아래 작은 글 건설품셈 · 산림품셈(단가산출 줄만 · 출처 첫 낱말)
- 시험 test_m02_labor_rowdrag(Node 가짜 DOM 하네스)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4uKaV4ZBhsJN4GHG7yRj4
2026-10-08 16:11:40 +09:00

86 lines
3.3 KiB
Python

"""102 — M02 일위대가 상세 줄 배치 · 줄 통째 끌기 · 구분 열 품셈 글.
끌기(102-2) = Node 헬퍼(`helper_m02_labor_rowdrag.cjs`)가 `M02_MasterTemplete_Labor_RowDrag.ts` 를 가짜 DOM 에서 돌림 ·
6px 문턱 · 끈 뒤 누름 삼킴 · 열린 줄 하위 줄에서 시작 · 단추 · 입력칸 · 수량 칸 막음 · 끄는 동안 다시 그림 미룸.
배치(102-1) · 품셈 글(102-3) = 소스 꼴.
"""
import json
import os
import subprocess
from pathlib import Path
import pytest
HERE = os.path.dirname(os.path.abspath(__file__))
M02 = Path(HERE).parents[1] / "M02_MasterTemplete"
@pytest.fixture(scope="module")
def r():
proc = subprocess.run(
["node", os.path.join(HERE, "helper_m02_labor_rowdrag.cjs")],
capture_output=True,
text=True,
encoding="utf-8",
timeout=60,
)
assert proc.returncode == 0, proc.stderr
return json.loads(proc.stdout)
def test_문턱_6px(r):
assert r["threshold"] == [False, True, True, False, True]
def test_작게_움직이면_누름(r):
assert r["small"] == {"moves": 0, "clickPasses": True, "capture": None}
def test_끌어_놓으면_순서만_누름_삼킴(r):
assert r["during"]["drawn"] == 0 # 끄는 동안 다시 그리지 않음
assert r["during"]["capture"] == 1 and r["during"]["select"] == "none"
assert r["during"]["classes"][0] == "is-dragging"
assert r["during"]["classes"][5] == "is-dragunder"
assert r["drop"]["moves"] == [[0, 2]]
assert r["drop"]["drawn"] == 1 # 끝난 뒤 마지막 것 한 번
assert r["drop"]["clickPasses"] is False # 열림 · 닫힘 그대로
assert set(r["drop"]["classes"]) == {""}
assert r["afterFrame"]["listeners"] == 0
assert r["idleDraw"] == 1
def test_열린_줄_하위_줄째(r):
assert r["fromSub"]["moves"] == [[1, 0]]
assert r["fromSub"]["classes"][:5] == ["is-dragover"] + ["is-dragging"] * 4
assert r["downMark"][4] == "is-dragunder" and r["downMark"][-1] == "[[0,1]]"
@pytest.mark.parametrize("name", ["button", "input", "qty"])
def test_단추_입력칸에선_시작_안_함(r, name):
assert r[f"block_{name}"] == {"moves": 0, "capture": None, "clickPasses": True}
def test_손잡이_제자리(r):
assert r["gripSelf"] == {"moves": 0, "clickPasses": False}
def test_배치_손잡이_차례칸_앞_단추칸():
rows = (M02 / "M02_MasterTemplete_Labor_Rows.ts").read_text(encoding="utf-8")
assert "children: move ? [grip(), String(i + 1)] : [String(i + 1)]," in rows
assert 'draggable: "true"' not in rows and "dragFrom" not in rows
assert "if (move) attachRowDrag(out, move);" in rows
css = (M02 / "M02_MasterTemplete_Labor.css").read_text(encoding="utf-8")
order = css[css.index(".m02-labrow__order {") :]
assert "flex-direction: column;" in order[: order.index("}")]
assert ".m02-labrow__tools > .ui-btn-group {\n align-items: stretch;" in css
detail = (M02 / "M02_MasterTemplete_Labor_Detail.ts").read_text(encoding="utf-8")
assert "afterRowDrag(logicHost, () =>" in detail
def test_구분열_품셈_글():
rows = (M02 / "M02_MasterTemplete_Labor_Rows.ts").read_text(encoding="utf-8")
assert "const BOOK = /^(건설|산림)품셈/;" in rows
assert 'const book = row.참조 ? undefined : BOOK.exec(logic?.출처 ?? "")?.[0];' in rows
assert 'className: "m02-labrow__book"' in rows