# -*- coding: utf-8 -*- """344-3 · 346-2 2파 — 세션 횡단 초안 측점 열쇠 · cross · masshaul · haul 단계. 못박는 것 - 옛 초안(누가거리 열쇠)은 읽을 때 측점 열쇠로 옮김 · 지금 측점에 없는 것은 지우지 않고 남김. - 쓰기 = 측점 열쇠(grid · pipe · structure) · 부르는 쪽은 누가거리로 읽음 · 암 경계 저장소도 같음. - 구조물 id 를 아직 모를 때(첫 열기)도 쓴 때 자리로 그 측점 고침을 읽음. - 노선이 바뀜 = 측점 열쇠로 넘김(관 · 구조물은 옮긴 자리로) · 넘김 = 카드 선택 넷 · 암 경계 · 단면 유형 · 측구 방향 · 포장 · 노견 확장은 안 넘김 · 사라진 측점 = 「노선 밖 고침 N 건」. - cross 단계: 같은 입력 다시 셈 0 · 측점 하나 고침 = 1 · 범위 밖 재사용. - masshaul 단계 = 계열 + 흙 배분 입력 · haul 단계 = 같은 열쇠 안 물음 · 끊김 = 앞 배분 그대로. Node 헬퍼 `helper_344_3_station_keys.mjs` 가 vite ssr 로 묶은 진짜 모듈(`helper_344_3_entry.ts`)을 부름. """ import json import shutil import subprocess import sys from pathlib import Path import pytest HERE = Path(__file__).resolve().parent ROOT = HERE.parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from config.config_system import STANDARD_CROSS_SECTION # noqa: E402 FIXTURE = HERE / "fixtures" / "b05_192_1_moved_pipe_longitudinal.json" @pytest.fixture(scope="module") def out(tmp_path_factory): work = tmp_path_factory.mktemp("b344") build = subprocess.run( [ "node", str(ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"), "build", "--configLoader", "runner", "--ssr", "../resources/tester/helper_344_3_entry.ts", "--outDir", str(work), "--logLevel", "error", ], cwd=ROOT, capture_output=True, text=True, encoding="utf-8", timeout=300, ) assert build.returncode == 0, build.stderr bundle = work / "bundle.mjs" shutil.copy(work / "helper_344_3_entry.js", bundle) policy = json.loads(FIXTURE.read_text(encoding="utf-8"))["profile_alignment"]["policy"] source = work / "input.json" source.write_text( json.dumps({"standard": STANDARD_CROSS_SECTION, "policy": policy}, default=str), encoding="utf-8", ) proc = subprocess.run( ["node", str(HERE / "helper_344_3_station_keys.mjs"), str(bundle), str(source)], cwd=ROOT, capture_output=True, text=True, encoding="utf-8", timeout=120, ) assert proc.returncode == 0, proc.stderr return json.loads(proc.stdout) def test_옛_초안은_읽을_때_측점_열쇠로_옮김(out): assert out["legacyRead"] == [20, 45.05, 52.5, 60] assert out["legacyKeys"] == ["99.00", "grid:1", "grid:3", "pipe:pipe-s1", "structure:st-1"] def test_쓰기는_측점_열쇠_읽기는_누가거리(out): assert out["writeKey"] is True assert out["shoulderKeys"] == ["grid:2"] assert out["rockKeys"] == ["grid:1"] assert out["rockLoaded"] == {"20.00": -0.8} assert out["rockSession"] == {"20.00": -0.8} def test_구조물_id_모를_때도_쓴_자리로_읽음(out): assert out["hintKeyNow"] == "at:52.50" assert out["hintRead"] is True def test_노선_바뀜_측점_열쇠로_넘김(out): assert out["outside"] == 2 # 60 m(노선이 짧아짐) · 99 m(옛 노선에도 없던 옛 초안) assert out["carriedKeys"] == ["grid:1", "grid:2", "pipe:pipe-s1", "structure:st-1"] assert out["carriedRead"] == [20, 40, 47, 55] # 관 · 구조물은 옮긴 자리로 assert out["carriedChoice"] == { "ground_type": "soil", "ditch_type": "l_type", "ditch_choice": False, "two_stage_slope": True, } assert out["carriedRock"] == {"20.00": -0.8} assert out["carriedShoulder"] == [] def test_cross_단계_국부_연산(out): assert out["samplesSorted"] is True and out["samplesCount"] == 49 assert out["crossFirst"] == {"computed": 6, "reused": 0, "keys": 6} assert out["crossHasArea"] is True assert out["crossSame"] == {"computed": 0, "reused": 6} assert out["crossOne"] == {"computed": 1, "reused": 5} assert out["crossOneChanged"] == "soil" assert out["crossGrade"]["computed"] <= 3 and out["crossGrade"]["reused"] >= 3 def test_masshaul_haul_단계(out): assert out["massSeries"] == ["cross", "longitudinal"] assert out["massHaulInput"] is True assert out["haul"] == {"posts": 1, "plan1": {"n": 1}, "plan2": {"n": 1}, "plan3": {"n": 1}}