06e06126ca
选点、对准、加载与录像分散在两个面板,状态靠隐藏相位判断。现改由不依赖 Qt 的采集控制器驱动,并加入录像选项、汇总平铺副本、保持到时自动结束、会话结束回到空闲,以及无设备时的模拟采集。已运行 Autocal 非 Qt 测试并通过范围内门禁;界面测试待 Windows 复核,未做实机验收。
103 lines
4.0 KiB
Python
103 lines
4.0 KiB
Python
"""Preferences must never be written outside the test scratch directory.
|
|
|
|
The installed app reads ``apps/autocal/preference.json`` at startup. A test that
|
|
builds a window and closes it saves preferences through ``closeEvent``, so a test
|
|
that forgets to redirect the path rewrites the operator's real settings — which is
|
|
exactly what happened: the finger screen started up pointing at a scratch bundle
|
|
from a previous run and reported it as missing.
|
|
|
|
``conftest._isolate_preference_file`` is the net. These tests pin it, because a
|
|
fixture that silently stopped applying would look like nothing at all until the app
|
|
was next launched by hand.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
APP_ROOT = Path(__file__).resolve().parents[1]
|
|
INSTALLED = APP_ROOT / "preference.json"
|
|
|
|
|
|
@pytest.mark.parametrize("stored", [{"calibrated": True}, {"zero_mm": 12.5, "calibrated": True}])
|
|
def test_loading_incomplete_press_calibration_does_not_invent_measurements(stored):
|
|
import json
|
|
from orisys_autocal import preferences
|
|
from orisys_autocal.motion.pose_move import PressAxis
|
|
|
|
Path(preferences.path()).write_text(json.dumps({"press_axis": stored}), encoding="utf-8")
|
|
loaded = preferences.load_preferences()
|
|
assert PressAxis.from_settings(loaded["press_axis"]).target_for(20) is None
|
|
|
|
|
|
def test_the_preference_path_is_redirected_under_the_scratch_root():
|
|
from orisys_autocal.preferences import path
|
|
|
|
resolved = Path(path()).resolve()
|
|
scratch = (APP_ROOT / "outputs" / "_test_scratch").resolve()
|
|
assert resolved != INSTALLED.resolve()
|
|
assert scratch in resolved.parents, resolved
|
|
|
|
|
|
def test_saving_preferences_leaves_the_installed_file_alone():
|
|
from orisys_autocal import preferences as prefs_mod
|
|
|
|
before = INSTALLED.read_bytes() if INSTALLED.is_file() else None
|
|
|
|
prefs = prefs_mod.default_preferences()
|
|
prefs["finger_bundle_path"] = str(APP_ROOT / "outputs" / "_test_scratch" / "gone")
|
|
written = Path(prefs_mod.save_preferences(prefs)).resolve()
|
|
|
|
assert written != INSTALLED.resolve()
|
|
assert written.is_file(), "the save did not reach the redirected file either"
|
|
|
|
after = INSTALLED.read_bytes() if INSTALLED.is_file() else None
|
|
assert after == before, "a test rewrote the installed preference.json"
|
|
|
|
|
|
def test_a_window_that_closes_still_lands_in_the_scratch_directory(qt_app):
|
|
"""The failure mode itself: construct, close, check where it wrote."""
|
|
from orisys_autocal import preferences as prefs_mod
|
|
from orisys_autocal.ui.window import AutoCalMainWindow
|
|
|
|
before = INSTALLED.read_bytes() if INSTALLED.is_file() else None
|
|
|
|
prefs = prefs_mod.default_preferences()
|
|
prefs["finger_bundle_path"] = str(APP_ROOT / "outputs" / "_test_scratch" / "gone")
|
|
window = AutoCalMainWindow(prefs=prefs, auto_load_bundle=False)
|
|
try:
|
|
window.poller.shutdown()
|
|
window.close()
|
|
finally:
|
|
window.poller.shutdown()
|
|
|
|
after = INSTALLED.read_bytes() if INSTALLED.is_file() else None
|
|
assert after == before, "closing a test window rewrote the installed preferences"
|
|
|
|
|
|
def test_a_stored_recording_block_without_the_newer_keys_gets_each_default():
|
|
"""The upgrade path for the recording preference, through the same net.
|
|
|
|
A stored ``recording`` block replaces the whole default block, exactly like
|
|
``safety_limits``: a codec or the lossless flag added later would otherwise
|
|
read as absent and the recorder would be configured from a hole.
|
|
"""
|
|
import json
|
|
|
|
from orisys_app_shared.paths import preference_path
|
|
|
|
from orisys_autocal.preferences import load_preferences
|
|
from orisys_autocal.recording_options import RecordingOptions, default_options
|
|
|
|
path = preference_path()
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_text(json.dumps({"recording": {"video": False}}), encoding="utf-8")
|
|
|
|
options = default_options(load_preferences())
|
|
|
|
assert options == RecordingOptions(video=False)
|
|
assert options.codec == "mp4v"
|
|
assert options.lossless_frames is False
|