Merge remote-tracking branch 'origin/dev' into sub_laptop_1

This commit is contained in:
2026-10-25 23:28:46 +09:00
3 changed files with 81 additions and 75 deletions
+54 -7
View File
@@ -5,6 +5,8 @@
측점 보기에 벽 폴리곤 · 목록 벽 수 · 벽 있는 측점만 지문이 바뀜
- 지하수: E02 우기 갈래를 바꾸면 측점 지문이 바뀜 · 측점 보기 수위선 = 고른 갈래
- 빠진 횡단: 횡단 파일이 없으면 result2d · stab/ground 의 missing_stations 에 그 측점
- E05 이음매: E05 가 E03 정본만 읽음(사본 없음) · 측점 수 · N.G 수 · 지배 비탈이 E03 과 같음
- result2d 덧칸: 지배 비탈 = fs / 기준 가장 낮은 쪽(깎기 1.22/1.2 · 쌓기 1.25/1.3 → 쌓기 · N.G)
./venv/Scripts/python.exe -m pytest resources/tester/test_532_5_e03_seam.py -q
"""
@@ -32,6 +34,7 @@ from E01_StabRegister import E01_StabRegister_Source as src # noqa: E402
from E02_StabGround import E02_StabGround_Model as ground_model # noqa: E402
from E02_StabGround import E02_StabGround_Router as e02 # noqa: E402
from E03_StabSection import E03_StabSection_Router as router # noqa: E402
from E03_StabSection import E03_StabSection_View as view # noqa: E402
from E03_StabSection import E03_StabSection_Worker as worker # noqa: E402
from E03_StabSection.E03_StabSection_Engine_Station import analyze_station # noqa: E402
@@ -190,27 +193,71 @@ def test_빠진_횡단_목록(project):
assert asyncio.run(router.result2d(UUID(PID), USER))["missing_stations"] == []
def test_E05_가_E03_저장본으로_보고서(project):
"""E03 [해석] 이 쓴 E05 꼴(result2d.json · results/ · representative stations)로 E05 가 돎."""
def test_E05_가_E03_정본으로_보고서(project):
"""E03 [해석] 정본(stab2d_summary · stab2d_station)으로 E05 가 돎 — 사본 안 씀 · 수가 같음."""
from E05_StabReport import E05_StabReport_Build as build
_analyze()
assert not (project / "E03_StabSection" / "_derived").exists() # 옛 사본 꼴 없음
body = asyncio.run(router.result2d(UUID(PID), USER))
inputs = build.gather(project)
rows = inputs["result2d"]["stations"]
assert len(rows) == 2 and WALL_KEY in {r["station_key"] for r in rows}
assert len(rows) == len(body["stations"]) == 2
assert WALL_KEY in {r["station_key"] for r in rows}
ng = sum(1 for r in body["stations"] if r["verdict_overall"] == "ng")
assert sum(1 for r in rows if r["verdict"] == "ng") == ng
e03 = {r["station_key"]: r for r in body["stations"]}
for r in rows:
assert r["side"] in ("cut", "fill") and r["verdict"] in ("ok", "ng")
assert r["fs_min"] == min(v for v in r["fs_by_condition"].values() if v is not None)
mine = e03[r["station_key"]]
assert r["side"] == mine["side"] in ("cut", "fill")
assert r["fs_by_condition"] == mine["fs_by_condition"]
assert r["verdict"] == mine["verdict_overall"] in ("ok", "ng")
reps = inputs["representatives"]
assert reps and all(rep["result"] and rep["result"]["cases"] for rep in reps)
book = build.form()
jobs = build.build_program(book, inputs)
assert len([k for k, svg in jobs if svg.startswith("<svg")]) >= len(reps)
# 대표 단면 끔 → E05 목록에서 빠짐 · E03 overrides 는 그대로 읽힘
# 대표 단면 끔 → E05 목록에서 빠짐 · representative.json = overrides 만
key = reps[0]["station_key"]
asyncio.run(
router.put_representative(UUID(PID), router.RepresentativeRequest(overrides={key: False}))
)
assert key not in [r["station_key"] for r in build.gather(project)["representatives"]]
assert router._overrides(project) == {key: False}
saved = json.loads((project / router.REPRESENTATIVE).read_text("utf-8"))
assert saved == {"overrides": {key: False}}
def _case(fs, need):
return {"fs": fs, "required": need, "ok": fs >= need}
def test_result2d_지배_비탈_기준_대비():
"""깎기 1.22/1.2(O.K) · 쌓기 1.25/1.3(N.G) — fs 만 낮은 깎기가 아니라 쌓기가 지배 · N.G."""
from E05_StabReport import E05_StabReport_Build as build
row = {
"key": "10.00",
"chainage_m": 10.0,
"sides": [{"side": "left", "role": "cut"}, {"side": "right", "role": "fill"}],
"cases": {
"dry": {"left": _case(1.6, 1.5), "right": _case(1.7, 1.5)},
"wet": {"left": _case(1.22, 1.2), "right": _case(1.25, 1.3)},
},
"min": {"dry": 1.6, "wet": 1.22},
"verdict": {"dry": "ok", "wet": "ng"},
}
out = view.governing_row(row)
assert out["side"] == "fill" and out["fs_min"] == 1.25
assert out["fs_by_condition"] == {"dry": 1.7, "wet": 1.25}
assert out["verdict_overall"] == "ng" and out["method"] == "bishop"
e05 = build._row2d(row, "bishop")
assert (e05["side"], e05["fs_by_condition"], e05["verdict"]) == (
out["side"],
out["fs_by_condition"],
out["verdict_overall"],
)
row["verdict"] = {"dry": "ok", "wet": "ok"}
assert view.governing_row(row)["verdict_overall"] == "ok"
bare = {**row, "cases": {"dry": {"left": {"fs": 1.4, "required": None}}}}
assert view.governing_row(bare)["side"] is None and view.governing_row(bare)["fs_min"] == 1.22