Files
Aislo/resources/tester/helper_510_propose.cjs
T
eomsangdonandClaude Opus 5.5 1abac6377f feat(510-1 자동 관 제안 = B05 배수유역 후보 고름): [자동 제안] = 서버 후보(지금 노선 × 세류선 교차 5 m 솎기 · 정수 m · 라벨 + 분석이 지금 노선이면 간격 보충) · 상태 있음(라벨 짝 · 교차 5 m 안 관) · 지운 관(지움 표지 짝) · 새 · 배수유역 칸 목록 + 지도 점선 원 · 고른 것만 관 넣기 길(addPipe · 세류선 교차 = 라벨 실음) · 옛 두 방식 창(전체 자동 · 지정 포함 추가) 걷음
- 서버 POST drainage/pipe-proposals(아무것도 안 씀) · propose_pipes(common_util_stream_crossing) · claim_crossings = {교차점: 라벨} 짝
- 라벨 왕복 — 계산 carry 가 화면 라벨 실음 · 관 속성 보관소가 응답 · 초안 · 요청에 라벨 실어 나름 · 옵션 고침에도 남김
- 지운 관을 다시 넣으면 지움 표지 걷음(keep_labels)
- 계산 등록부 D2 runner = propose_pipes · 시험 test_510 · 349 낡은 두 방식 기대 고침

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 12:36:48 +09:00

99 lines
3.2 KiB
JavaScript

/* 510-1 [자동 제안] 후보 목록 — 진짜 `B05_Profile_UI_Drainage_Propose.ts` · 관 속성 보관소를 가짜 DOM · fetch 로.
* node helper_510_propose.cjs (짝 = `test_510_auto_pipe_propose.py`) */
const path = require("path");
const { makeLoader } = require("./helper_ts_stub_loader.cjs");
const ROOT = path.join(__dirname, "..", "..");
/* ---- 가짜 DOM(쓰는 것만) ---- */
function el(tag) {
const listeners = {};
const node = {
tag,
children: [],
hidden: false,
disabled: false,
checked: false,
textContent: "",
append(...items) {
items.forEach((item) =>
node.children.push(typeof item === "string" ? { text: item } : item),
);
},
replaceChildren(...items) {
node.children = [];
node.append(...items);
},
addEventListener(type, fn) {
(listeners[type] ??= []).push(fn);
},
fire(type) {
(listeners[type] ?? []).forEach((fn) => fn());
},
};
return node;
}
globalThis.document = { createElement: el };
const sent = [];
globalThis.fetch = async (url, init) => {
sent.push({ url, body: JSON.parse(init.body) });
return {
ok: true,
json: async () => ({
spacing: true,
proposals: [
{ chainage_m: 50, kind: "stream", state: "dismissed", stream_label: { stream: "S1", order: 1 } },
{ chainage_m: 150, kind: "stream", state: "held", stream_label: { stream: "S2", order: 1 } },
{
chainage_m: 320,
kind: "stream",
state: "new",
stream_label: { stream: "S4", order: 1 },
stream_name: "작은골",
},
{ chainage_m: 420, kind: "spacing", state: "new" },
],
}),
};
};
const { load } = makeLoader({ root: ROOT });
const { createDrainagePropose } = load("B05_Profile", "B05_Profile_UI_Drainage_Propose.ts");
const { createFacilityStore } = load("B05_Profile", "B05_Profile_UI_Drainage_Facility.ts");
(async () => {
const added = [];
const propose = createDrainagePropose({
projectId: () => "p1",
pipeRequest: () => [{ chainage_m: 150, source: "user" }],
addPipes: (picks) =>
picks.forEach((item) => added.push([item.chainage_m, item.stream_label?.stream ?? null])),
redraw: () => undefined,
});
await propose.open();
const [head, list] = propose.root.children;
const [title, add] = head.children;
const boxes = list.children.map((row) => row.children[0].children[0]);
const out = {
sent: { url: sent[0].url, points: sent[0].body.points.length },
rows: list.children.map((row) => row.children[0].children[1].text.trim()),
title: title.textContent,
addOff: add.disabled,
candidates: propose.candidates(),
};
boxes[1].checked = true;
boxes[1].fire("change");
boxes[2].checked = true;
boxes[2].fire("change");
add.fire("click");
out.added = added;
out.afterClose = { hidden: propose.root.hidden, candidates: propose.candidates() };
// 관 속성 보관소 — 응답 라벨이 다음 요청에 실림(라벨만 있는 맨 배관도 보관)
const store = createFacilityStore();
store.replaceFromResponse([{ chainage_m: 320, stream_label: { stream: "S4", order: 1 } }]);
out.carried = store.attach([{ chainage_m: 320, source: "user" }])[0].stream_label ?? null;
console.log(JSON.stringify(out));
})();