- 마커 그림 = 맨 마지막(교각점 · 손잡이 · 맴돔 위) · 누름 · 맴돔 · 커서 = 재기 다음 마커 먼저 · 마커 누름 = 고른 교각점 풂 - 마커 아닌 곳 누름 · Esc = 공용 고름을 b05-plan 으로 비움(오른쪽 횡단 판 그대로) - 오른쪽 판 = 구조물 · 관 고름도 그 측점 횡단 · 묶음 뒤 열쇠로 붙듦(옮긴 뒤 새 자리) - 시험 399 차례 고쳐 씀 · 새 409 · 411-A Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
140 lines
6.0 KiB
Python
140 lines
6.0 KiB
Python
"""399 B05 평면 구조물 측점 마커(요구 250-2) — 알약과 같은 목록 · 고름 = 공용 고름 · 정보 창(알약 벌룬) ·
|
||
20 m 법선 · 끌기 · 방향키 = 노선 따라 정수 m 1 m 씩 · 시점 · 종점 밖 안 감 · 놓을 때 한 번 옮김(알약과 같은 길).
|
||
|
||
TS 셈은 `helper_399_plan_structure_marks.cjs`(Node · 노선 셈 · 법선 · 걸음은 진짜).
|
||
|
||
./venv/Scripts/python.exe -m pytest resources/tester/test_399_plan_structure_marks.py -q
|
||
"""
|
||
|
||
import json
|
||
import subprocess
|
||
from pathlib import Path
|
||
|
||
import pytest
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
HELPER = Path(__file__).with_name("helper_399_plan_structure_marks.cjs")
|
||
|
||
|
||
def _read(*parts: str) -> str:
|
||
return (ROOT.joinpath(*parts)).read_text(encoding="utf-8")
|
||
|
||
|
||
@pytest.fixture(scope="module")
|
||
def got() -> dict:
|
||
run = subprocess.run( # noqa: S603 — 고정 실행 파일
|
||
["node", str(HELPER)],
|
||
capture_output=True,
|
||
text=True,
|
||
encoding="utf-8",
|
||
timeout=120,
|
||
)
|
||
assert run.returncode == 0, run.stderr
|
||
return json.loads(run.stdout)
|
||
|
||
|
||
def test_마커_목록은_알약_목록(got) -> None:
|
||
assert got["laneGotSource"] is True # 알약 레인과 같은 `laneStructures`
|
||
assert got["plain"]["marks"] == [
|
||
{"color": "#e11d48", "at": [80, 0]}, # 40 m × 2 px · 종류 색
|
||
{"color": "#2563eb", "at": [160.34, 0]},
|
||
]
|
||
assert got["plain"]["normals"] == 0 and got["balloonsAfterPlain"] == 0
|
||
lane = _read("B05_Profile", "B05_Profile_UI_Structures_Marks.ts")
|
||
assert "const structures = laneStructures(options.structures);" in lane
|
||
marks = _read("B05_Profile", "B05_Profile_UI_RouteEdit_StructureMarks.ts")
|
||
assert "laneStructures(source.marks())" in marks
|
||
bridge = _read("B05_Profile", "B05_Profile_UI_Page_Structures.ts")
|
||
assert "setStructures([...ownStructures, ...pipeMarks]);" in bridge
|
||
assert "marks: (): StructureInstance[] => [...ownStructures, ...pipeMarks]," in bridge
|
||
assert "planMarksChanged(deps.projectId);" in bridge
|
||
|
||
|
||
def test_고름_정보_창_법선(got) -> None:
|
||
pipe = got["pickedPipe"]
|
||
assert pipe["ringAt"] == [[160.34, 0]] # 관 고름(누가거리만)도 그 마커
|
||
assert pipe["normal"] == [[160.34, -40], [160.34, 40]] # 좌우 20 m
|
||
assert pipe["balloon"]["lines"] == ["이름 pipe pos 80.17", "옵션 배수관"] # 알약 벌룬 줄
|
||
assert pipe["balloon"]["color"] == "#2563eb"
|
||
assert got["pickedStructureBalloon"] == ["이름 box pos 40", "옵션 BOX"]
|
||
assert got["balloonsAfterRelease"] == 0
|
||
|
||
|
||
def test_공용_고름과_같은_길() -> None:
|
||
view = _read("A00_Common", "design", "design_view_profile.ts")
|
||
assert " onStructureSelect,\n onStructureMarkMove,\n" in view # 알약 콜백 = 같은 함수
|
||
assert "select: onStructureSelect," in view and "move: onStructureMarkMove," in view
|
||
render = _read("B05_Profile", "B05_Profile_UI_RouteEdit_Render.ts")
|
||
labels = render.index("drawContourLabels(context, scene, band, style);")
|
||
nodes = render.index("scene.planned.forEach((vertex, index) => {")
|
||
hover = render.index("drawPickHover(context, scene, line, style, NODE_R);")
|
||
marks = render.index("drawStructureMarks(context, scene, line, style);")
|
||
turned = render.index("context.restore(); // 회전 끝")
|
||
assert labels < nodes < hover < marks < turned # 맨 위(409 — 교각점 · 손잡이 · 맴돔 위)
|
||
|
||
|
||
def test_집기_차례는_재기_다음_맨_앞() -> None:
|
||
pointer = _read("B05_Profile", "B05_Profile_UI_RouteEdit_Pointer.ts")
|
||
measure = pointer.index("void params.measure.pick(px, py);")
|
||
mark = pointer.index("if (marks.press(px, py)) {")
|
||
release = pointer.index("marks.deselect();")
|
||
node = pointer.index("if (hitNode >= 0) {")
|
||
handle = pointer.index("} else if (dragHandle) {")
|
||
tick = pointer.index('if (!pick || !("chainage" in pick)) return false;')
|
||
assert measure < mark < release < node < handle < tick # 409
|
||
|
||
|
||
def test_끌기_1m_정수_놓을_때_한_번(got) -> None:
|
||
assert got["pressMiss"] is False and got["pressA"] is True
|
||
assert got["selects"] == ["A"]
|
||
assert got["movesBeforeRelease"] == 0 # 끄는 동안은 미리보기만
|
||
assert got["dragMove"] == ["A", 43] # 3 m
|
||
assert "2+0 → 2+3(+3 m) 옮김" in got["dragDoneStatus"]
|
||
assert got["oldDecimalStay"] is True # 옛 소수 자리 눌렀다 떼기 = 안 옮김
|
||
assert got["oldDecimalMoved"] == ["pipe-80.17", 81]
|
||
|
||
|
||
def test_노선_밖_안_감(got) -> None:
|
||
assert got["pastEnd"] == ["A", 200]
|
||
assert got["beforeStart"] == ["A", 0]
|
||
assert got["logic"]["clamp"] == [0, 199] # 종점 199.6 → 199(정수 m 안쪽)
|
||
assert got["logic"]["step"] == [81, 0, 199]
|
||
|
||
|
||
def test_방향키_노선_따라_1m(got) -> None:
|
||
assert got["keyRight"] == ["A", 41]
|
||
assert got["keyLeft"] == ["A", 39]
|
||
assert got["keyUpPerpendicular"] == ["A", 41] # 직각 = → · ↑ 가 +
|
||
assert got["keyRightWestward"] == ["A", 39] # 노선이 서쪽으로 가면 → = 뒤로
|
||
assert got["keyWithNodePicked"] == 0 # 교각점 고름 = 교각점 방향키 몫
|
||
|
||
|
||
def test_관_목록이_늦게_와도_연달아_두_걸음(got) -> None:
|
||
assert got["lagHeldAt"] == [[162, 0]] # 옮긴 자리 · 고름 그대로(목록은 아직 80.17)
|
||
assert got["lagTwoSteps"] == [["pipe-80.17", 81], ["pipe-80.17", 82]]
|
||
assert got["lagCaught"] == [[164, 0]] # 목록이 따라오면 목록 자리
|
||
assert got["keyNoPick"] == 0
|
||
|
||
|
||
def test_고른_마커_찾기(got) -> None:
|
||
logic = got["logic"]
|
||
assert logic["round"] == [41, 42]
|
||
assert (logic["pickId"], logic["pickNear"], logic["pickFar"], logic["pickOther"]) == (
|
||
"A",
|
||
"A",
|
||
None,
|
||
None,
|
||
)
|
||
assert got["redrawnOnChange"] == 1
|
||
|
||
|
||
def test_편집기_줄_수_그대로() -> None:
|
||
edit = _read("B05_Profile", "B05_Profile_UI_RouteEdit.ts")
|
||
assert edit.count("\n") <= 695
|
||
for name in (
|
||
"B05_Profile_UI_RouteEdit_StructureMarks.ts",
|
||
"B05_Profile_UI_RouteEdit_Render.ts",
|
||
"B05_Profile_UI_RouteEdit_Pointer.ts",
|
||
):
|
||
assert _read("B05_Profile", name).count("\n") <= 700
|