Files
Aislo/resources/tester/test_m02_df_panel.py
T
eomsangdonandClaude Opus 5.5 3c78322350 feat(M02): 오른쪽 흐름도 패널 M02_DF_Panel.ts — mountFlowPanel(host, opts) → set · destroy · expand(PLAN 36-3)
- 세로: 머리(제목 · 크게 보기 · 접기) · 실행 취소 · 다이어그램 · 상세 내용 · 원가 · 검증(접기) · 저장 단추 없음
- 왼쪽 가장자리 끌기 · 화살표 키 → onResize(px) · 마지막 너비 localStorage · 접기 = 얇은 띠 「흐름도 ▸」
- 크게 보기 = 같은 판을 화면 전체로 옮겨 끼움 · 닫으면 패널로(고친 것 그대로) · Esc · Ctrl+Z
- 좁은 패널은 저절로 맞춤 바닥 0.5(한눈에) · 크게 보기는 0.9 — 다이어그램 opts.fitMin
- 시험 test_m02_df_panel.py 2 통과 · typecheck · DataFlow 전부 검사 초록

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ly2oHAaTDYRjcniAmHR81z
2026-10-01 23:30:18 +09:00

84 lines
2.8 KiB
Python

"""오른쪽 흐름도 패널(`M02_DF_Panel.ts`) 순수 부분 — 끌어서 정한 너비 · 저장해 둔 너비.
화면 TS 를 그 자리에서 트랜스파일해 node 로 돌림(부품 · 판은 빈 흉내 · 순수 함수만).
"""
import json
import shutil
import subprocess
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[2]
SOURCE = ROOT / "M02_MasterTemplete" / "DataFlow" / "M02_DF_Panel.ts"
RUNNER = r"""
const fs = require("fs");
const path = require("path");
const [root, file] = process.argv.slice(1);
const ts = require(path.join(root, "config", "node_modules", "typescript"));
const js = ts.transpileModule(fs.readFileSync(file, "utf8"), {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020 },
}).outputText;
const stub = new Proxy({}, { get: () => () => undefined });
const box = { exports: {} };
new Function("exports", "module", "require", js)(box.exports, box, () => stub);
const m = box.exports;
const jobs = JSON.parse(fs.readFileSync(0, "utf8"));
const out = jobs.map((j) =>
j.op === "drag" ? m.dragWidth(j.start, j.startX, j.x, j.viewport)
: j.op === "stored" ? m.storedWidth(j.raw)
: j.op === "consts" ? [m.PANEL_MIN, m.STRIP_WIDTH]
: null,
);
process.stdout.write(JSON.stringify(out));
"""
def run(jobs: list[dict]) -> list:
if shutil.which("node") is None:
pytest.skip("node 가 없음")
done = subprocess.run(
["node", "-e", RUNNER, str(ROOT), str(SOURCE)],
input=json.dumps(jobs, ensure_ascii=False),
capture_output=True,
text=True,
encoding="utf-8",
check=True,
)
return json.loads(done.stdout)
def test_왼쪽_가장자리_끌기_너비():
[consts, wider, narrower, floor, ceil] = run(
[
{"op": "consts"},
# 왼쪽으로 100 끌면 넓어짐
{"op": "drag", "start": 480, "startX": 1000, "x": 900, "viewport": 1600},
# 오른쪽으로 끌면 좁아짐
{"op": "drag", "start": 480, "startX": 1000, "x": 1060, "viewport": 1600},
# 너무 좁게 — 가장 작은 너비에서 멈춤
{"op": "drag", "start": 480, "startX": 1000, "x": 1400, "viewport": 1600},
# 너무 넓게 — 화면의 85% 에서 멈춤
{"op": "drag", "start": 480, "startX": 1000, "x": -2000, "viewport": 1600},
]
)
min_width, strip = consts
assert (min_width, strip) == (320, 40)
assert wider == 580 and narrower == 420
assert floor == min_width and ceil == 1360
def test_저장해_둔_너비():
got = run(
[
{"op": "stored", "raw": "640"},
{"op": "stored", "raw": "640.6"},
{"op": "stored", "raw": None},
{"op": "stored", "raw": "abc"},
{"op": "stored", "raw": "100"},
]
)
assert got == [640, 641, None, None, None]