Merge remote-tracking branch 'origin/sub_laptop_3' into main_laptop_1
This commit is contained in:
@@ -9,6 +9,7 @@ const { makeLoader } = require("./helper_ts_stub_loader.cjs");
|
||||
const ROOT = path.join(__dirname, "..", "..");
|
||||
const B05 = path.join(ROOT, "B05_Profile");
|
||||
let handlers = null;
|
||||
let iconOpen = null; // 445-C1 아이콘 누름 흉내 — 정보 창을 열어야 `show` 가 불림
|
||||
const shows = [];
|
||||
const STUBS = {
|
||||
"./B05_Profile_UI_RouteEdit_Label": {
|
||||
@@ -18,6 +19,12 @@ const STUBS = {
|
||||
},
|
||||
centerDirectionOf: () => null,
|
||||
},
|
||||
"./B05_Profile_UI_RouteEdit_CurveIcon": {
|
||||
createCurveIcon: (_canvas, onOpen) => {
|
||||
iconOpen = onOpen;
|
||||
return { update: () => {}, destroy: () => {} };
|
||||
},
|
||||
},
|
||||
"@ui/ui_template_elements": { showToast: () => {} }, // 곡선 삭제 경고(430)
|
||||
};
|
||||
|
||||
@@ -118,6 +125,7 @@ function editor(snap) {
|
||||
const pick = (k) => {
|
||||
state.picked = k;
|
||||
made.sync();
|
||||
iconOpen(); // 아이콘 누름 = 열림(열린 채 다른 교각점 = 이어서 열림)
|
||||
};
|
||||
const lastShow = () => shows[shows.length - 1];
|
||||
return { state, status, handlers: () => handlers, drawn, arcOf, mc, pick, lastShow, markEdited };
|
||||
|
||||
@@ -17,6 +17,9 @@ const STUBS = {
|
||||
},
|
||||
centerDirectionOf: () => null,
|
||||
},
|
||||
"./B05_Profile_UI_RouteEdit_CurveIcon": {
|
||||
createCurveIcon: () => ({ update: () => {}, destroy: () => {} }), // 445-C1 근처 아이콘(화면 없음)
|
||||
},
|
||||
"@ui/ui_template_elements": { showToast: () => {} }, // 곡선 삭제 경고(430)
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
"""445-C1 B05 교각점 정보 = 근처 아이콘 — 규칙(`logic/B05_Profile_RouteEdit_CurveIcon.ts`)을 Node 로 돌려 판정 +
|
||||
배선 글 대조(`_CurveBar` 가 열림을 봄 · 닫기는 고름도 풂 · 아이콘은 부품 상자 유리 꼴).
|
||||
|
||||
./venv/Scripts/python.exe -m pytest resources/tester/test_445_curve_icon.py -q
|
||||
"""
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
B05 = ROOT / "B05_Profile"
|
||||
LOGIC = B05 / "logic" / "B05_Profile_RouteEdit_CurveIcon.ts"
|
||||
TS = ROOT / "config" / "node_modules" / "typescript"
|
||||
|
||||
DRIVER = r"""
|
||||
const fs = require("fs");
|
||||
const ts = require(process.argv[1]);
|
||||
const js = ts.transpileModule(fs.readFileSync(process.argv[2], "utf8"), {
|
||||
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
|
||||
}).outputText;
|
||||
const m = { exports: {} };
|
||||
new Function("exports", "module", js)(m.exports, m);
|
||||
const L = m.exports;
|
||||
console.log(JSON.stringify({
|
||||
near: L.NEAR_PX,
|
||||
nearIn: L.isNear(L.NEAR_PX, false),
|
||||
nearOut: L.isNear(L.NEAR_PX + 1, false),
|
||||
nearOnIcon: L.isNear(500, true),
|
||||
keepOpenOther: L.openAfterPick(true, 3),
|
||||
closedStaysClosed: L.openAfterPick(false, 3),
|
||||
releaseCloses: L.openAfterPick(true, -1),
|
||||
noPick: L.iconVisible(-1, false, true, false),
|
||||
picked_near: L.iconVisible(2, false, true, false),
|
||||
picked_far: L.iconVisible(2, false, false, false),
|
||||
picked_far_touch: L.iconVisible(2, false, false, true),
|
||||
open_near: L.iconVisible(2, true, true, false),
|
||||
}));
|
||||
"""
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def got() -> dict:
|
||||
run = subprocess.run( # noqa: S603 — 고정 실행 파일
|
||||
["node", "-e", DRIVER, str(TS), str(LOGIC)],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
timeout=60,
|
||||
)
|
||||
assert run.returncode == 0, run.stderr
|
||||
return json.loads(run.stdout)
|
||||
|
||||
|
||||
def test_근처_판정(got) -> None:
|
||||
assert got["near"] == 40
|
||||
assert got["nearIn"] is True and got["nearOut"] is False
|
||||
assert got["nearOnIcon"] is True # 아이콘 위는 멀어도 근처
|
||||
|
||||
|
||||
def test_창_열림_이어감(got) -> None:
|
||||
assert got["keepOpenOther"] is True # 열린 채 다른 교각점 = 열린 채
|
||||
assert got["closedStaysClosed"] is False # 닫힘 = 닫힌 채
|
||||
assert got["releaseCloses"] is False # 고름 풂 = 닫힘
|
||||
|
||||
|
||||
def test_아이콘_보임(got) -> None:
|
||||
assert got["noPick"] is False
|
||||
assert got["picked_near"] is True and got["picked_far"] is False
|
||||
assert got["picked_far_touch"] is True # 터치 = 고르면 늘 보임
|
||||
assert got["open_near"] is False # 창이 열리면 아이콘 숨김
|
||||
|
||||
|
||||
def test_배선_글() -> None:
|
||||
bar = (B05 / "B05_Profile_UI_RouteEdit_CurveBar.ts").read_text(encoding="utf-8")
|
||||
assert "openAfterPick" in bar and "icon.update(" in bar
|
||||
assert "onClose: () => params.onUnselect()" in bar # 닫기 = 창 닫고 고름도 풂
|
||||
# 닫힘이면 창을 숨기고 아이콘만 — 창 show 보다 앞
|
||||
assert bar.index("if (!open) {") < bar.index("label.show({")
|
||||
icon = (B05 / "B05_Profile_UI_RouteEdit_CurveIcon.ts").read_text(encoding="utf-8")
|
||||
assert 'variant: "glass"' in icon and "createIconButton" in icon # 부품 상자 유리 꼴
|
||||
assert "document.createElement" not in icon.split("export function")[1] # 날 요소 없음
|
||||
@@ -78,6 +78,7 @@ def test_상태():
|
||||
assert '.ui-icon-btn:is(:hover, [data-state="hover"]):not(:disabled)' in css
|
||||
assert '.ui-icon-btn:is(:active, [data-state="active"]):not(:disabled)' in css
|
||||
assert '.ui-icon-btn[aria-pressed="true"]' in css and ".ui-icon-btn:disabled" in css
|
||||
assert '.ui-icon-btn--glass:is(:hover, [data-state="hover"]):not(:disabled)' in css # 445-C1
|
||||
src = _text(UI / "ui_template_button.ts")
|
||||
assert 'title: opts.title, "aria-label": opts.title' in src
|
||||
|
||||
|
||||
Reference in New Issue
Block a user