mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-12-27 09:31:18 +01:00
615 lines
23 KiB
Python
615 lines
23 KiB
Python
from typing import Literal
|
|
|
|
import pytest
|
|
from qtpy.QtCore import QPoint, Qt
|
|
from qtpy.QtGui import QContextMenuEvent
|
|
from qtpy.QtWidgets import QComboBox, QLabel, QMenu, QStyle, QToolButton, QWidget
|
|
|
|
from bec_widgets.utils.toolbars.actions import (
|
|
DeviceSelectionAction,
|
|
ExpandableMenuAction,
|
|
LongPressToolButton,
|
|
MaterialIconAction,
|
|
QtIconAction,
|
|
SeparatorAction,
|
|
SwitchableToolBarAction,
|
|
WidgetAction,
|
|
)
|
|
from bec_widgets.utils.toolbars.bundles import ToolbarBundle
|
|
from bec_widgets.utils.toolbars.toolbar import ModularToolBar
|
|
|
|
|
|
@pytest.fixture
|
|
def dummy_widget(qtbot):
|
|
"""Fixture to create a simple widget to be used as target widget."""
|
|
widget = QWidget()
|
|
qtbot.addWidget(widget)
|
|
qtbot.waitExposed(widget)
|
|
return widget
|
|
|
|
|
|
@pytest.fixture(params=["horizontal", "vertical"])
|
|
def toolbar_fixture(qtbot, request, dummy_widget):
|
|
"""Parametrized fixture to create a ModularToolBar with different orientations."""
|
|
orientation: Literal["horizontal", "vertical"] = request.param
|
|
toolbar = ModularToolBar(
|
|
orientation=orientation,
|
|
background_color="rgba(255, 255, 255, 255)", # White background for testing
|
|
)
|
|
qtbot.addWidget(toolbar)
|
|
qtbot.waitExposed(toolbar)
|
|
yield toolbar
|
|
|
|
|
|
@pytest.fixture
|
|
def separator_action():
|
|
"""Fixture to create a SeparatorAction."""
|
|
return SeparatorAction()
|
|
|
|
|
|
@pytest.fixture
|
|
def material_icon_action():
|
|
"""Fixture to create a MaterialIconAction."""
|
|
return MaterialIconAction(
|
|
icon_name="home", tooltip="Test Material Icon Action", checkable=False
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def material_icon_action_2():
|
|
"""Fixture to create another MaterialIconAction."""
|
|
return MaterialIconAction(
|
|
icon_name="home", tooltip="Test Material Icon Action 2", checkable=False
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def qt_icon_action():
|
|
"""Fixture to create a QtIconAction."""
|
|
return QtIconAction(standard_icon=QStyle.SP_FileIcon, tooltip="Qt File", checkable=True)
|
|
|
|
|
|
@pytest.fixture
|
|
def device_selection_action():
|
|
"""Fixture to create a DeviceSelectionAction."""
|
|
device_combobox = QComboBox()
|
|
device_combobox.addItems(["Device 1", "Device 2", "Device 3"])
|
|
device_combobox.setCurrentIndex(0)
|
|
return DeviceSelectionAction(label="Select Device:", device_combobox=device_combobox)
|
|
|
|
|
|
@pytest.fixture
|
|
def widget_action():
|
|
"""Fixture to create a WidgetAction."""
|
|
sample_widget = QLabel("Sample Widget")
|
|
return WidgetAction(label="Sample Label:", widget=sample_widget)
|
|
|
|
|
|
@pytest.fixture
|
|
def expandable_menu_action():
|
|
"""Fixture to create an ExpandableMenuAction."""
|
|
action1 = MaterialIconAction(icon_name="counter_1", tooltip="Menu Action 1", checkable=False)
|
|
action2 = MaterialIconAction(icon_name="counter_2", tooltip="Menu Action 2", checkable=True)
|
|
actions = {"action1": action1, "action2": action2}
|
|
return ExpandableMenuAction(
|
|
label="Expandable Menu", actions=actions, icon_path="assets/BEC-Icon.png"
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def switchable_toolbar_action():
|
|
"""Fixture to create a switchable toolbar action with two MaterialIconActions."""
|
|
action1 = MaterialIconAction(icon_name="counter_1", tooltip="Action 1", checkable=True)
|
|
action2 = MaterialIconAction(icon_name="counter_2", tooltip="Action 2", checkable=True)
|
|
switchable = SwitchableToolBarAction(
|
|
actions={"action1": action1, "action2": action2},
|
|
initial_action="action1",
|
|
tooltip="Switchable Action",
|
|
checkable=True,
|
|
)
|
|
return switchable
|
|
|
|
|
|
def test_initialization(toolbar_fixture):
|
|
"""Test that ModularToolBar initializes correctly with different orientations."""
|
|
toolbar = toolbar_fixture
|
|
if toolbar.orientation() == Qt.Horizontal:
|
|
assert toolbar.orientation() == Qt.Horizontal
|
|
elif toolbar.orientation() == Qt.Vertical:
|
|
assert toolbar.orientation() == Qt.Vertical
|
|
else:
|
|
pytest.fail("Toolbar orientation is neither horizontal nor vertical.")
|
|
assert toolbar.background_color == "rgba(255, 255, 255, 255)"
|
|
assert len(toolbar.components._components) == 1 # only the separator
|
|
assert not toolbar.isMovable()
|
|
assert not toolbar.isFloatable()
|
|
|
|
|
|
def test_set_background_color(toolbar_fixture):
|
|
"""Test setting the background color of the toolbar."""
|
|
toolbar = toolbar_fixture
|
|
new_color = "rgba(0, 0, 0, 255)" # Black
|
|
toolbar.set_background_color(new_color)
|
|
assert toolbar.background_color == new_color
|
|
# Verify stylesheet
|
|
expected_style = f"QToolBar {{ background-color: {new_color}; border: none; }}"
|
|
assert toolbar.styleSheet() == expected_style
|
|
|
|
|
|
def test_set_orientation(toolbar_fixture, qtbot, dummy_widget):
|
|
"""Test changing the orientation of the toolbar."""
|
|
toolbar = toolbar_fixture
|
|
if toolbar.orientation() == Qt.Horizontal:
|
|
new_orientation = "vertical"
|
|
else:
|
|
new_orientation = "horizontal"
|
|
toolbar.set_orientation(new_orientation)
|
|
qtbot.wait(100)
|
|
if new_orientation == "horizontal":
|
|
assert toolbar.orientation() == Qt.Horizontal
|
|
else:
|
|
assert toolbar.orientation() == Qt.Vertical
|
|
|
|
|
|
def test_add_action(toolbar_fixture, material_icon_action, qt_icon_action):
|
|
"""Test adding different types of actions to the toolbar components."""
|
|
toolbar = toolbar_fixture
|
|
|
|
# Add MaterialIconAction
|
|
toolbar.add_action("material_icon_action", material_icon_action)
|
|
assert toolbar.components.exists("material_icon_action")
|
|
assert toolbar.components.get_action("material_icon_action") == material_icon_action
|
|
|
|
# Add QtIconAction
|
|
toolbar.add_action("qt_icon_action", qt_icon_action)
|
|
assert toolbar.components.exists("qt_icon_action")
|
|
assert toolbar.components.get_action("qt_icon_action") == qt_icon_action
|
|
|
|
|
|
def test_hide_show_action(toolbar_fixture, qt_icon_action, qtbot):
|
|
"""Test hiding and showing actions on the toolbar."""
|
|
toolbar = toolbar_fixture
|
|
|
|
# Add an action
|
|
toolbar.add_action("icon_action", qt_icon_action)
|
|
assert qt_icon_action.action.isVisible()
|
|
|
|
# Hide the action
|
|
toolbar.hide_action("icon_action")
|
|
qtbot.wait(100)
|
|
assert not qt_icon_action.action.isVisible()
|
|
|
|
# Show the action
|
|
toolbar.show_action("icon_action")
|
|
qtbot.wait(100)
|
|
assert qt_icon_action.action.isVisible()
|
|
|
|
|
|
def test_add_duplicate_action(toolbar_fixture, qt_icon_action):
|
|
"""Test that adding an action with a duplicate action_id raises a ValueError."""
|
|
toolbar = toolbar_fixture
|
|
|
|
# Add an action
|
|
toolbar.add_action("qt_icon_action", qt_icon_action)
|
|
assert toolbar.components.exists("qt_icon_action")
|
|
|
|
# Attempt to add another action with the same ID
|
|
with pytest.raises(ValueError) as excinfo:
|
|
toolbar.add_action("qt_icon_action", qt_icon_action)
|
|
assert "Bundle with name 'qt_icon_action' already exists." in str(excinfo.value)
|
|
|
|
|
|
def test_update_material_icon_colors(toolbar_fixture, material_icon_action):
|
|
"""Test updating the color of MaterialIconAction icons."""
|
|
toolbar = toolbar_fixture
|
|
|
|
# Add MaterialIconAction
|
|
toolbar.add_action("material_icon_action", material_icon_action)
|
|
assert material_icon_action.action is not None
|
|
|
|
# Initial icon
|
|
initial_icon = material_icon_action.action.icon()
|
|
|
|
# Update color
|
|
new_color = "#ff0000" # Red
|
|
toolbar.update_material_icon_colors(new_color)
|
|
|
|
# Updated icon
|
|
updated_icon = material_icon_action.action.icon()
|
|
|
|
# Assuming that the icon changes when color is updated
|
|
assert initial_icon != updated_icon
|
|
|
|
|
|
def test_device_selection_action(toolbar_fixture, device_selection_action):
|
|
"""Test adding a DeviceSelectionAction to the toolbar."""
|
|
toolbar = toolbar_fixture
|
|
toolbar.add_action("device_selection", device_selection_action)
|
|
assert toolbar.components.exists("device_selection")
|
|
toolbar.show_bundles(["device_selection"])
|
|
# DeviceSelectionAction adds a QWidget, so it should be present in the toolbar's widgets
|
|
# Check if the widget is added
|
|
widget = device_selection_action.device_combobox.parentWidget()
|
|
assert widget in toolbar.findChildren(QWidget)
|
|
# Verify that the label is correct
|
|
label = widget.findChild(QLabel)
|
|
assert label.text() == "Select Device:"
|
|
|
|
|
|
def test_widget_action(toolbar_fixture, widget_action):
|
|
"""Test adding a WidgetAction to the toolbar."""
|
|
toolbar = toolbar_fixture
|
|
toolbar.add_action("widget_action", widget_action)
|
|
assert toolbar.components.exists("widget_action")
|
|
toolbar.show_bundles(["widget_action"])
|
|
# WidgetAction adds a QWidget to the toolbar
|
|
container = widget_action.widget.parentWidget()
|
|
assert container in toolbar.findChildren(QWidget)
|
|
# Verify the label if present
|
|
label = container.findChild(QLabel)
|
|
assert label.text() == "Sample Label:"
|
|
|
|
|
|
def test_expandable_menu_action(toolbar_fixture, expandable_menu_action):
|
|
"""Test adding an ExpandableMenuAction to the toolbar."""
|
|
toolbar = toolbar_fixture
|
|
toolbar.add_action("expandable_menu", expandable_menu_action)
|
|
assert toolbar.components.exists("expandable_menu")
|
|
toolbar.show_bundles(["expandable_menu"])
|
|
# ExpandableMenuAction adds a QToolButton with a QMenu
|
|
# Find the QToolButton
|
|
tool_buttons = toolbar.findChildren(QToolButton)
|
|
assert len(tool_buttons) > 0
|
|
button = tool_buttons[-1] # Assuming it's the last one added
|
|
menu = button.menu()
|
|
assert menu is not None
|
|
# Check that menu has the correct actions
|
|
for action_id, sub_action in expandable_menu_action.actions.items():
|
|
# Check if a sub-action with the correct tooltip exists
|
|
matched = False
|
|
for menu_action in menu.actions():
|
|
if menu_action.toolTip() == sub_action.tooltip:
|
|
matched = True
|
|
break
|
|
assert matched, f"Sub-action with tooltip '{sub_action.tooltip}' not found in menu."
|
|
|
|
|
|
def test_update_material_icon_colors_no_material_actions(toolbar_fixture, dummy_widget):
|
|
"""Test updating material icon colors when there are no MaterialIconActions."""
|
|
toolbar = toolbar_fixture
|
|
# Ensure there are no MaterialIconActions
|
|
toolbar.update_material_icon_colors("#00ff00")
|
|
|
|
|
|
def test_hide_action_nonexistent(toolbar_fixture):
|
|
"""Test hiding an action that does not exist raises a KeyError."""
|
|
toolbar = toolbar_fixture
|
|
with pytest.raises(KeyError) as excinfo:
|
|
toolbar.hide_action("nonexistent_action")
|
|
excinfo.match("Component with name 'nonexistent_action' does not exist.")
|
|
|
|
|
|
def test_show_action_nonexistent(toolbar_fixture):
|
|
"""Test showing an action that does not exist raises a KeyError."""
|
|
toolbar = toolbar_fixture
|
|
with pytest.raises(KeyError) as excinfo:
|
|
toolbar.show_action("nonexistent_action")
|
|
excinfo.match("Component with name 'nonexistent_action' does not exist.")
|
|
|
|
|
|
def test_add_bundle(toolbar_fixture, material_icon_action):
|
|
"""Test adding a bundle of actions to the toolbar."""
|
|
toolbar = toolbar_fixture
|
|
toolbar.add_action("material_icon_in_bundle", material_icon_action)
|
|
bundle = ToolbarBundle("test_bundle", toolbar.components)
|
|
bundle.add_action("material_icon_in_bundle")
|
|
|
|
toolbar.add_bundle(bundle)
|
|
|
|
assert toolbar.get_bundle("test_bundle")
|
|
assert toolbar.components.exists("material_icon_in_bundle")
|
|
|
|
toolbar.show_bundles(["test_bundle"])
|
|
|
|
assert material_icon_action.action in toolbar.actions()
|
|
|
|
|
|
def test_invalid_orientation():
|
|
"""Test that an invalid orientation raises a ValueError."""
|
|
try:
|
|
toolbar = ModularToolBar(orientation="horizontal")
|
|
with pytest.raises(ValueError):
|
|
toolbar.set_orientation("diagonal")
|
|
finally:
|
|
toolbar.close()
|
|
toolbar.deleteLater()
|
|
|
|
|
|
def test_widget_action_calculate_minimum_width(qtbot):
|
|
"""Test calculate_minimum_width with various combo box items."""
|
|
combo = QComboBox()
|
|
combo.addItems(["Short", "Longer Item", "The Longest Item In Combo"])
|
|
widget_action = WidgetAction(label="Test", widget=combo)
|
|
width = widget_action.calculate_minimum_width(combo)
|
|
assert width > 0
|
|
# Width should be large enough to accommodate the longest item plus additional space
|
|
assert width > 100
|
|
|
|
|
|
def test_add_action_to_bundle(toolbar_fixture, dummy_widget, material_icon_action):
|
|
# Create an initial bundle with one action
|
|
toolbar_fixture.add_action("initial_action", material_icon_action)
|
|
bundle = ToolbarBundle("test_bundle", toolbar_fixture.components)
|
|
bundle.add_action("initial_action")
|
|
toolbar_fixture.add_bundle(bundle)
|
|
|
|
# Create a new action to add to the existing bundle
|
|
new_action = MaterialIconAction(
|
|
icon_name="counter_1", tooltip="New Action", checkable=True, parent=dummy_widget
|
|
)
|
|
toolbar_fixture.components.add_safe("new_action", new_action)
|
|
toolbar_fixture.get_bundle("test_bundle").add_action("new_action")
|
|
|
|
toolbar_fixture.show_bundles(["test_bundle"])
|
|
|
|
# Verify the new action is registered in the toolbar's widgets
|
|
assert toolbar_fixture.components.exists("new_action")
|
|
assert toolbar_fixture.components.get_action("new_action") == new_action
|
|
|
|
# Verify the new action is included in the bundle tracking
|
|
assert toolbar_fixture.bundles["test_bundle"].bundle_actions["new_action"]() == new_action
|
|
|
|
# Verify the new action's QAction is present in the toolbar's action list
|
|
actions_list = toolbar_fixture.actions()
|
|
assert new_action.action in actions_list
|
|
|
|
# Verify that the new action is inserted immediately after the last action of the bundle
|
|
last_bundle_action = material_icon_action.action
|
|
index_last = actions_list.index(last_bundle_action)
|
|
index_new = actions_list.index(new_action.action)
|
|
assert index_new == index_last + 1
|
|
|
|
|
|
def test_context_menu_contains_added_actions(
|
|
toolbar_fixture, material_icon_action, material_icon_action_2, monkeypatch
|
|
):
|
|
"""
|
|
Test that the toolbar's context menu lists all added toolbar actions.
|
|
"""
|
|
toolbar = toolbar_fixture
|
|
|
|
# Add two different actions
|
|
toolbar.components.add_safe("material_icon_action", material_icon_action)
|
|
toolbar.components.add_safe("material_icon_action_2", material_icon_action_2)
|
|
bundle = toolbar.new_bundle("test_bundle")
|
|
bundle.add_action("material_icon_action")
|
|
bundle.add_action("material_icon_action_2")
|
|
|
|
toolbar.show_bundles(["test_bundle"])
|
|
# Mock the QMenu.exec_ method to prevent the context menu from being displayed and block CI pipeline
|
|
monkeypatch.setattr(QMenu, "exec_", lambda self, pos=None: None)
|
|
event = QContextMenuEvent(QContextMenuEvent.Mouse, QPoint(10, 10))
|
|
toolbar.contextMenuEvent(event)
|
|
menus = toolbar.findChildren(QMenu)
|
|
|
|
assert len(menus) > 0
|
|
menu = menus[-1]
|
|
menu_action_texts = [action.text() for action in menu.actions()]
|
|
tooltips = [
|
|
action.action.tooltip
|
|
for action in toolbar.components._components.values()
|
|
if not isinstance(action.action, SeparatorAction)
|
|
]
|
|
menu_actions_tooltips = [
|
|
action.toolTip() for action in menu.actions() if action.toolTip() != ""
|
|
]
|
|
assert menu_action_texts == tooltips
|
|
|
|
|
|
def test_context_menu_toggle_action_visibility(toolbar_fixture, material_icon_action, monkeypatch):
|
|
"""
|
|
Test that toggling action visibility works correctly through the toolbar's context menu.
|
|
"""
|
|
toolbar = toolbar_fixture
|
|
# Add an action
|
|
toolbar.add_action("material_icon_action", material_icon_action)
|
|
toolbar.show_bundles(["material_icon_action"])
|
|
assert material_icon_action.action.isVisible()
|
|
|
|
# Manually trigger the context menu event
|
|
monkeypatch.setattr(QMenu, "exec_", lambda self, pos=None: None)
|
|
event = QContextMenuEvent(QContextMenuEvent.Mouse, QPoint(10, 10))
|
|
toolbar.contextMenuEvent(event)
|
|
|
|
# Grab the menu that was created
|
|
menus = toolbar.findChildren(QMenu)
|
|
assert len(menus) > 0
|
|
menu = menus[-1]
|
|
|
|
# Locate the QAction in the menu
|
|
matching_actions = [m for m in menu.actions() if m.text() == material_icon_action.tooltip]
|
|
assert len(matching_actions) == 1
|
|
action_in_menu = matching_actions[0]
|
|
|
|
# Toggle it off (uncheck)
|
|
action_in_menu.setChecked(False)
|
|
menu.triggered.emit(action_in_menu)
|
|
# The action on the toolbar should now be hidden
|
|
assert not material_icon_action.action.isVisible()
|
|
|
|
# Toggle it on (check)
|
|
action_in_menu.setChecked(True)
|
|
menu.triggered.emit(action_in_menu)
|
|
# The action on the toolbar should be visible again
|
|
assert material_icon_action.action.isVisible()
|
|
|
|
|
|
def test_switchable_toolbar_action_add(toolbar_fixture, switchable_toolbar_action):
|
|
"""Test that a switchable toolbar action can be added to the toolbar correctly."""
|
|
toolbar = toolbar_fixture
|
|
toolbar.add_action("switch_action", switchable_toolbar_action)
|
|
toolbar.show_bundles(["switch_action"])
|
|
|
|
# Verify the action was added correctly
|
|
assert toolbar.components.exists("switch_action")
|
|
assert toolbar.components.get_action("switch_action") == switchable_toolbar_action
|
|
|
|
# Verify the button is present and is the correct type
|
|
button = switchable_toolbar_action.main_button
|
|
assert isinstance(button, LongPressToolButton)
|
|
|
|
# Verify initial state
|
|
assert switchable_toolbar_action.current_key == "action1"
|
|
assert button.toolTip() == "Action 1"
|
|
|
|
|
|
def test_switchable_toolbar_action_switching(toolbar_fixture, switchable_toolbar_action, qtbot):
|
|
toolbar = toolbar_fixture
|
|
toolbar.add_action("switch_action", switchable_toolbar_action)
|
|
toolbar.show_bundles(["switch_action"])
|
|
# Verify initial state is set to action1
|
|
assert switchable_toolbar_action.current_key == "action1"
|
|
assert switchable_toolbar_action.main_button.toolTip() == "Action 1"
|
|
# Access the dropdown menu from the main button
|
|
menu = switchable_toolbar_action.main_button.menu()
|
|
assert menu is not None
|
|
# Find the QAction corresponding to "Action 2"
|
|
action_for_2 = None
|
|
for act in menu.actions():
|
|
if act.text() == "Action 2":
|
|
action_for_2 = act
|
|
break
|
|
assert action_for_2 is not None, "Menu action for 'Action 2' not found."
|
|
# Trigger the QAction to switch to action2
|
|
action_for_2.trigger()
|
|
qtbot.wait(100)
|
|
# Verify that the switchable action has updated its state
|
|
assert switchable_toolbar_action.current_key == "action2"
|
|
assert switchable_toolbar_action.main_button.toolTip() == "Action 2"
|
|
|
|
|
|
def test_long_pressbutton(toolbar_fixture, switchable_toolbar_action, qtbot):
|
|
toolbar = toolbar_fixture
|
|
toolbar.add_action("switch_action", switchable_toolbar_action)
|
|
toolbar.show_bundles(["switch_action"])
|
|
|
|
# Verify the button is a LongPressToolButton
|
|
button = switchable_toolbar_action.main_button
|
|
assert isinstance(button, LongPressToolButton)
|
|
|
|
# Override showMenu() to record when it is called.
|
|
call_flag = []
|
|
|
|
# had to put some fake menu, we cannot call .isVisible at CI
|
|
def fake_showMenu():
|
|
call_flag.append(True)
|
|
|
|
button.showMenu = fake_showMenu
|
|
|
|
# Simulate a long press (exceeding the threshold, default 500ms).
|
|
qtbot.mousePress(button, Qt.LeftButton)
|
|
qtbot.wait(600) # wait longer than long_press_threshold
|
|
qtbot.mouseRelease(button, Qt.LeftButton)
|
|
|
|
# Verify that fake_showMenu() was called.
|
|
assert call_flag, "Long press did not trigger showMenu() as expected."
|
|
|
|
|
|
# Additional tests for action/bundle removal
|
|
def test_remove_standalone_action(toolbar_fixture, material_icon_action):
|
|
"""
|
|
Ensure that a standalone action is fully removed and no longer accessible.
|
|
"""
|
|
toolbar = toolbar_fixture
|
|
# Add the action and check it is present
|
|
toolbar.add_action("icon_action", material_icon_action)
|
|
|
|
assert toolbar.components.exists("icon_action")
|
|
|
|
toolbar.show_bundles(["icon_action"])
|
|
assert material_icon_action.action in toolbar.actions()
|
|
|
|
# Now remove it
|
|
toolbar.components.remove_action("icon_action")
|
|
|
|
# Action bookkeeping
|
|
assert not toolbar.components.exists("icon_action")
|
|
# QAction list
|
|
assert material_icon_action.action not in toolbar.actions()
|
|
# Attempting to hide / show it should raise
|
|
with pytest.raises(KeyError):
|
|
toolbar.hide_action("icon_action")
|
|
with pytest.raises(KeyError):
|
|
toolbar.show_action("icon_action")
|
|
|
|
|
|
def test_remove_action_from_bundle(toolbar_fixture, material_icon_action, material_icon_action_2):
|
|
"""
|
|
Remove a single action that is part of a bundle. This should not remove the action
|
|
from the toolbar's components, but only from the bundle tracking.
|
|
"""
|
|
toolbar = toolbar_fixture
|
|
bundle = toolbar.new_bundle("test_bundle")
|
|
# Add two actions to the bundle
|
|
toolbar.components.add_safe("material_action", material_icon_action)
|
|
toolbar.components.add_safe("material_action_2", material_icon_action_2)
|
|
bundle.add_action("material_action")
|
|
bundle.add_action("material_action_2")
|
|
|
|
toolbar.show_bundles(["test_bundle"])
|
|
|
|
# Initial assertions
|
|
assert "test_bundle" in toolbar.bundles
|
|
assert toolbar.components.exists("material_action")
|
|
assert toolbar.components.exists("material_action_2")
|
|
|
|
# Remove one action from the bundle
|
|
toolbar.get_bundle("test_bundle").remove_action("material_action")
|
|
|
|
# The bundle should still exist
|
|
assert "test_bundle" in toolbar.bundles
|
|
# The removed action should still exist in the components
|
|
assert toolbar.components.exists("material_action")
|
|
|
|
# The removed action should not be in the bundle anymore
|
|
assert "material_action" not in toolbar.bundles["test_bundle"].bundle_actions
|
|
|
|
|
|
def test_remove_entire_bundle(toolbar_fixture, material_icon_action, material_icon_action_2):
|
|
toolbar = toolbar_fixture
|
|
toolbar.components.add_safe("material_action", material_icon_action)
|
|
toolbar.components.add_safe("material_action_2", material_icon_action_2)
|
|
# Create a bundle with two actions
|
|
bundle = toolbar.new_bundle("to_remove")
|
|
bundle.add_action("material_action")
|
|
bundle.add_action("material_action_2")
|
|
|
|
# Confirm bundle presence
|
|
assert "to_remove" in toolbar.bundles
|
|
|
|
# Remove the whole bundle
|
|
toolbar.remove_bundle("to_remove")
|
|
|
|
# Bundle mapping gone
|
|
assert "to_remove" not in toolbar.bundles
|
|
|
|
|
|
def test_remove_nonexistent_action(toolbar_fixture):
|
|
"""
|
|
Attempting to remove an action that does not exist should raise KeyError.
|
|
"""
|
|
toolbar = toolbar_fixture
|
|
with pytest.raises(KeyError) as excinfo:
|
|
toolbar.components.remove_action("nonexistent_action")
|
|
assert "Action with ID 'nonexistent_action' does not exist." in str(excinfo.value)
|
|
|
|
|
|
def test_remove_nonexistent_bundle(toolbar_fixture):
|
|
"""
|
|
Attempting to remove a bundle that does not exist should raise KeyError.
|
|
"""
|
|
toolbar = toolbar_fixture
|
|
with pytest.raises(KeyError) as excinfo:
|
|
toolbar.remove_bundle("nonexistent_bundle")
|
|
excinfo.match("Bundle with name 'nonexistent_bundle' does not exist.")
|