feat(B08): 거리이정표 상자 모달 제목 · 상자 안 장소 그림(254-3)
- 상자 누름 모달 제목 = 「거래처 — 이름」 · 「기준점 — 이름」(표 머리 글 항목 정보 없음) - 장소 그림(256-1 place_images) = 상자 글 아래 132 × 88 · 그림 없으면 자리 없음 · 키 바뀔 때만 다시 받음 - 시험 = test_254_3 새로 · 244_6 · 244_10 node 입력 = stdin(명령 줄 길이) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STqEqztUthVFBmEP18wBSz
This commit is contained in:
@@ -59,9 +59,10 @@ console.log(JSON.stringify({ injected, hint: hint.textContent, boxHidden: box.hi
|
||||
"""
|
||||
)
|
||||
src = IMPORTS.sub("", _read(LAYOUT)) + script
|
||||
# 254 — 글이 길어 명령 줄(Windows 32767자)을 넘지 않게 stdin 으로 넘김
|
||||
result = subprocess.run(
|
||||
["node", "--experimental-strip-types", "--no-warnings",
|
||||
"--input-type=module-typescript", "-e", src],
|
||||
"--input-type=module-typescript", "-"], input=src,
|
||||
capture_output=True, text=True, encoding="utf-8", timeout=60,
|
||||
) # fmt: skip
|
||||
assert result.returncode == 0, result.stderr
|
||||
|
||||
@@ -27,9 +27,10 @@ def _node(script):
|
||||
IMPORTS.sub("", _read(rel))
|
||||
for rel in ("A00_Common/b_svg_zoom_pan.ts", "B08_Quantity/B08_Quantity_Milestone_Layout.ts")
|
||||
)
|
||||
# 254 — 글이 길어 명령 줄(Windows 32767자)을 넘지 않게 stdin 으로 넘김
|
||||
result = subprocess.run(
|
||||
["node", "--experimental-strip-types", "--no-warnings",
|
||||
"--input-type=module-typescript", "-e", src + "\n" + script],
|
||||
"--input-type=module-typescript", "-"], input=src + "\n" + script,
|
||||
capture_output=True, text=True, encoding="utf-8", timeout=60,
|
||||
) # fmt: skip
|
||||
assert result.returncode == 0, result.stderr
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
"""254-3 B08 거리이정표 상자 모달 제목 · 장소 그림(사용자 162-6 · 8).
|
||||
|
||||
① 상자 누름 모달 제목 = 「거래처 — 이름」 · 「기준점 — 이름」(표 머리 글 「항목 정보」 없음)
|
||||
② 장소 그림(256-1 `place_images`) = 상자 안 글 아래 작게 · 그림 없으면 자리 없음(상자 높이 그대로)
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
IMPORTS = re.compile(r"^import[^;]*;\n", re.MULTILINE)
|
||||
B08 = "B08_Quantity/B08_Quantity_"
|
||||
|
||||
|
||||
def _read(rel):
|
||||
return (ROOT / rel).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def _node(expr):
|
||||
src = IMPORTS.sub("", _read(B08 + "Milestone_Layout.ts"))
|
||||
result = subprocess.run(
|
||||
["node", "--experimental-strip-types", "--no-warnings",
|
||||
"--input-type=module-typescript", "-"],
|
||||
input=src + f"\nconsole.log(JSON.stringify({expr}));",
|
||||
capture_output=True, text=True, encoding="utf-8", timeout=60,
|
||||
) # fmt: skip
|
||||
assert result.returncode == 0, result.stderr
|
||||
return json.loads(result.stdout)
|
||||
|
||||
|
||||
DATA = {
|
||||
"site": {"mid_station_m": None, "mid_road": "비포장"},
|
||||
"bases": [{"id": "B", "name": "병곡리", "address": "거창읍", "dir": None, "to": "site",
|
||||
"legs": [{"road": None, "km": 0.6}], "linked": True}],
|
||||
"routes": [
|
||||
{"id": "g", "name": "거창군청", "address": "거창읍", "dir": "N", "to": "B",
|
||||
"legs": [{"road": None, "km": 23.8}],
|
||||
"rows": [{"item": "장비", "dest": "start", "note": ""}]},
|
||||
{"id": "k", "name": "김천역", "address": "", "dir": "E", "to": "site",
|
||||
"legs": [], "rows": [{"item": "", "dest": "start", "note": ""}]},
|
||||
],
|
||||
} # fmt: skip
|
||||
|
||||
|
||||
def test_장소_그림_상자_안_글_아래():
|
||||
d = json.dumps(DATA, ensure_ascii=False)
|
||||
plain, with_pic = _node(
|
||||
f"[layoutMilestone({d}, null, 0.5), layoutMilestone({d}, null, 0.5, new Set(['B', 'g']))]"
|
||||
)
|
||||
a = {b["id"]: b for b in plain["boxes"]}
|
||||
b = {b["id"]: b for b in with_pic["boxes"]}
|
||||
pic = _node("PIC")
|
||||
assert pic == {"w": 132, "h": 88} # 서버 480 × 320 과 같은 3:2 · 상자 안쪽 폭
|
||||
# 그림 없음 = 자리 없음(높이 그대로 · pic 없음)
|
||||
assert all("pic" not in box for box in a.values())
|
||||
assert "pic" not in b["k"] and b["k"]["h"] == a["k"]["h"]
|
||||
for bid in ("B", "g"):
|
||||
box, before = b[bid], a[bid]
|
||||
assert box["h"] == before["h"] + pic["h"] + 8 # 그림 + 아래 여백만큼 늘림
|
||||
p = box["pic"]
|
||||
# 안쪽 여백 안 · 글 아래(글 자리 = 그림 위 높이 = 그림 없을 때 높이)
|
||||
assert p["x"] == box["x"] + 8 and p["x"] + p["w"] == box["x"] + box["w"] - 8
|
||||
assert p["y"] - box["y"] == before["h"] and p["y"] + p["h"] == box["y"] + box["h"] - 8
|
||||
|
||||
|
||||
def test_모달_제목_화면_그림():
|
||||
modal = _read(B08 + "UI_Milestone_Modal.ts")
|
||||
assert "`거래처 — ${route!.name" in modal and "`기준점 — ${base.name" in modal
|
||||
assert "항목 정보 —" not in modal
|
||||
ui = _read(B08 + "UI_Milestone_Diagram.ts")
|
||||
assert "placeImageBlobUrl(projectId, id)" in ui and "placeImageKey(id)" in ui
|
||||
assert 'pic.setAttribute("href", url)' in ui and "() => pic.remove()" in ui
|
||||
assert "if (!got || got.key !== key)" in ui # 키(이름#시각) 바뀔 때만 다시 받음
|
||||
assert "const th = box.pic ? box.pic.y - box.y : box.h;" in ui # 글 = 그림 위 가운데
|
||||
css = _read(B08 + "UI_Milestone.css")
|
||||
pic = css[css.index(".b08-milestone__pic {") :]
|
||||
assert "pointer-events: none;" in pic[: pic.index("}")] # 누름 · 끌기 = 상자 몫
|
||||
for name in ("Milestone_Layout.ts", "UI_Milestone_Diagram.ts", "UI_Milestone_Modal.ts"):
|
||||
assert len(_read(B08 + name).splitlines()) <= 700, name
|
||||
Reference in New Issue
Block a user