- B05_Profile_UI_RouteEdit_StructureMarks · B05_Profile_UI_RouteEdit_Keys 의 창 keydown · keyup · blur 듣개를 listenWhileAlive 로 · 다음 키 누름 때만 떨어지던 detach 걷음 - 시험: test_298_3_page_dispose 두 칸 더함 · test_383_2 · helper_399 가 @ui 듣기 틀을 읽음 - 확인: 키 누름 없이 [저장] 다섯 번 GC 뒤 힙 39 → 123 → 205 → 205 → 206 → 206 MB(둘째부터 평탄) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
2.7 KiB
Python
79 lines
2.7 KiB
Python
"""298-3 노선 [저장] 뒤 옛 페이지 풀림 — 페이지를 다시 세워도 창 · 문서 듣개 수 그대로 · 코리도 캐시 한 칸.
|
|
|
|
./venv/Scripts/python.exe -m pytest resources/tester/test_298_3_page_dispose.py -q
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
HELPER = Path(__file__).resolve().parent / "helper_298_3_page_dispose.cjs"
|
|
|
|
|
|
def _read(rel: str) -> str:
|
|
return (ROOT / rel).read_text(encoding="utf-8")
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def out() -> dict:
|
|
run = subprocess.run( # noqa: S603 — 고정 실행 파일
|
|
["node", "--expose-gc", str(HELPER)], capture_output=True, text=True, encoding="utf-8"
|
|
)
|
|
assert run.returncode == 0, run.stderr
|
|
return json.loads(run.stdout)
|
|
|
|
|
|
def test_다시_세워도_창_듣개_수_그대로(out) -> None:
|
|
assert (
|
|
out["afterFirst"]["window"] == 5
|
|
) # beforeunload · pointermove · pointerup · pointercancel · resize
|
|
assert out["afterFive"] == out["afterFirst"]
|
|
|
|
|
|
def test_옛_페이지_풀림_지금_페이지는_들음(out) -> None:
|
|
assert out["oldAlive"] == 0
|
|
assert out["liveAlive"] is True
|
|
assert out["resizeSettles"] == 1 # 살아 있는 패널 하나만 다시 앉힘
|
|
assert out["unloadBlocked"] is False and out["guardSet"] is True
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("rel", "types"),
|
|
[
|
|
("A00_Common/design/design_leave.ts", "beforeunload"),
|
|
("ui_template/ui_template_overlay_drag.ts", "pointermove|pointerup|pointercancel|resize"),
|
|
(
|
|
"ui_template/ui_template_side_panels.ts",
|
|
"scroll|resize",
|
|
), # 끌기 동안 pointer 듣기는 끝에 뗌
|
|
("B05_Profile/B05_Profile_UI_Panel_Settings.ts", "pointerup|keyup"),
|
|
("B05_Profile/B05_Profile_UI_RouteEdit_StructureMarks.ts", "keydown|keyup|blur"),
|
|
("B05_Profile/B05_Profile_UI_RouteEdit_Keys.ts", "keydown|keyup|blur"),
|
|
],
|
|
)
|
|
def test_전역_듣기는_노드_수명으로만(rel: str, types: str) -> None:
|
|
code = _read(rel)
|
|
assert not re.search(rf'\b(window|document)\.addEventListener\(\s*"({types})"', code)
|
|
assert "listenWhileAlive(" in code
|
|
|
|
|
|
def test_옆_패널_크기_감시는_노드를_안_붙듦() -> None:
|
|
side = _read("ui_template/ui_template_side_panels.ts")
|
|
assert "new ResizeObserver(() => ref.deref()?.())" in side
|
|
assert "const ref = new WeakRef(place);" in side
|
|
|
|
|
|
def test_코리도_캐시는_지금_노선_한_칸() -> None:
|
|
code = _read("B05_Profile/B05_Profile_UI_Corridor.ts")
|
|
assert (
|
|
"function remember(key: string, entry: CacheEntry): void {\n cache.clear();\n cache.set(key, entry);\n}"
|
|
in code
|
|
)
|
|
assert code.count("cache.set(") == 1
|