Skip to content

Commit

Permalink
Testing: Check registering widget shortcuts for external plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
ccordoba12 committed Nov 29, 2024
1 parent d68bfcf commit 47ee224
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 6 deletions.
2 changes: 1 addition & 1 deletion spyder/app/tests/spyder-boilerplate/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
install_requires=[
"qtpy",
"qtawesome",
"spyder>=5.1.1",
"spyder>=6",
],
packages=find_packages(),
entry_points={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# Third party imports
import qtawesome as qta
from qtpy.QtWidgets import QHBoxLayout, QLabel
from qtpy.QtWidgets import QHBoxLayout, QTextEdit

# Spyder imports
from spyder.api.config.decorators import on_conf_change
Expand Down Expand Up @@ -50,12 +50,13 @@ class SpyderBoilerplateWidget(PluginMainWidget):
def __init__(self, name=None, plugin=None, parent=None):
super().__init__(name, plugin, parent)

# Create an example label
self._example_label = QLabel("Example Label")
# Create example widgets
self._example_widget = QTextEdit(self)
self._example_widget.setText("Example text")

# Add example label to layout
layout = QHBoxLayout()
layout.addWidget(self._example_label)
layout.addWidget(self._example_widget)
self.setLayout(layout)

# --- PluginMainWidget API
Expand All @@ -72,7 +73,7 @@ def setup(self):
name=SpyderBoilerplateActions.ExampleAction,
text="Example action",
tip="Example hover hint",
icon=self.create_icon("spyder"),
icon=self.create_icon("python"),
triggered=lambda: print("Example action triggered!"),
)

Expand All @@ -92,6 +93,19 @@ def setup(self):
SpyderBoilerplateOptionsMenuSections.ExampleSection,
)

# Shortcuts
self.register_shortcut_for_widget(
"Change text",
self.change_text,
)

self.register_shortcut_for_widget(
"new text",
self.new_text,
context="editor",
plugin_name=self._plugin.NAME,
)

def update_actions(self):
pass

Expand All @@ -101,6 +115,15 @@ def on_section_conf_change(self, section):

# --- Public API
# ------------------------------------------------------------------------
def change_text(self):
if self._example_widget.toPlainText() == "":
self._example_widget.setText("Example text")
else:
self._example_widget.setText("")

def new_text(self):
if self._example_widget.toPlainText() != "Another text":
self._example_widget.setText("Another text")


class SpyderBoilerplate(SpyderDockablePlugin):
Expand All @@ -115,6 +138,15 @@ class SpyderBoilerplate(SpyderDockablePlugin):
CONF_SECTION = NAME
CONF_WIDGET_CLASS = SpyderBoilerplateConfigPage
CUSTOM_LAYOUTS = [VerticalSplitLayout2]
CONF_DEFAULTS = [
(CONF_SECTION, {}),
(
"shortcuts",
# Note: These shortcut names are capitalized to check we can
# set/get/reset them correctly.
{f"{NAME}/Change text": "Ctrl+B", "editor/New text": "Ctrl+H"},
),
]

# --- Signals

Expand Down
86 changes: 86 additions & 0 deletions spyder/app/tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
from spyder.plugins.run.api import (
RunExecutionParameters, ExtendedRunExecutionParameters, WorkingDirOpts,
WorkingDirSource, RunContext)
from spyder.plugins.shortcuts.widgets.table import SEQUENCE
from spyder.py3compat import qbytearray_to_str, to_text_string
from spyder.utils.environ import set_user_env
from spyder.utils.conda import get_list_conda_envs
Expand Down Expand Up @@ -5434,6 +5435,91 @@ def test_add_external_plugins_to_dependencies(main_window, qtbot):
assert 'spyder-boilerplate' in external_names


@pytest.mark.skipif(
sys.platform.startswith("linux") and running_in_ci(),
reason="Fails on Linux and CI"
)
@pytest.mark.skipif(not running_in_ci(), reason="Only works in CIs")
def test_shortcuts_in_external_plugins(main_window, qtbot):
"""Test that keyboard shortcuts for widgets work in external plugins."""
# Wait until the window is fully up
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(
lambda: shell.spyder_kernel_ready and shell._prompt_html is not None,
timeout=SHELL_TIMEOUT)

# Show plugin
main_widget = main_window.get_plugin('spyder_boilerplate').get_widget()
main_widget.toggle_view_action.setChecked(True)

# Give focus to text edit area
example_widget = main_widget._example_widget
example_widget.setFocus()

# Check first shortcut is working
qtbot.keyClick(example_widget, Qt.Key_B, modifier=Qt.ControlModifier)
assert example_widget.toPlainText() == ""
qtbot.keyClick(example_widget, Qt.Key_B, modifier=Qt.ControlModifier)
assert example_widget.toPlainText() == "Example text"

# Check second shortcut is working
qtbot.keyClick(example_widget, Qt.Key_H, modifier=Qt.ControlModifier)
assert example_widget.toPlainText() == "Another text"
qtbot.keyClick(example_widget, Qt.Key_H, modifier=Qt.ControlModifier)
assert example_widget.toPlainText() == "Another text"

# Open Preferences and select shortcuts table
dlg, index, page = preferences_dialog_helper(
qtbot, main_window, 'shortcuts'
)
table = page.table

# Change shortcuts in table
new_shortcuts = [("change text", "Ctrl+J"), ("new text", "Alt+K")]
for name, sequence in new_shortcuts:
table.finder.setFocus()
table.finder.clear()
qtbot.keyClicks(table.finder, name)
index = table.proxy_model.mapToSource(table.currentIndex())
row = index.row()
sequence_index = table.source_model.index(row, SEQUENCE)
table.source_model.setData(sequence_index, sequence)

# Save new shortcuts
dlg.ok_btn.animateClick()
qtbot.wait(1000)

# Check new shortcuts are working
example_widget.setFocus()
qtbot.keyClick(example_widget, Qt.Key_J, modifier=Qt.ControlModifier)
assert example_widget.toPlainText() == ""
qtbot.keyClick(example_widget, Qt.Key_J, modifier=Qt.ControlModifier)
assert example_widget.toPlainText() == "Example text"

qtbot.keyClick(example_widget, Qt.Key_K, modifier=Qt.AltModifier)
assert example_widget.toPlainText() == "Another text"

# Open Preferences again and reset shortcuts
dlg, index, page = preferences_dialog_helper(
qtbot, main_window, 'shortcuts'
)
page.reset_to_default(force=True)

# Close preferences
dlg.ok_btn.animateClick()
qtbot.wait(1000)

# Check default shortcuts are working again
example_widget.setFocus()
qtbot.keyClick(example_widget, Qt.Key_B, modifier=Qt.ControlModifier)
assert example_widget.toPlainText() == ""
qtbot.keyClick(example_widget, Qt.Key_B, modifier=Qt.ControlModifier)
assert example_widget.toPlainText() == "Example text"

qtbot.keyClick(example_widget, Qt.Key_H, modifier=Qt.ControlModifier)
assert example_widget.toPlainText() == "Another text"


def test_locals_globals_var_debug(main_window, qtbot, tmpdir):
"""Test that the debugger can handle variables named globals and locals."""
ipyconsole = main_window.ipyconsole
Expand Down

0 comments on commit 47ee224

Please sign in to comment.