Files
orisys-app/apps/studio/tests/test_pause_controls.py
T
2026-09-27 19:20:43 +08:00

139 lines
6.0 KiB
Python

"""The live Pause control: what it stops, and what it deliberately leaves alone.
Pause means "stop computing and stop the picture, keep the camera". It must never be
confused with 停止 (which releases the device) or with the chart's own browse pause, and
it must not survive a session.
It lives on the rail's transport button — the same control the replay view uses to play
and pause a recording. ``checked`` means "acquiring and not paused", so unchecking the
button *while a session exists* is the pause, and checking it again is the resume. That
is how one two-state toggle carries a three-state transport: the session state, not the
button, is what tells stopped from paused.
"""
from __future__ import annotations
from orisys_app_shared.i18n import t
from tests.conftest import finish_run, running_window, show_window
def test_the_transport_is_idle_with_no_session(make_window):
"""Nothing to pause: the button says it runs, and there is no pause to reach."""
window = show_window(make_window(sensor_type="box", source_mode="camera"), (1440, 880))
assert not window.toolbar.btn_run.isChecked()
assert window.toolbar.btn_run.text() == t("toolbar.run_label")
assert not window.act_pause.isEnabled()
window.close()
def test_unchecking_the_transport_pauses_and_never_stops_the_device(make_window):
window, stuck = running_window(make_window)
try:
assert window.toolbar.btn_run.isChecked(), "the transport does not show acquiring"
assert window.toolbar.btn_run.text() == t("toolbar.pause")
window.toolbar.btn_run.setChecked(False)
assert window._display_paused is True
assert stuck.is_paused is True, "the worker was not asked to pause"
assert stuck.pause_requests == 1
assert window.act_pause.isChecked(), "the menu action did not follow the transport"
assert window.toolbar.btn_run.text() == t("toolbar.resume_label")
# The device is still open and the session is still the session.
assert window._running and window._session_phase == "running", (
"pausing ended the session instead of holding it"
)
assert "暂停" in window.statusBar().currentMessage() or (
"Paus" in window.statusBar().currentMessage()
)
window.toolbar.btn_run.setChecked(True)
assert window._display_paused is False
assert stuck.is_paused is False, "the worker was not asked to resume"
assert stuck.pause_requests == 2
assert not window.act_pause.isChecked()
assert window.toolbar.btn_run.text() == t("toolbar.pause")
finally:
finish_run(window, stuck)
def test_unchecking_the_transport_with_no_session_does_nothing(make_window):
"""The unchecked state only means paused *while a session exists*."""
window = show_window(make_window(sensor_type="box", source_mode="camera"), (1440, 880))
window._on_run_toggled(False)
assert window._display_paused is False
assert not window._running
assert window.toolbar.btn_run.text() == t("toolbar.run_label")
window.close()
def test_the_stop_button_is_what_ends_a_paused_session(make_window):
"""Pause holds the session; only Stop releases the device."""
window, stuck = running_window(make_window)
try:
window.toolbar.btn_run.setChecked(False)
assert window._display_paused is True and window._running
assert window.toolbar.btn_stop.isEnabled(), "no way out of the paused session"
window.toolbar.btn_stop.click()
assert not window._running, "Stop did not end the session"
assert window._session_phase == "idle"
finally:
stuck.release()
def test_the_shortcut_drives_the_same_state_as_the_transport(make_window):
"""One authoritative control, so the two can never disagree."""
window, stuck = running_window(make_window)
try:
window.act_pause.setChecked(True)
assert window._display_paused is True
assert stuck.is_paused is True
assert not window.toolbar.btn_run.isChecked(), (
"the transport did not follow the action"
)
assert window.toolbar.btn_run.text() == t("toolbar.resume_label")
window.act_pause.setChecked(False)
assert window._display_paused is False
assert stuck.is_paused is False
assert window.toolbar.btn_run.isChecked()
assert window.toolbar.btn_run.text() == t("toolbar.pause")
finally:
finish_run(window, stuck)
def test_the_transport_says_which_way_it_goes(make_window):
window, stuck = running_window(make_window)
try:
acquiring = window.toolbar.btn_run.text()
acquiring_tip = window.toolbar.btn_run.toolTip()
window.toolbar.btn_run.setChecked(False)
paused = window.toolbar.btn_run.text()
paused_tip = window.toolbar.btn_run.toolTip()
assert acquiring and paused and acquiring != paused, (acquiring, paused)
assert acquiring == t("toolbar.pause")
assert paused == t("toolbar.resume_label")
# The tooltips explain what each state does (the label cannot) — the pause
# one including the gap a pause leaves in a recording.
assert acquiring_tip == t("toolbar.pause_tip")
assert paused_tip == t("toolbar.resume_label_tip")
gap_tip = t("toolbar.pause_tip")
assert "gap" in gap_tip or "空档" in gap_tip, gap_tip
finally:
finish_run(window, stuck)
def test_stopping_a_paused_session_clears_the_pause(make_window):
"""The next run must compute: a latched pause would look like a dead device."""
window, stuck = running_window(make_window)
window.toolbar.btn_run.setChecked(False)
assert window._display_paused is True
window._stop_run(reason="user_stop")
assert window._display_paused is False
assert not window.act_pause.isChecked()
assert not window.toolbar.btn_run.isChecked()
# The session is over, so the transport is idle again — not paused.
assert window.toolbar.btn_run.text() == t("toolbar.run_label")
stuck.release()