feat: Windows v1.1.1 — 修复与改进(DSH 工作区归档)
This commit is contained in:
1 parent
4a5d676c7b
commit
e6880efdc6
21 files changed
+807
-106
No files matched your search
@@ -0,0 +1,119 @@
|
||||
"""自动验证「环境准备」窗口的检测 → 确认 → 放行 流程(不需要人工点按钮)。
|
||||
|
||||
验证点:
|
||||
1. 所有项最终都能检测完(不会卡在「检测中…」)
|
||||
2. 全部就绪时,「进入程序」按钮变为可用
|
||||
3. 调用 _on_confirm 后 proceeded=True(main() 才会继续启动服务)
|
||||
4. 关闭窗口(_on_close)时 proceeded=False(main() 应当退出)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
import tkinter as tk # noqa: E402
|
||||
|
||||
from core.setup_window import SetupWindow # noqa: E402
|
||||
|
||||
FAILURES: list[str] = []
|
||||
CALLBACK_ERRORS: list[str] = []
|
||||
|
||||
|
||||
def check(name: str, ok: bool, detail: str = "") -> None:
|
||||
print(f" [{'PASS' if ok else 'FAIL'}] {name}" + (f" — {detail}" if detail else ""))
|
||||
if not ok:
|
||||
FAILURES.append(name)
|
||||
|
||||
|
||||
def pump(root: tk.Tk, seconds: float) -> None:
|
||||
"""手动驱动 tkinter 事件循环(不进入 mainloop,便于断言)。"""
|
||||
deadline = time.monotonic() + seconds
|
||||
while time.monotonic() < deadline:
|
||||
try:
|
||||
root.update()
|
||||
except tk.TclError as exc:
|
||||
print(f" [pump] TclError 中断:{exc}")
|
||||
return
|
||||
time.sleep(0.02)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
root = tk.Tk()
|
||||
|
||||
def _on_cb_error(exc_type, exc_value, exc_tb) -> None: # Tk 回调里的异常
|
||||
text = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
|
||||
CALLBACK_ERRORS.append(text)
|
||||
print(f" [回调异常] {exc_value}")
|
||||
|
||||
root.report_callback_exception = _on_cb_error
|
||||
|
||||
win = SetupWindow(root, title="自检窗口")
|
||||
# Apple 驱动检测要做 27015 协议往返,留足时间
|
||||
pump(root, 25.0)
|
||||
|
||||
print(" 各项状态:")
|
||||
for item in win.items:
|
||||
st = win.state[item.key]
|
||||
print(f" {item.key:16s} required={item.required} ok={st.get('ok')} "
|
||||
f"busy={st.get('busy')} detail={str(st.get('detail'))[:46]}")
|
||||
|
||||
try:
|
||||
exists = bool(root.winfo_exists())
|
||||
except tk.TclError as exc:
|
||||
exists = False
|
||||
print(f" 窗口已不可用:{exc}")
|
||||
print(f" 窗口存在:{exists} proceeded={win.proceeded}")
|
||||
check("窗口在检测期间没有被意外销毁", exists)
|
||||
check("Tk 回调没有抛异常", not CALLBACK_ERRORS,
|
||||
f"{len(CALLBACK_ERRORS)} 个" if CALLBACK_ERRORS else "")
|
||||
|
||||
stuck = [i.key for i in win.items
|
||||
if win.state[i.key].get("ok") is None and not win.state[i.key].get("busy")]
|
||||
check("没有卡在「检测中…」的项", not stuck, str(stuck))
|
||||
|
||||
required = [i for i in win.items if i.required]
|
||||
pending = [i.key for i in required if win.state[i.key].get("ok") is not True]
|
||||
check("必需项全部就绪(本机环境)", not pending, str(pending))
|
||||
|
||||
try:
|
||||
enabled = bool(win.confirm_button.instate(["!disabled"]))
|
||||
detail = f"state={win.confirm_button.state()}"
|
||||
except tk.TclError as exc:
|
||||
enabled, detail = False, f"控件已失效:{exc}"
|
||||
check("「进入程序」按钮可用", enabled, detail)
|
||||
|
||||
# 模拟点击「进入程序」
|
||||
win._on_confirm()
|
||||
check("点击后 proceeded=True", win.proceeded is True, f"proceeded={win.proceeded}")
|
||||
try:
|
||||
root.destroy()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 再测「关闭窗口」分支
|
||||
root2 = tk.Tk()
|
||||
win2 = SetupWindow(root2, title="自检窗口2")
|
||||
pump(root2, 1.0)
|
||||
win2._on_close()
|
||||
check("关闭窗口时 proceeded=False", win2.proceeded is False,
|
||||
f"proceeded={win2.proceeded}")
|
||||
try:
|
||||
root2.destroy()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
print()
|
||||
if FAILURES:
|
||||
print(f"失败 {len(FAILURES)} 项:{FAILURES}")
|
||||
return 1
|
||||
print("全部通过")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user