"""Status presentation without a main window or running acquisition.""" from dataclasses import replace from types import SimpleNamespace import pytest from orisys_app_shared.i18n import t from orisys_app_shared.record.experiment import RecordStats from orisys_studio.status_presenter import RailState, StatusPresenter from orisys_studio.ui.toolbar import ToolbarWidget @pytest.fixture def surface(qt_app): toolbar = ToolbarWidget(theme="dark") yield toolbar, StatusPresenter(toolbar) toolbar.close() toolbar.deleteLater() def rail(**changes): return replace( RailState( sensor_type="finger", config_name="finger/r01/sensor.json", view_preset="live", video_path="D:/clips/box.mp4", has_video=True, replay_warnings="video warning", calibration_summary="calibration", ), **changes, ) def test_live_summary_keeps_video_details_out_and_reports_capture_cost(surface): toolbar, presenter = surface state = rail( show_fps=True, fps=16.67, process_ms=58.4, capture_fps=30.0, capture_dropped=7, ) presenter.refresh_rail(state) text = toolbar.source_summary.text() assert "box.mp4" not in text assert "video warning" not in toolbar.source_summary.toolTip() assert "16.7 FPS" in text and "58 ms" in text assert "30.0" in text and "(-7)" in text assert state.view_preset == "live" @pytest.mark.parametrize( "loaded,key", [ (True, "status.rail_video_name"), (False, "status.rail_recent_video"), ], ) def test_replay_distinguishes_open_video_from_remembered_path(surface, loaded, key): toolbar, presenter = surface presenter.refresh_rail(rail(view_preset="replay", has_video=loaded)) assert toolbar.source_summary.text() == t(key, name="box.mp4") assert ("video warning" in toolbar.source_summary.toolTip()) is loaded @pytest.mark.parametrize( "progress,key", [ ("reused", "status.rail_result_reused"), ("complete", "status.rail_result_complete"), ("running", "status.rail_result_running"), ("", "status.rail_result_ready"), ], ) def test_result_identity_belongs_to_the_result_not_the_picker(surface, progress, key): toolbar, presenter = surface presenter.refresh_rail( rail( view_preset="replay", result_sensor_type="box", result_progress=progress, ) ) text = toolbar.source_summary.text() assert text.startswith(t("status.rail_result_profile", type="box")) assert text.endswith(t(key)) assert "FINGER" in toolbar.btn_sensor.text() @pytest.mark.parametrize( "version,fallback,axes,key,labels", [ ("", None, None, "status.uncalibrated", ""), ("confirmed", None, None, "status.calibrated", ""), ("confirmed", True, (True, True, True), "status.uncalibrated", ""), ("confirmed", False, None, "status.uncalibrated", ""), ("confirmed", False, (False, False, False), "status.uncalibrated", ""), ("confirmed", False, (True, True, True), "status.calibrated_all", ""), ("confirmed", False, (True, False, True), "status.calibrated_axes", "FN+FY"), ], ) def test_calibration_summary_preserves_unknown_raw_and_partial_axes( version, fallback, axes, key, labels, ): assert StatusPresenter.calibration_summary(version, fallback, axes) == t( key, axes=labels ) def test_phase_repaints_after_a_theme_change_without_changing_the_phase(surface): toolbar, presenter = surface presenter.refresh_phase("connecting", theme="dark") assert toolbar.status_chip.text() == f"● {t('status.phase_connecting')}" presenter.refresh_phase("connecting", theme="light") assert toolbar.status_chip.text() == f"● {t('status.phase_connecting')}" def test_record_close_and_all_gap_counts_remain_visible(surface): toolbar, presenter = surface stats = RecordStats( frames=12, duration_s=2.5, dropped_data=1, dropped_video=2, dropped_gaps=3, unrecorded_gaps=4, write_errors=1, last_error="disk full", ) recording = SimpleNamespace( recorder=SimpleNamespace(directory="D:/recordings/run", stats=lambda: stats), is_recording=False, report_pending=True, last_report=SimpleNamespace(stats=RecordStats()), ) snapshot = presenter.record_stats(recording) assert snapshot == ("closing", stats, "run") presenter.refresh_record(*snapshot) displayed = toolbar.record_chip.stats() assert displayed["state"] == "closing" assert displayed["dropped"] == 10 assert displayed["dropped_gaps"] == 7 assert displayed["errors"] == 1 @pytest.mark.parametrize( "failed,errors,expected", [ (False, 0, "done"), (True, 0, "error"), (False, 1, "error"), ], ) def test_finished_recording_uses_the_final_report(surface, failed, errors, expected): toolbar, presenter = surface stats = RecordStats(failed=failed, write_errors=errors) recording = SimpleNamespace( recorder=SimpleNamespace(directory=None), is_recording=False, report_pending=False, last_report=SimpleNamespace(stats=stats), ) assert presenter.record_stats(recording) == (expected, stats, "") presenter.refresh_record(expected, stats, "") assert toolbar.record_chip.state() == expected