# -*- coding: utf-8 -*- """PLAN 316 — 기본값 둘. 316-1 B06 횡단 「복합경사」(two_stage_slope) 기본 = 꺼짐 · 저장된 고른 값은 그대로. 두 짝(파이썬 `compute_cross_design` ↔ TS `computeCrossDesign`)의 같은 기본은 `test_b06_cross_design_mirror.py` 「발파암 복합경사 값 없음」 갈래가 실제 대조. 316-2 B05 3D 영역 첫 보기 = 원근 · 화면 설정에 기억한 값이 있으면 그 값. """ import re import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) from B06_Section.B06_Section_Engine_Design import compute_cross_design # noqa: E402 from B06_Section.B06_Section_Schema import CrossDesignRequest # noqa: E402 from config.config_system import STANDARD_CROSS_SECTION # noqa: E402 def _read(rel: str) -> str: return (ROOT / rel).read_text(encoding="utf-8") def _samples() -> list[dict]: offsets = [round(-12 + i * 0.5, 3) for i in range(49)] return [{"offset_m": x, "elevation_m": 100.0 - 0.55 * x, "valid": True} for x in offsets] def _rock(**extra) -> dict: return compute_cross_design( _samples(), 99.0, ground_type="blasting_rock", section_mode="left_cut", ditch_side="left", standard=STANDARD_CROSS_SECTION, rock_boundary_offset_m=-1.4, **extra, ) def test_engine_default_off(): plain, off, on = _rock(), _rock(two_stage_slope=False), _rock(two_stage_slope=True) assert plain["two_stage_slope"] is False assert plain["cut_area_m2"] == off["cut_area_m2"] # 고른 「켬」은 그대로 — 면적이 실제로 달라야 기본값 시험이 뜻이 있음 assert on["two_stage_slope"] is True assert on["cut_area_m2"] != off["cut_area_m2"] def test_request_schema_default_off(): field = CrossDesignRequest.model_fields["two_stage_slope"] assert field.default is False def test_python_stored_reads_default_off(): for rel in ( "B06_Section/B06_Section_Router_Design.py", "B06_Section/B06_Section_Engine_SpoilFill.py", "B06_Section/B06_Section_Engine_SampleExtend.py", "B05_Profile/B05_Profile_Router_Confirm.py", ): src = _read(rel) assert '"two_stage_slope", True' not in src, rel assert '"two_stage_slope", False' in src, rel def test_ts_defaults_off_and_stored_kept(): engine = _read("common_util/common_util_cross_design.ts") assert engine.count("options.twoStageSlope ?? false") == 2 assert "twoStageSlope ?? true" not in engine # 카드 토글 — 저장된 고른 값 그대로 · 없으면 꺼짐 assert "twoStage: design?.two_stage_slope ?? false," in _read( "B06_Section/B06_Section_UI_Cross_Design.ts" ) # 브라우저 재계산 인자 — 세션 선택 → 저장값 → 꺼짐 assert "twoStageSlope: choice?.two_stage_slope ?? Boolean(design.two_stage_slope)," in _read( "B06_Section/B06_Section_Cross_Refresh.ts" ) assert "two_stage_slope: design.two_stage_slope ?? false," in _read( "B06_Section/B06_Section_UI_Page_Design_Sync.ts" ) def test_3d_first_view_perspective(): camera = _read("B05_Profile/B05_Profile_UI_Viewer_Camera.ts") assert 'let kind: ProjectionKind = "perspective";' in camera state = _read("A00_Common/b_page_state.ts") assert re.search(r'"b05-3d-projection": \{ bucket: "pref", scope: "global" \}', state) def test_3d_remembered_projection_wins(): src = _read("B05_Profile/B05_Profile_UI_Panel_View.ts") # 기억 = ortho 일 때만 직교 · 그 밖(없음 · 손상)은 원근 assert re.search( r'const initialProjection = readStateRaw\("b05-3d-projection"\) === "ortho"\s*\?\s*"ortho"\s*:\s*"perspective";', src, ) assert 'writeStateRaw("b05-3d-projection", kind);' in src assert 'if (initialProjection === "ortho") callbacks.onProjection("ortho");' in src # 단추 강조도 처음 값 따라 assert 'element.classList.toggle("is-active", kind === initialProjection);' in src