Merge remote-tracking branches 'origin/sub_laptop_3' and 'origin/sub_laptop_8' into sub_laptop_6

This commit is contained in:
2026-09-29 10:03:45 +09:00
5 changed files with 87 additions and 6 deletions
+3 -1
View File
@@ -1,6 +1,6 @@
// 저장 왕복 시험용 — 화면 TS 를 node 로 묶어 저장 본문을 만든다.
// node helper_b05_save_payload.mjs <저장소 뿌리> · 표준입력 = 작업 목록(JSON) · 표준출력 끝 줄 = 결과 목록
// {op:"attach", entries:[관 응답], points:[{chainage_m, source}]} → attach 결과(DetailPipeInput[])
// {op:"attach", entries:[관 응답], moves:[[옛, 새]], points:[{chainage_m, source}]} → attach 결과
// {op:"station", chainage, interval} → 구조물 측점 칸에 쓰고 다시 읽은 값
// {op:"culvert", server:[관 응답], pending:{측점:조각}, moves:{측점:새 측점}} → PUT 본문 points 또는 null
import fs from "node:fs";
@@ -78,6 +78,8 @@ try {
if (job.op === "attach") {
const store = mod.createFacilityStore();
store.replaceFromResponse(job.entries);
// 지도에서 끈 관 — 화면이 끌기를 마치면 속성을 새 측점으로 옮김(onMove)
for (const [from, to] of job.moves ?? []) store.move(from, to);
results.push(store.attach(job.points));
} else if (job.op === "station") {
const fields = mod.stationFields("측점", () => job.interval);
@@ -301,7 +301,8 @@ class Flow:
}
for p in self.want_pipes
]
(attached,) = _screen([{"op": "attach", "entries": entries, "points": points}])
job = {"op": "attach", "entries": entries, "moves": [self.pipe_move], "points": points}
(attached,) = _screen([job])
return attached
def b06_pipe_payload(self) -> list[dict[str, Any]]:
+23
View File
@@ -13,8 +13,10 @@ from B05_Profile.B05_Profile_Engine_RouteInitial import (
Terrain,
generate_initial_route,
grade_line,
read_initial_choice,
resolve_weights,
stream_lines,
write_initial_choice,
)
GRADE = 0.14
@@ -124,3 +126,24 @@ def test_weights_and_stream_filter() -> None:
def test_unknown_mode_rejected(hill: Terrain) -> None:
with pytest.raises(ValueError):
_run(hill, "shortest")
def test_initial_choice_roundtrip(tmp_path) -> None:
"""[확인] 때 적은 현재 초기값을 다시 읽음 · 없거나 깨지면 추종."""
assert read_initial_choice(tmp_path)["logic"] == "follow"
write_initial_choice(tmp_path, "weighted", {"expected": 60, "earthwork": 20, "grade": 20})
assert read_initial_choice(tmp_path) == {
"logic": "weighted",
"weights": {"expected": 60.0, "earthwork": 20.0, "grade": 20.0},
}
(tmp_path / "B05_Profile" / "route" / "initial_choice.json").write_text("{", encoding="utf-8")
assert read_initial_choice(tmp_path)["logic"] == "follow"
def test_request_accepts_logic_name() -> None:
from B05_Profile.B05_Profile_Router_Replan import RouteInitialRequest, RouteReplanRequest
assert RouteInitialRequest.model_validate({"logic": "gentle"}).mode == "gentle"
assert RouteInitialRequest.model_validate({"mode": "earthwork"}).mode == "earthwork"
replan = RouteReplanRequest.model_validate({"vertices": [], "initial": {"logic": "weighted"}})
assert replan.initial is not None and replan.initial.mode == "weighted"