148 lines
5.4 KiB
Python
148 lines
5.4 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""「检测引擎」卡片冒烟测试:offscreen 实例化 DashboardPage,
|
||
验证初始状态、信号契约、radio 置灰联动;并轻量验证
|
||
MainWindow 的设置加载校验与合并保存逻辑。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
import os
|
||
import sys
|
||
|
||
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
|
||
sys.argv = [sys.argv[0], "--qt-smoke-test"]
|
||
|
||
from PySide6.QtWidgets import QApplication
|
||
|
||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||
|
||
import wechat_gui_qt as gui
|
||
|
||
FAILED = []
|
||
|
||
|
||
def check(name: str, cond: bool, detail: str = "") -> None:
|
||
tag = "PASS" if cond else "FAIL"
|
||
print(f"[{tag}] {name}" + (f" ({detail})" if detail else ""))
|
||
if not cond:
|
||
FAILED.append(name)
|
||
|
||
|
||
app = QApplication.instance() or QApplication(sys.argv)
|
||
|
||
# ---------- 1. DashboardPage 初始状态 ----------
|
||
page = gui.DashboardPage(engine_settings={
|
||
"engine_a_enabled": True,
|
||
"enable_engine_b": False,
|
||
"engine_b_data_source": "db",
|
||
})
|
||
check("引擎A默认勾选", page.engine_a_check.isChecked() is True)
|
||
check("引擎B默认勾选(传入False)", page.engine_b_check.isChecked() is False)
|
||
check("数据源=db 时仅DB单选", page.engine_b_db_only.isChecked() is True
|
||
and page.engine_b_parallel.isChecked() is False)
|
||
check("引擎B关闭→数据源置灰", page.engine_b_parallel.isEnabled() is False
|
||
and page.engine_b_db_only.isEnabled() is False
|
||
and page.engine_b_json_only.isEnabled() is False)
|
||
|
||
# ---------- 2. 信号契约 ----------
|
||
captured: list[dict] = []
|
||
page.settingsChanged.connect(captured.append)
|
||
|
||
# 2a. 打开引擎 B(radio 应恢复可用)
|
||
page.engine_b_check.setChecked(True)
|
||
check("引擎B打开→数据源恢复可用", page.engine_b_parallel.isEnabled() is True)
|
||
check("信号已发射(打开B)", len(captured) == 1, str(captured[-1]) if captured else "none")
|
||
|
||
# 2b. 切换数据源 → json
|
||
page.engine_b_json_only.setChecked(True)
|
||
check("信号含 engine_b_data_source=json",
|
||
captured and captured[-1].get("engine_b_data_source") == "json",
|
||
str(captured[-1]) if captured else "none")
|
||
|
||
# 2c. 关引擎 A
|
||
page.engine_a_check.setChecked(False)
|
||
check("信号含 engine_a_enabled=False",
|
||
captured and captured[-1].get("engine_a_enabled") is False,
|
||
str(captured[-1]) if captured else "none")
|
||
check("信号含 enable_engine_b=True",
|
||
captured and captured[-1].get("enable_engine_b") is True,
|
||
str(captured[-1]) if captured else "none")
|
||
|
||
# 2d. 键集合完整(不多不少)
|
||
last = captured[-1] if captured else {}
|
||
expect_keys = {"engine_a_enabled", "enable_engine_b", "engine_b_data_source"}
|
||
check("信号键集合完整", set(last.keys()) == expect_keys, str(sorted(last.keys())))
|
||
|
||
# 2e. parallel 模式
|
||
page.engine_b_parallel.setChecked(True)
|
||
check("parallel 模式信号", captured[-1].get("engine_b_data_source") == "parallel",
|
||
str(captured[-1]))
|
||
|
||
# ---------- 3. 独立实例默认 parallel ----------
|
||
page2 = gui.DashboardPage(engine_settings={})
|
||
check("空配置默认 parallel", page2.engine_b_parallel.isChecked() is True)
|
||
check("空配置默认双开", page2.engine_a_check.isChecked() is True
|
||
and page2.engine_b_check.isChecked() is True)
|
||
|
||
# ---------- 4. MainWindow 设置加载校验(轻量,不建 WebEngine)----------
|
||
mw = gui.MainWindow.__new__(gui.MainWindow)
|
||
# 指向临时设置文件,避免污染真实配置
|
||
import tempfile
|
||
from pathlib import Path
|
||
|
||
tmp_settings = Path(tempfile.mkdtemp()) / "app_settings.json"
|
||
tmp_settings.write_text(
|
||
'{"engine_a_enabled": false, "enable_engine_b": true, '
|
||
'"engine_b_data_source": "weird", "poll_interval": 1.5}',
|
||
encoding="utf-8",
|
||
)
|
||
orig_file = gui.APP_SETTINGS_FILE
|
||
gui.APP_SETTINGS_FILE = tmp_settings
|
||
try:
|
||
loaded = mw._load_runtime_settings()
|
||
finally:
|
||
gui.APP_SETTINGS_FILE = orig_file
|
||
check("加载: engine_a_enabled 转 bool False", loaded.get("engine_a_enabled") is False,
|
||
str(loaded.get("engine_a_enabled")))
|
||
check("加载: 非法数据源回落 parallel",
|
||
loaded.get("engine_b_data_source") == "parallel",
|
||
str(loaded.get("engine_b_data_source")))
|
||
check("加载: enable_engine_b 保留 True", loaded.get("enable_engine_b") is True)
|
||
|
||
# ---------- 5. _on_dashboard_engine_settings 合并保存 ----------
|
||
saved: dict = {}
|
||
class FakePage:
|
||
def mark_saved(self, ok, msg): # noqa: N802
|
||
pass
|
||
def values(self):
|
||
return {}
|
||
|
||
mw.runtime_settings = {"engine_a_enabled": True, "enable_engine_b": True,
|
||
"engine_b_data_source": "parallel", "poll_interval": 2.0}
|
||
mw.settings_page = FakePage()
|
||
logs: list = []
|
||
mw.append_log = lambda msg, level="": logs.append((msg, level)) # noqa: E731
|
||
mw._sync_auto_launch = lambda enabled: None # noqa: E731
|
||
|
||
gui.APP_SETTINGS_FILE = tmp_settings
|
||
try:
|
||
mw._on_dashboard_engine_settings({
|
||
"engine_a_enabled": False,
|
||
"engine_b_data_source": "db",
|
||
})
|
||
saved = dict(mw.runtime_settings)
|
||
finally:
|
||
gui.APP_SETTINGS_FILE = orig_file
|
||
check("合并: engine_a_enabled=False 生效", saved.get("engine_a_enabled") is False)
|
||
check("合并: engine_b_data_source=db 生效", saved.get("engine_b_data_source") == "db")
|
||
check("合并: 未涉及的键保留", saved.get("enable_engine_b") is True
|
||
and saved.get("poll_interval") == 2.0)
|
||
check("合并: 已持久化到文件",
|
||
json.loads(tmp_settings.read_text(encoding="utf-8")).get("engine_a_enabled") is False)
|
||
|
||
print()
|
||
if FAILED:
|
||
print(f"RESULT: FAIL ({len(FAILED)}) -> {FAILED}")
|
||
sys.exit(1)
|
||
print("RESULT: ALL PASS")
|