mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-03-13 04:08:01 +01:00
refactor: global refactoring to use device-signal pair names
This commit is contained in:
@@ -58,8 +58,8 @@ def test_rpc_add_dock_with_plots_e2e(qtbot, bec_client_lib, connected_client_gui
|
||||
assert gui._ipython_registry[mm._gui_id].__class__ == MotorMap
|
||||
|
||||
mm.map("samx", "samy")
|
||||
curve = wf.plot(x_name="samx", y_name="bpm4i")
|
||||
im_item = im.image(device_name="eiger", device_entry="preview")
|
||||
curve = wf.plot(device_x="samx", device_y="bpm4i")
|
||||
im_item = im.image(device="eiger", signal="preview")
|
||||
|
||||
assert curve.__class__.__name__ == "RPCReference"
|
||||
assert curve.__class__ == RPCReference
|
||||
|
||||
@@ -34,7 +34,7 @@ def test_rpc_plotting_shortcuts_init_configs(qtbot, connected_client_gui_obj):
|
||||
sw = dock_area.new("ScatterWaveform")
|
||||
mw = dock_area.new("MultiWaveform")
|
||||
|
||||
c1 = wf.plot(x_name="samx", y_name="bpm4i")
|
||||
c1 = wf.plot(device_x="samx", device_y="bpm4i")
|
||||
# Adding custom curves, removing one and adding it again should not crash
|
||||
c2 = wf.plot(y=[1, 2, 3], x=[1, 2, 3])
|
||||
assert c2.object_name == "Curve_0"
|
||||
@@ -42,9 +42,9 @@ def test_rpc_plotting_shortcuts_init_configs(qtbot, connected_client_gui_obj):
|
||||
c3 = wf.plot(y=[1, 2, 3], x=[1, 2, 3])
|
||||
assert c3.object_name == "Curve_0"
|
||||
|
||||
im.image(device_name="eiger", device_entry="preview")
|
||||
mm.map(x_name="samx", y_name="samy")
|
||||
sw.plot(x_name="samx", y_name="samy", z_name="bpm4a")
|
||||
im.image(device="eiger", signal="preview")
|
||||
mm.map(device_x="samx", device_y="samy")
|
||||
sw.plot(device_x="samx", device_y="samy", device_z="bpm4a")
|
||||
mw.plot(monitor="waveform")
|
||||
# Adding multiple custom curves sho
|
||||
|
||||
@@ -70,8 +70,8 @@ def test_rpc_plotting_shortcuts_init_configs(qtbot, connected_client_gui_obj):
|
||||
# Curve
|
||||
assert c1._config_dict["signal"] == {
|
||||
"dap": None,
|
||||
"name": "bpm4i",
|
||||
"entry": "bpm4i",
|
||||
"device": "bpm4i",
|
||||
"signal": "bpm4i",
|
||||
"dap_oversample": 1,
|
||||
}
|
||||
assert c1._config_dict["source"] == "device"
|
||||
@@ -90,9 +90,9 @@ def test_rpc_waveform_scan(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
wf = dock_area.new("Waveform")
|
||||
|
||||
# add 3 different curves to track
|
||||
wf.plot(x_name="samx", y_name="bpm4i")
|
||||
wf.plot(x_name="samx", y_name="bpm3a")
|
||||
wf.plot(x_name="samx", y_name="bpm4d")
|
||||
wf.plot(device_x="samx", device_y="bpm4i")
|
||||
wf.plot(device_x="samx", device_y="bpm3a")
|
||||
wf.plot(device_x="samx", device_y="bpm4d")
|
||||
|
||||
status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
|
||||
status.wait()
|
||||
@@ -133,7 +133,7 @@ def test_async_plotting(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
dev.waveform.async_update.set("add").wait()
|
||||
dev.waveform.waveform_shape.set(10000).wait()
|
||||
wf = dock_area.new("Waveform")
|
||||
curve = wf.plot(y_name="waveform")
|
||||
curve = wf.plot(device_y="waveform")
|
||||
|
||||
status = scans.line_scan(dev.samx, -5, 5, steps=5, exp_time=0.05, relative=False)
|
||||
status.wait()
|
||||
@@ -165,7 +165,7 @@ def test_rpc_image(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
scans = client.scans
|
||||
|
||||
im = dock_area.new("Image")
|
||||
im.image(device_name="eiger", device_entry="preview")
|
||||
im.image(device="eiger", signal="preview")
|
||||
|
||||
status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
|
||||
status.wait()
|
||||
@@ -188,7 +188,7 @@ def test_rpc_motor_map(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
dock_area = gui.bec
|
||||
|
||||
motor_map = dock_area.new("MotorMap")
|
||||
motor_map.map(x_name="samx", y_name="samy")
|
||||
motor_map.map(device_x="samx", device_y="samy")
|
||||
|
||||
initial_pos_x = dev.samx.read()["samx"]["value"]
|
||||
initial_pos_y = dev.samy.read()["samy"]["value"]
|
||||
@@ -219,7 +219,7 @@ def test_dap_rpc(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
dock_area = gui.bec
|
||||
|
||||
wf = dock_area.new("Waveform")
|
||||
wf.plot(x_name="samx", y_name="bpm4i", dap="GaussianModel")
|
||||
wf.plot(device_x="samx", device_y="bpm4i", dap="GaussianModel")
|
||||
|
||||
dev.bpm4i.sim.select_model("GaussianModel")
|
||||
params = dev.bpm4i.sim.params
|
||||
@@ -262,7 +262,7 @@ def test_waveform_passing_device(qtbot, bec_client_lib, connected_client_gui_obj
|
||||
|
||||
wf = dock_area.new("Waveform")
|
||||
c1 = wf.plot(
|
||||
y_name=dev.samx, y_entry=dev.samx.setpoint
|
||||
device_y=dev.samx, signal_y=dev.samx.setpoint
|
||||
) # using setpoint to not use readback signal
|
||||
|
||||
assert c1.object_name == "samx_samx_setpoint"
|
||||
@@ -342,7 +342,7 @@ def test_rpc_waveform_history_curve(
|
||||
|
||||
# Add curve from history using the chosen selector; single curve per scan to avoid duplicates
|
||||
kwargs = {history_selector: sel_value}
|
||||
curve = wf.plot(x_name="samx", y_name="bpm4i", **kwargs)
|
||||
curve = wf.plot(device_x="samx", device_y="bpm4i", **kwargs)
|
||||
|
||||
num_elements = 10
|
||||
|
||||
|
||||
@@ -12,19 +12,19 @@ def test_rpc_reference_objects(connected_client_gui_obj):
|
||||
dock_area = gui.window_list[0]
|
||||
plt = dock_area.new("Waveform", object_name="fig")
|
||||
|
||||
plt.plot(x_name="samx", y_name="bpm4i")
|
||||
plt.plot(device_x="samx", device_y="bpm4i")
|
||||
|
||||
im = dock_area.new("Image")
|
||||
im.image(device_name="eiger", device_entry="preview")
|
||||
im.image(device="eiger", signal="preview")
|
||||
motor_map = dock_area.new("MotorMap")
|
||||
motor_map.map("samx", "samy")
|
||||
plt_z = dock_area.new("Waveform")
|
||||
plt_z.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
plt_z.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
assert len(plt_z.curves) == 1
|
||||
assert len(plt.curves) == 1
|
||||
assert im.device_name == "eiger"
|
||||
assert im.device_entry == "preview"
|
||||
assert im.device == "eiger"
|
||||
assert im.signal == "preview"
|
||||
|
||||
assert isinstance(im.main_image, RPCReference)
|
||||
image_item = gui._ipython_registry.get(im.main_image._gui_id, None)
|
||||
|
||||
@@ -234,7 +234,7 @@ def test_widgets_e2e_image(qtbot, connected_client_gui_obj, random_generator_fro
|
||||
scans = bec.scans
|
||||
dev = bec.device_manager.devices
|
||||
# Test rpc calls
|
||||
img = widget.image(device_name=dev.eiger.name, device_entry="preview")
|
||||
img = widget.image(device=dev.eiger.name, signal="preview")
|
||||
assert img.get_data() is None
|
||||
# Run a scan and plot the image
|
||||
s = scans.line_scan(dev.samx, -3, 3, steps=50, exp_time=0.01, relative=False)
|
||||
@@ -254,7 +254,7 @@ def test_widgets_e2e_image(qtbot, connected_client_gui_obj, random_generator_fro
|
||||
assert np.allclose(img.get_data(), last_img)
|
||||
|
||||
# Now add a device with a preview signal
|
||||
img = widget.image(device_name="eiger", device_entry="preview")
|
||||
img = widget.image(device="eiger", signal="preview")
|
||||
s = scans.line_scan(dev.samx, -3, 3, steps=50, exp_time=0.01, relative=False)
|
||||
s.wait()
|
||||
|
||||
|
||||
@@ -179,15 +179,15 @@ def test_add_new_curve(curve_tree_fixture):
|
||||
assert curve_tree.tree.topLevelItemCount() == 0
|
||||
|
||||
with patch.object(curve_tree, "_ensure_color_buffer_size") as ensure_spy:
|
||||
new_item = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
|
||||
new_item = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
|
||||
ensure_spy.assert_called_once()
|
||||
|
||||
assert curve_tree.tree.topLevelItemCount() == 1
|
||||
last_item = curve_tree.all_items[-1]
|
||||
assert last_item is new_item
|
||||
assert new_item.config.source == "device"
|
||||
assert new_item.config.signal.name == "bpm4i"
|
||||
assert new_item.config.signal.entry == "bpm4i"
|
||||
assert new_item.config.signal.device == "bpm4i"
|
||||
assert new_item.config.signal.signal == "bpm4i"
|
||||
assert new_item.config.color in curve_tree.color_buffer
|
||||
|
||||
|
||||
@@ -197,8 +197,8 @@ def test_renormalize_colors(curve_tree_fixture):
|
||||
"""
|
||||
curve_tree, wf = curve_tree_fixture
|
||||
# Add multiple curves
|
||||
c1 = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
|
||||
c2 = curve_tree.add_new_curve(name="bpm3a", entry="bpm3a")
|
||||
c1 = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
|
||||
c2 = curve_tree.add_new_curve(device="bpm3a", signal="bpm3a")
|
||||
curve_tree.color_buffer = []
|
||||
|
||||
set_color_spy_c1 = patch.object(c1.color_button, "set_color")
|
||||
@@ -215,7 +215,7 @@ def test_expand_collapse(curve_tree_fixture):
|
||||
Test expand_all_daps() and collapse_all_daps() calls expand/collapse on every top-level item.
|
||||
"""
|
||||
curve_tree, wf = curve_tree_fixture
|
||||
c1 = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
|
||||
c1 = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
|
||||
curve_tree.tree.expandAll()
|
||||
expand_spy = patch.object(curve_tree.tree, "expandItem")
|
||||
collapse_spy = patch.object(curve_tree.tree, "collapseItem")
|
||||
@@ -236,8 +236,8 @@ def test_send_curve_json(curve_tree_fixture, monkeypatch):
|
||||
"""
|
||||
curve_tree, wf = curve_tree_fixture
|
||||
# Add multiple curves
|
||||
curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
|
||||
curve_tree.add_new_curve(name="bpm3a", entry="bpm3a")
|
||||
curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
|
||||
curve_tree.add_new_curve(device="bpm3a", signal="bpm3a")
|
||||
|
||||
curve_tree.color_palette = "viridis"
|
||||
curve_tree.send_curve_json()
|
||||
@@ -282,7 +282,7 @@ def test_add_dap_row(curve_tree_fixture):
|
||||
curve_tree, wf = curve_tree_fixture
|
||||
|
||||
# Add a device curve first
|
||||
device_row = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
|
||||
device_row = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
|
||||
assert device_row.source == "device"
|
||||
assert curve_tree.tree.topLevelItemCount() == 1
|
||||
assert device_row.childCount() == 0
|
||||
@@ -299,8 +299,8 @@ def test_add_dap_row(curve_tree_fixture):
|
||||
assert dap_child.config.parent_label == device_row.config.label
|
||||
|
||||
# Check that the DAP inherits device name/entry from parent
|
||||
assert dap_child.config.signal.name == "bpm4i"
|
||||
assert dap_child.config.signal.entry == "bpm4i"
|
||||
assert dap_child.config.signal.device == "bpm4i"
|
||||
assert dap_child.config.signal.signal == "bpm4i"
|
||||
|
||||
# Check that the item is in the curve_tree's all_items list
|
||||
assert dap_child in curve_tree.all_items
|
||||
@@ -313,8 +313,8 @@ def test_remove_self_top_level(curve_tree_fixture):
|
||||
curve_tree, wf = curve_tree_fixture
|
||||
|
||||
# Add two device curves
|
||||
row1 = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
|
||||
row2 = curve_tree.add_new_curve(name="bpm3a", entry="bpm3a")
|
||||
row1 = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
|
||||
row2 = curve_tree.add_new_curve(device="bpm3a", signal="bpm3a")
|
||||
assert curve_tree.tree.topLevelItemCount() == 2
|
||||
assert len(curve_tree.all_items) == 2
|
||||
|
||||
@@ -335,7 +335,7 @@ def test_remove_self_child(curve_tree_fixture):
|
||||
curve_tree, wf = curve_tree_fixture
|
||||
|
||||
# Add a device curve and a DAP child
|
||||
device_row = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
|
||||
device_row = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
|
||||
device_row.add_dap_row()
|
||||
dap_child = device_row.child(0)
|
||||
|
||||
@@ -360,7 +360,7 @@ def test_export_data_dap(curve_tree_fixture):
|
||||
curve_tree, wf = curve_tree_fixture
|
||||
|
||||
# Add a device curve with specific parameters
|
||||
device_row = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
|
||||
device_row = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
|
||||
|
||||
# Add a DAP child
|
||||
device_row.add_dap_row()
|
||||
@@ -375,8 +375,8 @@ def test_export_data_dap(curve_tree_fixture):
|
||||
# Check the exported data
|
||||
assert exported["source"] == "dap"
|
||||
assert exported["parent_label"] == "bpm4i-bpm4i"
|
||||
assert exported["signal"]["name"] == "bpm4i"
|
||||
assert exported["signal"]["entry"] == "bpm4i"
|
||||
assert exported["signal"]["device"] == "bpm4i"
|
||||
assert exported["signal"]["signal"] == "bpm4i"
|
||||
assert exported["signal"]["dap"] == "GaussianModel"
|
||||
assert exported["label"] == "bpm4i-bpm4i-GaussianModel"
|
||||
|
||||
@@ -422,7 +422,7 @@ def test_export_data_history_curve(curve_tree_fixture, scan_history_factory):
|
||||
wf.client.queue.scan_storage.current_scan = None
|
||||
|
||||
# Create a device row and select scan index "2"
|
||||
device_row = curve_tree.add_new_curve(name="bpm4i", entry="bpm4i")
|
||||
device_row = curve_tree.add_new_curve(device="bpm4i", signal="bpm4i")
|
||||
device_row.scan_index_combo.setCurrentText("2")
|
||||
|
||||
exported = device_row.export_data()
|
||||
|
||||
@@ -30,11 +30,11 @@ def heatmap_widget(qtbot, mocked_client):
|
||||
|
||||
|
||||
def test_heatmap_plot(heatmap_widget):
|
||||
heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
assert heatmap_widget._image_config.x_device.name == "samx"
|
||||
assert heatmap_widget._image_config.y_device.name == "samy"
|
||||
assert heatmap_widget._image_config.z_device.name == "bpm4i"
|
||||
assert heatmap_widget._image_config.device_x.device == "samx"
|
||||
assert heatmap_widget._image_config.device_y.device == "samy"
|
||||
assert heatmap_widget._image_config.device_z.device == "bpm4i"
|
||||
|
||||
|
||||
def test_heatmap_on_scan_status_no_scan_id(heatmap_widget):
|
||||
@@ -78,7 +78,7 @@ def test_heatmap_get_image_data_grid_scan(heatmap_widget):
|
||||
info={},
|
||||
request_inputs={"arg_bundle": ["samx", -5, 5, 10, "samy", -5, 5, 10], "kwargs": {}},
|
||||
)
|
||||
heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
heatmap_widget.status_message = scan_msg
|
||||
with mock.patch.object(heatmap_widget, "get_grid_scan_image") as mock_get_grid_scan_image:
|
||||
@@ -147,9 +147,9 @@ def test_heatmap_get_grid_scan_image(heatmap_widget):
|
||||
)
|
||||
heatmap_widget._image_config = HeatmapConfig(
|
||||
parent_id="parent_id",
|
||||
x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
|
||||
y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
|
||||
z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
|
||||
device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
|
||||
device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
|
||||
device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
|
||||
color_map="viridis",
|
||||
)
|
||||
img, _ = heatmap_widget.get_grid_scan_image(list(range(100)), msg=scan_msg)
|
||||
@@ -174,9 +174,9 @@ def _grid_positions(
|
||||
def test_heatmap_grid_scan_direction_and_snaking_x_fast(heatmap_widget):
|
||||
heatmap_widget._image_config = HeatmapConfig(
|
||||
parent_id="parent_id",
|
||||
x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
|
||||
y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
|
||||
z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
|
||||
device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
|
||||
device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
|
||||
device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
|
||||
color_map="viridis",
|
||||
)
|
||||
|
||||
@@ -219,9 +219,9 @@ def test_heatmap_grid_scan_direction_and_snaking_x_fast(heatmap_widget):
|
||||
def test_heatmap_grid_scan_direction_and_snaking_y_fast(heatmap_widget):
|
||||
heatmap_widget._image_config = HeatmapConfig(
|
||||
parent_id="parent_id",
|
||||
x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
|
||||
y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
|
||||
z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
|
||||
device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
|
||||
device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
|
||||
device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
|
||||
color_map="viridis",
|
||||
)
|
||||
|
||||
@@ -277,13 +277,13 @@ def test_heatmap_get_step_scan_image(heatmap_widget):
|
||||
heatmap_widget.scan_item.status_message = scan_msg
|
||||
heatmap_widget._image_config = HeatmapConfig(
|
||||
parent_id="parent_id",
|
||||
x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
|
||||
y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
|
||||
z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
|
||||
device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
|
||||
device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
|
||||
device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
|
||||
color_map="viridis",
|
||||
)
|
||||
img, _ = heatmap_widget.get_step_scan_image(
|
||||
list(np.random.rand(100)), list(np.random.rand(100)), list(range(100)), msg=scan_msg
|
||||
list(np.random.rand(100)), list(np.random.rand(100)), list(range(100))
|
||||
)
|
||||
assert img.shape > (10, 10)
|
||||
|
||||
@@ -291,9 +291,9 @@ def test_heatmap_get_step_scan_image(heatmap_widget):
|
||||
def test_heatmap_update_plot_no_scan_item(heatmap_widget):
|
||||
heatmap_widget._image_config = HeatmapConfig(
|
||||
parent_id="parent_id",
|
||||
x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
|
||||
y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
|
||||
z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
|
||||
device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
|
||||
device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
|
||||
device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
|
||||
color_map="viridis",
|
||||
)
|
||||
with mock.patch.object(heatmap_widget.main_image, "setImage") as mock_set_image:
|
||||
@@ -304,9 +304,9 @@ def test_heatmap_update_plot_no_scan_item(heatmap_widget):
|
||||
def test_heatmap_update_plot(heatmap_widget):
|
||||
heatmap_widget._image_config = HeatmapConfig(
|
||||
parent_id="parent_id",
|
||||
x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
|
||||
y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
|
||||
z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
|
||||
device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
|
||||
device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
|
||||
device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
|
||||
color_map="viridis",
|
||||
)
|
||||
heatmap_widget.scan_item = create_dummy_scan_item()
|
||||
@@ -331,9 +331,9 @@ def test_heatmap_update_plot(heatmap_widget):
|
||||
def test_heatmap_update_plot_without_status_message(heatmap_widget):
|
||||
heatmap_widget._image_config = HeatmapConfig(
|
||||
parent_id="parent_id",
|
||||
x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
|
||||
y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
|
||||
z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
|
||||
device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
|
||||
device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
|
||||
device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
|
||||
color_map="viridis",
|
||||
)
|
||||
heatmap_widget.scan_item = create_dummy_scan_item()
|
||||
@@ -346,9 +346,9 @@ def test_heatmap_update_plot_without_status_message(heatmap_widget):
|
||||
def test_heatmap_update_plot_no_img_data(heatmap_widget):
|
||||
heatmap_widget._image_config = HeatmapConfig(
|
||||
parent_id="parent_id",
|
||||
x_device=HeatmapDeviceSignal(name="samx", entry="samx"),
|
||||
y_device=HeatmapDeviceSignal(name="samy", entry="samy"),
|
||||
z_device=HeatmapDeviceSignal(name="bpm4i", entry="bpm4i"),
|
||||
device_x=HeatmapDeviceSignal(device="samx", signal="samx"),
|
||||
device_y=HeatmapDeviceSignal(device="samy", signal="samy"),
|
||||
device_z=HeatmapDeviceSignal(device="bpm4i", signal="bpm4i"),
|
||||
color_map="viridis",
|
||||
)
|
||||
heatmap_widget.scan_item = create_dummy_scan_item()
|
||||
@@ -407,7 +407,7 @@ def test_heatmap_settings_popup_accept_changes(heatmap_widget, qtbot):
|
||||
"""
|
||||
Test that changes made in the settings dialog are applied correctly.
|
||||
"""
|
||||
heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
assert heatmap_widget.color_map == "plasma" # Default colormap
|
||||
heatmap_widget.show_heatmap_settings()
|
||||
qtbot.waitUntil(lambda: heatmap_widget.heatmap_dialog is not None)
|
||||
@@ -431,7 +431,7 @@ def test_heatmap_settings_popup_show_settings(heatmap_widget, qtbot):
|
||||
"""
|
||||
Test that the settings dialog opens and contains the expected elements.
|
||||
"""
|
||||
heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
heatmap_widget.show_heatmap_settings()
|
||||
qtbot.waitUntil(lambda: heatmap_widget.heatmap_dialog is not None)
|
||||
|
||||
@@ -439,13 +439,13 @@ def test_heatmap_settings_popup_show_settings(heatmap_widget, qtbot):
|
||||
assert dialog.isVisible()
|
||||
assert dialog.widget is not None
|
||||
assert hasattr(dialog.widget.ui, "color_map")
|
||||
assert hasattr(dialog.widget.ui, "x_name")
|
||||
assert hasattr(dialog.widget.ui, "y_name")
|
||||
assert hasattr(dialog.widget.ui, "z_name")
|
||||
assert hasattr(dialog.widget.ui, "device_x")
|
||||
assert hasattr(dialog.widget.ui, "device_y")
|
||||
assert hasattr(dialog.widget.ui, "device_z")
|
||||
|
||||
# Check that the ui elements are correctly initialized
|
||||
assert dialog.widget.ui.color_map.colormap == heatmap_widget.color_map
|
||||
assert dialog.widget.ui.x_name.currentText() == heatmap_widget._image_config.x_device.name
|
||||
assert dialog.widget.ui.device_x.currentText() == heatmap_widget._image_config.device_x.device
|
||||
|
||||
dialog.reject()
|
||||
qtbot.waitUntil(lambda: heatmap_widget.heatmap_dialog is None)
|
||||
@@ -458,7 +458,7 @@ def test_heatmap_widget_reset(heatmap_widget):
|
||||
heatmap_widget._pending_interpolation_request = object()
|
||||
heatmap_widget._latest_interpolation_version = 5
|
||||
heatmap_widget.scan_item = create_dummy_scan_item()
|
||||
heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
heatmap_widget.reset()
|
||||
assert heatmap_widget._grid_index is None
|
||||
@@ -476,12 +476,12 @@ def test_heatmap_widget_update_plot_with_scan_history(heatmap_widget, grid_scan_
|
||||
heatmap_widget.client.history._scan_ids.append(grid_scan_history_msg.scan_id)
|
||||
heatmap_widget.client.queue.scan_storage.current_scan = None
|
||||
heatmap_widget.plot(
|
||||
x_name="samx",
|
||||
y_name="samy",
|
||||
z_name="bpm4i",
|
||||
x_entry="samx",
|
||||
y_entry="samy",
|
||||
z_entry="bpm4i",
|
||||
device_x="samx",
|
||||
device_y="samy",
|
||||
device_z="bpm4i",
|
||||
signal_x="samx",
|
||||
signal_y="samy",
|
||||
signal_z="bpm4i",
|
||||
)
|
||||
qtbot.waitUntil(lambda: heatmap_widget.main_image.raw_data is not None)
|
||||
qtbot.waitUntil(lambda: heatmap_widget.main_image.raw_data.shape == (10, 10))
|
||||
@@ -602,219 +602,219 @@ def test_finish_interpolation_thread_cleans_references(heatmap_widget):
|
||||
def test_device_safe_properties_get(heatmap_widget):
|
||||
"""Test that device SafeProperty getters work correctly."""
|
||||
# Initially devices should be empty
|
||||
assert heatmap_widget.x_device_name == ""
|
||||
assert heatmap_widget.x_device_entry == ""
|
||||
assert heatmap_widget.y_device_name == ""
|
||||
assert heatmap_widget.y_device_entry == ""
|
||||
assert heatmap_widget.z_device_name == ""
|
||||
assert heatmap_widget.z_device_entry == ""
|
||||
assert heatmap_widget.device_x == ""
|
||||
assert heatmap_widget.signal_x == ""
|
||||
assert heatmap_widget.device_y == ""
|
||||
assert heatmap_widget.signal_y == ""
|
||||
assert heatmap_widget.device_z == ""
|
||||
assert heatmap_widget.signal_z == ""
|
||||
|
||||
# Set devices via plot
|
||||
heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
# Check properties return device names and entries separately
|
||||
assert heatmap_widget.x_device_name == "samx"
|
||||
assert heatmap_widget.x_device_entry # Should have some entry
|
||||
assert heatmap_widget.y_device_name == "samy"
|
||||
assert heatmap_widget.y_device_entry # Should have some entry
|
||||
assert heatmap_widget.z_device_name == "bpm4i"
|
||||
assert heatmap_widget.z_device_entry # Should have some entry
|
||||
assert heatmap_widget.device_x == "samx"
|
||||
assert heatmap_widget.signal_x # Should have some entry
|
||||
assert heatmap_widget.device_y == "samy"
|
||||
assert heatmap_widget.signal_y # Should have some entry
|
||||
assert heatmap_widget.device_z == "bpm4i"
|
||||
assert heatmap_widget.signal_z # Should have some entry
|
||||
|
||||
|
||||
def test_device_safe_properties_set_name(heatmap_widget):
|
||||
"""Test that device SafeProperty setters work for device names."""
|
||||
# Set x_device_name - should auto-validate entry
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
assert heatmap_widget._image_config.x_device is not None
|
||||
assert heatmap_widget._image_config.x_device.name == "samx"
|
||||
assert heatmap_widget._image_config.x_device.entry is not None # Entry should be validated
|
||||
assert heatmap_widget.x_device_name == "samx"
|
||||
# Set device_x - should auto-validate entry
|
||||
heatmap_widget.device_x = "samx"
|
||||
assert heatmap_widget._image_config.device_x is not None
|
||||
assert heatmap_widget._image_config.device_x.device == "samx"
|
||||
assert heatmap_widget._image_config.device_x.signal is not None # Entry should be validated
|
||||
assert heatmap_widget.device_x == "samx"
|
||||
|
||||
# Set y_device_name
|
||||
heatmap_widget.y_device_name = "samy"
|
||||
assert heatmap_widget._image_config.y_device is not None
|
||||
assert heatmap_widget._image_config.y_device.name == "samy"
|
||||
assert heatmap_widget._image_config.y_device.entry is not None
|
||||
assert heatmap_widget.y_device_name == "samy"
|
||||
# Set device_y
|
||||
heatmap_widget.device_y = "samy"
|
||||
assert heatmap_widget._image_config.device_y is not None
|
||||
assert heatmap_widget._image_config.device_y.device == "samy"
|
||||
assert heatmap_widget._image_config.device_y.signal is not None
|
||||
assert heatmap_widget.device_y == "samy"
|
||||
|
||||
# Set z_device_name
|
||||
heatmap_widget.z_device_name = "bpm4i"
|
||||
assert heatmap_widget._image_config.z_device is not None
|
||||
assert heatmap_widget._image_config.z_device.name == "bpm4i"
|
||||
assert heatmap_widget._image_config.z_device.entry is not None
|
||||
assert heatmap_widget.z_device_name == "bpm4i"
|
||||
# Set device_z
|
||||
heatmap_widget.device_z = "bpm4i"
|
||||
assert heatmap_widget._image_config.device_z is not None
|
||||
assert heatmap_widget._image_config.device_z.device == "bpm4i"
|
||||
assert heatmap_widget._image_config.device_z.signal is not None
|
||||
assert heatmap_widget.device_z == "bpm4i"
|
||||
|
||||
|
||||
def test_device_safe_properties_set_entry(heatmap_widget):
|
||||
"""Test that device entry properties can override default entries."""
|
||||
# Set device name first - this auto-validates entry
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
initial_entry = heatmap_widget.x_device_entry
|
||||
heatmap_widget.device_x = "samx"
|
||||
initial_entry = heatmap_widget.signal_x
|
||||
assert initial_entry # Should have auto-validated entry
|
||||
|
||||
# Override with specific entry
|
||||
heatmap_widget.x_device_entry = "samx"
|
||||
assert heatmap_widget._image_config.x_device.entry == "samx"
|
||||
assert heatmap_widget.x_device_entry == "samx"
|
||||
heatmap_widget.signal_x = "samx"
|
||||
assert heatmap_widget._image_config.device_x.signal == "samx"
|
||||
assert heatmap_widget.signal_x == "samx"
|
||||
|
||||
# Same for y device
|
||||
heatmap_widget.y_device_name = "samy"
|
||||
heatmap_widget.y_device_entry = "samy_setpoint"
|
||||
assert heatmap_widget._image_config.y_device.entry == "samy_setpoint"
|
||||
heatmap_widget.device_y = "samy"
|
||||
heatmap_widget.signal_y = "samy_setpoint"
|
||||
assert heatmap_widget._image_config.device_y.signal == "samy_setpoint"
|
||||
|
||||
# Same for z device
|
||||
heatmap_widget.z_device_name = "bpm4i"
|
||||
heatmap_widget.z_device_entry = "bpm4i"
|
||||
assert heatmap_widget._image_config.z_device.entry == "bpm4i"
|
||||
heatmap_widget.device_z = "bpm4i"
|
||||
heatmap_widget.signal_z = "bpm4i"
|
||||
assert heatmap_widget._image_config.device_z.signal == "bpm4i"
|
||||
|
||||
|
||||
def test_device_entry_cannot_be_set_without_name(heatmap_widget):
|
||||
"""Test that setting entry without device name logs warning and does nothing."""
|
||||
# Try to set entry without device name
|
||||
heatmap_widget.x_device_entry = "some_entry"
|
||||
heatmap_widget.signal_x = "some_entry"
|
||||
# Should not crash, entry should remain empty
|
||||
assert heatmap_widget.x_device_entry == ""
|
||||
assert heatmap_widget._image_config.x_device is None
|
||||
assert heatmap_widget.signal_x == ""
|
||||
assert heatmap_widget._image_config.device_x is None
|
||||
|
||||
|
||||
def test_device_safe_properties_set_empty(heatmap_widget):
|
||||
"""Test that device SafeProperty setters handle empty strings."""
|
||||
# Set device first
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
assert heatmap_widget._image_config.x_device is not None
|
||||
heatmap_widget.device_x = "samx"
|
||||
assert heatmap_widget._image_config.device_x is not None
|
||||
|
||||
# Set to empty string - should clear the device
|
||||
heatmap_widget.x_device_name = ""
|
||||
assert heatmap_widget.x_device_name == ""
|
||||
assert heatmap_widget._image_config.x_device is None
|
||||
heatmap_widget.device_x = ""
|
||||
assert heatmap_widget.device_x == ""
|
||||
assert heatmap_widget._image_config.device_x is None
|
||||
|
||||
|
||||
def test_device_safe_properties_auto_plot(heatmap_widget):
|
||||
"""Test that setting all three devices triggers auto-plot."""
|
||||
# Set all three devices
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
heatmap_widget.y_device_name = "samy"
|
||||
heatmap_widget.z_device_name = "bpm4i"
|
||||
heatmap_widget.device_x = "samx"
|
||||
heatmap_widget.device_y = "samy"
|
||||
heatmap_widget.device_z = "bpm4i"
|
||||
|
||||
# Check that plot was called (image_config should be updated)
|
||||
assert heatmap_widget._image_config.x_device is not None
|
||||
assert heatmap_widget._image_config.y_device is not None
|
||||
assert heatmap_widget._image_config.z_device is not None
|
||||
assert heatmap_widget._image_config.device_x is not None
|
||||
assert heatmap_widget._image_config.device_y is not None
|
||||
assert heatmap_widget._image_config.device_z is not None
|
||||
|
||||
|
||||
def test_device_properties_update_labels(heatmap_widget):
|
||||
"""Test that setting device properties updates axis labels."""
|
||||
# Set x device - should update x label
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
heatmap_widget.device_x = "samx"
|
||||
assert heatmap_widget.x_label == "samx"
|
||||
|
||||
# Set y device - should update y label
|
||||
heatmap_widget.y_device_name = "samy"
|
||||
heatmap_widget.device_y = "samy"
|
||||
assert heatmap_widget.y_label == "samy"
|
||||
|
||||
# Set z device - should update title
|
||||
heatmap_widget.z_device_name = "bpm4i"
|
||||
heatmap_widget.device_z = "bpm4i"
|
||||
assert heatmap_widget.title == "bpm4i"
|
||||
|
||||
|
||||
def test_device_properties_partial_configuration(heatmap_widget):
|
||||
"""Test that widget handles partial device configuration gracefully."""
|
||||
# Set only x device
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
assert heatmap_widget.x_device_name == "samx"
|
||||
assert heatmap_widget.y_device_name == ""
|
||||
assert heatmap_widget.z_device_name == ""
|
||||
heatmap_widget.device_x = "samx"
|
||||
assert heatmap_widget.device_x == "samx"
|
||||
assert heatmap_widget.device_y == ""
|
||||
assert heatmap_widget.device_z == ""
|
||||
|
||||
# Set only y device (x already set)
|
||||
heatmap_widget.y_device_name = "samy"
|
||||
assert heatmap_widget.x_device_name == "samx"
|
||||
assert heatmap_widget.y_device_name == "samy"
|
||||
assert heatmap_widget.z_device_name == ""
|
||||
heatmap_widget.device_y = "samy"
|
||||
assert heatmap_widget.device_x == "samx"
|
||||
assert heatmap_widget.device_y == "samy"
|
||||
assert heatmap_widget.device_z == ""
|
||||
|
||||
# Auto-plot should not trigger yet (z missing)
|
||||
# But devices should be configured
|
||||
assert heatmap_widget._image_config.x_device is not None
|
||||
assert heatmap_widget._image_config.y_device is not None
|
||||
assert heatmap_widget._image_config.device_x is not None
|
||||
assert heatmap_widget._image_config.device_y is not None
|
||||
|
||||
|
||||
def test_device_properties_in_user_access(heatmap_widget):
|
||||
"""Test that device properties are exposed in USER_ACCESS for RPC."""
|
||||
from bec_widgets.widgets.plots.heatmap.heatmap import Heatmap
|
||||
|
||||
assert "x_device_name" in Heatmap.USER_ACCESS
|
||||
assert "x_device_name.setter" in Heatmap.USER_ACCESS
|
||||
assert "x_device_entry" in Heatmap.USER_ACCESS
|
||||
assert "x_device_entry.setter" in Heatmap.USER_ACCESS
|
||||
assert "y_device_name" in Heatmap.USER_ACCESS
|
||||
assert "y_device_name.setter" in Heatmap.USER_ACCESS
|
||||
assert "y_device_entry" in Heatmap.USER_ACCESS
|
||||
assert "y_device_entry.setter" in Heatmap.USER_ACCESS
|
||||
assert "z_device_name" in Heatmap.USER_ACCESS
|
||||
assert "z_device_name.setter" in Heatmap.USER_ACCESS
|
||||
assert "z_device_entry" in Heatmap.USER_ACCESS
|
||||
assert "z_device_entry.setter" in Heatmap.USER_ACCESS
|
||||
assert "device_x" in Heatmap.USER_ACCESS
|
||||
assert "device_x.setter" in Heatmap.USER_ACCESS
|
||||
assert "signal_x" in Heatmap.USER_ACCESS
|
||||
assert "signal_x.setter" in Heatmap.USER_ACCESS
|
||||
assert "device_y" in Heatmap.USER_ACCESS
|
||||
assert "device_y.setter" in Heatmap.USER_ACCESS
|
||||
assert "signal_y" in Heatmap.USER_ACCESS
|
||||
assert "signal_y.setter" in Heatmap.USER_ACCESS
|
||||
assert "device_z" in Heatmap.USER_ACCESS
|
||||
assert "device_z.setter" in Heatmap.USER_ACCESS
|
||||
assert "signal_z" in Heatmap.USER_ACCESS
|
||||
assert "signal_z.setter" in Heatmap.USER_ACCESS
|
||||
|
||||
|
||||
def test_device_properties_validation(heatmap_widget):
|
||||
"""Test that device entries are validated through entry_validator."""
|
||||
# Set device name - entry should be auto-validated
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
initial_entry = heatmap_widget.x_device_entry
|
||||
heatmap_widget.device_x = "samx"
|
||||
initial_entry = heatmap_widget.signal_x
|
||||
|
||||
# The entry should be validated (will be "samx" in the mock)
|
||||
assert initial_entry == "samx"
|
||||
|
||||
# Set a different entry - should also be validated
|
||||
heatmap_widget.x_device_entry = "samx" # Use same name as validated entry
|
||||
assert heatmap_widget.x_device_entry == "samx"
|
||||
heatmap_widget.signal_x = "samx" # Use same name as validated entry
|
||||
assert heatmap_widget.signal_x == "samx"
|
||||
|
||||
|
||||
def test_device_properties_with_plot_method(heatmap_widget):
|
||||
"""Test that device properties reflect values set via plot() method."""
|
||||
# Use plot method
|
||||
heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
# Properties should reflect the plotted devices
|
||||
assert heatmap_widget.x_device_name == "samx"
|
||||
assert heatmap_widget.y_device_name == "samy"
|
||||
assert heatmap_widget.z_device_name == "bpm4i"
|
||||
assert heatmap_widget.device_x == "samx"
|
||||
assert heatmap_widget.device_y == "samy"
|
||||
assert heatmap_widget.device_z == "bpm4i"
|
||||
|
||||
# Entries should be validated
|
||||
assert heatmap_widget.x_device_entry == "samx"
|
||||
assert heatmap_widget.y_device_entry == "samy"
|
||||
assert heatmap_widget.z_device_entry == "bpm4i"
|
||||
assert heatmap_widget.signal_x == "samx"
|
||||
assert heatmap_widget.signal_y == "samy"
|
||||
assert heatmap_widget.signal_z == "bpm4i"
|
||||
|
||||
|
||||
def test_device_properties_overwrite_via_properties(heatmap_widget):
|
||||
"""Test that device properties can overwrite values set via plot()."""
|
||||
# First set via plot
|
||||
heatmap_widget.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
heatmap_widget.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
# Overwrite x device via properties
|
||||
heatmap_widget.x_device_name = "samz"
|
||||
assert heatmap_widget.x_device_name == "samz"
|
||||
assert heatmap_widget._image_config.x_device.name == "samz"
|
||||
heatmap_widget.device_x = "samz"
|
||||
assert heatmap_widget.device_x == "samz"
|
||||
assert heatmap_widget._image_config.device_x.device == "samz"
|
||||
|
||||
# Overwrite y device entry
|
||||
heatmap_widget.y_device_entry = "samy"
|
||||
assert heatmap_widget.y_device_entry == "samy"
|
||||
heatmap_widget.signal_y = "samy"
|
||||
assert heatmap_widget.signal_y == "samy"
|
||||
|
||||
|
||||
def test_device_properties_clearing_devices(heatmap_widget):
|
||||
"""Test clearing devices by setting to empty string."""
|
||||
# Set all devices
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
heatmap_widget.y_device_name = "samy"
|
||||
heatmap_widget.z_device_name = "bpm4i"
|
||||
heatmap_widget.device_x = "samx"
|
||||
heatmap_widget.device_y = "samy"
|
||||
heatmap_widget.device_z = "bpm4i"
|
||||
|
||||
# Clear x device
|
||||
heatmap_widget.x_device_name = ""
|
||||
assert heatmap_widget.x_device_name == ""
|
||||
assert heatmap_widget._image_config.x_device is None
|
||||
heatmap_widget.device_x = ""
|
||||
assert heatmap_widget.device_x == ""
|
||||
assert heatmap_widget._image_config.device_x is None
|
||||
|
||||
# Y and Z should still be set
|
||||
assert heatmap_widget.y_device_name == "samy"
|
||||
assert heatmap_widget.z_device_name == "bpm4i"
|
||||
assert heatmap_widget.device_y == "samy"
|
||||
assert heatmap_widget.device_z == "bpm4i"
|
||||
|
||||
|
||||
def test_device_properties_property_changed_signal(heatmap_widget):
|
||||
@@ -826,12 +826,12 @@ def test_device_properties_property_changed_signal(heatmap_widget):
|
||||
heatmap_widget.property_changed.connect(mock_handler)
|
||||
|
||||
# Set device name
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
heatmap_widget.device_x = "samx"
|
||||
|
||||
# Signal should have been emitted
|
||||
assert mock_handler.called
|
||||
# Check it was called with correct arguments
|
||||
mock_handler.assert_any_call("x_device_name", "samx")
|
||||
mock_handler.assert_any_call("device_x", "samx")
|
||||
|
||||
|
||||
def test_auto_emit_syncs_heatmap_toolbar_actions(heatmap_widget):
|
||||
@@ -855,7 +855,7 @@ def test_auto_emit_syncs_heatmap_toolbar_actions(heatmap_widget):
|
||||
def test_device_entry_validation_with_invalid_device(heatmap_widget):
|
||||
"""Test that invalid device names are handled gracefully."""
|
||||
# Try to set invalid device name
|
||||
heatmap_widget.x_device_name = "nonexistent_device"
|
||||
heatmap_widget.device_x = "nonexistent_device"
|
||||
|
||||
# Should not crash, but device might not be set if validation fails
|
||||
# The implementation silently fails, so we just check it doesn't crash
|
||||
@@ -864,28 +864,28 @@ def test_device_entry_validation_with_invalid_device(heatmap_widget):
|
||||
def test_device_properties_sequential_entry_changes(heatmap_widget):
|
||||
"""Test changing device entry multiple times."""
|
||||
# Set device
|
||||
heatmap_widget.x_device_name = "samx"
|
||||
heatmap_widget.device_x = "samx"
|
||||
|
||||
# Change entry multiple times
|
||||
heatmap_widget.x_device_entry = "samx_velocity"
|
||||
assert heatmap_widget.x_device_entry == "samx_velocity"
|
||||
heatmap_widget.signal_x = "samx_velocity"
|
||||
assert heatmap_widget.signal_x == "samx_velocity"
|
||||
|
||||
heatmap_widget.x_device_entry = "samx_setpoint"
|
||||
assert heatmap_widget.x_device_entry == "samx_setpoint"
|
||||
heatmap_widget.signal_x = "samx_setpoint"
|
||||
assert heatmap_widget.signal_x == "samx_setpoint"
|
||||
|
||||
heatmap_widget.x_device_entry = "samx"
|
||||
assert heatmap_widget.x_device_entry == "samx"
|
||||
heatmap_widget.signal_x = "samx"
|
||||
assert heatmap_widget.signal_x == "samx"
|
||||
|
||||
|
||||
def test_device_properties_with_none_values(heatmap_widget):
|
||||
"""Test that None values are handled as empty strings."""
|
||||
# Device name None should be treated as empty
|
||||
heatmap_widget.x_device_name = None
|
||||
assert heatmap_widget.x_device_name == ""
|
||||
heatmap_widget.device_x = None
|
||||
assert heatmap_widget.device_x == ""
|
||||
|
||||
# Set a device first
|
||||
heatmap_widget.y_device_name = "samy"
|
||||
heatmap_widget.device_y = "samy"
|
||||
|
||||
# Entry None should not change anything
|
||||
heatmap_widget.y_device_entry = None
|
||||
assert heatmap_widget.y_device_entry # Should still have validated entry
|
||||
heatmap_widget.signal_y = None
|
||||
assert heatmap_widget.signal_y # Should still have validated entry
|
||||
|
||||
@@ -14,14 +14,9 @@ from tests.unit_tests.conftest import create_widget
|
||||
|
||||
|
||||
def _set_signal_config(
|
||||
client,
|
||||
device_name: str,
|
||||
signal_name: str,
|
||||
signal_class: str,
|
||||
ndim: int,
|
||||
obj_name: str | None = None,
|
||||
client, device: str, signal_name: str, signal_class: str, ndim: int, obj_name: str | None = None
|
||||
):
|
||||
device = client.device_manager.devices[device_name]
|
||||
device = client.device_manager.devices[device]
|
||||
device._info["signals"][signal_name] = {
|
||||
"obj_name": obj_name or signal_name,
|
||||
"signal_class": signal_class,
|
||||
@@ -153,14 +148,14 @@ def test_image_setup_preview_signal_1d(qtbot, mocked_client):
|
||||
obj_name="waveform1d_img",
|
||||
)
|
||||
|
||||
view.image(device_name="waveform1d", device_entry="img")
|
||||
view.image(device="waveform1d", signal="img")
|
||||
|
||||
# Subscriptions should indicate 1‑D preview connection
|
||||
sub = view.subscriptions["main"]
|
||||
assert sub.source == "device_monitor_1d"
|
||||
assert sub.monitor_type == "1d"
|
||||
assert view.device_name == "waveform1d"
|
||||
assert view.device_entry == "img"
|
||||
assert view.device == "waveform1d"
|
||||
assert view.signal == "img"
|
||||
|
||||
# Simulate a waveform update from the dispatcher
|
||||
waveform = np.arange(25, dtype=float)
|
||||
@@ -187,14 +182,14 @@ def test_image_setup_preview_signal_2d(qtbot, mocked_client):
|
||||
obj_name="eiger_img2d",
|
||||
)
|
||||
|
||||
view.image(device_name="eiger", device_entry="img2d")
|
||||
view.image(device="eiger", signal="img2d")
|
||||
|
||||
# Subscriptions should indicate 2‑D preview connection
|
||||
sub = view.subscriptions["main"]
|
||||
assert sub.source == "device_monitor_2d"
|
||||
assert sub.monitor_type == "2d"
|
||||
assert view.device_name == "eiger"
|
||||
assert view.device_entry == "img2d"
|
||||
assert view.device == "eiger"
|
||||
assert view.signal == "img2d"
|
||||
|
||||
# Simulate a 2‑D image update
|
||||
test_data = np.arange(16, dtype=float).reshape(4, 4)
|
||||
@@ -259,7 +254,7 @@ def test_image_async_signal_uses_obj_name(qtbot, mocked_client, monkeypatch):
|
||||
mocked_client, "eiger", "img", signal_class="AsyncSignal", ndim=1, obj_name="async_obj"
|
||||
)
|
||||
|
||||
view.image(device_name="eiger", device_entry="img")
|
||||
view.image(device="eiger", signal="img")
|
||||
assert view.subscriptions["main"].async_signal_name == "async_obj"
|
||||
assert view.async_update is True
|
||||
|
||||
@@ -300,7 +295,7 @@ def test_disconnect_clears_async_state(qtbot, mocked_client, monkeypatch):
|
||||
mocked_client, "eiger", "img", signal_class="AsyncSignal", ndim=2, obj_name="async_obj"
|
||||
)
|
||||
|
||||
view.image(device_name="eiger", device_entry="img")
|
||||
view.image(device="eiger", signal="img")
|
||||
view.scan_id = "scan_x"
|
||||
view.old_scan_id = "scan_y"
|
||||
view.subscriptions["main"].async_signal_name = "async_obj"
|
||||
@@ -308,7 +303,7 @@ def test_disconnect_clears_async_state(qtbot, mocked_client, monkeypatch):
|
||||
# Avoid touching real dispatcher
|
||||
monkeypatch.setattr(view.bec_dispatcher, "disconnect_slot", lambda *args, **kwargs: None)
|
||||
|
||||
view.disconnect_monitor(device_name="eiger", device_entry="img")
|
||||
view.disconnect_monitor(device="eiger", signal="img")
|
||||
|
||||
assert view.subscriptions["main"].async_signal_name is None
|
||||
assert view.async_update is False
|
||||
@@ -322,7 +317,7 @@ def test_image_setup_rejects_unsupported_signal_class(qtbot, mocked_client):
|
||||
view = create_widget(qtbot, Image, client=mocked_client)
|
||||
_set_signal_config(mocked_client, "eiger", "img", signal_class="Signal", ndim=2)
|
||||
|
||||
view.image(device_name="eiger", device_entry="img")
|
||||
view.image(device="eiger", signal="img")
|
||||
|
||||
assert view.subscriptions["main"].source is None
|
||||
assert view.subscriptions["main"].monitor_type is None
|
||||
@@ -333,13 +328,13 @@ def test_image_disconnects_with_missing_entry(qtbot, mocked_client):
|
||||
view = create_widget(qtbot, Image, client=mocked_client)
|
||||
_set_signal_config(mocked_client, "eiger", "img", signal_class="PreviewSignal", ndim=2)
|
||||
|
||||
view.image(device_name="eiger", device_entry="img")
|
||||
assert view.device_name == "eiger"
|
||||
assert view.device_entry == "img"
|
||||
view.image(device="eiger", signal="img")
|
||||
assert view.device == "eiger"
|
||||
assert view.signal == "img"
|
||||
|
||||
view.image(device_name="eiger", device_entry=None)
|
||||
assert view.device_name == ""
|
||||
assert view.device_entry == ""
|
||||
view.image(device="eiger", signal=None)
|
||||
assert view.device == ""
|
||||
assert view.signal == ""
|
||||
|
||||
|
||||
def test_handle_scan_change_clears_buffers_and_resets_crosshair(qtbot, mocked_client, monkeypatch):
|
||||
@@ -541,8 +536,8 @@ def test_setup_image_from_toolbar(qtbot, mocked_client, monkeypatch):
|
||||
bec_image_view.on_device_selection_changed(None)
|
||||
qtbot.wait(200)
|
||||
|
||||
assert bec_image_view.device_name == "eiger"
|
||||
assert bec_image_view.device_entry == "img"
|
||||
assert bec_image_view.device == "eiger"
|
||||
assert bec_image_view.signal == "img"
|
||||
assert bec_image_view.subscriptions["main"].source == "device_monitor_2d"
|
||||
assert bec_image_view.subscriptions["main"].monitor_type == "2d"
|
||||
assert bec_image_view.main_image.raw_data is None
|
||||
@@ -834,8 +829,8 @@ def test_device_selection_syncs_from_properties(qtbot, mocked_client, monkeypatc
|
||||
),
|
||||
)
|
||||
|
||||
view.device_name = "eiger"
|
||||
view.device_entry = "img2d"
|
||||
view.device = "eiger"
|
||||
view.signal = "img2d"
|
||||
|
||||
qtbot.wait(200) # Allow signal processing
|
||||
|
||||
@@ -847,19 +842,19 @@ def test_device_selection_syncs_from_properties(qtbot, mocked_client, monkeypatc
|
||||
)
|
||||
|
||||
|
||||
def test_device_entry_syncs_from_toolbar(qtbot, mocked_client):
|
||||
def test_signal_syncs_from_toolbar(qtbot, mocked_client):
|
||||
view = create_widget(qtbot, Image, client=mocked_client)
|
||||
_set_signal_config(mocked_client, "eiger", "img_a", signal_class="PreviewSignal", ndim=2)
|
||||
_set_signal_config(mocked_client, "eiger", "img_b", signal_class="PreviewSignal", ndim=2)
|
||||
|
||||
view.device_name = "eiger"
|
||||
view.device_entry = "img_a"
|
||||
view.device = "eiger"
|
||||
view.signal = "img_a"
|
||||
|
||||
device_selection = view.toolbar.components.get_action("device_selection").widget
|
||||
device_selection.signal_combo_box.blockSignals(True)
|
||||
device_selection.signal_combo_box.setCurrentText("img_b")
|
||||
device_selection.signal_combo_box.blockSignals(False)
|
||||
|
||||
view._sync_device_entry_from_toolbar()
|
||||
view._sync_signal_from_toolbar()
|
||||
|
||||
assert view.device_entry == "img_b"
|
||||
assert view.signal == "img_b"
|
||||
|
||||
@@ -23,12 +23,12 @@ def test_motor_map_select_motor(qtbot, mocked_client):
|
||||
"""Test selecting motors for the motor map."""
|
||||
mm = create_widget(qtbot, MotorMap, client=mocked_client)
|
||||
|
||||
mm.map(x_name="samx", y_name="samy", validate_bec=True)
|
||||
mm.map(device_x="samx", device_y="samy", validate_bec=True)
|
||||
|
||||
assert mm.config.x_motor.name == "samx"
|
||||
assert mm.config.y_motor.name == "samy"
|
||||
assert mm.config.x_motor.limits == [-10, 10]
|
||||
assert mm.config.y_motor.limits == [-5, 5]
|
||||
assert mm.config.device_x.device == "samx"
|
||||
assert mm.config.device_y.device == "samy"
|
||||
assert mm.config.device_x.limits == [-10, 10]
|
||||
assert mm.config.device_y.limits == [-5, 5]
|
||||
assert mm.config.scatter_size == 5
|
||||
assert mm.config.max_points == 5000
|
||||
assert mm.config.num_dim_points == 100
|
||||
@@ -39,7 +39,7 @@ def test_motor_map_select_motor(qtbot, mocked_client):
|
||||
def test_motor_map_properties(qtbot, mocked_client):
|
||||
"""Test setting and getting properties of MotorMap."""
|
||||
mm = create_widget(qtbot, MotorMap, client=mocked_client)
|
||||
mm.map(x_name="samx", y_name="samy")
|
||||
mm.map(device_x="samx", device_y="samy")
|
||||
|
||||
# Test color property
|
||||
mm.color = (100, 150, 200, 255)
|
||||
@@ -86,7 +86,7 @@ def test_motor_map_properties(qtbot, mocked_client):
|
||||
def test_motor_map_get_limits(qtbot, mocked_client):
|
||||
"""Test getting motor limits."""
|
||||
mm = create_widget(qtbot, MotorMap, client=mocked_client)
|
||||
mm.map(x_name="samx", y_name="samy")
|
||||
mm.map(device_x="samx", device_y="samy")
|
||||
expected_limits = {"samx": [-10, 10], "samy": [-5, 5]}
|
||||
|
||||
for motor_name, expected_limit in expected_limits.items():
|
||||
@@ -133,7 +133,7 @@ def test_motor_map_reset_history(qtbot, mocked_client):
|
||||
def test_motor_map_on_device_readback(qtbot, mocked_client):
|
||||
"""Test the motor map updates when receiving device readback."""
|
||||
mm = create_widget(qtbot, MotorMap, client=mocked_client)
|
||||
mm.map(x_name="samx", y_name="samy")
|
||||
mm.map(device_x="samx", device_y="samy")
|
||||
|
||||
# Clear the buffer and add initial position
|
||||
mm._buffer = {"x": [1.0], "y": [2.0]}
|
||||
@@ -161,7 +161,7 @@ def test_motor_map_on_device_readback(qtbot, mocked_client):
|
||||
def test_motor_map_max_points_limit(qtbot, mocked_client):
|
||||
"""Test that the buffer doesn't exceed max_points."""
|
||||
mm = create_widget(qtbot, MotorMap, client=mocked_client)
|
||||
mm.map(x_name="samx", y_name="samy")
|
||||
mm.map(device_x="samx", device_y="samy")
|
||||
|
||||
# Add more points than max_points
|
||||
mm._buffer = {"x": [1.0, 2.0, 3.0, 4.0], "y": [5.0, 6.0, 7.0, 8.0]}
|
||||
@@ -219,7 +219,7 @@ def test_motor_map_limit_map(qtbot, mocked_client):
|
||||
|
||||
def test_motor_map_change_limits(qtbot, mocked_client):
|
||||
mm = create_widget(qtbot, MotorMap, client=mocked_client)
|
||||
mm.map(x_name="samx", y_name="samy")
|
||||
mm.map(device_x="samx", device_y="samy")
|
||||
|
||||
# Original mocked limits are
|
||||
# samx: [-10, 10]
|
||||
@@ -229,8 +229,8 @@ def test_motor_map_change_limits(qtbot, mocked_client):
|
||||
rect = mm._limit_map.boundingRect()
|
||||
assert rect.width() == 20 # -10 to 10 inclusive
|
||||
assert rect.height() == 10 # -5 to 5 inclusive
|
||||
assert mm.config.x_motor.limits == [-10, 10]
|
||||
assert mm.config.y_motor.limits == [-5, 5]
|
||||
assert mm.config.device_x.limits == [-10, 10]
|
||||
assert mm.config.device_y.limits == [-5, 5]
|
||||
|
||||
# Change the limits of the samx motor
|
||||
mm.dev["samx"].limits = [-20, 20]
|
||||
@@ -239,8 +239,8 @@ def test_motor_map_change_limits(qtbot, mocked_client):
|
||||
qtbot.wait(200) # Allow time for the update to process
|
||||
|
||||
# Check that the limits map was updated
|
||||
assert mm.config.x_motor.limits == [-20, 20]
|
||||
assert mm.config.y_motor.limits == [-5, 5]
|
||||
assert mm.config.device_x.limits == [-20, 20]
|
||||
assert mm.config.device_y.limits == [-5, 5]
|
||||
rect = mm._limit_map.boundingRect()
|
||||
assert rect.width() == 40 # -20 to 20 inclusive
|
||||
assert rect.height() == 10 # -5 to 5 inclusive -> same as before
|
||||
@@ -276,13 +276,13 @@ def test_motor_map_toolbar_selection(qtbot, mocked_client):
|
||||
motor_selection.widget.motor_x.setCurrentText("samx")
|
||||
motor_selection.widget.motor_y.setCurrentText("samy")
|
||||
|
||||
assert mm.config.x_motor.name == "samx"
|
||||
assert mm.config.y_motor.name == "samy"
|
||||
assert mm.config.device_x.device == "samx"
|
||||
assert mm.config.device_y.device == "samy"
|
||||
|
||||
motor_selection.widget.motor_y.setCurrentText("samz")
|
||||
|
||||
assert mm.config.x_motor.name == "samx"
|
||||
assert mm.config.y_motor.name == "samz"
|
||||
assert mm.config.device_x.device == "samx"
|
||||
assert mm.config.device_y.device == "samz"
|
||||
|
||||
|
||||
def test_motor_selection_set_motors_blocks_signals(qtbot, mocked_client):
|
||||
@@ -306,19 +306,19 @@ def test_motor_properties_partial_then_complete_map(qtbot, mocked_client):
|
||||
mm = create_widget(qtbot, MotorMap, client=mocked_client)
|
||||
|
||||
spy = QSignalSpy(mm.property_changed)
|
||||
mm.x_motor = "samx"
|
||||
mm.device_x = "samx"
|
||||
|
||||
assert mm.config.x_motor.name == "samx"
|
||||
assert mm.config.y_motor.name is None
|
||||
assert mm.config.device_x.device == "samx"
|
||||
assert mm.config.device_y.device is None
|
||||
assert mm._trace is None # map not triggered yet
|
||||
assert spy.at(0) == ["x_motor", "samx"]
|
||||
assert spy.at(0) == ["device_x", "samx"]
|
||||
|
||||
mm.y_motor = "samy"
|
||||
mm.device_y = "samy"
|
||||
|
||||
assert mm.config.x_motor.name == "samx"
|
||||
assert mm.config.y_motor.name == "samy"
|
||||
assert mm.config.device_x.device == "samx"
|
||||
assert mm.config.device_y.device == "samy"
|
||||
assert mm._trace is not None # map called once both valid
|
||||
assert spy.at(1) == ["y_motor", "samy"]
|
||||
assert spy.at(1) == ["device_y", "samy"]
|
||||
assert len(mm._buffer["x"]) == 1
|
||||
assert len(mm._buffer["y"]) == 1
|
||||
|
||||
@@ -331,9 +331,9 @@ def test_set_motor_name_emits_and_syncs_toolbar(qtbot, mocked_client):
|
||||
spy = QSignalSpy(mm.property_changed)
|
||||
mm._set_motor_name("x", "samx")
|
||||
|
||||
assert mm.config.x_motor.name == "samx"
|
||||
assert mm.config.device_x.device == "samx"
|
||||
assert motor_selection.motor_x.currentText() == "samx"
|
||||
assert spy.at(0) == ["x_motor", "samx"]
|
||||
assert spy.at(0) == ["device_x", "samx"]
|
||||
|
||||
# Calling with same name should be a no-op
|
||||
initial_count = spy.count()
|
||||
@@ -350,7 +350,7 @@ def test_motor_map_settings_dialog(qtbot, mocked_client):
|
||||
assert action_ref().action.isVisible()
|
||||
|
||||
# set properties to be fetched by dialog
|
||||
mm.map(x_name="samx", y_name="samy")
|
||||
mm.map(device_x="samx", device_y="samy")
|
||||
mm.precision = 2
|
||||
mm.max_points = 1000
|
||||
mm.scatter_size = 10
|
||||
|
||||
@@ -37,7 +37,7 @@ def test_scatter_waveform_plot(qtbot, mocked_client):
|
||||
|
||||
assert curve is not None
|
||||
assert isinstance(curve.config, ScatterCurveConfig)
|
||||
assert curve.config.x_device == ScatterDeviceSignal(name="samx", entry="samx")
|
||||
assert curve.config.device_x == ScatterDeviceSignal(device="samx", signal="samx")
|
||||
assert curve.config.label == "bpm4i-bpm4i"
|
||||
|
||||
|
||||
@@ -144,49 +144,49 @@ def test_device_safe_properties_get(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Initially devices should be empty
|
||||
assert swf.x_device_name == ""
|
||||
assert swf.x_device_entry == ""
|
||||
assert swf.y_device_name == ""
|
||||
assert swf.y_device_entry == ""
|
||||
assert swf.z_device_name == ""
|
||||
assert swf.z_device_entry == ""
|
||||
assert swf.device_x == ""
|
||||
assert swf.signal_x == ""
|
||||
assert swf.device_y == ""
|
||||
assert swf.signal_y == ""
|
||||
assert swf.device_z == ""
|
||||
assert swf.signal_z == ""
|
||||
|
||||
# Set devices via plot
|
||||
swf.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
swf.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
# Check properties return device names and entries separately
|
||||
assert swf.x_device_name == "samx"
|
||||
assert swf.x_device_entry # Should have some entry
|
||||
assert swf.y_device_name == "samy"
|
||||
assert swf.y_device_entry # Should have some entry
|
||||
assert swf.z_device_name == "bpm4i"
|
||||
assert swf.z_device_entry # Should have some entry
|
||||
assert swf.device_x == "samx"
|
||||
assert swf.signal_x # Should have some entry
|
||||
assert swf.device_y == "samy"
|
||||
assert swf.signal_y # Should have some entry
|
||||
assert swf.device_z == "bpm4i"
|
||||
assert swf.signal_z # Should have some entry
|
||||
|
||||
|
||||
def test_device_safe_properties_set_name(qtbot, mocked_client):
|
||||
"""Test that device SafeProperty setters work for device names."""
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Set x_device_name - should auto-validate entry
|
||||
swf.x_device_name = "samx"
|
||||
assert swf._main_curve.config.x_device is not None
|
||||
assert swf._main_curve.config.x_device.name == "samx"
|
||||
assert swf._main_curve.config.x_device.entry is not None # Entry should be validated
|
||||
assert swf.x_device_name == "samx"
|
||||
# Set device_x - should auto-validate entry
|
||||
swf.device_x = "samx"
|
||||
assert swf._main_curve.config.device_x is not None
|
||||
assert swf._main_curve.config.device_x.device == "samx"
|
||||
assert swf._main_curve.config.device_x.signal is not None # Entry should be validated
|
||||
assert swf.device_x == "samx"
|
||||
|
||||
# Set y_device_name
|
||||
swf.y_device_name = "samy"
|
||||
assert swf._main_curve.config.y_device is not None
|
||||
assert swf._main_curve.config.y_device.name == "samy"
|
||||
assert swf._main_curve.config.y_device.entry is not None
|
||||
assert swf.y_device_name == "samy"
|
||||
# Set device_y
|
||||
swf.device_y = "samy"
|
||||
assert swf._main_curve.config.device_y is not None
|
||||
assert swf._main_curve.config.device_y.device == "samy"
|
||||
assert swf._main_curve.config.device_y.signal is not None
|
||||
assert swf.device_y == "samy"
|
||||
|
||||
# Set z_device_name
|
||||
swf.z_device_name = "bpm4i"
|
||||
assert swf._main_curve.config.z_device is not None
|
||||
assert swf._main_curve.config.z_device.name == "bpm4i"
|
||||
assert swf._main_curve.config.z_device.entry is not None
|
||||
assert swf.z_device_name == "bpm4i"
|
||||
# Set device_z
|
||||
swf.device_z = "bpm4i"
|
||||
assert swf._main_curve.config.device_z is not None
|
||||
assert swf._main_curve.config.device_z.device == "bpm4i"
|
||||
assert swf._main_curve.config.device_z.signal is not None
|
||||
assert swf.device_z == "bpm4i"
|
||||
|
||||
|
||||
def test_device_safe_properties_set_entry(qtbot, mocked_client):
|
||||
@@ -194,24 +194,24 @@ def test_device_safe_properties_set_entry(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Set device name first - this auto-validates entry
|
||||
swf.x_device_name = "samx"
|
||||
initial_entry = swf.x_device_entry
|
||||
swf.device_x = "samx"
|
||||
initial_entry = swf.signal_x
|
||||
assert initial_entry # Should have auto-validated entry
|
||||
|
||||
# Override with specific entry
|
||||
swf.x_device_entry = "samx"
|
||||
assert swf._main_curve.config.x_device.entry == "samx"
|
||||
assert swf.x_device_entry == "samx"
|
||||
swf.signal_x = "samx"
|
||||
assert swf._main_curve.config.device_x.signal == "samx"
|
||||
assert swf.signal_x == "samx"
|
||||
|
||||
# Same for y device
|
||||
swf.y_device_name = "samy"
|
||||
swf.y_device_entry = "samy_setpoint"
|
||||
assert swf._main_curve.config.y_device.entry == "samy_setpoint"
|
||||
swf.device_y = "samy"
|
||||
swf.signal_y = "samy_setpoint"
|
||||
assert swf._main_curve.config.device_y.signal == "samy_setpoint"
|
||||
|
||||
# Same for z device
|
||||
swf.z_device_name = "bpm4i"
|
||||
swf.z_device_entry = "bpm4i"
|
||||
assert swf._main_curve.config.z_device.entry == "bpm4i"
|
||||
swf.device_z = "bpm4i"
|
||||
swf.signal_z = "bpm4i"
|
||||
assert swf._main_curve.config.device_z.signal == "bpm4i"
|
||||
|
||||
|
||||
def test_device_entry_cannot_be_set_without_name(qtbot, mocked_client):
|
||||
@@ -219,10 +219,10 @@ def test_device_entry_cannot_be_set_without_name(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Try to set entry without device name
|
||||
swf.x_device_entry = "some_entry"
|
||||
swf.signal_x = "some_entry"
|
||||
# Should not crash, entry should remain empty
|
||||
assert swf.x_device_entry == ""
|
||||
assert swf._main_curve.config.x_device is None
|
||||
assert swf.signal_x == ""
|
||||
assert swf._main_curve.config.device_x is None
|
||||
|
||||
|
||||
def test_device_safe_properties_set_empty(qtbot, mocked_client):
|
||||
@@ -230,13 +230,13 @@ def test_device_safe_properties_set_empty(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Set device first
|
||||
swf.x_device_name = "samx"
|
||||
assert swf._main_curve.config.x_device is not None
|
||||
swf.device_x = "samx"
|
||||
assert swf._main_curve.config.device_x is not None
|
||||
|
||||
# Set to empty string - should clear the device
|
||||
swf.x_device_name = ""
|
||||
assert swf.x_device_name == ""
|
||||
assert swf._main_curve.config.x_device is None
|
||||
swf.device_x = ""
|
||||
assert swf.device_x == ""
|
||||
assert swf._main_curve.config.device_x is None
|
||||
|
||||
|
||||
def test_device_safe_properties_auto_plot(qtbot, mocked_client):
|
||||
@@ -244,14 +244,14 @@ def test_device_safe_properties_auto_plot(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Set all three devices
|
||||
swf.x_device_name = "samx"
|
||||
swf.y_device_name = "samy"
|
||||
swf.z_device_name = "bpm4i"
|
||||
swf.device_x = "samx"
|
||||
swf.device_y = "samy"
|
||||
swf.device_z = "bpm4i"
|
||||
|
||||
# Check that plot was called (config should be updated)
|
||||
assert swf._main_curve.config.x_device is not None
|
||||
assert swf._main_curve.config.y_device is not None
|
||||
assert swf._main_curve.config.z_device is not None
|
||||
assert swf._main_curve.config.device_x is not None
|
||||
assert swf._main_curve.config.device_y is not None
|
||||
assert swf._main_curve.config.device_z is not None
|
||||
|
||||
|
||||
def test_device_properties_update_labels(qtbot, mocked_client):
|
||||
@@ -259,11 +259,11 @@ def test_device_properties_update_labels(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Set x device - should update x label
|
||||
swf.x_device_name = "samx"
|
||||
swf.device_x = "samx"
|
||||
assert swf.x_label == "samx"
|
||||
|
||||
# Set y device - should update y label
|
||||
swf.y_device_name = "samy"
|
||||
swf.device_y = "samy"
|
||||
assert swf.y_label == "samy"
|
||||
|
||||
# Note: ScatterWaveform doesn't have a title like Heatmap does for z_device
|
||||
@@ -274,39 +274,39 @@ def test_device_properties_partial_configuration(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Set only x device
|
||||
swf.x_device_name = "samx"
|
||||
assert swf.x_device_name == "samx"
|
||||
assert swf.y_device_name == ""
|
||||
assert swf.z_device_name == ""
|
||||
swf.device_x = "samx"
|
||||
assert swf.device_x == "samx"
|
||||
assert swf.device_y == ""
|
||||
assert swf.device_z == ""
|
||||
|
||||
# Set only y device (x already set)
|
||||
swf.y_device_name = "samy"
|
||||
assert swf.x_device_name == "samx"
|
||||
assert swf.y_device_name == "samy"
|
||||
assert swf.z_device_name == ""
|
||||
swf.device_y = "samy"
|
||||
assert swf.device_x == "samx"
|
||||
assert swf.device_y == "samy"
|
||||
assert swf.device_z == ""
|
||||
|
||||
# Auto-plot should not trigger yet (z missing)
|
||||
# But devices should be configured
|
||||
assert swf._main_curve.config.x_device is not None
|
||||
assert swf._main_curve.config.y_device is not None
|
||||
assert swf._main_curve.config.device_x is not None
|
||||
assert swf._main_curve.config.device_y is not None
|
||||
|
||||
|
||||
def test_device_properties_in_user_access(qtbot, mocked_client):
|
||||
"""Test that device properties are exposed in USER_ACCESS for RPC."""
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
assert "x_device_name" in ScatterWaveform.USER_ACCESS
|
||||
assert "x_device_name.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "x_device_entry" in ScatterWaveform.USER_ACCESS
|
||||
assert "x_device_entry.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "y_device_name" in ScatterWaveform.USER_ACCESS
|
||||
assert "y_device_name.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "y_device_entry" in ScatterWaveform.USER_ACCESS
|
||||
assert "y_device_entry.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "z_device_name" in ScatterWaveform.USER_ACCESS
|
||||
assert "z_device_name.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "z_device_entry" in ScatterWaveform.USER_ACCESS
|
||||
assert "z_device_entry.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "device_x" in ScatterWaveform.USER_ACCESS
|
||||
assert "device_x.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "signal_x" in ScatterWaveform.USER_ACCESS
|
||||
assert "signal_x.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "device_y" in ScatterWaveform.USER_ACCESS
|
||||
assert "device_y.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "signal_y" in ScatterWaveform.USER_ACCESS
|
||||
assert "signal_y.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "device_z" in ScatterWaveform.USER_ACCESS
|
||||
assert "device_z.setter" in ScatterWaveform.USER_ACCESS
|
||||
assert "signal_z" in ScatterWaveform.USER_ACCESS
|
||||
assert "signal_z.setter" in ScatterWaveform.USER_ACCESS
|
||||
|
||||
|
||||
def test_device_properties_validation(qtbot, mocked_client):
|
||||
@@ -314,15 +314,15 @@ def test_device_properties_validation(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Set device name - entry should be auto-validated
|
||||
swf.x_device_name = "samx"
|
||||
initial_entry = swf.x_device_entry
|
||||
swf.device_x = "samx"
|
||||
initial_entry = swf.signal_x
|
||||
|
||||
# The entry should be validated (will be "samx" in the mock)
|
||||
assert initial_entry == "samx"
|
||||
|
||||
# Set a different entry - should also be validated
|
||||
swf.x_device_entry = "samx" # Use same name as validated entry
|
||||
assert swf.x_device_entry == "samx"
|
||||
swf.signal_x = "samx" # Use same name as validated entry
|
||||
assert swf.signal_x == "samx"
|
||||
|
||||
|
||||
def test_device_properties_with_plot_method(qtbot, mocked_client):
|
||||
@@ -330,17 +330,17 @@ def test_device_properties_with_plot_method(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Use plot method
|
||||
swf.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
swf.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
# Properties should reflect the plotted devices
|
||||
assert swf.x_device_name == "samx"
|
||||
assert swf.y_device_name == "samy"
|
||||
assert swf.z_device_name == "bpm4i"
|
||||
assert swf.device_x == "samx"
|
||||
assert swf.device_y == "samy"
|
||||
assert swf.device_z == "bpm4i"
|
||||
|
||||
# Entries should be validated
|
||||
assert swf.x_device_entry == "samx"
|
||||
assert swf.y_device_entry == "samy"
|
||||
assert swf.z_device_entry == "bpm4i"
|
||||
assert swf.signal_x == "samx"
|
||||
assert swf.signal_y == "samy"
|
||||
assert swf.signal_z == "bpm4i"
|
||||
|
||||
|
||||
def test_device_properties_overwrite_via_properties(qtbot, mocked_client):
|
||||
@@ -348,16 +348,16 @@ def test_device_properties_overwrite_via_properties(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# First set via plot
|
||||
swf.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
swf.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
# Overwrite x device via properties
|
||||
swf.x_device_name = "samz"
|
||||
assert swf.x_device_name == "samz"
|
||||
assert swf._main_curve.config.x_device.name == "samz"
|
||||
swf.device_x = "samz"
|
||||
assert swf.device_x == "samz"
|
||||
assert swf._main_curve.config.device_x.device == "samz"
|
||||
|
||||
# Overwrite y device entry
|
||||
swf.y_device_entry = "samy"
|
||||
assert swf.y_device_entry == "samy"
|
||||
swf.signal_y = "samy"
|
||||
assert swf.signal_y == "samy"
|
||||
|
||||
|
||||
def test_device_properties_clearing_devices(qtbot, mocked_client):
|
||||
@@ -365,18 +365,18 @@ def test_device_properties_clearing_devices(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Set all devices
|
||||
swf.x_device_name = "samx"
|
||||
swf.y_device_name = "samy"
|
||||
swf.z_device_name = "bpm4i"
|
||||
swf.device_x = "samx"
|
||||
swf.device_y = "samy"
|
||||
swf.device_z = "bpm4i"
|
||||
|
||||
# Clear x device
|
||||
swf.x_device_name = ""
|
||||
assert swf.x_device_name == ""
|
||||
assert swf._main_curve.config.x_device is None
|
||||
swf.device_x = ""
|
||||
assert swf.device_x == ""
|
||||
assert swf._main_curve.config.device_x is None
|
||||
|
||||
# Y and Z should still be set
|
||||
assert swf.y_device_name == "samy"
|
||||
assert swf.z_device_name == "bpm4i"
|
||||
assert swf.device_y == "samy"
|
||||
assert swf.device_z == "bpm4i"
|
||||
|
||||
|
||||
def test_device_properties_property_changed_signal(qtbot, mocked_client):
|
||||
@@ -390,12 +390,12 @@ def test_device_properties_property_changed_signal(qtbot, mocked_client):
|
||||
swf.property_changed.connect(mock_handler)
|
||||
|
||||
# Set device name
|
||||
swf.x_device_name = "samx"
|
||||
swf.device_x = "samx"
|
||||
|
||||
# Signal should have been emitted
|
||||
assert mock_handler.called
|
||||
# Check it was called with correct arguments
|
||||
mock_handler.assert_any_call("x_device_name", "samx")
|
||||
mock_handler.assert_any_call("device_x", "samx")
|
||||
|
||||
|
||||
def test_device_entry_validation_with_invalid_device(qtbot, mocked_client):
|
||||
@@ -403,7 +403,7 @@ def test_device_entry_validation_with_invalid_device(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Try to set invalid device name
|
||||
swf.x_device_name = "nonexistent_device"
|
||||
swf.device_x = "nonexistent_device"
|
||||
|
||||
# Should not crash, but device might not be set if validation fails
|
||||
# The implementation silently fails, so we just check it doesn't crash
|
||||
@@ -414,17 +414,17 @@ def test_device_properties_sequential_entry_changes(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Set device
|
||||
swf.x_device_name = "samx"
|
||||
swf.device_x = "samx"
|
||||
|
||||
# Change entry multiple times
|
||||
swf.x_device_entry = "samx_velocity"
|
||||
assert swf.x_device_entry == "samx_velocity"
|
||||
swf.signal_x = "samx_velocity"
|
||||
assert swf.signal_x == "samx_velocity"
|
||||
|
||||
swf.x_device_entry = "samx_setpoint"
|
||||
assert swf.x_device_entry == "samx_setpoint"
|
||||
swf.signal_x = "samx_setpoint"
|
||||
assert swf.signal_x == "samx_setpoint"
|
||||
|
||||
swf.x_device_entry = "samx"
|
||||
assert swf.x_device_entry == "samx"
|
||||
swf.signal_x = "samx"
|
||||
assert swf.signal_x == "samx"
|
||||
|
||||
|
||||
def test_device_properties_with_none_values(qtbot, mocked_client):
|
||||
@@ -432,15 +432,15 @@ def test_device_properties_with_none_values(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# Device name None should be treated as empty
|
||||
swf.x_device_name = None
|
||||
assert swf.x_device_name == ""
|
||||
swf.device_x = None
|
||||
assert swf.device_x == ""
|
||||
|
||||
# Set a device first
|
||||
swf.y_device_name = "samy"
|
||||
swf.device_y = "samy"
|
||||
|
||||
# Entry None should not change anything
|
||||
swf.y_device_entry = None
|
||||
assert swf.y_device_entry # Should still have validated entry
|
||||
swf.signal_y = None
|
||||
assert swf.signal_y # Should still have validated entry
|
||||
|
||||
|
||||
################################################################################
|
||||
@@ -457,9 +457,9 @@ def test_scatter_curve_settings_accept_changes(qtbot, mocked_client):
|
||||
qtbot.addWidget(settings)
|
||||
|
||||
# Set up the widgets with test values
|
||||
settings.ui.x_name.set_device("samx")
|
||||
settings.ui.y_name.set_device("samy")
|
||||
settings.ui.z_name.set_device("bpm4i")
|
||||
settings.ui.device_x.set_device("samx")
|
||||
settings.ui.device_y.set_device("samy")
|
||||
settings.ui.device_z.set_device("bpm4i")
|
||||
|
||||
# Mock the plot method to verify it gets called with correct arguments
|
||||
with patch.object(swf, "plot") as mock_plot:
|
||||
@@ -472,9 +472,9 @@ def test_scatter_curve_settings_accept_changes(qtbot, mocked_client):
|
||||
call_kwargs = mock_plot.call_args[1]
|
||||
|
||||
# Verify device names were extracted correctly
|
||||
assert call_kwargs["x_name"] == "samx"
|
||||
assert call_kwargs["y_name"] == "samy"
|
||||
assert call_kwargs["z_name"] == "bpm4i"
|
||||
assert call_kwargs["device_x"] == "samx"
|
||||
assert call_kwargs["device_y"] == "samy"
|
||||
assert call_kwargs["device_z"] == "bpm4i"
|
||||
|
||||
|
||||
def test_scatter_curve_settings_accept_changes_with_entries(qtbot, mocked_client):
|
||||
@@ -486,9 +486,9 @@ def test_scatter_curve_settings_accept_changes_with_entries(qtbot, mocked_client
|
||||
qtbot.addWidget(settings)
|
||||
|
||||
# Set devices first to populate signal comboboxes
|
||||
settings.ui.x_name.set_device("samx")
|
||||
settings.ui.y_name.set_device("samy")
|
||||
settings.ui.z_name.set_device("bpm4i")
|
||||
settings.ui.device_x.set_device("samx")
|
||||
settings.ui.device_y.set_device("samy")
|
||||
settings.ui.device_z.set_device("bpm4i")
|
||||
qtbot.wait(100) # Allow time for signals to populate
|
||||
|
||||
# Mock the plot method
|
||||
@@ -499,9 +499,9 @@ def test_scatter_curve_settings_accept_changes_with_entries(qtbot, mocked_client
|
||||
call_kwargs = mock_plot.call_args[1]
|
||||
|
||||
# Verify entries are extracted (will use get_signal_name())
|
||||
assert "x_entry" in call_kwargs
|
||||
assert "y_entry" in call_kwargs
|
||||
assert "z_entry" in call_kwargs
|
||||
assert "signal_x" in call_kwargs
|
||||
assert "signal_y" in call_kwargs
|
||||
assert "signal_z" in call_kwargs
|
||||
|
||||
|
||||
def test_scatter_curve_settings_accept_changes_color_map(qtbot, mocked_client):
|
||||
@@ -514,9 +514,9 @@ def test_scatter_curve_settings_accept_changes_color_map(qtbot, mocked_client):
|
||||
qtbot.addWidget(settings)
|
||||
|
||||
# Set devices
|
||||
settings.ui.x_name.set_device("samx")
|
||||
settings.ui.y_name.set_device("samy")
|
||||
settings.ui.z_name.set_device("bpm4i")
|
||||
settings.ui.device_x.set_device("samx")
|
||||
settings.ui.device_y.set_device("samy")
|
||||
settings.ui.device_z.set_device("bpm4i")
|
||||
|
||||
# Get the current colormap
|
||||
color_map = settings.ui.color_map.colormap
|
||||
@@ -532,13 +532,13 @@ def test_scatter_curve_settings_fetch_all_properties(qtbot, mocked_client):
|
||||
swf = create_widget(qtbot, ScatterWaveform, client=mocked_client)
|
||||
|
||||
# First set up the scatter waveform with some data
|
||||
swf.plot(x_name="samx", y_name="samy", z_name="bpm4i")
|
||||
swf.plot(device_x="samx", device_y="samy", device_z="bpm4i")
|
||||
|
||||
# Create the settings widget - it should fetch properties automatically
|
||||
settings = ScatterCurveSettings(parent=None, target_widget=swf, popup=True)
|
||||
qtbot.addWidget(settings)
|
||||
|
||||
# Verify the settings widget has fetched the values
|
||||
assert settings.ui.x_name.currentText() == "samx"
|
||||
assert settings.ui.y_name.currentText() == "samy"
|
||||
assert settings.ui.z_name.currentText() == "bpm4i"
|
||||
assert settings.ui.device_x.currentText() == "samx"
|
||||
assert settings.ui.device_y.currentText() == "samy"
|
||||
assert settings.ui.device_z.currentText() == "bpm4i"
|
||||
|
||||
@@ -107,8 +107,8 @@ def test_plot_single_arg_input_sync(qtbot, mocked_client):
|
||||
|
||||
assert c1.config.source == "device"
|
||||
assert c2.config.source == "device"
|
||||
assert c1.config.signal == DeviceSignal(name="bpm4i", entry="bpm4i", dap=None)
|
||||
assert c2.config.signal == DeviceSignal(name="bpm3a", entry="bpm3a", dap=None)
|
||||
assert c1.config.signal == DeviceSignal(device="bpm4i", signal="bpm4i", dap=None)
|
||||
assert c2.config.signal == DeviceSignal(device="bpm3a", signal="bpm3a", dap=None)
|
||||
|
||||
# Check that the curve is added to the plot
|
||||
assert len(wf.plot_item.curves) == 2
|
||||
@@ -122,8 +122,8 @@ def test_plot_single_arg_input_async(qtbot, mocked_client):
|
||||
|
||||
assert c1.config.source == "device"
|
||||
assert c2.config.source == "device"
|
||||
assert c1.config.signal == DeviceSignal(name="eiger", entry="eiger", dap=None)
|
||||
assert c2.config.signal == DeviceSignal(name="async_device", entry="async_device", dap=None)
|
||||
assert c1.config.signal == DeviceSignal(device="eiger", signal="eiger", dap=None)
|
||||
assert c2.config.signal == DeviceSignal(device="async_device", signal="async_device", dap=None)
|
||||
|
||||
# Check that the curve is added to the plot
|
||||
assert len(wf.plot_item.curves) == 2
|
||||
@@ -305,7 +305,7 @@ def test_curve_json_setter_ignores_custom(qtbot, mocked_client):
|
||||
"label": "device_curve",
|
||||
"color": "#ff0000",
|
||||
"source": "device",
|
||||
"signal": {"name": "bpm4i", "entry": "bpm4i", "dap": None},
|
||||
"signal": {"device": "bpm4i", "signal": "bpm4i", "dap": None},
|
||||
}
|
||||
custom_curve_config = {
|
||||
"widget_class": "Curve",
|
||||
@@ -475,7 +475,7 @@ def test_add_dap_curve(qtbot, mocked_client_with_dap, monkeypatch):
|
||||
dap_curve = wf.add_dap_curve(device_label="bpm4i-bpm4i", dap_name="GaussianModel")
|
||||
assert dap_curve is not None
|
||||
assert dap_curve.config.source == "dap"
|
||||
assert dap_curve.config.signal.name == "bpm4i"
|
||||
assert dap_curve.config.signal.device == "bpm4i"
|
||||
assert dap_curve.config.signal.dap == "GaussianModel"
|
||||
|
||||
|
||||
@@ -491,8 +491,8 @@ def test_add_dap_curve_custom_source(qtbot, mocked_client_with_dap):
|
||||
dap_curve = wf.add_dap_curve(device_label=custom_curve.name(), dap_name="GaussianModel")
|
||||
assert dap_curve.config.source == "dap"
|
||||
assert dap_curve.config.parent_label == custom_curve.name()
|
||||
assert dap_curve.config.signal.name == custom_curve.name()
|
||||
assert dap_curve.config.signal.entry == "custom"
|
||||
assert dap_curve.config.signal.device == custom_curve.name()
|
||||
assert dap_curve.config.signal.signal == "custom"
|
||||
assert dap_curve.config.signal.dap == "GaussianModel"
|
||||
|
||||
|
||||
@@ -764,7 +764,7 @@ def test_curve_set_data_error_non_custom(qtbot, mocked_client):
|
||||
Test that calling set_data on a non-custom (device) curve raises a ValueError.
|
||||
"""
|
||||
wf = create_widget(qtbot, Waveform, client=mocked_client)
|
||||
# Create a device curve by providing y_name (which makes source 'device')
|
||||
# Create a device curve by providing device_y (which makes source 'device')
|
||||
# Assume that entry_validator returns a valid entry.
|
||||
c = wf.plot(arg1="bpm4i", label="device_curve")
|
||||
with pytest.raises(ValueError):
|
||||
@@ -1136,20 +1136,20 @@ def test_update_with_scan_history_by_index(qtbot, mocked_client, scan_history_fa
|
||||
assert len(wf.client.history._scan_ids) == 2, "Expected two history scans"
|
||||
|
||||
# Do history curve plotting
|
||||
wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="hist1")
|
||||
wf.plot(y_name="bpm4i", scan_number=2)
|
||||
wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="hist1")
|
||||
wf.plot(device_y="bpm4i", scan_number=2)
|
||||
|
||||
assert len(wf.plot_item.curves) == 2, "Expected two curves for history scans"
|
||||
c1, c2 = wf.plot_item.curves
|
||||
# First curve should be for hist1, second for hist2
|
||||
assert c1.config.signal.name == "bpm4i"
|
||||
assert c1.config.signal.entry == "bpm4i"
|
||||
assert c1.config.signal.device == "bpm4i"
|
||||
assert c1.config.signal.signal == "bpm4i"
|
||||
assert c1.config.scan_id == "hist1"
|
||||
assert c1.config.scan_number == 1
|
||||
assert c1.name() == "bpm4i-bpm4i-scan-1"
|
||||
|
||||
assert c2.config.signal.name == "bpm4i"
|
||||
assert c2.config.signal.entry == "bpm4i"
|
||||
assert c2.config.signal.device == "bpm4i"
|
||||
assert c2.config.signal.signal == "bpm4i"
|
||||
assert c2.config.scan_id == "hist2"
|
||||
assert c2.config.scan_number == 2
|
||||
assert c2.name() == "bpm4i-bpm4i-scan-2"
|
||||
@@ -1163,7 +1163,7 @@ def test_history_curve_x_modes_pre_plot(qtbot, mocked_client, scan_history_facto
|
||||
wf = create_widget(qtbot, Waveform, client=mocked_client)
|
||||
hist1, hist2 = inject_scan_history(wf, scan_history_factory, ("hist1", 1), ("hist2", 2))
|
||||
wf.x_mode = mode
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="hist1")
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="hist1")
|
||||
assert c.config.current_x_mode == mode
|
||||
|
||||
|
||||
@@ -1174,7 +1174,7 @@ def test_history_curve_x_modes_post_plot(qtbot, mocked_client, scan_history_fact
|
||||
"""
|
||||
wf = create_widget(qtbot, Waveform, client=mocked_client)
|
||||
hist1, hist2 = inject_scan_history(wf, scan_history_factory, ("hist1", 1), ("hist2", 2))
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="hist1")
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="hist1")
|
||||
# Change x_mode after plotting
|
||||
wf.x_mode = mode
|
||||
# Refresh history curves
|
||||
@@ -1191,7 +1191,7 @@ def test_history_curve_incompatible_x_mode_hides_curve(qtbot, mocked_client, sca
|
||||
# Inject history scan for this test
|
||||
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_bad", 1))
|
||||
# Plot history curve
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
|
||||
# Curve should be hidden due to incompatible x_mode
|
||||
assert not c.isVisible()
|
||||
|
||||
@@ -1212,7 +1212,7 @@ def test_fetch_history_data_no_stored_data_raises(
|
||||
# Force get_history_scan_item to return our dummy
|
||||
monkeypatch.setattr(wf, "get_history_scan_item", lambda scan_id, scan_index: dummy_scan)
|
||||
# Attempt to plot history curve should be suppressed by SafeSlot and return None
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="dummy", scan_number=1)
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="dummy", scan_number=1)
|
||||
assert c is None
|
||||
assert len(wf.curves) == 0
|
||||
|
||||
@@ -1224,7 +1224,7 @@ def test_history_curve_device_missing_returns_none(qtbot, mocked_client, scan_hi
|
||||
wf = create_widget(qtbot, Waveform, client=mocked_client)
|
||||
wf.x_mode = "index"
|
||||
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_dev_missing", 1))
|
||||
c = wf.plot(y_name="non-existing", y_entry="non-existing", scan_id=history_msg.scan_id)
|
||||
c = wf.plot(device_y="non-existing", signal_y="non-existing", scan_id=history_msg.scan_id)
|
||||
assert c is None
|
||||
|
||||
|
||||
@@ -1238,7 +1238,7 @@ def test_history_curve_custom_shape_mismatch_hides_curve(
|
||||
wf.x_mode = "async_device"
|
||||
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_custom_shape", 1))
|
||||
# Force shape mismatch for x-data
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
|
||||
assert c is not None
|
||||
assert not c.isVisible()
|
||||
|
||||
@@ -1250,7 +1250,7 @@ def test_history_curve_index_mode_plots_curve(qtbot, mocked_client, scan_history
|
||||
wf = create_widget(qtbot, Waveform, client=mocked_client)
|
||||
wf.x_mode = "index"
|
||||
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_index", 1))
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
|
||||
assert c is not None
|
||||
assert c.isVisible()
|
||||
assert c.config.current_x_mode == "index"
|
||||
@@ -1263,7 +1263,7 @@ def test_history_curve_timestamp_mode_plots_curve(qtbot, mocked_client, scan_his
|
||||
wf = create_widget(qtbot, Waveform, client=mocked_client)
|
||||
wf.x_mode = "timestamp"
|
||||
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_time", 1))
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
|
||||
assert c is not None
|
||||
assert c.isVisible()
|
||||
assert c.config.current_x_mode == "timestamp"
|
||||
@@ -1279,7 +1279,7 @@ def test_history_curve_auto_valid_uses_first_report_device(
|
||||
wf.x_mode = "auto"
|
||||
[history_msg] = inject_scan_history(wf, scan_history_factory, ("hist_auto_valid", 1))
|
||||
# Plot history curve
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
|
||||
assert c is not None
|
||||
assert c.isVisible()
|
||||
# Should have fallen back to the first scan_report_device
|
||||
@@ -1295,7 +1295,7 @@ def test_history_curve_file_not_found_returns_none(qtbot, mocked_client, scan_hi
|
||||
# Inject a valid history message then corrupt its file_path
|
||||
[history_msg] = inject_scan_history(wf, scan_history_factory, ("bad_file", 1))
|
||||
history_msg.file_path = "/nonexistent/path.h5"
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id=history_msg.scan_id)
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id=history_msg.scan_id)
|
||||
assert c is None
|
||||
|
||||
|
||||
@@ -1306,5 +1306,5 @@ def test_history_curve_scan_not_found_returns_none(qtbot, mocked_client):
|
||||
wf = create_widget(qtbot, Waveform, client=mocked_client)
|
||||
wf.x_mode = "index"
|
||||
# No history scans injected for this widget
|
||||
c = wf.plot(y_name="bpm4i", y_entry="bpm4i", scan_id="unknown_scan")
|
||||
c = wf.plot(device_y="bpm4i", signal_y="bpm4i", scan_id="unknown_scan")
|
||||
assert c is None
|
||||
|
||||
Reference in New Issue
Block a user