- 손잡이 = 차례 칸 앞 · 단추 칸 = [▲ · ▼ 세로][옵션|수정][삭제] · 클래스 이름 그대로 - 줄 통째 끌기 = 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
86 lines
3.3 KiB
Python
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
|