chore: import original project baseline

Import the pre-repair source tree as the history baseline.
Runtime data (data/), virtualenvs, bytecode caches and logs are
gitignored so local secrets and user state stay out of the repo.
This commit is contained in:
2026-09-17 16:40:01 +08:00
commit a7412824e0
124 changed files with 26747 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
"""offscreen 模式切换功能测试:DB 持久化 + 首条消息锁定 + worker 分派
运行: QT_QPA_PLATFORM=offscreen python tests/smoke_mode.py
"""
import os
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
os.environ.setdefault("HAOCODE_RENDER", "software")
os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--disable-gpu" # 绕过 AMD 核显 context lost
os.environ.setdefault("PYTHONIOENCODING", "utf-8")
# 铁律:测试不得污染真实 data/chat_history.db → DBManager 默认路径重定向到临时文件
import tempfile as _tf # noqa: E402
import core.db_manager as _dbm # noqa: E402
_dbm._DEFAULT_DB = os.path.join(_tf.gettempdir(), f"haocode_test_smoke_mode_{os.getpid()}.db")
from PyQt6.QtWidgets import QApplication # noqa: E402
from ui.views.main_window import MainWindow # noqa: E402 (QtWebEngine 须先于 QApplication import 完成)
app = QApplication(sys.argv)
ok = True
def check(name, cond):
global ok
print((" PASS " if cond else " FAIL ") + name)
if not cond:
ok = False
window = MainWindow()
# 本套件验证「默认锁定」语义:显式置 mode_switch=false,不受本机 data/config.json 影响
# (仅内存,不会写回配置文件)
window.config_data["mode_switch"] = False
window._refresh_mode_button()
# 1) 新建会话 → 未锁定
window.on_new_chat_clicked()
sid = window.current_session_id
check("新会话未锁定 (mode=None)", window._get_current_mode() is None)
check("按钮显示待选 Chat", "Chat" in window.btn_mode.text() and "🔒" not in window.btn_mode.text())
# 2) 浮动弹窗开/关 + 选择
window.show_mode_popup()
check("弹窗打开", window.mode_popup.isVisible())
window._select_mode("worker")
check("选 worker 后按钮更新", "Worker" in window.btn_mode.text())
check("选择后弹窗自动关闭", not window.mode_popup.isVisible())
# 3) 首条发送 → 锁定
window._lock_session_mode()
check("发送后锁定 worker", window.db.get_session_mode(sid) == "worker")
check("按钮显示锁定", "🔒" in window.btn_mode.text())
# 4) 锁定后不可改
window._select_mode("chat")
check("锁定后选择无效", window.db.get_session_mode(sid) == "worker")
# 5) worker 分派
w1 = window._create_stream_worker([], "worker")
w2 = window._create_stream_worker([], "chat")
from core.llm_engine import AgentWorker, ChatWorker # noqa: E402
check("worker 模式 → AgentWorker", isinstance(w1, AgentWorker))
check("chat 模式 → ChatWorker", isinstance(w2, ChatWorker))
check("ChatWorker 有基础信号", all(hasattr(w2, s) for s in
("chunk_received", "reasoning_received", "error_occurred")))
check("ChatWorker 无工具信号(chat 模式不暴露)",
not hasattr(w2, "tool_execution_started"))
# 6) 切回新会话 → 解锁
window.on_new_chat_clicked()
check("新会话恢复可选", window._get_current_mode() is None and "🔒" not in window.btn_mode.text())
# 7) 旧会话(无 mode 列值)→ 默认 chat 路径
window.load_messages_to_web(sid)
check("切回已锁定会话显示锁定", window._get_current_mode() == "worker" and "🔒" in window.btn_mode.text())
# 8) mode_switch=true → 中途切换放行(旧锁定会话解锁 + 选择立即落库)
window.config_data["mode_switch"] = True
window._refresh_mode_button()
check("开关开启后旧会话解锁显示", "🔒" not in window.btn_mode.text())
window._select_mode("chat")
check("开关开启后中途切换生效", window.db.get_session_mode(sid) == "chat")
window.config_data["mode_switch"] = False
try:
window.close()
except Exception:
pass
app.quit()
print("\n===== " + ("ALL PASS" if ok else "HAS FAILURES") + " =====")
sys.exit(0 if ok else 1)