From 979a813d4575fd9357834ef4299b69fb155f1a15 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Mon, 8 Apr 2024 22:04:19 +0100 Subject: [PATCH 1/7] Move import in one test file inside functions As a side-effect of PR spyder-ide/spyder#21734, a QApplication needs to be running before importing spyder.plugins.preferences.widgets.configdialog. Moving the import inside a function achieves this. --- spyder_unittest/widgets/tests/test_confpage.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/spyder_unittest/widgets/tests/test_confpage.py b/spyder_unittest/widgets/tests/test_confpage.py index 6790a18..9d06311 100644 --- a/spyder_unittest/widgets/tests/test_confpage.py +++ b/spyder_unittest/widgets/tests/test_confpage.py @@ -20,7 +20,6 @@ from spyder.api.plugin_registration.registry import PLUGIN_REGISTRY from spyder.app.cli_options import get_options from spyder.config.manager import CONF -from spyder.plugins.preferences.plugin import Preferences # Local imports from spyder_unittest.unittestplugin import UnitTestPlugin @@ -34,6 +33,10 @@ class MainWindowMock(QMainWindow): register_shortcut = Mock() def __init__(self, parent): + # This import assumes that an QApplication is already running, + # so we can not put it at the top of the file + from spyder.plugins.preferences.plugin import Preferences + super().__init__(parent) self.default_style = None self.widgetlist = [] @@ -75,6 +78,10 @@ def get_plugin(self, plugin_name, error=True): class ConfigDialogTester(QWidget): def __init__(self, parent, main_class, general_config_plugins, plugins): + # This import assumes that an QApplication is already running, + # so we can not put it at the top of the file + from spyder.plugins.preferences.plugin import Preferences + super().__init__(parent) self._main = main_class(self) if main_class else None if self._main is None: From defdcbf4f2d049e3a36496ad2c8b2ea895a36b6a Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Sun, 7 Apr 2024 19:16:05 +0100 Subject: [PATCH 2/7] Use new API for Editor plugin This was introduced in PR spyder-ide/spyder#21353 --- spyder_unittest/unittestplugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spyder_unittest/unittestplugin.py b/spyder_unittest/unittestplugin.py index 53c5bf3..e645061 100644 --- a/spyder_unittest/unittestplugin.py +++ b/spyder_unittest/unittestplugin.py @@ -126,9 +126,9 @@ def on_editor_available(self): """ editor = self.get_plugin(Plugins.Editor) run_action = self.get_action(UnitTestPluginActions.Run) - editor.pythonfile_dependent_actions += [run_action] + editor.get_widget().pythonfile_dependent_actions += [run_action] # FIXME: Previous line does not do anything - self.get_widget().pre_test_hook = editor.save_all + self.get_widget().pre_test_hook = editor.get_widget().save_all self.get_widget().sig_edit_goto.connect(self.goto_in_editor) @on_plugin_teardown(plugin=Plugins.Editor) From 53268096769d2cccba92deb6a0ac77a5f388c292 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Fri, 12 Apr 2024 23:13:01 +0100 Subject: [PATCH 3/7] Properly close main window in fixture This mirrors the changes in PR spyder-ide/spyder#21353 --- spyder_unittest/tests/conftest.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/spyder_unittest/tests/conftest.py b/spyder_unittest/tests/conftest.py index 3b633d8..3207e8a 100644 --- a/spyder_unittest/tests/conftest.py +++ b/spyder_unittest/tests/conftest.py @@ -19,7 +19,6 @@ from qtpy import QtWebEngineWidgets # noqa # Spyder imports -from spyder import dependencies from spyder import version_info as spyder_version_info from spyder.api.plugin_registration.registry import PLUGIN_REGISTRY from spyder.app import start @@ -41,10 +40,6 @@ def main_window(monkeypatch): CONF.set('tours', 'show_tour_message', False) QApplication.processEvents() - # Reset global state - dependencies.DEPENDENCIES = [] - PLUGIN_REGISTRY.reset() - # Start the window window = start.main() QApplication.processEvents() @@ -52,5 +47,8 @@ def main_window(monkeypatch): yield window # Close main window + window.closing(close_immediately=True) window.close() CONF.reset_to_defaults(notification=False) + CONF.reset_manager() + PLUGIN_REGISTRY.reset() From 51e1a5fbfaf44ccf62c25b152aaaccf76f70aaac Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Mon, 15 Apr 2024 21:10:48 +0100 Subject: [PATCH 4/7] Turn introspection on in the main_window fixture It is not clear why this is needed, but without this the tests abort on exit with "QThread: Destroyed while thread is still running" --- spyder_unittest/tests/conftest.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spyder_unittest/tests/conftest.py b/spyder_unittest/tests/conftest.py index 3207e8a..fe39d66 100644 --- a/spyder_unittest/tests/conftest.py +++ b/spyder_unittest/tests/conftest.py @@ -10,6 +10,9 @@ available for integration tests. """ +# Standard library imports +import os + # Third-party imports from qtpy.QtWidgets import QApplication import pytest @@ -38,6 +41,12 @@ def main_window(monkeypatch): # Don't show tours message CONF.set('tours', 'show_tour_message', False) + + # Turn introspection on, even though it's slower and more memory + # intensive, because otherwise tests are aborted at end with + # "QThread: Destroyed while thread is still running". + os.environ['SPY_TEST_USE_INTROSPECTION'] = 'True' + QApplication.processEvents() # Start the window @@ -52,3 +61,5 @@ def main_window(monkeypatch): CONF.reset_to_defaults(notification=False) CONF.reset_manager() PLUGIN_REGISTRY.reset() + + os.environ.pop('SPY_TEST_USE_INTROSPECTION') From 05236003f350a0cc803e209a84088c6c38edb2a9 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Fri, 5 Apr 2024 15:57:28 +0100 Subject: [PATCH 5/7] Replace QStylePalette by SpyderPalette This follows the new API after PR spyder-ide/spyder#21844. --- spyder_unittest/widgets/datatree.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spyder_unittest/widgets/datatree.py b/spyder_unittest/widgets/datatree.py index 427fbaa..616ad4a 100644 --- a/spyder_unittest/widgets/datatree.py +++ b/spyder_unittest/widgets/datatree.py @@ -16,7 +16,7 @@ from qtpy.QtWidgets import QMenu, QTreeView from spyder.api.config.mixins import SpyderConfigurationAccessor from spyder.config.base import get_translation -from spyder.utils.palette import QStylePalette, SpyderPalette +from spyder.utils.palette import SpyderPalette from spyder.utils.qthelpers import create_action # Local imports @@ -33,8 +33,8 @@ Category.OK: SpyderPalette.COLOR_SUCCESS_1, Category.FAIL: SpyderPalette.COLOR_ERROR_1, Category.SKIP: SpyderPalette.COLOR_WARN_1, - Category.PENDING: QStylePalette.COLOR_BACKGROUND_1, - Category.COVERAGE: QStylePalette.COLOR_ACCENT_1 + Category.PENDING: SpyderPalette.COLOR_BACKGROUND_1, + Category.COVERAGE: SpyderPalette.COLOR_ACCENT_1 } STATUS_COLUMN = 0 From 0506d7df88b0f96439d29c57eb2106aa9a4a48fe Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Thu, 18 Apr 2024 20:52:10 +0100 Subject: [PATCH 6/7] CI: Bump versions of GitHub actions * This is to get Node 20 because older versions are deprecated. * Also replace Replace mambaforge by miniforge now that conda uses the same solver as mamba. --- .github/workflows/run-tests.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 734e1d8..7665d59 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -26,21 +26,21 @@ jobs: PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }} steps: - name: Checkout branch - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install System Packages if: matrix.OS == 'ubuntu' run: | sudo apt-get update --fix-missing sudo apt-get install -qq pyqt5-dev-tools libxcb-xinerama0 xterm --fix-missing - name: Install Conda - uses: conda-incubator/setup-miniconda@v2 + uses: conda-incubator/setup-miniconda@v3 with: - miniforge-variant: Mambaforge + miniforge-version: latest auto-update-conda: true python-version: ${{ matrix.PYTHON_VERSION }} - name: Checkout Spyder from git if: matrix.SPYDER_SOURCE == 'git' - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: 'spyder-ide/spyder' path: 'spyder' @@ -85,7 +85,7 @@ jobs: mamba list - name: Run tests (Linux) if: matrix.OS == 'ubuntu' - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 10 max_attempts: 3 @@ -95,7 +95,7 @@ jobs: xvfb-run --auto-servernum pytest spyder_unittest -vv - name: Run tests (MacOS) if: matrix.OS == 'macos' - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 10 max_attempts: 3 @@ -105,7 +105,7 @@ jobs: pytest spyder_unittest -vv - name: Run tests (Windows) if: matrix.OS == 'windows' - uses: nick-fields/retry@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 10 max_attempts: 3 From 251bee8b0d0355c3e2fdab4363edf328c20e648f Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Thu, 18 Apr 2024 20:58:01 +0100 Subject: [PATCH 7/7] CI: Put Spyder source tree outside the plugin source tree Before, the Spyder source tree was nested inside the plugin source tree which was messy and may have generated errors. --- .github/scripts/generate-without-spyder.py | 10 +++++++--- .github/workflows/run-tests.yml | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.github/scripts/generate-without-spyder.py b/.github/scripts/generate-without-spyder.py index 26a94a6..491ce99 100644 --- a/.github/scripts/generate-without-spyder.py +++ b/.github/scripts/generate-without-spyder.py @@ -7,11 +7,15 @@ """Script to generate requirements/without-spyder.txt""" import re +from pathlib import Path -with open('requirements/conda.txt') as infile: - with open('requirements/without-spyder.txt', 'w') as outfile: +rootdir = Path(__file__).parents[2] +input_filename = rootdir / 'requirements' / 'conda.txt' +output_filename = rootdir / 'requirements' / 'without-spyder.txt' + +with open(input_filename) as infile: + with open(output_filename, 'w') as outfile: for line in infile: package_name = re.match('[-a-z0-9_]*', line).group(0) if package_name != 'spyder': outfile.write(line) - diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 7665d59..c95bf7a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -27,6 +27,8 @@ jobs: steps: - name: Checkout branch uses: actions/checkout@v4 + with: + path: 'spyder-unittest' - name: Install System Packages if: matrix.OS == 'ubuntu' run: | @@ -64,20 +66,20 @@ jobs: if: matrix.SPYDER_SOURCE == 'git' shell: bash -l {0} run: | - python .github/scripts/generate-without-spyder.py - mamba install --file requirements/without-spyder.txt -y + python spyder-unittest/.github/scripts/generate-without-spyder.py + mamba install --file spyder-unittest/requirements/without-spyder.txt -y - name: Install plugin dependencies if: matrix.SPYDER_SOURCE == 'conda' shell: bash -l {0} - run: mamba install --file requirements/conda.txt -y + run: mamba install --file spyder-unittest/requirements/conda.txt -y - name: Install test dependencies shell: bash -l {0} run: | mamba install nomkl -y -q - mamba install --file requirements/tests.txt -y + mamba install --file spyder-unittest/requirements/tests.txt -y - name: Install plugin shell: bash -l {0} - run: pip install --no-deps -e . + run: pip install --no-deps -e spyder-unittest - name: Show environment information shell: bash -l {0} run: | @@ -92,7 +94,7 @@ jobs: shell: bash command: | . ~/.profile - xvfb-run --auto-servernum pytest spyder_unittest -vv + xvfb-run --auto-servernum pytest spyder-unittest/spyder_unittest -vv - name: Run tests (MacOS) if: matrix.OS == 'macos' uses: nick-fields/retry@v3 @@ -102,11 +104,11 @@ jobs: shell: bash command: | . ~/.profile - pytest spyder_unittest -vv + pytest spyder-unittest/spyder_unittest -vv - name: Run tests (Windows) if: matrix.OS == 'windows' uses: nick-fields/retry@v3 with: timeout_minutes: 10 max_attempts: 3 - command: pytest spyder_unittest -vv + command: pytest spyder-unittest/spyder_unittest -vv