Merge remote-tracking branch 'origin/sub_laptop_4' into main_laptop_1

This commit is contained in:
2026-10-22 20:17:48 +09:00
8 changed files with 132 additions and 18 deletions
@@ -0,0 +1,38 @@
/* 513-3 우클릭 「구조물 삭제」 관 아닌 구조물도(요구 327-1) — `design_pipe_ids.removeStationOwner` 를 Node 로
* 돌려 JSON 한 줄(`test_513_3_remove_station_owner.py` 가 판정). 관 장부 · 고름은 가짜 · 주인 가르기는 진짜.
* node helper_513_3_remove_station_owner.cjs
*/
const path = require("path");
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const BOOK = { next: 4, ids: [{ id: "pipe-s3", at: 55 }] };
const STUBS = {
"../b_page_state": { readState: () => BOOK, writeState() {} },
"./design_selection": {
PIPE_MATCH_M: 0.51,
isNear: () => false,
nearestWithin: () => null,
readSelection: () => null,
selectDesign() {},
},
common_util_pick_tag: { setPipeTagSource() {} },
};
const { loadTs } = makeLoader({ root: path.join(__dirname, "..", ".."), stubs: STUBS });
const ids = loadTs(path.join(__dirname, "..", "..", "A00_Common", "design", "design_pipe_ids.ts"));
ids.usePipeIds("p1");
const calls = [];
const remove = {
pipe: (m) => calls.push(["pipe", m]),
structure: (id) => calls.push(["structure", id]),
};
const cases = [
[{ id: "pipe-s1", chainage_m: 40 }, true], // 관 기준 측점
[{ id: "wall-7", chainage_m: 80 }, false], // 구조물 기준 측점
[{ id: "wall-8:start", chainage_m: 100 }, false], // 구간 구조물 시작
[{ id: "wall-8:end", chainage_m: 130 }, false], // 구간 구조물 끝
[{ id: "pipe-s3:end", chainage_m: 60 }, false], // 관 구간 끝 = 장부 자리
[{ id: "pipe-12.50:start", chainage_m: 10 }, false], // 옛 자리 이름 관
];
for (const [station, pipe] of cases) ids.removeStationOwner(station, pipe, remove);
process.stdout.write(JSON.stringify({ calls }));
@@ -0,0 +1,44 @@
"""513-3 종단 · 평면 우클릭 「구조물 삭제」 관 아닌 구조물도(요구 327-1) — 측점 주인을 갈라 관 = 관 지점 정본 ·
그 밖 = 좌측 칸 [삭제]와 같은 `removeById`(공용 `removeStationOwner`).
TS 셈은 `helper_513_3_remove_station_owner.cjs`(Node · 주인 가르기는 진짜).
./venv/Scripts/python.exe -m pytest resources/tester/test_513_3_remove_station_owner.py -q
"""
import json
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
HELPER = Path(__file__).with_name("helper_513_3_remove_station_owner.cjs")
def test_주인대로_지움() -> None:
run = subprocess.run( # noqa: S603 — 고정 실행 파일
["node", str(HELPER)],
capture_output=True,
text=True,
encoding="utf-8",
timeout=120,
)
assert run.returncode == 0, run.stderr
assert json.loads(run.stdout)["calls"] == [
["pipe", 40],
["structure", "wall-7"],
["structure", "wall-8"],
["structure", "wall-8"],
["pipe", 55],
["pipe", 12.5],
]
def test_두_보기_배선() -> None:
view = (ROOT / "A00_Common" / "design" / "design_view_profile.ts").read_text(encoding="utf-8")
assert "removeStationOwner(station, isPipeStation(station)" in view
assert "panel.structures.removeById(structureId)" in view
cross = (ROOT / "B06_Section" / "B06_Section_UI_Section_View_Profile.ts").read_text(
encoding="utf-8"
)
assert "removeStationOwner(station, isPipeStation(station)" in cross
assert "structure: edit.removeStructure" in cross