- 카카오 지도 처음 한 번만 맞춤 · 고르기 · 끌기 뒤 중심 · 줌 그대로 - 공사지 강조색 · 기준점 경고색 · 거래처 성공색(테마 변수 · 밝음 · 어두움) - 거래처 · 기준점 상자 끌어 옮김(pos 저장) · [자동 정렬] Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LLCk2y5xE8YGVgjbTntWsY
107 lines
5.0 KiB
Python
107 lines
5.0 KiB
Python
"""PLAN 250(사용자 149 · 150 · 152) — 거리이정표 도로 구분 = 선 자리 · 모달 정리 · 폭 · 지도 높이."""
|
|
|
|
import json
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
from B08_Quantity.B08_Quantity_Milestone_Calc import compute_milestone, road_of # noqa: E402
|
|
|
|
IMPORTS = re.compile(r"^import[^;]*;\n", re.MULTILINE)
|
|
|
|
|
|
def _read(rel: str) -> str:
|
|
return (ROOT / rel).read_text(encoding="utf-8")
|
|
|
|
|
|
def _ts(expr: str):
|
|
src = IMPORTS.sub("", _read("B08_Quantity/B08_Quantity_Milestone_Calc.ts"))
|
|
out = subprocess.run(
|
|
["node", "--experimental-strip-types", "--no-warnings", "--input-type=module-typescript",
|
|
"-e", src + f"\nconsole.log(JSON.stringify({expr}));"],
|
|
capture_output=True, text=True, encoding="utf-8", timeout=60,
|
|
) # fmt: skip
|
|
assert out.returncode == 0, out.stderr
|
|
return json.loads(out.stdout)
|
|
|
|
|
|
def test_도로_구분_선_자리_짝():
|
|
cases = [
|
|
(r, k)
|
|
for r in (None, "2차포장", "1차포장", "포장", "비포장")
|
|
for k in ("via", "base", "direct", "mid")
|
|
]
|
|
py = [road_of(r, k) for r, k in cases]
|
|
assert py == _ts(f"{json.dumps(cases)}.map(([r, k]) => roadOf(r, k))")
|
|
assert road_of(None, "via") == "2차포장" and road_of("포장", "base") == "1차포장"
|
|
assert road_of("2차포장", "direct") == "포장" and road_of("비포장", "via") == "비포장"
|
|
|
|
|
|
def test_기준점_생기면_2차_1차_없으면_포장():
|
|
leg = lambda road, km: {"road": road, "km": km} # noqa: E731
|
|
route = {"id": "r", "name": "거창군청", "address": "", "via_base": True, "dir": None,
|
|
"legs": [leg(None, 23.8)], "rows": [{"item": "장비", "dest": "mid", "note": ""}]} # fmt: skip
|
|
data = {"site": {"mid_station_m": 800, "mid_road": "비포장"},
|
|
"base": {"enabled": True, "name": "병곡리", "address": "", "dir": None,
|
|
"legs": [leg(None, 0.6)]},
|
|
"routes": [route]} # fmt: skip
|
|
(a,) = compute_milestone(data, None)
|
|
assert (a["s2"], a["s1"], a["pv"], a["un"], a["total"]) == (23.8, 0.6, 0, 0.8, 25.2)
|
|
data["base"]["enabled"] = False
|
|
(b,) = compute_milestone(data, None)
|
|
assert (b["s2"], b["s1"], b["pv"], b["un"], b["total"]) == (0, 0, 23.8, 0.8, 24.6)
|
|
|
|
|
|
def test_모달_상자_하나_항목_하나_수정_글():
|
|
modal = _read("B08_Quantity/B08_Quantity_UI_Milestone_Modal.ts")
|
|
leg = _read("B08_Quantity/B08_Quantity_UI_Milestone_LegModal.ts")
|
|
assert '"+ 줄"' not in modal and "same.rows" not in modal
|
|
assert 'label: "고침"' not in modal + leg and modal.count('"수정"') >= 2
|
|
assert 'item.root.style.visibility = dest.root.style.visibility = k === "base"' in modal
|
|
|
|
|
|
def test_폭_전체_지도_높이_한_값():
|
|
css = _read("B08_Quantity/B08_Quantity_UI_Milestone.css")
|
|
block = css[css.index(".b08-milestone {") :]
|
|
assert "width: 100%;" in block[: block.index("}")]
|
|
assert ".b08-milestone > .ui-data-table .ui-data-table__table {\n width: 100%;" in css
|
|
assert css.count("height: 480px;") == 1 and ".b08-milestone__map {" in css
|
|
|
|
|
|
def test_153_지도_보기_유지_상자_색_끌어_옮김():
|
|
kmap = _read("B08_Quantity/B08_Quantity_UI_Milestone_KakaoMap.ts")
|
|
assert (
|
|
"let fitted = false;" in kmap and "map.panTo(" in kmap
|
|
) # 처음 한 번만 맞춤 · 그 뒤 줌 그대로
|
|
css = _read("B08_Quantity/B08_Quantity_UI_Milestone.css")
|
|
for kind, var in (
|
|
("is-site", "--color-accent"),
|
|
("is-base", "--color-warning"),
|
|
("is-route", "--color-success"),
|
|
):
|
|
block = css[css.index(f".b08-milestone__box.{kind} rect {{") :]
|
|
assert var in block[: block.index("}")], kind
|
|
ui = _read("B08_Quantity/B08_Quantity_UI_Milestone_Diagram.ts")
|
|
assert 'if (box.kind === "route" || box.kind === "base") dragBox(g, box, shift);' in ui
|
|
assert 'label: "자동 정렬"' in ui and "fresh.routes.forEach((r) => (r.pos = null));" in ui
|
|
|
|
|
|
def test_153_끌어_놓은_자리_레이아웃():
|
|
src = IMPORTS.sub("", _read("B08_Quantity/B08_Quantity_Milestone_Layout.ts"))
|
|
data = {"site": {"mid_station_m": None, "mid_road": "비포장"},
|
|
"base": {"enabled": True, "name": "기준", "address": "", "dir": "W", "legs": [], "pos": [500, -40]},
|
|
"routes": [{"id": "r", "name": "a", "address": "", "via_base": False, "dir": "N", "legs": [],
|
|
"rows": [], "pos": [-700, 300]}]} # fmt: skip
|
|
expr = f"layoutMilestone({json.dumps(data)}, {{}}, 0.5).boxes.filter((b) => b.id === 'base' || b.id === 'r').map((b) => [b.id, b.x, b.y])"
|
|
out = subprocess.run(
|
|
["node", "--experimental-strip-types", "--no-warnings", "--input-type=module-typescript",
|
|
"-e", src + f"\nconsole.log(JSON.stringify({expr}));"],
|
|
capture_output=True, text=True, encoding="utf-8", timeout=60,
|
|
) # fmt: skip
|
|
assert out.returncode == 0, out.stderr
|
|
assert sorted(json.loads(out.stdout)) == [["base", 500, -40], ["r", -700, 300]]
|