- 종단 도구줄 [배수유역도] 뒤 [새 창] 단추 — 종단도·표·유토곡선·배수유역도 묶음을 같은 출처 팝업으로 옮김 · 코드·자료·가게는 메인 창 그대로 - 스타일 시트·html 테마 속성 복사 · 팝업 크기 변화 시 팝업 ResizeObserver 로 다시 그림 - 팝업 키·포인터(keydown·keyup·pointerdown·pointerup·pointercancel)·blur 를 메인 문서로 넘김 — 대상 요소 유지 - 팝업 닫힘·[제자리로]·메인 창 떠남·페이지 정리 때 원래 자리로 되돌림 · 팝업 차단 시 알림 한 줄 - 우클릭 메뉴 화면 밖 보정을 요소 소속 창 기준으로 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EYJJRCfHfdCGNhmXTjQKV7
85 lines
3.3 KiB
Python
85 lines
3.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""종단도 한 벌(계획서 24-2c) 회귀검증.
|
|
|
|
두 보기(B05 종단 · B06 횡단)가 **같은 종단도**(`A00_Common/design/design_profile.ts`)를 쓰고
|
|
같은 오른쪽 판(배수유역도)을 끼우는지, 옛 B06 위쪽 붙박이 종단이 남지 않았는지, 계획고 초안이
|
|
등록부 칸(`alignment-draft`)으로 옮겨져 되돌리기가 그 칸을 찍는지 본다.
|
|
Node 헬퍼(`helper_design_profile_single.cjs`)가 TS 를 트랜스파일해 돌린다.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
ROOT = HERE.parent.parent
|
|
|
|
|
|
def _read(relative: str) -> str:
|
|
return (ROOT / relative).read_text(encoding="utf-8")
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def results():
|
|
proc = subprocess.run(
|
|
["node", os.path.join(HERE, "helper_design_profile_single.cjs")],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
timeout=60,
|
|
)
|
|
assert proc.returncode == 0, proc.stderr
|
|
return json.loads(proc.stdout)
|
|
|
|
|
|
def test_두_보기가_같은_종단도와_같은_판():
|
|
"""종단도는 한 페이지 한 벌(계획서 24-3b) — 두 보기는 같은 노드에 제 알림만 건다."""
|
|
shared = _read("A00_Common/design/design_shared.ts")
|
|
assert shared.count("createDesignProfile(") == 1
|
|
assert "side: drainageSide" in shared and "drainageSideTool(board)" in shared
|
|
b05 = _read("B05_Profile/B05_Profile_UI_Profile_Panel.ts")
|
|
b06 = _read("B06_Section/B06_Section_UI_Section_View_Profile.ts")
|
|
for source, view in ((b05, "profile"), (b06, "cross")):
|
|
assert "createDesignProfile(" not in source
|
|
assert "sharedProfile(shared)" in source
|
|
assert f'bindDesignView(shared, "{view}"' in source
|
|
|
|
|
|
def test_옛_B06_위쪽_종단이_남지_않음():
|
|
view = _read("B06_Section/B06_Section_UI_Section_View.ts")
|
|
assert "createSectionProfile(" in view
|
|
assert "drawLongitudinalPanel" not in view
|
|
assert "b06-section__panel" not in view
|
|
for gone in ("Draw", "Chart", "Panel"):
|
|
assert not (ROOT / f"B06_Section/B06_Section_UI_Section_View_{gone}.ts").exists()
|
|
|
|
|
|
def test_막기_규칙은_종단도_한_곳():
|
|
profile = _read("A00_Common/design/design_profile.ts")
|
|
assert profile.count("blocksMinCover(") == 1
|
|
# 판이 없는 보기도 관 목록을 넘겨 최소 흙덮기를 판정한다.
|
|
assert "setMinCoverPipes(" in profile
|
|
assert "setMinCoverPipes(" in _read("B06_Section/B06_Section_UI_Section_View_Profile.ts")
|
|
|
|
|
|
def test_크기_접기_키는_하나():
|
|
drag = _read("B05_Profile/B05_Profile_UI_Profile_Drag.ts")
|
|
assert 'stateKey("profile-height")' in drag
|
|
assert '"profile-collapsed"' in drag
|
|
assert '["section-panel-height", "profile-height"]' in drag # 옛 값 옮겨 받음
|
|
|
|
|
|
def test_초안은_등록부_칸으로_옮겨_받음(results):
|
|
assert results["adopted"] == {"station_offsets": {"20.000": 0.3}, "curve_radii": {}}
|
|
assert results["keysAfterAdopt"] == ["aislo:draft:alignment-draft:p-1:7"]
|
|
assert results["sameSlot"]["station_offsets"] == {"40.000": 0.1}
|
|
|
|
|
|
def test_되돌리기가_새_칸을_찍음(results):
|
|
assert results["beforeUndo"]["station_offsets"] == {"40.000": 0.2}
|
|
assert results["undone"] is True
|
|
assert results["afterUndo"]["station_offsets"] == {"40.000": 0.1}
|