- 10-14 판 자리(판 좌상단)로 되살리며 축 띠(z5 · 불투명) 아래로 들어가 안 보이던 것 · 누름은 축이 통과시켜 시험에선 안 잡힘 - 화면 확인(밝음 · 어두움) · test_354_1 에 z6 판정 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Se7ytqbohmBQnfYpwYFnYf
143 lines
6.5 KiB
Python
143 lines
6.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""354-1 → 392-2 유토곡선 판 = 10-14 판(9edaec82e) 되살림(요구 242-10).
|
|
|
|
- 유토곡선 = 종단 칸(bodyWrap) 바닥 덮는 판(absolute · z5) · 자기 판(종단 열 아래 칸) 지움.
|
|
- 메인 판 끌기 = 종단 · 유토 · 표 세 영역 같은 비율 · 놓을 때 유토 · 표 높이 확정(commitHeight).
|
|
- 유토 손잡이 = 판 위 경계 밖(bottom = 판 높이) · 표 손잡이와 ±44 px 나란히 · 접기 = 숨김.
|
|
- 표 판 = 열린 유토 위에 쌓임(setBottomOffset).
|
|
- 남김 = 유토 [창 분할](판 안 좌상단 = 펼친 때만 보임) · 367-1 늘 전체 맞춤 · 325-2 뿌리 안 판정.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import re
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
ROOT = Path(HERE).parents[1]
|
|
|
|
|
|
def read(rel: str) -> str:
|
|
return (ROOT / rel).read_text(encoding="utf-8")
|
|
|
|
|
|
def css_block(css: str, selector: str) -> str:
|
|
m = re.search(r"(?:^|\n)" + re.escape(selector) + r" \{([^}]*)\}", css)
|
|
assert m, selector
|
|
return m.group(1)
|
|
|
|
|
|
# 진짜 높이 나눔(createHeightCascade) — 메인 끌기 중 세 영역 비례
|
|
NODE = r"""
|
|
const path = require("path"), fs = require("fs");
|
|
const root = process.argv[1];
|
|
const ts = require(path.join(root, "config", "node_modules", "typescript"));
|
|
const src = fs.readFileSync(path.join(root, "B05_Profile", "B05_Profile_UI_Profile_Heights.ts"), "utf8");
|
|
const js = ts.transpileModule(src, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 } }).outputText;
|
|
const exp = {};
|
|
new Function("exports", "require", "window", js)(exp, (id) =>
|
|
id.includes("MassHaul") ? { MASSHAUL_MIN_HEIGHT: 160 }
|
|
: id.includes("TableOverlay") ? { TABLE_OVERLAY_MIN_HEIGHT: 120 }
|
|
: id.includes("Structures_Marks") ? { STRUCTURE_LANE_HEIGHT_PX: 40 } : { frameOf: () => 0 },
|
|
{ innerHeight: 900 });
|
|
const el = () => { const n = { hidden: false, style: { height: "" }, parent: null };
|
|
n.append = (k) => ((k.parent = n), k);
|
|
n.contains = (o) => { for (let a = o; a; a = a.parent) if (a === n) return true; return false; };
|
|
return n; };
|
|
function run(bodyH) {
|
|
const rootEl = el(); rootEl.offsetHeight = bodyH + 100;
|
|
const body = rootEl.append(el()); body.clientHeight = bodyH;
|
|
const mass = body.append(el()), table = body.append(el());
|
|
const seen = { handle: 0, offset: null };
|
|
const c = exp.createHeightCascade({
|
|
root: rootEl, body,
|
|
massHaul: { overlay: mass, desiredHeight: () => 200, syncHandle: () => seen.handle++ },
|
|
tableOverlay: { overlay: table, isOpen: () => true, desiredHeight: () => 200,
|
|
setBottomOffset: (v) => (seen.offset = v) },
|
|
isMainDragging: () => true, isSubDragging: () => false,
|
|
// 끌기 시작 = 종단 400 · 유토 200 · 표 200
|
|
mainDragRef: () => ({ chart: 400, mass: 200, table: 200 }),
|
|
isMainDragCooldown: () => true, hasDetail: () => true,
|
|
});
|
|
const { chartHeight } = c.apply(false);
|
|
return { chart: chartHeight, mass: mass.style.height, table: table.style.height, ...seen };
|
|
}
|
|
// 본문 − 알약 40 − 손잡이 띠 13 = 나눌 자리 · 800 → 1.0 배 · 1200 → 1.5 배
|
|
process.stdout.write(JSON.stringify({ same: run(853), grow: run(1253) }));
|
|
"""
|
|
|
|
|
|
def test_메인_끌기_세_영역_같은_비율():
|
|
res = subprocess.run(
|
|
["node", "-e", NODE, str(ROOT)],
|
|
capture_output=True,
|
|
text=True,
|
|
encoding="utf-8",
|
|
check=True,
|
|
)
|
|
out = json.loads(res.stdout)
|
|
assert out["same"] == {
|
|
"chart": 400,
|
|
"mass": "200px",
|
|
"table": "200px",
|
|
"handle": 1,
|
|
"offset": 200,
|
|
}
|
|
# 1.5 배 — 셋 다 같은 비율 · 표는 유토 위에 쌓임(바닥 간격 = 유토 높이)
|
|
assert out["grow"] == {
|
|
"chart": 600,
|
|
"mass": "300px",
|
|
"table": "300px",
|
|
"handle": 1,
|
|
"offset": 300,
|
|
}
|
|
|
|
|
|
def test_놓을_때_높이_확정_뿌리_안_판정():
|
|
drag = read("B05_Profile/B05_Profile_UI_Profile_Drag.ts")
|
|
assert "if (massDocked()) massHaul.commitHeight(massHaul.overlay.offsetHeight);" in drag
|
|
assert "if (tableOverlay.isOpen()) tableOverlay.commitHeight(" in drag
|
|
# 325-2 「열림 && 뿌리 안」 한 곳 · 하한에 유토 최소
|
|
assert drag.count("massHaul.overlay.hidden") == 1
|
|
assert "root.contains(massHaul.overlay)" in drag
|
|
assert "const massMin = massDocked() ? MASSHAUL_MIN_HEIGHT : 0;" in drag
|
|
heights = read("B05_Profile/B05_Profile_UI_Profile_Heights.ts")
|
|
assert '{ key: "mass", ref: Math.max(1, dragRef.mass), min: MASSHAUL_MIN_HEIGHT }' in heights
|
|
|
|
|
|
def test_종단_칸_바닥_덮는_판():
|
|
overlays = read("A00_Common/design/design_profile_overlays.ts")
|
|
assert "bodyWrap.append(massHaul.overlay, massHaul.handle);" in overlays
|
|
assert "b05-route-profile__column" not in overlays
|
|
assert "massHaul.attachScrollSync" not in overlays # 367-1 측점 연계 없앰
|
|
profile = read("A00_Common/design/design_profile.ts")
|
|
assert "content.append(bodyWrap);" in profile
|
|
assert sum(1 for _ in profile.splitlines()) <= 700
|
|
css = read("B05_Profile/B05_Profile_UI_Style_MassHaul.css")
|
|
panel = css_block(css, ".b05-profile__masshaul-overlay")
|
|
assert "position: absolute;" in panel and "bottom: 0;" in panel and "z-index: 5;" in panel
|
|
assert "masshaul-head" not in css and "is-collapsed:not(.is-popout)" not in css
|
|
|
|
|
|
def test_손잡이_자리_접기_숨김():
|
|
css = read("B05_Profile/B05_Profile_UI_Style_MassHaul.css")
|
|
assert "left: calc(50% + 44px);" in css_block(css, ".b05-profile__masshaul-handle")
|
|
assert "left: calc(50% - 44px);" in css_block(css, ".b05-profile__table-handle")
|
|
mass = read("B05_Profile/B05_Profile_UI_Profile_MassHaul.ts")
|
|
# 손잡이 = 판 위 경계 밖 · 접으면 바닥 · 접기 = 판 숨김
|
|
assert 'handle.style.bottom = open ? `${overlay.offsetHeight}px` : "0px";' in mass
|
|
assert "overlay.hidden = !open;" in mass and "overlay.hidden = !next;" in mass
|
|
table = read("B05_Profile/B05_Profile_UI_Profile_TableOverlay.ts")
|
|
assert "overlay.style.bottom = `${bottomOffset}px`;" in table
|
|
|
|
|
|
def test_창_분할_판_좌상단():
|
|
popout = read("A00_Common/design/design_profile_popout.ts")
|
|
assert "massOverlay.append(button);" in popout
|
|
assert "home: () => massHandle.before(massOverlay)," in popout
|
|
page = read("A00_Common/design/design_page.css")
|
|
button = css_block(page, ".b05-profile__masshaul-overlay > .b05-subpanel__popout")
|
|
# 고정 Y축(z5) 위 — 아래면 단추가 축 띠에 가려짐
|
|
assert "position: absolute;" in button and "z-index: 6;" in button
|