- 왼쪽 「실무문서」 칸(Practice.ts) · 일위대가 가져오기 「실무문서」 탭 · 복사 원본 고르기 · 낱 CSS · locale 열쇠 걷음 - 서버 `from_layer=practice`(_copy_practice) · `DELETE /api/m02/practice`(drop_practice) · 조합 목록 · 키 하나 읽기 길 걷음 · 조합 길 시스템 관리자 문 걷음(담을 로직 읽기는 그대로) - 옛 마스터 조합 파일 `일위대가조합.json`(UA 37) = 쓰는 곳 있음(구조물집계표 일위대가 칸 · labor 본뜬키 · 프로젝트 초기값 사본 · 불러오기 맞춤 씨앗) → 파일 · 읽기 길 유지 · 지우지 않음 - 낡은 시험: test_m02_practice 지움(화면 · 길 없음) · 조합 길 읽던 시험(combo · combo_inputs · combo_layers)은 저장소 함수로 · 실무문서 복사 시험(labor_copy · pair_copy) 줄 지움 · 탭 · 차례 단정(layer_screen · structure_options · structure_panel · 720 · precombo_scope · ui_loading) 고침 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
84 lines
3.7 KiB
Python
84 lines
3.7 KiB
Python
"""컨테이너 안 「불러오는 중」(PLAN 30-6 · `ui_template_loading.ts`) — 0.3초 · 실패 글 · M02 자리.
|
|
|
|
① `delayedShow` 를 Node 로 가짜 시계로 돌림 — 0.3초 전에 끝나면 안 보임(깜빡임 없음) · 넘으면 보이고
|
|
끝나면 걷힘 · 끝낸 뒤 시계가 와도 안 보임.
|
|
② 실패 자리 = 까닭 글(「불러오지 못함 — 까닭」) + [새로고침] · 화면 전체 잠금 안 씀.
|
|
③ M02 나무 · 상세(표 · 도면) · 조합 목록 · 조합 상세 · 항목 카드가 이 부품을 씀.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
LOADING = ROOT / "ui_template" / "ui_template_loading.ts"
|
|
M02 = ROOT / "M02_MasterTemplete"
|
|
|
|
|
|
def _text(path: Path) -> str:
|
|
return path.read_text(encoding="utf-8")
|
|
|
|
|
|
@pytest.mark.skipif(shutil.which("node") is None, reason="node 가 없음")
|
|
def test_0점3초_넘을_때만_보임():
|
|
found = re.search(r"^export function delayedShow[\s\S]*?^}", _text(LOADING), re.M)
|
|
assert found, "delayedShow 를 못 찾음"
|
|
script = (
|
|
"const LOADING_DELAY_MS = 300;\n"
|
|
+ found.group(0).replace("export ", "")
|
|
+ """
|
|
let now = 0; const jobs = [];
|
|
const timer = {
|
|
set: (fn, ms) => { jobs.push({ at: now + ms, fn, live: true }); return jobs.length - 1; },
|
|
clear: (id) => { if (jobs[id]) jobs[id].live = false; },
|
|
};
|
|
const tick = (ms) => {
|
|
now += ms;
|
|
for (const j of jobs) if (j.live && j.at <= now) { j.live = false; j.fn(); }
|
|
};
|
|
const log = [];
|
|
const on = (n) => () => log.push(n + ":show"); const off = (n) => () => log.push(n + ":hide");
|
|
const fast = delayedShow(on("fast"), off("fast"), undefined, timer);
|
|
tick(200); fast(); tick(500);
|
|
const slow = delayedShow(on("slow"), off("slow"), undefined, timer);
|
|
tick(299); log.push("299"); tick(1); slow(); tick(500);
|
|
console.log(JSON.stringify(log));
|
|
"""
|
|
)
|
|
result = subprocess.run(
|
|
["node", "--experimental-strip-types", "--no-warnings",
|
|
"--input-type=module-typescript", "-e", script],
|
|
capture_output=True, text=True, encoding="utf-8", timeout=60,
|
|
) # fmt: skip
|
|
assert result.returncode == 0, result.stderr
|
|
assert json.loads(result.stdout) == ["299", "slow:show", "slow:hide"]
|
|
|
|
|
|
def test_실패_글과_다시_불러오기_M02_자리():
|
|
src = _text(LOADING)
|
|
assert 'reason ? `${t("Common_Load_Failed")} — ${reason}` : t("Common_Load_Failed")' in src
|
|
assert 'createButton({ label: t("Common_Reload")' in src and 'role: "alert"' in src
|
|
assert "showLoadingOverlay()" not in src # 칸 안만(화면 전체 잠금 안 부름)
|
|
# 브라우저 setTimeout 을 객체 메서드로 부르면 Illegal invocation — 감싼 기본값(ORCA 흠)
|
|
assert "set: (fn, ms) => setTimeout(fn, ms)," in src
|
|
assert "clear: (id) => clearTimeout(id)," in src
|
|
locale = _text(ROOT / "ui_template" / "ui_template_locale_common.ts")
|
|
assert 'Common_Load_Failed: ["불러오지 못함"' in locale
|
|
assert 'Common_Reload: ["새로고침"' in locale
|
|
tree = _text(M02 / "M02_MasterTemplete_TreePanel.ts")
|
|
assert "const stop = showLoading(body);" in tree
|
|
assert "loadingError(why(error), () => void refresh())" in tree
|
|
main = _text(M02 / "M02_MasterTemplete_UI_Main.ts")
|
|
assert "const stop = showLoading(host);" in main
|
|
assert "loadingError(why, () => void open(next))" in main
|
|
cards = _text(M02 / "M02_MasterTemplete_ItemCards.ts")
|
|
# 일위대가 카드는 뺌 — 몸(Labor_View)을 덮었다 지우면 빈 카드(40 D1)
|
|
assert "cards.filter((c) => c !== laborCard).map((c) => c.shell.loading())" in cards
|
|
assert "loading: () => showLoading(host)," in _text(M02 / "M02_MasterTemplete_CardShell.ts")
|