"""347-2 · 347-3 배수유역 자동/수동 · 제안 — 화면 쪽 순수 규칙(logic/ 두 파일). - 기본 수동 · 자동 = 3 초 조용한 뒤 · 노선 초안이 있을 때만 낡음. - 늦은 답 버림: 옛 차례 · 서버가 그만둔 답 · 답 차례가 다른 것은 안 올림. - 제안: 관경(배관 · 추천 ≠ 지금) · 시설(BOX암거 · 세월교) · 관 자리(기존 관 근처 뺌) · [적용] = 한 번에 얹음 · 입력 목록은 안 고침(자동 바꿈 없음). Node 헬퍼(`helper_347_2_drainage_live.cjs`)가 TS 를 그 자리에서 돌린다. """ import json import os import subprocess import pytest HERE = os.path.dirname(os.path.abspath(__file__)) @pytest.fixture(scope="module") def r(): proc = subprocess.run( ["node", os.path.join(HERE, "helper_347_2_drainage_live.cjs")], capture_output=True, text=True, timeout=60, encoding="utf-8", ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def test_mode_and_stale(r): assert r["quietMs"] == 3000 assert r["modes"] == ["manual", "auto", "manual"] assert r["stale"] == [False, True] def test_late_answers_dropped(r): assert r["accept"] == [True, False, False, False] assert r["body"] == {"generation": 5, "route": None, "points": [{"chainage_m": 1}]} def test_suggestions_collected(r): assert r["suggestions"] == [ {"kind": "diameter", "chainageM": 100, "from": 1000, "to": 1200}, {"kind": "position", "chainageM": 200}, {"kind": "facility", "chainageM": 300, "from": "pipe", "to": "ford_bridge"}, ] def test_apply_once_without_touching_input(r): assert r["untouched"] applied = {pipe["chainage_m"]: pipe for pipe in r["applied"]} assert sorted(applied) == [100, 200, 300, 500] assert applied[100]["options"]["pipe_diameter_mm"] == 1200 assert applied[200]["source"] == "spacing" assert applied[300]["facility"] == "ford_bridge" assert applied[500]["facility"] == "box_culvert" # 이미 그 종류 — 그대로