Merge remote-tracking branch 'origin/dev' into sub_laptop_4
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
/* 472-4 C6 거울 헬퍼 — 맹암거 얹기 TS 짝(vite ssr) · test_472_4_underdrain_mirror.py 가 JSON 으로 받음. */
|
||||
export {
|
||||
attachUnderdrainSpecs,
|
||||
underdrainSpecsFrom,
|
||||
} from "../../common_util/common_util_structure_underdrain";
|
||||
@@ -42,8 +42,11 @@ def test_글은_재계산에서도_남는다(monkeypatch):
|
||||
monkeypatch.setattr(design_mod, "ford_surface_drops", lambda root: [])
|
||||
monkeypatch.setattr(design_mod, "design_elevation_from_longitudinal", lambda lon, ch: 100.0)
|
||||
monkeypatch.setattr(design_mod, "curve_widening_args", lambda section: {})
|
||||
# 472-4 ② — [저장] 다시 셈은 측점 묶음(Node) 한 번 · 그 자리를 갈아 끼움
|
||||
monkeypatch.setattr(
|
||||
design_mod, "compute_cross_design", lambda samples, elev, **kw: {"paved": kw["paved"]}
|
||||
design_mod,
|
||||
"compute_cross_designs",
|
||||
lambda jobs, standard: [{"paved": kw["paved"]} for _s, _z, kw in jobs],
|
||||
)
|
||||
sections = [{"chainage_m": 40.0, "design": {"paved": False, "structure_note": "메모"}}]
|
||||
assert design_mod.enforce_pavement_ranges({}, sections, Path("."), None) == 1
|
||||
|
||||
@@ -202,7 +202,8 @@ def test_좌측_패널_칸_구간_깊이_나름():
|
||||
"""옛 구조물 옵션 depth_m → 세션 구간 → 측점 제원(기본값) · 서버 payload(같은 꼴).
|
||||
|
||||
좌측 칸은 194-1 에서 숨김 — 옮기기는 횡단도 ▲▼(`test_194_1_berm_depth`)."""
|
||||
source = (ROOT / "B06_Section" / "B06_Section_UI_Page_Persist.ts").read_text(encoding="utf-8")
|
||||
# 소단 구간 셈은 472-4 C4 에서 `common_util_berm_spans.ts` 로 옮김
|
||||
source = (ROOT / "common_util" / "common_util_berm_spans.ts").read_text(encoding="utf-8")
|
||||
assert "options.depth_m" in source and "Math.max(rawDepth, 0)" in source
|
||||
refresh = (ROOT / "B06_Section" / "B06_Section_Cross_Refresh.ts").read_text(encoding="utf-8")
|
||||
assert "depthM: spec.depth_m" in refresh
|
||||
|
||||
@@ -59,8 +59,11 @@ def test_CAD_칸은_재계산에서도_남는다(monkeypatch):
|
||||
monkeypatch.setattr(design_mod, "ford_surface_drops", lambda root: [])
|
||||
monkeypatch.setattr(design_mod, "design_elevation_from_longitudinal", lambda lon, ch: 100.0)
|
||||
monkeypatch.setattr(design_mod, "curve_widening_args", lambda section: {})
|
||||
# 472-4 ② — [저장] 다시 셈은 측점 묶음(Node) 한 번 · 그 자리를 갈아 끼움
|
||||
monkeypatch.setattr(
|
||||
design_mod, "compute_cross_design", lambda samples, elev, **kw: {"paved": kw["paved"]}
|
||||
design_mod,
|
||||
"compute_cross_designs",
|
||||
lambda jobs, standard: [{"paved": kw["paved"]} for _s, _z, kw in jobs],
|
||||
)
|
||||
sections = [{"chainage_m": 40.0, "design": {"paved": False, "structure_note_cad": CAD}}]
|
||||
assert design_mod.enforce_pavement_ranges({}, sections, Path("."), None) == 1
|
||||
|
||||
@@ -19,6 +19,7 @@ X3 면적 두 갈래(구조물 = 관 351 하나 · 두 길 다 Node TS 로 셈)
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
|
||||
@@ -131,6 +132,25 @@ def test_두_길_사이_알려진_차만(got, pair) -> None:
|
||||
assert not gone, f"안 나타난 알려진 차 {gone} — KNOWN 에서 지움"
|
||||
|
||||
|
||||
def test_저장_설계선_점_정본과_1e4_안(tmp_path) -> None:
|
||||
"""[저장] 다시 셈 설계선(472-4 ② = Node TS) — 정본과 점 수 · offset 같음 · 고도 1e-4 m 안.
|
||||
|
||||
알려진 차 = 반올림 동점(파이썬 round 짝수 쪽 · TS 위쪽) 13 점(브레인 10-19 승인).
|
||||
"""
|
||||
detail = copy.deepcopy(paths.read("detail.json"))
|
||||
before = {s["chainage_m"]: s["design"]["design_line"] for s in detail["cross_sections"]}
|
||||
sections, _ = paths._save_tail(detail, paths.stage_project(tmp_path / "project"))
|
||||
moved = 0
|
||||
for section in sections:
|
||||
old, new = before[section["chainage_m"]], section["design"]["design_line"]
|
||||
assert [p["offset_m"] for p in new] == [p["offset_m"] for p in old], section["chainage_m"]
|
||||
for a, b in zip(old, new, strict=True):
|
||||
gap = abs(a["elevation_m"] - b["elevation_m"])
|
||||
assert gap <= 1e-4 + 1e-9, (section["chainage_m"], a, b)
|
||||
moved += gap > 0
|
||||
assert moved == 13, f"반올림 동점 점 수 {moved} — 알려진 차(13)와 다름"
|
||||
|
||||
|
||||
def test_화면_참값() -> None:
|
||||
stored = GOLDEN["stored"]
|
||||
assert stored["final_cumulative_m3"] == -17570.7
|
||||
|
||||
@@ -40,6 +40,8 @@ NODE_IDS = {
|
||||
"haul.plan",
|
||||
"excavation.trench",
|
||||
"corridor.mesh",
|
||||
"cross.design",
|
||||
"cross.berm_spans",
|
||||
}
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
@@ -196,7 +198,7 @@ def test_id_마다_실행기_있음(loaded) -> None:
|
||||
if row["site"] == "browser_only":
|
||||
ok = kind == "browser" and _has_name(ref)
|
||||
elif kind == "node":
|
||||
ok = ref == row["id"] and ref in NODE_IDS
|
||||
ok = ref in NODE_IDS # 한 셈에서 나오는 값(면적 · 소단 사면)은 그 셈의 id
|
||||
else:
|
||||
ok = kind == "py" and _has_name(ref)
|
||||
ok = ok and ("until" not in row or kind == "py")
|
||||
@@ -205,8 +207,10 @@ def test_id_마다_실행기_있음(loaded) -> None:
|
||||
if not ok:
|
||||
bad.append(row["id"])
|
||||
assert bad == []
|
||||
node_rows = {row["id"] for row in loaded["registry"] if row["runner"].startswith("node:")}
|
||||
assert node_rows == NODE_IDS
|
||||
node_runs = {
|
||||
row["runner"][5:] for row in loaded["registry"] if row["runner"].startswith("node:")
|
||||
}
|
||||
assert node_runs == NODE_IDS
|
||||
|
||||
|
||||
def test_묶음_STAGE_DEPS_등록부_입력과_같음(loaded) -> None:
|
||||
|
||||
@@ -68,3 +68,36 @@ def test_실행기_값_server_calc_와_같음() -> None:
|
||||
def test_Node_실행기_아닌_id_는_ValueError() -> None:
|
||||
with pytest.raises(ValueError, match="stations.list"):
|
||||
runner.run_calc(["masshaul.cumulative", "stations.list"], {})
|
||||
|
||||
|
||||
# ── 472-4 ② — 횡단 설계선 · 소단 구간 Node 길 ──────────────────────────────────
|
||||
|
||||
|
||||
def test_소단_구간_Node_와_파이썬_짝_같음(tmp_path, monkeypatch) -> None:
|
||||
from test_272_berm_source import STRUCTURE_CASES, _project
|
||||
|
||||
from B06_Section import B06_Section_Engine_Design_Node as node_mod
|
||||
from B06_Section.B06_Section_Engine_Structures_Wall import berm_span_at, load_berm_spans
|
||||
|
||||
calls = []
|
||||
real = node_mod.run_calc
|
||||
monkeypatch.setattr(
|
||||
node_mod, "run_calc", lambda ids, inputs: calls.append(ids) or real(ids, inputs)
|
||||
)
|
||||
chainages = [0.0, 5.0, 50.0, 65.0, 80.0, 100.0, 150.0, 250.0]
|
||||
for index, structures in enumerate(STRUCTURE_CASES):
|
||||
root = _project(tmp_path / f"c{index}", structures)
|
||||
got = node_mod.berm_specs_at(root, chainages)
|
||||
spans = load_berm_spans(root)
|
||||
want = [berm_span_at(spans, c) for c in chainages]
|
||||
assert got == [pytest.approx(w) if w else w for w in want], index
|
||||
assert len(calls) == len(STRUCTURE_CASES) # 파이썬 물러섬 아님
|
||||
|
||||
|
||||
def test_횡단_설계_못_세운_측점은_None() -> None:
|
||||
from B06_Section.B06_Section_Engine_Design_Node import compute_cross_designs
|
||||
|
||||
ground = [{"offset_m": o, "elevation_m": 100.0 + 0.3 * o} for o in range(-20, 21)]
|
||||
options = {"ground_type": "soil", "section_mode": "left_cut"}
|
||||
got = compute_cross_designs([(ground, 100.0, options), (ground, None, options)], None)
|
||||
assert got[0]["cut_area_m2"] > 0 and got[1] is None
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
"""PLAN 472-4 ② C6 (요구 273) — 맹암거 얹기 거울: TS `common_util_structure_underdrain` ↔ 파이썬
|
||||
`B06_Section_Engine_Tilt.underdrains_from` · `attach_underdrain_specs`.
|
||||
|
||||
못박는 것
|
||||
- 구조물 목록 → 제원(높이 · 경사 · 빈 값 · 0 · 음수 · 글 · 맹암거 아닌 종류) 두 쪽 같음.
|
||||
- 기준 측점(±0.02 m) 얹기 · 얹은 수 같음.
|
||||
- 알려진 차 하나 — 옛 `underdrain` 이 남은 측점: TS 는 걷음 · 파이썬은 둠
|
||||
(서버는 파일에서 새로 읽어 옛 값 없음 · Node 로 옮길 때 한 벌).
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_472_4_underdrain_mirror.py -q
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from B05_Profile.B05_Profile_Structures_Schema import StructureInstance
|
||||
from B06_Section.B06_Section_Engine_Tilt import attach_underdrain_specs, underdrains_from
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
ROOT = HERE.parents[1]
|
||||
|
||||
pytestmark = pytest.mark.skipif(
|
||||
not (ROOT / "config" / "node_modules" / "vite").is_dir(),
|
||||
reason="프론트엔드 의존성 미설치",
|
||||
)
|
||||
|
||||
|
||||
def _drain(at: float, **options) -> dict:
|
||||
return {
|
||||
"type_id": "cross_underdrain",
|
||||
"placement": "point",
|
||||
"chainage_m": at,
|
||||
"options": options,
|
||||
}
|
||||
|
||||
|
||||
STRUCTURES = [
|
||||
_drain(40.0, culvert_height_m=1.2, culvert_slope_pct=3),
|
||||
_drain(80.0, culvert_height_m="", culvert_slope_pct="2.5"),
|
||||
_drain(120.0, culvert_height_m=0, culvert_slope_pct=-1),
|
||||
_drain(160.0),
|
||||
{"type_id": "berm", "placement": "interval", "start_m": 0.0, "end_m": 50.0, "options": {}},
|
||||
]
|
||||
SECTIONS = [
|
||||
{"chainage_m": 40.01},
|
||||
{"chainage_m": 79.99},
|
||||
{"chainage_m": 120.0},
|
||||
{"chainage_m": 160.03}, # 0.02 밖
|
||||
{"chainage_m": 200.0, "underdrain": {"chainage_m": 200.0}}, # 옛 값 — 알려진 차
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def ts(tmp_path_factory) -> dict:
|
||||
work = tmp_path_factory.mktemp("u4724")
|
||||
subprocess.run( # noqa: S603 — 고정 실행 파일
|
||||
[
|
||||
"node",
|
||||
str(ROOT / "config" / "node_modules" / "vite" / "bin" / "vite.js"),
|
||||
"build",
|
||||
"--configLoader",
|
||||
"runner",
|
||||
"--ssr",
|
||||
"../resources/tester/helper_472_4_underdrain_entry.ts",
|
||||
"--outDir",
|
||||
str(work),
|
||||
"--logLevel",
|
||||
"error",
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
timeout=300,
|
||||
)
|
||||
bundle = work / "bundle.mjs"
|
||||
shutil.copy(work / "helper_472_4_underdrain_entry.js", bundle)
|
||||
job = json.dumps({"structures": STRUCTURES, "sections": SECTIONS})
|
||||
script = (
|
||||
f"const m = await import({json.dumps(bundle.as_uri())});"
|
||||
f"const job = {job};"
|
||||
"const specs = m.underdrainSpecsFrom(job.structures);"
|
||||
"const count = m.attachUnderdrainSpecs(job.sections, specs);"
|
||||
"console.log(JSON.stringify({specs, count, sections: job.sections}));"
|
||||
)
|
||||
out = subprocess.run( # noqa: S603
|
||||
["node", "--input-type=module", "-e", script],
|
||||
cwd=ROOT,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
timeout=60,
|
||||
)
|
||||
return json.loads(out.stdout)
|
||||
|
||||
|
||||
def _python() -> tuple[list[dict], int, list[dict]]:
|
||||
specs = underdrains_from([StructureInstance(**item) for item in STRUCTURES])
|
||||
sections = copy.deepcopy(SECTIONS)
|
||||
return specs, attach_underdrain_specs(sections, specs), sections
|
||||
|
||||
|
||||
def test_제원_같음(ts) -> None:
|
||||
specs, _count, _sections = _python()
|
||||
assert ts["specs"] == specs
|
||||
|
||||
|
||||
def test_얹기_같음_알려진_차_하나(ts) -> None:
|
||||
_specs, count, sections = _python()
|
||||
assert ts["count"] == count == 3
|
||||
assert ts["sections"][:4] == sections[:4]
|
||||
# 알려진 차 — 옛 underdrain: TS 걷음 · 파이썬 둠
|
||||
assert "underdrain" not in ts["sections"][4] and "underdrain" in sections[4]
|
||||
@@ -0,0 +1,130 @@
|
||||
"""PLAN 472 덧 (요구 272) — 구조물 측점을 다시 떠도 사용자 상단측 · 포장 제안 표기가 남음.
|
||||
|
||||
증상 — [저장] 상단측 차례(`POST /route/confirm` → `_append_irregular_cross_sections`) · 측점 맞춤
|
||||
(`ensure_structure_stations`)이 `_merge_irregular_into_longitudinal` 로 구조물 측점 줄을 새 줄로
|
||||
통째 갈음 → 같은 자리 옛 줄의 `uphill_side_source: user`(상단측 손 지정 · 값은 자동으로 돌아감) ·
|
||||
`pavement_*`(포장 제안 표기)가 사라짐(검증_sub8 측점 351).
|
||||
고침 — 같은 자리(누가거리) 옛 줄에서 `STATION_CARRY_KEYS` 를 들고 감 · 사용자 상단측은 새 자동값을
|
||||
이김 · 옛 줄 없는 새 자리는 포장 표기를 지금 계획선으로 셈.
|
||||
X6 — 옮긴 측점이 들고 가는 횡단 입력 TS `ROW_CARRY_KEYS` = 파이썬 `CARRY_INPUT_KEYS`(거울).
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_472_station_user_fields.py -q
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
ROOT = HERE.parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from B05_Profile.B05_Profile_Router_Confirm import ( # noqa: E402
|
||||
_merge_irregular_into_longitudinal,
|
||||
)
|
||||
from B06_Section.B06_Section_Router_Design import CARRY_INPUT_KEYS # noqa: E402
|
||||
|
||||
RELATIVE = "B06_Section/longitudinal/longitudinal.json"
|
||||
CRITERIA = {
|
||||
"max_grade_pct": 14.0,
|
||||
"max_reverse_grade_pct": 5.0,
|
||||
"min_vertical_radius_m": 100.0,
|
||||
"min_curve_length_m": 20.0,
|
||||
"min_tangent_length_m": 20.0,
|
||||
"vertical_curve_skip_delta_pct": 5.0,
|
||||
"design_speed_kph": 20,
|
||||
"terrain_type": "special",
|
||||
"paved": False,
|
||||
"main_direction": "auto",
|
||||
"balance_segment_length_m": None,
|
||||
"start_elevation_offset_m": 0.0,
|
||||
"end_elevation_offset_m": 0.0,
|
||||
"enforce_pipe_clearance": False,
|
||||
"resolved_main_direction": "ascending",
|
||||
}
|
||||
|
||||
|
||||
def _row(at: float, kind: str = "regular", **extra) -> dict:
|
||||
return {"chainage_m": at, "kind": kind, "station_id": f"s{at}", "uphill_side": "left", **extra}
|
||||
|
||||
|
||||
def _pave(grade: float) -> dict:
|
||||
return {
|
||||
"pavement_suggested": grade > 14.0,
|
||||
"pavement_grade_pct": grade,
|
||||
"pavement_grade_limit_pct": 14.0,
|
||||
}
|
||||
|
||||
|
||||
def _write(tmp_path: Path) -> Path:
|
||||
# 계획선 0 → 100 m 고르게 20 % 오르막(포장 상한 14 % 넘음)
|
||||
samples = [{"chainage_m": float(s), "elevation_m": 0.2 * s} for s in range(0, 101, 5)]
|
||||
stations = [
|
||||
_row(0.0, "bp", uphill_side_source="user", **_pave(20.0)),
|
||||
_row(20.0, uphill_side_source="user", **_pave(20.0)),
|
||||
_row(
|
||||
35.0,
|
||||
"irregular",
|
||||
structure="관 D1000",
|
||||
uphill_side="right",
|
||||
uphill_side_source="user",
|
||||
**_pave(20.0),
|
||||
), # fmt: skip
|
||||
_row(40.0, uphill_side="right", uphill_side_source="user", **_pave(20.0)),
|
||||
_row(100.0, "ep", uphill_side_source="user", **_pave(20.0)),
|
||||
]
|
||||
path = tmp_path / RELATIVE
|
||||
path.parent.mkdir(parents=True)
|
||||
longitudinal = {
|
||||
"stations": stations,
|
||||
"samples": samples,
|
||||
"design_profiles": [{"criteria": CRITERIA, "samples": samples}],
|
||||
}
|
||||
path.write_text(json.dumps(longitudinal), encoding="utf-8")
|
||||
return path
|
||||
|
||||
|
||||
def _fresh(at: float, **extra) -> dict:
|
||||
"""새로 뜬 구조물 측점 — 상단측은 지형 자동값 · 포장 표기 · 출처 칸 없음."""
|
||||
return {"chainage_m": at, "kind": "irregular", "station_id": f"n{at}", "uphill_side": "left",
|
||||
"structure": "관 D1000", **extra} # fmt: skip
|
||||
|
||||
|
||||
def _merged(tmp_path: Path, fresh: list[dict]) -> dict[float, dict]:
|
||||
path = _write(tmp_path)
|
||||
_merge_irregular_into_longitudinal(tmp_path, RELATIVE, fresh)
|
||||
rows = json.loads(path.read_text(encoding="utf-8"))["stations"]
|
||||
return {row["chainage_m"]: row for row in rows}
|
||||
|
||||
|
||||
def test_같은_자리_다시_떠도_사용자_상단측_포장_표기_남음(tmp_path) -> None:
|
||||
rows = _merged(tmp_path, [_fresh(35.0)])
|
||||
row = rows[35.0]
|
||||
assert row["station_id"] == "n35.0" # 기하 · 글은 새 줄
|
||||
assert row["uphill_side"] == "right" and row["uphill_side_source"] == "user"
|
||||
assert row["pavement_suggested"] is True and row["pavement_grade_pct"] == 20.0
|
||||
|
||||
|
||||
def test_격자_자리에_구조물이_얹혀도_사용자_상단측_남음(tmp_path) -> None:
|
||||
rows = _merged(tmp_path, [_fresh(35.0), _fresh(40.0, grid=True)])
|
||||
assert rows[40.0]["uphill_side"] == "right" and rows[40.0]["uphill_side_source"] == "user"
|
||||
assert rows[40.0]["pavement_grade_limit_pct"] == 14.0
|
||||
|
||||
|
||||
def test_새_자리는_포장_표기를_지금_계획선으로(tmp_path) -> None:
|
||||
rows = _merged(tmp_path, [_fresh(55.0)])
|
||||
assert 35.0 not in rows # 옛 구조물 측점은 걷힘
|
||||
row = rows[55.0]
|
||||
assert row["uphill_side"] == "left" and "uphill_side_source" not in row # 새 자리 = 지형 자동
|
||||
assert row["pavement_suggested"] is True
|
||||
assert row["pavement_grade_pct"] == 20.0 and row["pavement_grade_limit_pct"] == 14.0
|
||||
|
||||
|
||||
def test_X6_옮긴_측점_횡단_입력_TS_파이썬_한_벌() -> None:
|
||||
source = (ROOT / "B06_Section/logic/B06_Section_Station_Swap.ts").read_text(encoding="utf-8")
|
||||
body = re.search(r"export const ROW_CARRY_KEYS = \[(.*?)\] as const;", source, re.S)
|
||||
assert body is not None
|
||||
assert tuple(re.findall(r'"([a-z_0-9]+)"', body.group(1))) == CARRY_INPUT_KEYS
|
||||
@@ -31,6 +31,8 @@ TSC = PROJECT_ROOT / "config" / "node_modules" / "typescript" / "bin" / "tsc"
|
||||
|
||||
# 값이 소수점 아래에서 갈리는지 보려면 자릿수를 그대로 비교해야 한다. 두 쪽 다 반올림해
|
||||
# 내보내므로 완전 일치를 기대하되, 부동소수 마지막 자리만 어긋나는 것은 허용한다.
|
||||
# 알려진 차(472-4 ②) — 반올림 동점(…5)에서 파이썬 round 는 짝수 쪽 · TS 는 위쪽이라 설계선 점이
|
||||
# 1e-4 m 갈릴 수 있음(이 시험 입력엔 없음 · [저장] 정본은 Node TS 쪽 · test_472_1_golden).
|
||||
_TOLERANCE = 1e-9
|
||||
|
||||
|
||||
|
||||
@@ -146,8 +146,11 @@ def test_enforce_turns_paved_on_and_off(monkeypatch):
|
||||
monkeypatch.setattr(design_mod, "ford_surface_drops", lambda root: [])
|
||||
monkeypatch.setattr(design_mod, "design_elevation_from_longitudinal", lambda lon, ch: 100.0)
|
||||
monkeypatch.setattr(design_mod, "curve_widening_args", lambda section: {})
|
||||
# 472-4 ② — [저장] 다시 셈은 측점 묶음(Node) 한 번 · 그 자리를 갈아 끼움
|
||||
monkeypatch.setattr(
|
||||
design_mod, "compute_cross_design", lambda samples, elev, **kw: {"paved": kw["paved"]}
|
||||
design_mod,
|
||||
"compute_cross_designs",
|
||||
lambda jobs, standard: [{"paved": kw["paved"]} for _s, _z, kw in jobs],
|
||||
)
|
||||
sections = [
|
||||
{"chainage_m": 20.0, "design": {"paved": False}}, # 범위 안 · 끔 → 켬
|
||||
|
||||
@@ -80,7 +80,12 @@ def _install_fakes(monkeypatch) -> dict:
|
||||
}
|
||||
|
||||
monkeypatch.setattr(design_mod, "pavement_ranges", lambda root: [(0.0, 200.0)])
|
||||
monkeypatch.setattr(design_mod, "compute_cross_design", fake_compute)
|
||||
# 472-4 ② — [저장] 다시 셈은 측점 묶음(Node) 한 번 · 그 자리를 갈아 끼움
|
||||
monkeypatch.setattr(
|
||||
design_mod,
|
||||
"compute_cross_designs",
|
||||
lambda jobs, standard: [fake_compute(s, z, standard=standard, **kw) for s, z, kw in jobs],
|
||||
)
|
||||
monkeypatch.setattr(design_mod, "design_elevation_from_longitudinal", lambda lon, ch: 100.0)
|
||||
monkeypatch.setattr(design_mod, "curve_widening_args", lambda section: {})
|
||||
return seen
|
||||
|
||||
@@ -120,7 +120,12 @@ def _fake_engine(monkeypatch):
|
||||
return {"paved": True, "cut_area_m2": 1.0, "fill_area_m2": 2.0}
|
||||
|
||||
monkeypatch.setattr(design_mod, "pavement_ranges", lambda root: [(0.0, 200.0)])
|
||||
monkeypatch.setattr(design_mod, "compute_cross_design", fake_compute)
|
||||
# 472-4 ② — [저장] 다시 셈은 측점 묶음(Node) 한 번 · 그 자리를 갈아 끼움
|
||||
monkeypatch.setattr(
|
||||
design_mod,
|
||||
"compute_cross_designs",
|
||||
lambda jobs, standard: [fake_compute(s, z, standard=standard, **kw) for s, z, kw in jobs],
|
||||
)
|
||||
monkeypatch.setattr(design_mod, "design_elevation_from_longitudinal", lambda lon, ch: 100.0)
|
||||
monkeypatch.setattr(design_mod, "curve_widening_args", lambda section: {})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user