bec-widgets 0.99.8__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.
Files changed (155) hide show
  1. CHANGELOG.md +6 -6
  2. PKG-INFO +1 -1
  3. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/METADATA +1 -1
  4. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/RECORD +8 -155
  5. pyproject.toml +6 -1
  6. docs/Makefile +0 -20
  7. docs/_static/custom.css +0 -170
  8. docs/_templates/custom-class-template.rst +0 -34
  9. docs/_templates/custom-module-template.rst +0 -66
  10. docs/api_reference/api_reference.md +0 -12
  11. docs/assets/apps_48dp.svg +0 -1
  12. docs/assets/display_settings_48dp.svg +0 -1
  13. docs/assets/index_api.svg +0 -97
  14. docs/assets/index_contribute.svg +0 -76
  15. docs/assets/index_getting_started.svg +0 -66
  16. docs/assets/index_user_guide.svg +0 -67
  17. docs/assets/rocket_launch_48dp.svg +0 -1
  18. docs/assets/widget_screenshots/buttons.png +0 -0
  19. docs/assets/widget_screenshots/device_box.png +0 -0
  20. docs/assets/widget_screenshots/device_browser.png +0 -0
  21. docs/assets/widget_screenshots/device_inputs.png +0 -0
  22. docs/assets/widget_screenshots/dock_area.png +0 -0
  23. docs/assets/widget_screenshots/figure.png +0 -0
  24. docs/assets/widget_screenshots/image_widget.png +0 -0
  25. docs/assets/widget_screenshots/motor_map_widget.png +0 -0
  26. docs/assets/widget_screenshots/position_indicator.png +0 -0
  27. docs/assets/widget_screenshots/queue.png +0 -0
  28. docs/assets/widget_screenshots/ring_progress_bar.png +0 -0
  29. docs/assets/widget_screenshots/scan_controller.png +0 -0
  30. docs/assets/widget_screenshots/spinner.gif +0 -0
  31. docs/assets/widget_screenshots/status_box.png +0 -0
  32. docs/assets/widget_screenshots/text_box.png +0 -0
  33. docs/assets/widget_screenshots/toggle.png +0 -0
  34. docs/assets/widget_screenshots/waveform_widget.png +0 -0
  35. docs/assets/widget_screenshots/website.png +0 -0
  36. docs/conf.py +0 -82
  37. docs/developer/developer.md +0 -52
  38. docs/developer/introduction/concepts.md +0 -14
  39. docs/developer/introduction/contributing.md +0 -28
  40. docs/developer/introduction/introduction.md +0 -16
  41. docs/developer/introduction/useful_links.md +0 -23
  42. docs/developer/widget_development/bec_dispatcher.md +0 -143
  43. docs/developer/widget_development/widget_base_class.md +0 -171
  44. docs/developer/widget_development/widget_development.md +0 -14
  45. docs/index.md +0 -74
  46. docs/introduction/introduction.md +0 -18
  47. docs/make.bat +0 -35
  48. docs/requirements.txt +0 -12
  49. docs/user/api_reference/api_reference.md +0 -11
  50. docs/user/applications/applications.md +0 -10
  51. docs/user/customisation.md +0 -123
  52. docs/user/getting_started/BECDockArea.png +0 -0
  53. docs/user/getting_started/auto_updates.md +0 -82
  54. docs/user/getting_started/getting_started.md +0 -15
  55. docs/user/getting_started/gui_complex_gui.gif +0 -0
  56. docs/user/getting_started/installation.md +0 -33
  57. docs/user/getting_started/quick_start.md +0 -110
  58. docs/user/getting_started/video_tutorials.md +0 -17
  59. docs/user/user.md +0 -71
  60. docs/user/widgets/bec_figure/BECFigure.png +0 -0
  61. docs/user/widgets/bec_figure/bec_figure.md +0 -105
  62. docs/user/widgets/bec_status_box/bec_status_box.gif +0 -0
  63. docs/user/widgets/bec_status_box/bec_status_box.md +0 -38
  64. docs/user/widgets/buttons/buttons.md +0 -90
  65. docs/user/widgets/buttons/dark_mode_disabled.png +0 -0
  66. docs/user/widgets/buttons/dark_mode_enabled.png +0 -0
  67. docs/user/widgets/device_browser/device_browser.md +0 -36
  68. docs/user/widgets/device_browser/device_browser.png +0 -0
  69. docs/user/widgets/device_input/device_input.md +0 -100
  70. docs/user/widgets/dock_area/BECDockArea.png +0 -0
  71. docs/user/widgets/dock_area/bec_dock_area.md +0 -109
  72. docs/user/widgets/image/image_plot.gif +0 -0
  73. docs/user/widgets/image/image_widget.md +0 -84
  74. docs/user/widgets/motor_map/motor.gif +0 -0
  75. docs/user/widgets/motor_map/motor_map.md +0 -80
  76. docs/user/widgets/position_indicator/position_indicator.md +0 -69
  77. docs/user/widgets/positioner_box/positioner_box.md +0 -63
  78. docs/user/widgets/progress_bar/progress_bar.gif +0 -0
  79. docs/user/widgets/progress_bar/ring_progress_bar.md +0 -103
  80. docs/user/widgets/queue/queue.md +0 -41
  81. docs/user/widgets/scan_control/hide_scan_control.png +0 -0
  82. docs/user/widgets/scan_control/scan_control.gif +0 -0
  83. docs/user/widgets/scan_control/scan_control.md +0 -54
  84. docs/user/widgets/spinner/spinner.md +0 -68
  85. docs/user/widgets/text_box/text_box.md +0 -74
  86. docs/user/widgets/toggle/toggle.md +0 -66
  87. docs/user/widgets/waveform/bec_figure_dap.gif +0 -0
  88. docs/user/widgets/waveform/scatter_2D.gif +0 -0
  89. docs/user/widgets/waveform/w1D.gif +0 -0
  90. docs/user/widgets/waveform/waveform_widget.md +0 -132
  91. docs/user/widgets/website/website.md +0 -69
  92. docs/user/widgets/widgets.md +0 -220
  93. tests/__init__.py +0 -0
  94. tests/end-2-end/__init__.py +0 -0
  95. tests/end-2-end/conftest.py +0 -53
  96. tests/end-2-end/test_bec_dock_rpc_e2e.py +0 -298
  97. tests/end-2-end/test_bec_figure_rpc_e2e.py +0 -212
  98. tests/end-2-end/test_rpc_register_e2e.py +0 -40
  99. tests/end-2-end/test_scan_control_e2e.py +0 -71
  100. tests/references/SpinnerWidget/SpinnerWidget_darwin.png +0 -0
  101. tests/references/SpinnerWidget/SpinnerWidget_linux.png +0 -0
  102. tests/references/SpinnerWidget/SpinnerWidget_started_darwin.png +0 -0
  103. tests/references/SpinnerWidget/SpinnerWidget_started_linux.png +0 -0
  104. tests/unit_tests/__init__.py +0 -0
  105. tests/unit_tests/client_mocks.py +0 -189
  106. tests/unit_tests/conftest.py +0 -64
  107. tests/unit_tests/test_bec_connector.py +0 -80
  108. tests/unit_tests/test_bec_dispatcher.py +0 -119
  109. tests/unit_tests/test_bec_dock.py +0 -155
  110. tests/unit_tests/test_bec_figure.py +0 -270
  111. tests/unit_tests/test_bec_image.py +0 -63
  112. tests/unit_tests/test_bec_image_widget.py +0 -217
  113. tests/unit_tests/test_bec_motor_map.py +0 -282
  114. tests/unit_tests/test_bec_queue.py +0 -111
  115. tests/unit_tests/test_bec_status_box.py +0 -123
  116. tests/unit_tests/test_client_utils.py +0 -76
  117. tests/unit_tests/test_color_map_selector.py +0 -42
  118. tests/unit_tests/test_color_validation.py +0 -75
  119. tests/unit_tests/test_configs/config_device.yaml +0 -33
  120. tests/unit_tests/test_configs/config_device_no_entry.yaml +0 -27
  121. tests/unit_tests/test_configs/config_scan.yaml +0 -82
  122. tests/unit_tests/test_crosshair.py +0 -143
  123. tests/unit_tests/test_dark_mode_button.py +0 -70
  124. tests/unit_tests/test_device_browser.py +0 -83
  125. tests/unit_tests/test_device_input_base.py +0 -76
  126. tests/unit_tests/test_device_input_widgets.py +0 -178
  127. tests/unit_tests/test_error_utils.py +0 -63
  128. tests/unit_tests/test_generate_cli_client.py +0 -123
  129. tests/unit_tests/test_generate_plugin.py +0 -155
  130. tests/unit_tests/test_motor_map_widget.py +0 -194
  131. tests/unit_tests/test_msgs/__init__.py +0 -0
  132. tests/unit_tests/test_msgs/available_scans_message.py +0 -989
  133. tests/unit_tests/test_plot_base.py +0 -95
  134. tests/unit_tests/test_plugin_utils.py +0 -13
  135. tests/unit_tests/test_positioner_box.py +0 -130
  136. tests/unit_tests/test_ring_progress_bar.py +0 -337
  137. tests/unit_tests/test_rpc_register.py +0 -52
  138. tests/unit_tests/test_rpc_server.py +0 -42
  139. tests/unit_tests/test_rpc_widget_handler.py +0 -7
  140. tests/unit_tests/test_scan_control.py +0 -324
  141. tests/unit_tests/test_scan_control_group_box.py +0 -160
  142. tests/unit_tests/test_setting_dialog.py +0 -96
  143. tests/unit_tests/test_spinner.py +0 -31
  144. tests/unit_tests/test_stop_button.py +0 -27
  145. tests/unit_tests/test_text_box_widget.py +0 -54
  146. tests/unit_tests/test_toggle.py +0 -38
  147. tests/unit_tests/test_vscode_widget.py +0 -75
  148. tests/unit_tests/test_waveform1d.py +0 -712
  149. tests/unit_tests/test_waveform_widget.py +0 -462
  150. tests/unit_tests/test_website_widget.py +0 -25
  151. tests/unit_tests/test_widget_io.py +0 -90
  152. tests/unit_tests/test_yaml_dialog.py +0 -163
  153. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/WHEEL +0 -0
  154. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/entry_points.txt +0 -0
  155. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/licenses/LICENSE +0 -0
@@ -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: "magma"
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: "magma"
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: "magma"
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 np.isclose(crosshair.v_line.pos().x(), 2)
53
- assert np.isclose(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")
@@ -1,83 +0,0 @@
1
- from typing import TYPE_CHECKING
2
- from unittest import mock
3
-
4
- import pytest
5
- from qtpy.QtCore import Qt
6
-
7
- from bec_widgets.widgets.device_browser.device_browser import DeviceBrowser
8
-
9
- from .client_mocks import mocked_client
10
-
11
- if TYPE_CHECKING:
12
- from qtpy.QtWidgets import QListWidgetItem
13
-
14
- from bec_widgets.widgets.device_browser.device_item.device_item import DeviceItem
15
-
16
-
17
- @pytest.fixture
18
- def device_browser(qtbot, mocked_client):
19
- dev_browser = DeviceBrowser(client=mocked_client)
20
- qtbot.addWidget(dev_browser)
21
- qtbot.waitExposed(dev_browser)
22
- yield dev_browser
23
-
24
-
25
- def test_device_browser_init_with_devices(device_browser):
26
- """
27
- Test that the device browser is initialized with the correct number of devices.
28
- """
29
- device_list = device_browser.ui.device_list
30
- assert device_list.count() == len(device_browser.dev)
31
-
32
-
33
- def test_device_browser_filtering(qtbot, device_browser):
34
- """
35
- Test that the device browser is able to filter the device list.
36
- """
37
- device_list = device_browser.ui.device_list
38
- device_browser.ui.filter_input.setText("sam")
39
- qtbot.wait(1000)
40
- assert device_list.count() == 3
41
-
42
- device_browser.ui.filter_input.setText("nonexistent")
43
- qtbot.wait(1000)
44
- assert device_list.count() == 0
45
-
46
- device_browser.ui.filter_input.setText("")
47
- qtbot.wait(1000)
48
- assert device_list.count() == len(device_browser.dev)
49
-
50
-
51
- def test_device_item_mouse_press_event(device_browser, qtbot):
52
- """
53
- Test that the mousePressEvent is triggered correctly.
54
- """
55
- # Simulate a left mouse press event on the device item
56
- device_item: QListWidgetItem = device_browser.ui.device_list.itemAt(0, 0)
57
- widget: DeviceItem = device_browser.ui.device_list.itemWidget(device_item)
58
- qtbot.mousePress(widget.label, Qt.MouseButton.LeftButton)
59
-
60
-
61
- def test_device_item_mouse_press_event_creates_drag(device_browser, qtbot):
62
- """
63
- Test that the mousePressEvent is triggered correctly and initiates a drag.
64
- """
65
- device_item: QListWidgetItem = device_browser.ui.device_list.itemAt(0, 0)
66
- widget: DeviceItem = device_browser.ui.device_list.itemWidget(device_item)
67
- device_name = widget.device
68
- with mock.patch("qtpy.QtGui.QDrag.exec_") as mock_exec:
69
- with mock.patch("qtpy.QtGui.QDrag.setMimeData") as mock_set_mimedata:
70
- qtbot.mousePress(widget.label, Qt.MouseButton.LeftButton)
71
- mock_set_mimedata.assert_called_once()
72
- mock_exec.assert_called_once()
73
- assert mock_set_mimedata.call_args[0][0].text() == device_name
74
-
75
-
76
- def test_device_item_double_click_event(device_browser, qtbot):
77
- """
78
- Test that the mouseDoubleClickEvent is triggered correctly.
79
- """
80
- # Simulate a left mouse press event on the device item
81
- device_item: QListWidgetItem = device_browser.ui.device_list.itemAt(0, 0)
82
- widget: DeviceItem = device_browser.ui.device_list.itemWidget(device_item)
83
- qtbot.mouseDClick(widget, Qt.LeftButton)
@@ -1,76 +0,0 @@
1
- import pytest
2
- from qtpy.QtWidgets import QWidget
3
-
4
- from bec_widgets.widgets.base_classes.device_input_base import DeviceInputBase
5
-
6
- from .client_mocks import mocked_client
7
-
8
-
9
- # DeviceInputBase is meant to be mixed in a QWidget
10
- class DeviceInputWidget(DeviceInputBase, QWidget):
11
- def __init__(self, parent=None, client=None, config=None, gui_id=None):
12
- super().__init__(client=client, config=config, gui_id=gui_id)
13
- QWidget.__init__(self, parent=parent)
14
-
15
-
16
- @pytest.fixture
17
- def device_input_base(qtbot, mocked_client):
18
- widget = DeviceInputWidget(client=mocked_client)
19
- qtbot.addWidget(widget)
20
- qtbot.waitExposed(widget)
21
- yield widget
22
-
23
-
24
- def test_device_input_base_init(device_input_base):
25
- assert device_input_base is not None
26
- assert device_input_base.client is not None
27
- assert isinstance(device_input_base, DeviceInputBase)
28
- assert device_input_base.config.widget_class == "DeviceInputWidget"
29
- assert device_input_base.config.device_filter is None
30
- assert device_input_base.config.default is None
31
- assert device_input_base.devices == []
32
-
33
-
34
- def test_device_input_base_init_with_config(mocked_client):
35
- config = {
36
- "widget_class": "DeviceInputWidget",
37
- "gui_id": "test_gui_id",
38
- "device_filter": "FakePositioner",
39
- "default": "samx",
40
- }
41
- widget = DeviceInputWidget(client=mocked_client, config=config)
42
- assert widget.config.gui_id == "test_gui_id"
43
- assert widget.config.device_filter == "FakePositioner"
44
- assert widget.config.default == "samx"
45
-
46
-
47
- def test_device_input_base_set_device_filter(device_input_base):
48
- device_input_base.set_device_filter("FakePositioner")
49
- assert device_input_base.config.device_filter == "FakePositioner"
50
-
51
-
52
- def test_device_input_base_set_device_filter_error(device_input_base):
53
- with pytest.raises(ValueError) as excinfo:
54
- device_input_base.set_device_filter("NonExistingClass")
55
- assert "Device filter NonExistingClass is not in the device list." in str(excinfo.value)
56
-
57
-
58
- def test_device_input_base_set_default_device(device_input_base):
59
- device_input_base.set_default_device("samx")
60
- assert device_input_base.config.default == "samx"
61
-
62
-
63
- def test_device_input_base_set_default_device_error(device_input_base):
64
- with pytest.raises(ValueError) as excinfo:
65
- device_input_base.set_default_device("NonExistingDevice")
66
- assert "Default device NonExistingDevice is not in the device list." in str(excinfo.value)
67
-
68
-
69
- def test_device_input_base_get_device_list(device_input_base):
70
- devices = device_input_base.get_device_list("FakePositioner")
71
- assert devices == ["samx", "samy", "samz", "aptrx", "aptry"]
72
-
73
-
74
- def test_device_input_base_get_filters(device_input_base):
75
- filters = device_input_base.get_available_filters()
76
- assert filters == {"FakePositioner", "FakeDevice", "Positioner", "Device"}