bec-widgets 0.99.1__py3-none-any.whl → 0.99.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- .gitlab-ci.yml +0 -1
- CHANGELOG.md +76 -70
- PKG-INFO +2 -2
- bec_widgets/cli/client.py +3 -3
- bec_widgets/qt_utils/toolbar.py +11 -5
- bec_widgets/utils/bec_widget.py +11 -2
- bec_widgets/utils/colors.py +18 -2
- bec_widgets/utils/plugin_templates/plugin.template +2 -2
- bec_widgets/widgets/bec_queue/bec_queue.py +2 -0
- bec_widgets/widgets/bec_queue/bec_queue_plugin.py +1 -1
- bec_widgets/widgets/bec_status_box/bec_status_box.py +2 -0
- bec_widgets/widgets/bec_status_box/bec_status_box_plugin.py +1 -1
- bec_widgets/widgets/color_button/color_button.py +2 -0
- bec_widgets/widgets/color_button/color_button_plugin.py +1 -1
- bec_widgets/widgets/colormap_selector/colormap_selector.py +1 -0
- bec_widgets/widgets/colormap_selector/colormap_selector_plugin.py +1 -1
- bec_widgets/widgets/dark_mode_button/dark_mode_button.py +12 -3
- bec_widgets/widgets/dark_mode_button/dark_mode_button_plugin.py +1 -1
- bec_widgets/widgets/device_browser/device_browser.py +2 -0
- bec_widgets/widgets/device_browser/device_browser_plugin.py +1 -1
- bec_widgets/widgets/device_combobox/device_combo_box_plugin.py +1 -1
- bec_widgets/widgets/device_combobox/device_combobox.py +2 -0
- bec_widgets/widgets/device_line_edit/device_line_edit.py +2 -0
- bec_widgets/widgets/device_line_edit/device_line_edit_plugin.py +1 -1
- bec_widgets/widgets/dock/dock.py +1 -0
- bec_widgets/widgets/dock/dock_area.py +30 -10
- bec_widgets/widgets/dock/dock_area_plugin.py +1 -1
- bec_widgets/widgets/figure/figure.py +1 -1
- bec_widgets/widgets/figure/plots/waveform/waveform.py +12 -7
- bec_widgets/widgets/figure/plots/waveform/waveform_curve.py +3 -3
- bec_widgets/widgets/image/bec_image_widget_plugin.py +1 -1
- bec_widgets/widgets/image/image_widget.py +1 -0
- bec_widgets/widgets/motor_map/bec_motor_map_widget_plugin.py +1 -1
- bec_widgets/widgets/motor_map/motor_map_widget.py +1 -0
- bec_widgets/widgets/position_indicator/position_indicator.py +2 -0
- bec_widgets/widgets/position_indicator/position_indicator_plugin.py +1 -1
- bec_widgets/widgets/positioner_box/positioner_box.py +1 -0
- bec_widgets/widgets/positioner_box/positioner_box_plugin.py +1 -1
- bec_widgets/widgets/positioner_box/positioner_control_line.py +2 -0
- bec_widgets/widgets/positioner_box/positioner_control_line_plugin.py +1 -1
- bec_widgets/widgets/ring_progress_bar/ring_progress_bar.py +1 -0
- bec_widgets/widgets/ring_progress_bar/ring_progress_bar_plugin.py +1 -1
- bec_widgets/widgets/scan_control/scan_control.py +2 -0
- bec_widgets/widgets/scan_control/scan_control_plugin.py +1 -4
- bec_widgets/widgets/spinner/spinner.py +2 -0
- bec_widgets/widgets/spinner/spinner_widget_plugin.py +1 -1
- bec_widgets/widgets/stop_button/stop_button.py +2 -0
- bec_widgets/widgets/stop_button/stop_button_plugin.py +1 -1
- bec_widgets/widgets/text_box/text_box.py +1 -0
- bec_widgets/widgets/text_box/text_box_plugin.py +1 -1
- bec_widgets/widgets/toggle/toggle.py +1 -0
- bec_widgets/widgets/toggle/toggle_switch_plugin.py +1 -1
- bec_widgets/widgets/vscode/vs_code_editor_plugin.py +1 -1
- bec_widgets/widgets/vscode/vscode.py +1 -0
- bec_widgets/widgets/waveform/bec_waveform_widget_plugin.py +1 -1
- bec_widgets/widgets/waveform/waveform_popups/curve_dialog/curve_dialog.py +14 -13
- bec_widgets/widgets/waveform/waveform_widget.py +3 -2
- bec_widgets/widgets/website/website.py +42 -10
- bec_widgets/widgets/website/website_widget_plugin.py +1 -1
- {bec_widgets-0.99.1.dist-info → bec_widgets-0.99.9.dist-info}/METADATA +2 -2
- bec_widgets-0.99.9.dist-info/RECORD +231 -0
- pyproject.toml +7 -2
- bec_widgets/assets/toolbar_icons/add.svg +0 -3
- bec_widgets/assets/toolbar_icons/attach_all.svg +0 -3
- bec_widgets/assets/toolbar_icons/auto_range.svg +0 -3
- bec_widgets/assets/toolbar_icons/compare.svg +0 -3
- bec_widgets/assets/toolbar_icons/connection.svg +0 -4
- bec_widgets/assets/toolbar_icons/device_line_edit.svg +0 -3
- bec_widgets/assets/toolbar_icons/drag_pan_mode.svg +0 -3
- bec_widgets/assets/toolbar_icons/export.svg +0 -9
- bec_widgets/assets/toolbar_icons/fft.svg +0 -11
- bec_widgets/assets/toolbar_icons/fitting_parameters.svg +0 -3
- bec_widgets/assets/toolbar_icons/history.svg +0 -4
- bec_widgets/assets/toolbar_icons/image.svg +0 -3
- bec_widgets/assets/toolbar_icons/image_autorange.svg +0 -3
- bec_widgets/assets/toolbar_icons/import.svg +0 -9
- bec_widgets/assets/toolbar_icons/line_axis.svg +0 -3
- bec_widgets/assets/toolbar_icons/line_curve.svg +0 -3
- bec_widgets/assets/toolbar_icons/lock_aspect_ratio.svg +0 -3
- bec_widgets/assets/toolbar_icons/log_scale.png +0 -0
- bec_widgets/assets/toolbar_icons/motor_map.svg +0 -3
- bec_widgets/assets/toolbar_icons/photo_library.svg +0 -3
- bec_widgets/assets/toolbar_icons/positioner_box.svg +0 -3
- bec_widgets/assets/toolbar_icons/progress.svg +0 -3
- bec_widgets/assets/toolbar_icons/queue.svg +0 -3
- bec_widgets/assets/toolbar_icons/rectangle_mode.svg +0 -3
- bec_widgets/assets/toolbar_icons/remove.svg +0 -5
- bec_widgets/assets/toolbar_icons/reset_settings.svg +0 -3
- bec_widgets/assets/toolbar_icons/restore_state.svg +0 -3
- bec_widgets/assets/toolbar_icons/ring_progress.svg +0 -3
- bec_widgets/assets/toolbar_icons/rotate_left.svg +0 -3
- bec_widgets/assets/toolbar_icons/rotate_right.svg +0 -3
- bec_widgets/assets/toolbar_icons/save.svg +0 -3
- bec_widgets/assets/toolbar_icons/save_state.svg +0 -3
- bec_widgets/assets/toolbar_icons/scan_control.svg +0 -3
- bec_widgets/assets/toolbar_icons/settings.svg +0 -4
- bec_widgets/assets/toolbar_icons/status.svg +0 -3
- bec_widgets/assets/toolbar_icons/terminal.svg +0 -3
- bec_widgets/assets/toolbar_icons/transform.svg +0 -3
- bec_widgets/assets/toolbar_icons/waveform.svg +0 -3
- bec_widgets-0.99.1.dist-info/RECORD +0 -415
- docs/Makefile +0 -20
- docs/_static/custom.css +0 -170
- docs/_templates/custom-class-template.rst +0 -34
- docs/_templates/custom-module-template.rst +0 -66
- docs/api_reference/api_reference.md +0 -12
- docs/assets/apps_48dp.svg +0 -1
- docs/assets/display_settings_48dp.svg +0 -1
- docs/assets/index_api.svg +0 -97
- docs/assets/index_contribute.svg +0 -76
- docs/assets/index_getting_started.svg +0 -66
- docs/assets/index_user_guide.svg +0 -67
- docs/assets/rocket_launch_48dp.svg +0 -1
- docs/assets/widget_screenshots/buttons.png +0 -0
- docs/assets/widget_screenshots/device_box.png +0 -0
- docs/assets/widget_screenshots/device_browser.png +0 -0
- docs/assets/widget_screenshots/device_inputs.png +0 -0
- docs/assets/widget_screenshots/dock_area.png +0 -0
- docs/assets/widget_screenshots/figure.png +0 -0
- docs/assets/widget_screenshots/image_widget.png +0 -0
- docs/assets/widget_screenshots/motor_map_widget.png +0 -0
- docs/assets/widget_screenshots/position_indicator.png +0 -0
- docs/assets/widget_screenshots/queue.png +0 -0
- docs/assets/widget_screenshots/ring_progress_bar.png +0 -0
- docs/assets/widget_screenshots/scan_controller.png +0 -0
- docs/assets/widget_screenshots/spinner.gif +0 -0
- docs/assets/widget_screenshots/status_box.png +0 -0
- docs/assets/widget_screenshots/text_box.png +0 -0
- docs/assets/widget_screenshots/toggle.png +0 -0
- docs/assets/widget_screenshots/waveform_widget.png +0 -0
- docs/assets/widget_screenshots/website.png +0 -0
- docs/conf.py +0 -82
- docs/developer/developer.md +0 -52
- docs/developer/introduction/concepts.md +0 -14
- docs/developer/introduction/contributing.md +0 -28
- docs/developer/introduction/introduction.md +0 -16
- docs/developer/introduction/useful_links.md +0 -23
- docs/developer/widget_development/bec_dispatcher.md +0 -143
- docs/developer/widget_development/widget_development.md +0 -13
- docs/index.md +0 -74
- docs/introduction/introduction.md +0 -18
- docs/make.bat +0 -35
- docs/requirements.txt +0 -12
- docs/user/api_reference/api_reference.md +0 -11
- docs/user/applications/applications.md +0 -10
- docs/user/customisation.md +0 -123
- docs/user/getting_started/BECDockArea.png +0 -0
- docs/user/getting_started/auto_updates.md +0 -82
- docs/user/getting_started/getting_started.md +0 -15
- docs/user/getting_started/gui_complex_gui.gif +0 -0
- docs/user/getting_started/installation.md +0 -33
- docs/user/getting_started/quick_start.md +0 -110
- docs/user/getting_started/video_tutorials.md +0 -17
- docs/user/user.md +0 -71
- docs/user/widgets/bec_figure/BECFigure.png +0 -0
- docs/user/widgets/bec_figure/bec_figure.md +0 -105
- docs/user/widgets/bec_status_box/bec_status_box.gif +0 -0
- docs/user/widgets/bec_status_box/bec_status_box.md +0 -38
- docs/user/widgets/buttons/buttons.md +0 -63
- docs/user/widgets/buttons/dark_mode_disabled.png +0 -0
- docs/user/widgets/buttons/dark_mode_enabled.png +0 -0
- docs/user/widgets/device_browser/device_browser.md +0 -36
- docs/user/widgets/device_browser/device_browser.png +0 -0
- docs/user/widgets/device_input/device_input.md +0 -100
- docs/user/widgets/dock_area/BECDockArea.png +0 -0
- docs/user/widgets/dock_area/bec_dock_area.md +0 -107
- docs/user/widgets/image/image_plot.gif +0 -0
- docs/user/widgets/image/image_widget.md +0 -84
- docs/user/widgets/motor_map/motor.gif +0 -0
- docs/user/widgets/motor_map/motor_map.md +0 -80
- docs/user/widgets/position_indicator/position_indicator.md +0 -76
- docs/user/widgets/positioner_box/positioner_box.md +0 -63
- docs/user/widgets/progress_bar/progress_bar.gif +0 -0
- docs/user/widgets/progress_bar/ring_progress_bar.md +0 -103
- docs/user/widgets/queue/queue.md +0 -41
- docs/user/widgets/scan_control/hide_scan_control.png +0 -0
- docs/user/widgets/scan_control/scan_control.gif +0 -0
- docs/user/widgets/scan_control/scan_control.md +0 -54
- docs/user/widgets/spinner/spinner.md +0 -75
- docs/user/widgets/text_box/text_box.md +0 -74
- docs/user/widgets/toggle/toggle.md +0 -66
- docs/user/widgets/waveform/bec_figure_dap.gif +0 -0
- docs/user/widgets/waveform/scatter_2D.gif +0 -0
- docs/user/widgets/waveform/w1D.gif +0 -0
- docs/user/widgets/waveform/waveform_widget.md +0 -132
- docs/user/widgets/website/website.md +0 -69
- docs/user/widgets/widgets.md +0 -220
- tests/__init__.py +0 -0
- tests/end-2-end/__init__.py +0 -0
- tests/end-2-end/conftest.py +0 -53
- tests/end-2-end/test_bec_dock_rpc_e2e.py +0 -298
- tests/end-2-end/test_bec_figure_rpc_e2e.py +0 -212
- tests/end-2-end/test_rpc_register_e2e.py +0 -40
- tests/end-2-end/test_scan_control_e2e.py +0 -71
- tests/references/SpinnerWidget/SpinnerWidget_darwin.png +0 -0
- tests/references/SpinnerWidget/SpinnerWidget_linux.png +0 -0
- tests/references/SpinnerWidget/SpinnerWidget_started_darwin.png +0 -0
- tests/references/SpinnerWidget/SpinnerWidget_started_linux.png +0 -0
- tests/unit_tests/__init__.py +0 -0
- tests/unit_tests/client_mocks.py +0 -189
- tests/unit_tests/conftest.py +0 -64
- tests/unit_tests/test_bec_connector.py +0 -80
- tests/unit_tests/test_bec_dispatcher.py +0 -119
- tests/unit_tests/test_bec_dock.py +0 -155
- tests/unit_tests/test_bec_figure.py +0 -270
- tests/unit_tests/test_bec_image.py +0 -63
- tests/unit_tests/test_bec_image_widget.py +0 -217
- tests/unit_tests/test_bec_motor_map.py +0 -282
- tests/unit_tests/test_bec_queue.py +0 -111
- tests/unit_tests/test_bec_status_box.py +0 -123
- tests/unit_tests/test_client_utils.py +0 -76
- tests/unit_tests/test_color_map_selector.py +0 -42
- tests/unit_tests/test_color_validation.py +0 -75
- tests/unit_tests/test_configs/config_device.yaml +0 -33
- tests/unit_tests/test_configs/config_device_no_entry.yaml +0 -27
- tests/unit_tests/test_configs/config_scan.yaml +0 -82
- tests/unit_tests/test_crosshair.py +0 -143
- tests/unit_tests/test_dark_mode_button.py +0 -70
- tests/unit_tests/test_device_browser.py +0 -83
- tests/unit_tests/test_device_input_base.py +0 -76
- tests/unit_tests/test_device_input_widgets.py +0 -178
- tests/unit_tests/test_error_utils.py +0 -63
- tests/unit_tests/test_generate_cli_client.py +0 -123
- tests/unit_tests/test_generate_plugin.py +0 -155
- tests/unit_tests/test_motor_map_widget.py +0 -194
- tests/unit_tests/test_msgs/__init__.py +0 -0
- tests/unit_tests/test_msgs/available_scans_message.py +0 -989
- tests/unit_tests/test_plot_base.py +0 -95
- tests/unit_tests/test_plugin_utils.py +0 -13
- tests/unit_tests/test_positioner_box.py +0 -130
- tests/unit_tests/test_ring_progress_bar.py +0 -337
- tests/unit_tests/test_rpc_register.py +0 -52
- tests/unit_tests/test_rpc_server.py +0 -42
- tests/unit_tests/test_rpc_widget_handler.py +0 -7
- tests/unit_tests/test_scan_control.py +0 -324
- tests/unit_tests/test_scan_control_group_box.py +0 -160
- tests/unit_tests/test_setting_dialog.py +0 -96
- tests/unit_tests/test_spinner.py +0 -31
- tests/unit_tests/test_stop_button.py +0 -27
- tests/unit_tests/test_text_box_widget.py +0 -54
- tests/unit_tests/test_toggle.py +0 -38
- tests/unit_tests/test_vscode_widget.py +0 -75
- tests/unit_tests/test_waveform1d.py +0 -712
- tests/unit_tests/test_waveform_widget.py +0 -462
- tests/unit_tests/test_website_widget.py +0 -25
- tests/unit_tests/test_widget_io.py +0 -90
- tests/unit_tests/test_yaml_dialog.py +0 -163
- {bec_widgets-0.99.1.dist-info → bec_widgets-0.99.9.dist-info}/WHEEL +0 -0
- {bec_widgets-0.99.1.dist-info → bec_widgets-0.99.9.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.99.1.dist-info → bec_widgets-0.99.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,123 +0,0 @@
|
|
1
|
-
# pylint: skip-file
|
2
|
-
from unittest import mock
|
3
|
-
|
4
|
-
import pytest
|
5
|
-
from bec_lib.messages import BECStatus, ServiceMetricMessage, StatusMessage
|
6
|
-
|
7
|
-
from bec_widgets.widgets.bec_status_box.bec_status_box import BECServiceInfoContainer, BECStatusBox
|
8
|
-
|
9
|
-
from .client_mocks import mocked_client
|
10
|
-
|
11
|
-
|
12
|
-
@pytest.fixture
|
13
|
-
def service_status_fixture():
|
14
|
-
yield mock.MagicMock()
|
15
|
-
|
16
|
-
|
17
|
-
@pytest.fixture
|
18
|
-
def status_box(qtbot, mocked_client, service_status_fixture):
|
19
|
-
widget = BECStatusBox(client=mocked_client, bec_service_status_mixin=service_status_fixture)
|
20
|
-
qtbot.addWidget(widget)
|
21
|
-
qtbot.waitExposed(widget)
|
22
|
-
yield widget
|
23
|
-
|
24
|
-
|
25
|
-
def test_update_top_item(status_box):
|
26
|
-
assert status_box.tree.children()[0].children()[0].config.status == "IDLE"
|
27
|
-
name = status_box.box_name
|
28
|
-
status_box.update_top_item_status(status="RUNNING")
|
29
|
-
assert status_box.status_container[name]["info"].status == "RUNNING"
|
30
|
-
assert status_box.tree.children()[0].children()[0].config.status == "RUNNING"
|
31
|
-
|
32
|
-
|
33
|
-
def test_create_status_widget(status_box):
|
34
|
-
name = "test_service"
|
35
|
-
status = BECStatus.IDLE
|
36
|
-
info = {"test": "test"}
|
37
|
-
metrics = {"metric": "test_metric"}
|
38
|
-
item = status_box._create_status_widget(name, status, info, metrics)
|
39
|
-
assert item.config.service_name == name
|
40
|
-
assert item.config.status == status.name
|
41
|
-
assert item.config.info == info
|
42
|
-
assert item.config.metrics == metrics
|
43
|
-
|
44
|
-
|
45
|
-
def test_bec_service_container(status_box):
|
46
|
-
name = "test_service"
|
47
|
-
status = BECStatus.IDLE
|
48
|
-
info = {"test": "test"}
|
49
|
-
metrics = {"metric": "test_metric"}
|
50
|
-
expected_return = BECServiceInfoContainer(
|
51
|
-
service_name=name, status=status.name, info=info, metrics=metrics
|
52
|
-
)
|
53
|
-
assert status_box.box_name in status_box.status_container
|
54
|
-
assert len(status_box.status_container) == 1
|
55
|
-
status_box._update_status_container(name, status, info, metrics)
|
56
|
-
assert len(status_box.status_container) == 2
|
57
|
-
assert status_box.status_container[name]["info"] == expected_return
|
58
|
-
|
59
|
-
|
60
|
-
def test_add_tree_item(status_box):
|
61
|
-
name = "test_service"
|
62
|
-
status = BECStatus.IDLE
|
63
|
-
info = {"test": "test"}
|
64
|
-
metrics = {"metric": "test_metric"}
|
65
|
-
assert len(status_box.tree.children()[0].children()) == 1
|
66
|
-
status_box.add_tree_item(name, status, info, metrics)
|
67
|
-
assert len(status_box.tree.children()[0].children()) == 2
|
68
|
-
assert name in status_box.status_container
|
69
|
-
|
70
|
-
|
71
|
-
def test_update_service_status(status_box):
|
72
|
-
"""Also checks check redundant tree items"""
|
73
|
-
name = "test_service"
|
74
|
-
status = BECStatus.IDLE
|
75
|
-
info = {"test": "test"}
|
76
|
-
metrics = {"metric": "test_metric"}
|
77
|
-
status_box.add_tree_item(name, status, info, {})
|
78
|
-
not_connected_name = "invalid_service"
|
79
|
-
status_box.add_tree_item(not_connected_name, status, info, metrics)
|
80
|
-
|
81
|
-
services_status = {name: StatusMessage(name=name, status=status, info=info)}
|
82
|
-
services_metrics = {name: ServiceMetricMessage(name=name, metrics=metrics)}
|
83
|
-
|
84
|
-
with mock.patch.object(status_box, "update_core_services", return_value=services_status):
|
85
|
-
assert not_connected_name in status_box.status_container
|
86
|
-
status_box.update_service_status(services_status, services_metrics)
|
87
|
-
assert status_box.status_container[name]["widget"].config.metrics == metrics
|
88
|
-
assert not_connected_name not in status_box.status_container
|
89
|
-
|
90
|
-
|
91
|
-
def test_update_core_services(status_box):
|
92
|
-
status_box.CORE_SERVICES = ["test_service"]
|
93
|
-
name = "test_service"
|
94
|
-
status = BECStatus.RUNNING
|
95
|
-
info = {"test": "test"}
|
96
|
-
metrics = {"metric": "test_metric"}
|
97
|
-
services_status = {name: StatusMessage(name=name, status=status, info=info)}
|
98
|
-
services_metrics = {name: ServiceMetricMessage(name=name, metrics=metrics)}
|
99
|
-
|
100
|
-
status_box.update_core_services(services_status, services_metrics)
|
101
|
-
assert status_box.tree.children()[0].children()[0].config.status == "RUNNING"
|
102
|
-
assert status_box.status_container[name]["widget"].config.metrics == metrics
|
103
|
-
|
104
|
-
status = BECStatus.IDLE
|
105
|
-
services_status = {name: StatusMessage(name=name, status=status, info=info)}
|
106
|
-
services_metrics = {name: ServiceMetricMessage(name=name, metrics=metrics)}
|
107
|
-
status_box.update_core_services(services_status, services_metrics)
|
108
|
-
assert status_box.tree.children()[0].children()[0].config.status == status.name
|
109
|
-
assert status_box.status_container[name]["widget"].config.metrics == metrics
|
110
|
-
|
111
|
-
|
112
|
-
def test_double_click_item(status_box):
|
113
|
-
name = "test_service"
|
114
|
-
status = BECStatus.IDLE
|
115
|
-
info = {"test": "test"}
|
116
|
-
metrics = {"MyData": "This should be shown nicely"}
|
117
|
-
status_box.add_tree_item(name, status, info, metrics)
|
118
|
-
container = status_box.status_container[name]
|
119
|
-
item = container["item"]
|
120
|
-
status_item = container["widget"]
|
121
|
-
with mock.patch.object(status_item, "show_popup") as mock_show_popup:
|
122
|
-
status_box.tree.itemDoubleClicked.emit(item, 0)
|
123
|
-
assert mock_show_popup.call_count == 1
|
@@ -1,76 +0,0 @@
|
|
1
|
-
from unittest import mock
|
2
|
-
|
3
|
-
import pytest
|
4
|
-
|
5
|
-
from bec_widgets.cli.client import BECFigure
|
6
|
-
from bec_widgets.cli.client_utils import BECGuiClientMixin, _start_plot_process
|
7
|
-
|
8
|
-
from .client_mocks import FakeDevice
|
9
|
-
|
10
|
-
|
11
|
-
@pytest.fixture
|
12
|
-
def cli_figure():
|
13
|
-
fig = BECFigure(gui_id="test")
|
14
|
-
with mock.patch.object(fig, "_run_rpc") as mock_rpc_call:
|
15
|
-
with mock.patch.object(fig, "gui_is_alive", return_value=True):
|
16
|
-
yield fig, mock_rpc_call
|
17
|
-
|
18
|
-
|
19
|
-
def test_rpc_call_plot(cli_figure):
|
20
|
-
fig, mock_rpc_call = cli_figure
|
21
|
-
fig.plot(x_name="samx", y_name="bpm4i")
|
22
|
-
mock_rpc_call.assert_called_with("plot", x_name="samx", y_name="bpm4i")
|
23
|
-
|
24
|
-
|
25
|
-
def test_rpc_call_accepts_device_as_input(cli_figure):
|
26
|
-
dev1 = FakeDevice("samx")
|
27
|
-
dev2 = FakeDevice("bpm4i")
|
28
|
-
fig, mock_rpc_call = cli_figure
|
29
|
-
fig.plot(x_name=dev1, y_name=dev2)
|
30
|
-
mock_rpc_call.assert_called_with("plot", x_name="samx", y_name="bpm4i")
|
31
|
-
|
32
|
-
|
33
|
-
@pytest.mark.parametrize(
|
34
|
-
"config, call_config",
|
35
|
-
[
|
36
|
-
(None, None),
|
37
|
-
("/path/to/config.yml", "/path/to/config.yml"),
|
38
|
-
({"key": "value"}, '{"key": "value"}'),
|
39
|
-
],
|
40
|
-
)
|
41
|
-
def test_client_utils_start_plot_process(config, call_config):
|
42
|
-
with mock.patch("bec_widgets.cli.client_utils.subprocess.Popen") as mock_popen:
|
43
|
-
_start_plot_process("gui_id", BECFigure, config)
|
44
|
-
command = ["bec-gui-server", "--id", "gui_id", "--gui_class", "BECFigure"]
|
45
|
-
if call_config:
|
46
|
-
command.extend(["--config", call_config])
|
47
|
-
mock_popen.assert_called_once_with(
|
48
|
-
command,
|
49
|
-
text=True,
|
50
|
-
start_new_session=True,
|
51
|
-
stdout=mock.ANY,
|
52
|
-
stderr=mock.ANY,
|
53
|
-
env=mock.ANY,
|
54
|
-
)
|
55
|
-
|
56
|
-
|
57
|
-
def test_client_utils_passes_client_config_to_server(bec_dispatcher):
|
58
|
-
"""
|
59
|
-
Test that the client config is passed to the server. This ensures that
|
60
|
-
changes to the client config (either through config files or plugins) are
|
61
|
-
reflected in the server.
|
62
|
-
"""
|
63
|
-
mixin = BECGuiClientMixin()
|
64
|
-
mixin._client = bec_dispatcher.client
|
65
|
-
mixin._gui_id = "gui_id"
|
66
|
-
mixin.gui_is_alive = mock.MagicMock()
|
67
|
-
mixin.gui_is_alive.side_effect = [True]
|
68
|
-
|
69
|
-
with mock.patch("bec_widgets.cli.client_utils._start_plot_process") as mock_start_plot:
|
70
|
-
with mock.patch.object(mixin, "_start_update_script") as mock_start_update:
|
71
|
-
mock_start_plot.return_value = [mock.MagicMock(), mock.MagicMock()]
|
72
|
-
mixin.show()
|
73
|
-
mock_start_plot.assert_called_once_with(
|
74
|
-
"gui_id", BECGuiClientMixin, mixin._client._service_config.config
|
75
|
-
)
|
76
|
-
mock_start_update.assert_called_once()
|
@@ -1,42 +0,0 @@
|
|
1
|
-
import pyqtgraph as pg
|
2
|
-
import pytest
|
3
|
-
|
4
|
-
from bec_widgets.widgets.colormap_selector.colormap_selector import ColormapSelector
|
5
|
-
|
6
|
-
|
7
|
-
@pytest.fixture
|
8
|
-
def color_map_selector(qtbot):
|
9
|
-
widget = ColormapSelector()
|
10
|
-
qtbot.addWidget(widget)
|
11
|
-
qtbot.waitExposed(widget)
|
12
|
-
yield widget
|
13
|
-
|
14
|
-
|
15
|
-
def test_color_map_selector_init(color_map_selector):
|
16
|
-
assert color_map_selector is not None
|
17
|
-
assert isinstance(color_map_selector, ColormapSelector)
|
18
|
-
|
19
|
-
all_maps = pg.colormap.listMaps()
|
20
|
-
loaded_maps = [
|
21
|
-
color_map_selector.combo.itemText(i) for i in range(color_map_selector.combo.count())
|
22
|
-
]
|
23
|
-
assert len(loaded_maps) > 0
|
24
|
-
assert all_maps == loaded_maps
|
25
|
-
|
26
|
-
|
27
|
-
def test_color_map_selector_add_color_maps(color_map_selector):
|
28
|
-
color_map_selector.add_color_maps(["cividis", "viridis"])
|
29
|
-
assert color_map_selector.combo.count() == 2
|
30
|
-
assert color_map_selector.combo.itemText(0) == "cividis"
|
31
|
-
assert color_map_selector.combo.itemText(1) == "viridis"
|
32
|
-
assert color_map_selector.combo.itemText(2) != "cividis"
|
33
|
-
assert color_map_selector.combo.itemText(2) != "viridis"
|
34
|
-
|
35
|
-
|
36
|
-
def test_colormap_add_maps_by_property(color_map_selector):
|
37
|
-
color_map_selector.colormaps = ["cividis", "viridis"]
|
38
|
-
assert color_map_selector.combo.count() == 2
|
39
|
-
assert color_map_selector.combo.itemText(0) == "cividis"
|
40
|
-
assert color_map_selector.combo.itemText(1) == "viridis"
|
41
|
-
assert color_map_selector.combo.itemText(2) != "cividis"
|
42
|
-
assert color_map_selector.combo.itemText(2) != "viridis"
|
@@ -1,75 +0,0 @@
|
|
1
|
-
import pytest
|
2
|
-
from pydantic import ValidationError
|
3
|
-
|
4
|
-
from bec_widgets.utils import Colors
|
5
|
-
from bec_widgets.widgets.figure.plots.waveform.waveform_curve import CurveConfig
|
6
|
-
|
7
|
-
|
8
|
-
def test_color_validation_CSS():
|
9
|
-
# Test valid color
|
10
|
-
color = Colors.validate_color("teal")
|
11
|
-
assert color == "teal"
|
12
|
-
|
13
|
-
# Test invalid color
|
14
|
-
with pytest.raises(ValidationError) as excinfo:
|
15
|
-
CurveConfig(color="invalid_color")
|
16
|
-
|
17
|
-
errors = excinfo.value.errors()
|
18
|
-
assert len(errors) == 1
|
19
|
-
assert errors[0]["type"] == ("unsupported color")
|
20
|
-
assert "The color must be a valid HEX string or CSS Color." in str(excinfo.value)
|
21
|
-
|
22
|
-
|
23
|
-
def test_color_validation_hex():
|
24
|
-
# Test valid color
|
25
|
-
color = Colors.validate_color("#ff0000")
|
26
|
-
assert color == "#ff0000"
|
27
|
-
|
28
|
-
# Test invalid color
|
29
|
-
with pytest.raises(ValidationError) as excinfo:
|
30
|
-
CurveConfig(color="#ff00000")
|
31
|
-
|
32
|
-
errors = excinfo.value.errors()
|
33
|
-
assert len(errors) == 1
|
34
|
-
assert errors[0]["type"] == ("unsupported color")
|
35
|
-
assert "The color must be a valid HEX string or CSS Color." in str(excinfo.value)
|
36
|
-
|
37
|
-
|
38
|
-
def test_color_validation_RGBA():
|
39
|
-
# Test valid color
|
40
|
-
color = Colors.validate_color((255, 0, 0, 255))
|
41
|
-
assert color == (255, 0, 0, 255)
|
42
|
-
|
43
|
-
# Test invalid color
|
44
|
-
with pytest.raises(ValidationError) as excinfo:
|
45
|
-
CurveConfig(color=(255, 0, 0))
|
46
|
-
|
47
|
-
errors = excinfo.value.errors()
|
48
|
-
assert len(errors) == 1
|
49
|
-
assert errors[0]["type"] == ("unsupported color")
|
50
|
-
assert "The color must be a tuple of 4 elements (R, G, B, A)." in str(excinfo.value)
|
51
|
-
|
52
|
-
with pytest.raises(ValidationError) as excinfo:
|
53
|
-
CurveConfig(color=(255, 0, 0, 355))
|
54
|
-
|
55
|
-
errors = excinfo.value.errors()
|
56
|
-
assert len(errors) == 1
|
57
|
-
assert errors[0]["type"] == ("unsupported color")
|
58
|
-
assert "The color values must be between 0 and 255 in RGBA format (R,G,B,A)" in str(
|
59
|
-
excinfo.value
|
60
|
-
)
|
61
|
-
|
62
|
-
|
63
|
-
def test_hex_to_rgba():
|
64
|
-
assert Colors.hex_to_rgba("#FF5733") == (255, 87, 51, 255)
|
65
|
-
assert Colors.hex_to_rgba("#FF573380") == (255, 87, 51, 128)
|
66
|
-
assert Colors.hex_to_rgba("#FF5733", 128) == (255, 87, 51, 128)
|
67
|
-
|
68
|
-
with pytest.raises(ValueError):
|
69
|
-
Colors.hex_to_rgba("#FF573")
|
70
|
-
|
71
|
-
|
72
|
-
def test_rgba_to_hex():
|
73
|
-
assert Colors.rgba_to_hex(255, 87, 51, 255) == "#FF5733FF"
|
74
|
-
assert Colors.rgba_to_hex(255, 87, 51, 128) == "#FF573380"
|
75
|
-
assert Colors.rgba_to_hex(255, 87, 51) == "#FF5733FF"
|
@@ -1,33 +0,0 @@
|
|
1
|
-
plot_settings:
|
2
|
-
background_color: "black"
|
3
|
-
num_columns: 1
|
4
|
-
colormap: "plasma"
|
5
|
-
scan_types: false
|
6
|
-
plot_data:
|
7
|
-
- plot_name: "BPM4i plots vs samx"
|
8
|
-
x_label: "Motor X"
|
9
|
-
y_label: "bpm4i"
|
10
|
-
sources:
|
11
|
-
- type: "scan_segment"
|
12
|
-
signals:
|
13
|
-
x:
|
14
|
-
- name : "samx"
|
15
|
-
entry: "samx"
|
16
|
-
y:
|
17
|
-
- name : "bpm4i"
|
18
|
-
entry: "bpm4i"
|
19
|
-
|
20
|
-
- plot_name: "Gauss plots vs samx"
|
21
|
-
x_label: "Motor X"
|
22
|
-
y_label: "Gauss"
|
23
|
-
sources:
|
24
|
-
- type: "scan_segment"
|
25
|
-
signals:
|
26
|
-
x:
|
27
|
-
- name: "samx"
|
28
|
-
entry: "samx"
|
29
|
-
y:
|
30
|
-
- name: "gauss_adc1"
|
31
|
-
entry: "gauss_adc1"
|
32
|
-
- name: "gauss_adc2"
|
33
|
-
entry: "gauss_adc2"
|
@@ -1,27 +0,0 @@
|
|
1
|
-
plot_settings:
|
2
|
-
background_color: "black"
|
3
|
-
num_columns: 1
|
4
|
-
colormap: "plasma"
|
5
|
-
scan_types: false
|
6
|
-
plot_data:
|
7
|
-
- plot_name: "BPM4i plots vs samx"
|
8
|
-
x_label: "Motor X"
|
9
|
-
y_label: "bpm4i"
|
10
|
-
sources:
|
11
|
-
- type: "scan_segment"
|
12
|
-
signals:
|
13
|
-
x:
|
14
|
-
- name : "samx"
|
15
|
-
y:
|
16
|
-
- name : "bpm4i"
|
17
|
-
|
18
|
-
- plot_name: "Gauss plots vs samx"
|
19
|
-
x_label: "Motor X"
|
20
|
-
y_label: "Gauss"
|
21
|
-
sources:
|
22
|
-
- type: "scan_segment"
|
23
|
-
signals:
|
24
|
-
x:
|
25
|
-
- name: "samx"
|
26
|
-
y:
|
27
|
-
- name: "gauss_bpm"
|
@@ -1,82 +0,0 @@
|
|
1
|
-
plot_settings:
|
2
|
-
background_color: "white"
|
3
|
-
num_columns: 3
|
4
|
-
colormap: "plasma"
|
5
|
-
scan_types: true
|
6
|
-
plot_data:
|
7
|
-
grid_scan:
|
8
|
-
- plot_name: "Grid plot 1"
|
9
|
-
x_label: "Motor X"
|
10
|
-
y_label: "BPM"
|
11
|
-
sources:
|
12
|
-
- type: "scan_segment"
|
13
|
-
signals:
|
14
|
-
x:
|
15
|
-
- name: "samx"
|
16
|
-
entry: "samx"
|
17
|
-
y:
|
18
|
-
- name: "gauss_bpm"
|
19
|
-
entry: "gauss_bpm"
|
20
|
-
- plot_name: "Grid plot 2"
|
21
|
-
x_label: "Motor X"
|
22
|
-
y_label: "BPM"
|
23
|
-
sources:
|
24
|
-
- type: "scan_segment"
|
25
|
-
signals:
|
26
|
-
x:
|
27
|
-
- name: "samx"
|
28
|
-
entry: "samx"
|
29
|
-
y:
|
30
|
-
- name: "gauss_adc1"
|
31
|
-
entry: "gauss_adc1"
|
32
|
-
- plot_name: "Grid plot 3"
|
33
|
-
x_label: "Motor X"
|
34
|
-
y_label: "BPM"
|
35
|
-
sources:
|
36
|
-
- type: "scan_segment"
|
37
|
-
signals:
|
38
|
-
x:
|
39
|
-
- name: "samx"
|
40
|
-
entry: "samx"
|
41
|
-
y:
|
42
|
-
- name: "gauss_adc2"
|
43
|
-
entry: "gauss_adc2"
|
44
|
-
- plot_name: "Grid plot 4"
|
45
|
-
x_label: "Motor X"
|
46
|
-
y_label: "BPM"
|
47
|
-
sources:
|
48
|
-
- type: "scan_segment"
|
49
|
-
signals:
|
50
|
-
x:
|
51
|
-
- name: "samx"
|
52
|
-
entry: "samx"
|
53
|
-
y:
|
54
|
-
- name: "bpm4i"
|
55
|
-
entry: "bpm4i"
|
56
|
-
line_scan:
|
57
|
-
- plot_name: "Multiple Gauss Plot"
|
58
|
-
x_label: "Motor X"
|
59
|
-
y_label: "BPM"
|
60
|
-
sources:
|
61
|
-
- type: "scan_segment"
|
62
|
-
signals:
|
63
|
-
x:
|
64
|
-
- name: "samx"
|
65
|
-
y:
|
66
|
-
- name: "gauss_bpm"
|
67
|
-
entry: "gauss_bpm"
|
68
|
-
- name: "gauss_adc1"
|
69
|
-
entry: "gauss_adc1"
|
70
|
-
- name: "gauss_adc2"
|
71
|
-
entry: "gauss_adc2"
|
72
|
-
- plot_name: "BPM Plot"
|
73
|
-
x_label: "Motor X"
|
74
|
-
y_label: "BPM"
|
75
|
-
sources:
|
76
|
-
- type: "scan_segment"
|
77
|
-
signals:
|
78
|
-
x:
|
79
|
-
- name: "samx"
|
80
|
-
y:
|
81
|
-
- name: "bpm4i"
|
82
|
-
entry: "bpm4i"
|
@@ -1,143 +0,0 @@
|
|
1
|
-
# pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
|
2
|
-
import numpy as np
|
3
|
-
import pytest
|
4
|
-
from qtpy.QtCore import QPointF
|
5
|
-
|
6
|
-
from bec_widgets.widgets.image.image_widget import BECImageWidget
|
7
|
-
from bec_widgets.widgets.waveform.waveform_widget import BECWaveformWidget
|
8
|
-
|
9
|
-
from .client_mocks import mocked_client
|
10
|
-
|
11
|
-
# pylint: disable = redefined-outer-name
|
12
|
-
|
13
|
-
|
14
|
-
@pytest.fixture
|
15
|
-
def plot_widget_with_crosshair(qtbot, mocked_client):
|
16
|
-
widget = BECWaveformWidget(client=mocked_client())
|
17
|
-
widget.plot(x=[1, 2, 3], y=[4, 5, 6])
|
18
|
-
widget.waveform.hook_crosshair()
|
19
|
-
qtbot.addWidget(widget)
|
20
|
-
qtbot.waitExposed(widget)
|
21
|
-
|
22
|
-
yield widget.waveform.crosshair, widget.waveform.plot_item
|
23
|
-
|
24
|
-
|
25
|
-
@pytest.fixture
|
26
|
-
def image_widget_with_crosshair(qtbot, mocked_client):
|
27
|
-
widget = BECImageWidget(client=mocked_client())
|
28
|
-
widget._image.add_custom_image(name="test", data=np.random.random((100, 200)))
|
29
|
-
widget._image.hook_crosshair()
|
30
|
-
qtbot.addWidget(widget)
|
31
|
-
qtbot.waitExposed(widget)
|
32
|
-
|
33
|
-
yield widget._image.crosshair, widget._image.plot_item
|
34
|
-
|
35
|
-
|
36
|
-
def test_mouse_moved_lines(plot_widget_with_crosshair):
|
37
|
-
crosshair, plot_item = plot_widget_with_crosshair
|
38
|
-
|
39
|
-
# Connect the signals to slots that will store the emitted values
|
40
|
-
emitted_values_1D = []
|
41
|
-
crosshair.coordinatesChanged1D.connect(emitted_values_1D.append)
|
42
|
-
|
43
|
-
# Simulate a mouse moved event at a specific position
|
44
|
-
pos_in_view = QPointF(2, 5)
|
45
|
-
pos_in_scene = plot_item.vb.mapViewToScene(pos_in_view)
|
46
|
-
event_mock = [pos_in_scene]
|
47
|
-
|
48
|
-
# Call the mouse_moved method
|
49
|
-
crosshair.mouse_moved(event_mock)
|
50
|
-
|
51
|
-
# Assert the expected behavior
|
52
|
-
assert crosshair.v_line.pos().x() == 2
|
53
|
-
assert crosshair.h_line.pos().y() == 5
|
54
|
-
|
55
|
-
|
56
|
-
def test_mouse_moved_signals(plot_widget_with_crosshair):
|
57
|
-
crosshair, plot_item = plot_widget_with_crosshair
|
58
|
-
|
59
|
-
# Create a slot that will store the emitted values as tuples
|
60
|
-
emitted_values_1D = []
|
61
|
-
|
62
|
-
def slot(coordinates):
|
63
|
-
emitted_values_1D.append(coordinates)
|
64
|
-
|
65
|
-
# Connect the signal to the custom slot
|
66
|
-
crosshair.coordinatesChanged1D.connect(slot)
|
67
|
-
|
68
|
-
# Simulate a mouse moved event at a specific position
|
69
|
-
pos_in_view = QPointF(2, 5)
|
70
|
-
pos_in_scene = plot_item.vb.mapViewToScene(pos_in_view)
|
71
|
-
event_mock = [pos_in_scene]
|
72
|
-
|
73
|
-
# Call the mouse_moved method
|
74
|
-
crosshair.mouse_moved(event_mock)
|
75
|
-
|
76
|
-
# Assert the expected behavior
|
77
|
-
assert emitted_values_1D == [("Curve 1", 2, 5)]
|
78
|
-
|
79
|
-
|
80
|
-
def test_mouse_moved_signals_outside(plot_widget_with_crosshair):
|
81
|
-
crosshair, plot_item = plot_widget_with_crosshair
|
82
|
-
|
83
|
-
# Create a slot that will store the emitted values as tuples
|
84
|
-
emitted_values_1D = []
|
85
|
-
|
86
|
-
def slot(x, y_values):
|
87
|
-
emitted_values_1D.append((x, y_values))
|
88
|
-
|
89
|
-
# Connect the signal to the custom slot
|
90
|
-
crosshair.coordinatesChanged1D.connect(slot)
|
91
|
-
|
92
|
-
# Simulate a mouse moved event at a specific position
|
93
|
-
pos_in_view = QPointF(22, 55)
|
94
|
-
pos_in_scene = plot_item.vb.mapViewToScene(pos_in_view)
|
95
|
-
event_mock = [pos_in_scene]
|
96
|
-
|
97
|
-
# Call the mouse_moved method
|
98
|
-
crosshair.mouse_moved(event_mock)
|
99
|
-
|
100
|
-
# Assert the expected behavior
|
101
|
-
assert emitted_values_1D == []
|
102
|
-
|
103
|
-
|
104
|
-
def test_mouse_moved_signals_2D(image_widget_with_crosshair):
|
105
|
-
crosshair, plot_item = image_widget_with_crosshair
|
106
|
-
|
107
|
-
# Create a slot that will store the emitted values as tuples
|
108
|
-
emitted_values_2D = []
|
109
|
-
|
110
|
-
def slot(coordinates):
|
111
|
-
emitted_values_2D.append(coordinates)
|
112
|
-
|
113
|
-
# Connect the signal to the custom slot
|
114
|
-
crosshair.coordinatesChanged2D.connect(slot)
|
115
|
-
# Simulate a mouse moved event at a specific position
|
116
|
-
pos_in_view = QPointF(22.0, 55.0)
|
117
|
-
pos_in_scene = plot_item.vb.mapViewToScene(pos_in_view)
|
118
|
-
event_mock = [pos_in_scene]
|
119
|
-
# Call the mouse_moved method
|
120
|
-
crosshair.mouse_moved(event_mock)
|
121
|
-
# Assert the expected behavior
|
122
|
-
assert emitted_values_2D == [("test", 22.0, 55.0)]
|
123
|
-
|
124
|
-
|
125
|
-
def test_mouse_moved_signals_2D_outside(image_widget_with_crosshair):
|
126
|
-
crosshair, plot_item = image_widget_with_crosshair
|
127
|
-
|
128
|
-
# Create a slot that will store the emitted values as tuples
|
129
|
-
emitted_values_2D = []
|
130
|
-
|
131
|
-
def slot(x, y):
|
132
|
-
emitted_values_2D.append((x, y))
|
133
|
-
|
134
|
-
# Connect the signal to the custom slot
|
135
|
-
crosshair.coordinatesChanged2D.connect(slot)
|
136
|
-
# Simulate a mouse moved event at a specific position
|
137
|
-
pos_in_view = QPointF(220.0, 555.0)
|
138
|
-
pos_in_scene = plot_item.vb.mapViewToScene(pos_in_view)
|
139
|
-
event_mock = [pos_in_scene]
|
140
|
-
# Call the mouse_moved method
|
141
|
-
crosshair.mouse_moved(event_mock)
|
142
|
-
# Assert the expected behavior
|
143
|
-
assert emitted_values_2D == []
|
@@ -1,70 +0,0 @@
|
|
1
|
-
from unittest import mock
|
2
|
-
|
3
|
-
import pytest
|
4
|
-
from qtpy.QtCore import Qt
|
5
|
-
|
6
|
-
from bec_widgets.widgets.dark_mode_button.dark_mode_button import DarkModeButton
|
7
|
-
|
8
|
-
# pylint: disable=unused-import
|
9
|
-
from .client_mocks import mocked_client
|
10
|
-
|
11
|
-
# pylint: disable=redefined-outer-name
|
12
|
-
|
13
|
-
|
14
|
-
@pytest.fixture
|
15
|
-
def dark_mode_button(qtbot, mocked_client):
|
16
|
-
"""
|
17
|
-
Fixture for the dark mode button.
|
18
|
-
"""
|
19
|
-
button = DarkModeButton(client=mocked_client)
|
20
|
-
qtbot.addWidget(button)
|
21
|
-
qtbot.waitExposed(button)
|
22
|
-
yield button
|
23
|
-
|
24
|
-
|
25
|
-
def test_dark_mode_button_init(dark_mode_button):
|
26
|
-
"""
|
27
|
-
Test that the dark mode button is initialized correctly.
|
28
|
-
"""
|
29
|
-
assert dark_mode_button.dark_mode_enabled is False
|
30
|
-
assert dark_mode_button.mode_button.toolTip() == "Set Dark Mode"
|
31
|
-
|
32
|
-
|
33
|
-
def test_dark_mode_button_toggle(dark_mode_button):
|
34
|
-
"""
|
35
|
-
Test that the dark mode button toggles correctly.
|
36
|
-
"""
|
37
|
-
dark_mode_button.toggle_dark_mode()
|
38
|
-
assert dark_mode_button.dark_mode_enabled is True
|
39
|
-
assert dark_mode_button.mode_button.toolTip() == "Set Light Mode"
|
40
|
-
|
41
|
-
dark_mode_button.toggle_dark_mode()
|
42
|
-
assert dark_mode_button.dark_mode_enabled == False
|
43
|
-
assert dark_mode_button.mode_button.toolTip() == "Set Dark Mode"
|
44
|
-
|
45
|
-
|
46
|
-
def test_dark_mode_button_toggles_on_click(dark_mode_button, qtbot):
|
47
|
-
"""
|
48
|
-
Test that the dark mode button toggles correctly when clicked.
|
49
|
-
"""
|
50
|
-
qtbot.mouseClick(dark_mode_button.mode_button, Qt.MouseButton.LeftButton)
|
51
|
-
assert dark_mode_button.dark_mode_enabled is True
|
52
|
-
assert dark_mode_button.mode_button.toolTip() == "Set Light Mode"
|
53
|
-
|
54
|
-
qtbot.mouseClick(dark_mode_button.mode_button, Qt.MouseButton.LeftButton)
|
55
|
-
assert dark_mode_button.dark_mode_enabled is False
|
56
|
-
assert dark_mode_button.mode_button.toolTip() == "Set Dark Mode"
|
57
|
-
|
58
|
-
|
59
|
-
def test_dark_mode_button_changes_theme(dark_mode_button):
|
60
|
-
"""
|
61
|
-
Test that the dark mode button changes the theme correctly.
|
62
|
-
"""
|
63
|
-
with mock.patch(
|
64
|
-
"bec_widgets.widgets.dark_mode_button.dark_mode_button.set_theme"
|
65
|
-
) as mocked_set_theme:
|
66
|
-
dark_mode_button.toggle_dark_mode()
|
67
|
-
mocked_set_theme.assert_called_with("dark")
|
68
|
-
|
69
|
-
dark_mode_button.toggle_dark_mode()
|
70
|
-
mocked_set_theme.assert_called_with("light")
|