"""Smoke tests for Sensor Bench SDK acquisition and UI construction.""" from __future__ import annotations import os import sys import time from pathlib import Path from types import SimpleNamespace from unittest.mock import MagicMock, patch import numpy as np ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / "src")) os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") def test_load_fixed_mode() -> None: from sensor_bench.acquisition import load_fixed_mode mode = load_fixed_mode(ROOT / "tests" / "fixtures" / "ddjx01_min.json") assert mode.width == 1920 assert mode.height == 1080 assert mode.fps == 30.0 assert mode.stitch_width == 365 assert "1920x1080" in mode.label() def test_translator_chinese_default() -> None: from sensor_bench.i18n import DEFAULT_LOCALE, Translator from sensor_bench.paths import default_locales_dir assert DEFAULT_LOCALE == "zh_CN" tr = Translator(default_locales_dir()) assert tr.locale == "zh_CN" assert "传感器" in tr.t("app.title") tr.set_locale("en_US") assert tr.t("app.title") == "Sensor Bench" assert "Power on" in tr.step_title("power_on") def test_sdk_worker_packet_mapping() -> None: from sensor_bench.acquisition import SdkAcquisitionWorker raw = np.zeros((1080, 1920, 3), dtype=np.uint8) processed = np.full((365, 365, 3), 40, dtype=np.uint8) class FakeSensor: def __init__(self, *args, **kwargs): self.frame = raw.copy() self.info = SimpleNamespace(FNORMAL=1, FSHEARX=2, FSHEARY=3) def get_img(self): self.frame = raw.copy() return processed.copy() def compute_deformation(self, **kwargs): return True def compute_contact(self): return True def read_info(self, *args): return 1.0, 2.0, 3.0 def disconnect(self): pass fake_orisys = MagicMock() fake_orisys.Sensor = FakeSensor fake_orisys.__version__ = "test" worker = SdkAcquisitionWorker() with patch.dict(sys.modules, {"orisys": fake_orisys}): with patch("sensor_bench.acquisition.orisys_importable", return_value=(True, "test")): mode = worker.start( 0, config_path=ROOT / "tests" / "fixtures" / "ddjx01_min.json", backend="cpu", ) assert mode.width == 1920 deadline = time.time() + 2.0 packet = None while time.time() < deadline: packet = worker.latest() if packet is not None: break time.sleep(0.02) worker.stop() assert packet is not None assert packet.width == 1920 assert packet.height == 1080 assert packet.processed_width == 365 assert packet.processed_height == 365 assert packet.normal_force == 1.0 assert packet.shear_x == 2.0 assert packet.shear_y == 3.0 assert packet.raw_frame.shape[:2] == (1080, 1920) assert packet.processed_frame.shape[:2] == (365, 365) def test_mainwindow_offscreen() -> None: from PyQt5.QtWidgets import QApplication from sensor_bench.app import MainWindow from sensor_bench.acquisition import FixedCameraMode from sensor_bench.i18n import DEFAULT_LOCALE app = QApplication.instance() or QApplication([]) win = MainWindow() assert win.tr.locale == DEFAULT_LOCALE == "zh_CN" assert "传感器" in win.windowTitle() assert win.btn_start.text() == "开始预览" assert win.camera_index.value() == 0 assert win.btn_next is not None assert win.btn_revert is not None assert win.btn_reset is not None assert win.sensor_type_combo.count() == 2 assert win.indentor_combo.count() == 2 assert win.platform_combo.count() == 3 assert win.selected_sensor_options()["sensor_type"] == "BOX" assert win.selected_sensor_options()["indentor"] == "1mm_circle" assert win.selected_sensor_options()["platform"] == "manual" assert not hasattr(win, "resolution_combo") assert not hasattr(win, "btn_search") assert win._current_step_index == 0 assert not win.btn_revert.isEnabled() assert win.btn_next.isEnabled() # Language switch refreshes labels without restart. win.language_combo.setCurrentIndex(1) assert win.tr.locale == "en_US" assert win.windowTitle() == "Sensor Bench" assert win.btn_start.text() == "Start Preview" # Workflow next / revert / reset. total = len(win.workflow.steps) win._on_step_next() assert win._current_step_index == 1 assert win.btn_revert.isEnabled() win._on_step_revert() assert win._current_step_index == 0 for _ in range(total): win._on_step_next() assert win._current_step_index == total assert not win.btn_next.isEnabled() assert "completed" in win.workflow_status.text().lower() or "完成" in win.workflow_status.text() win._on_step_reset() assert win._current_step_index == 0 assert win.btn_next.isEnabled() win._fixed_mode = FixedCameraMode( width=1920, height=1080, fps=30.0, config_ref=str(ROOT / "tests" / "fixtures" / "ddjx01_min.json"), stitch_width=365, stitch_height=365, ) win.mode_label.setText(win.t("labels.fixed_mode", mode=win._fixed_mode.label())) assert "1920x1080" in win.mode_label.text() win.close() if __name__ == "__main__": test_load_fixed_mode() test_translator_chinese_default() test_sdk_worker_packet_mapping() test_mainwindow_offscreen() print("ok")