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 734e1d8..c95bf7a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -26,21 +26,23 @@ jobs: PYTHON_VERSION: ${{ matrix.PYTHON_VERSION }} steps: - name: Checkout branch - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + path: 'spyder-unittest' - 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' @@ -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: | @@ -85,28 +87,28 @@ 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 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@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 10 max_attempts: 3 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@v2 + uses: nick-fields/retry@v3 with: timeout_minutes: 10 max_attempts: 3 - command: pytest spyder_unittest -vv + command: pytest spyder-unittest/spyder_unittest -vv diff --git a/spyder_unittest/tests/conftest.py b/spyder_unittest/tests/conftest.py index 3b633d8..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 @@ -19,7 +22,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 @@ -39,11 +41,13 @@ def main_window(monkeypatch): # Don't show tours message CONF.set('tours', 'show_tour_message', False) - QApplication.processEvents() - # Reset global state - dependencies.DEPENDENCIES = [] - PLUGIN_REGISTRY.reset() + # 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 window = start.main() @@ -52,5 +56,10 @@ 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() + + os.environ.pop('SPY_TEST_USE_INTROSPECTION') 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) 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 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: