napari-plugin-manager 0.1.2__py3-none-any.whl → 0.1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- napari_plugin_manager/_tests/test_base_installer_process.py +23 -0
- napari_plugin_manager/_tests/test_installer_process.py +69 -39
- napari_plugin_manager/_tests/test_npe2api.py +1 -1
- napari_plugin_manager/_tests/test_qt_plugin_dialog.py +108 -84
- napari_plugin_manager/_version.py +2 -2
- napari_plugin_manager/base_qt_package_installer.py +629 -0
- napari_plugin_manager/base_qt_plugin_dialog.py +1816 -0
- napari_plugin_manager/npe2api.py +0 -1
- napari_plugin_manager/qt_package_installer.py +29 -605
- napari_plugin_manager/qt_plugin_dialog.py +106 -1359
- {napari_plugin_manager-0.1.2.dist-info → napari_plugin_manager-0.1.4.dist-info}/METADATA +22 -7
- napari_plugin_manager-0.1.4.dist-info/RECORD +22 -0
- {napari_plugin_manager-0.1.2.dist-info → napari_plugin_manager-0.1.4.dist-info}/WHEEL +1 -1
- napari_plugin_manager-0.1.2.dist-info/RECORD +0 -19
- {napari_plugin_manager-0.1.2.dist-info → napari_plugin_manager-0.1.4.dist-info}/LICENSE +0 -0
- {napari_plugin_manager-0.1.2.dist-info → napari_plugin_manager-0.1.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from napari_plugin_manager.base_qt_package_installer import (
|
|
4
|
+
AbstractInstallerTool,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_not_implemented_methods():
|
|
9
|
+
tool = AbstractInstallerTool('install', ['requests'])
|
|
10
|
+
with pytest.raises(NotImplementedError):
|
|
11
|
+
tool.executable()
|
|
12
|
+
|
|
13
|
+
with pytest.raises(NotImplementedError):
|
|
14
|
+
tool.arguments()
|
|
15
|
+
|
|
16
|
+
with pytest.raises(NotImplementedError):
|
|
17
|
+
tool.environment()
|
|
18
|
+
|
|
19
|
+
with pytest.raises(NotImplementedError):
|
|
20
|
+
tool.constraints()
|
|
21
|
+
|
|
22
|
+
with pytest.raises(NotImplementedError):
|
|
23
|
+
tool.available()
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import re
|
|
3
|
+
import sys
|
|
2
4
|
import time
|
|
3
5
|
from pathlib import Path
|
|
4
6
|
from types import MethodType
|
|
@@ -7,13 +9,16 @@ from typing import TYPE_CHECKING
|
|
|
7
9
|
import pytest
|
|
8
10
|
from qtpy.QtCore import QProcessEnvironment
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
import napari_plugin_manager.base_qt_package_installer as bqpi
|
|
13
|
+
from napari_plugin_manager.base_qt_package_installer import (
|
|
11
14
|
AbstractInstallerTool,
|
|
12
|
-
CondaInstallerTool,
|
|
13
15
|
InstallerActions,
|
|
14
|
-
InstallerQueue,
|
|
15
16
|
InstallerTools,
|
|
16
|
-
|
|
17
|
+
)
|
|
18
|
+
from napari_plugin_manager.qt_package_installer import (
|
|
19
|
+
NapariCondaInstallerTool,
|
|
20
|
+
NapariInstallerQueue,
|
|
21
|
+
NapariPipInstallerTool,
|
|
17
22
|
)
|
|
18
23
|
|
|
19
24
|
if TYPE_CHECKING:
|
|
@@ -55,25 +60,20 @@ class _NonExistingTool(AbstractInstallerTool):
|
|
|
55
60
|
return QProcessEnvironment.systemEnvironment()
|
|
56
61
|
|
|
57
62
|
|
|
58
|
-
def
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
with pytest.raises(NotImplementedError):
|
|
64
|
-
tool.arguments()
|
|
65
|
-
|
|
66
|
-
with pytest.raises(NotImplementedError):
|
|
67
|
-
tool.environment()
|
|
68
|
-
|
|
69
|
-
with pytest.raises(NotImplementedError):
|
|
70
|
-
tool.available()
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def test_pip_installer_tasks(qtbot, tmp_virtualenv: 'Session', monkeypatch):
|
|
74
|
-
installer = InstallerQueue()
|
|
63
|
+
def test_pip_installer_tasks(
|
|
64
|
+
qtbot, tmp_virtualenv: 'Session', monkeypatch, caplog
|
|
65
|
+
):
|
|
66
|
+
caplog.set_level(logging.DEBUG, logger=bqpi.__name__)
|
|
67
|
+
installer = NapariInstallerQueue()
|
|
75
68
|
monkeypatch.setattr(
|
|
76
|
-
|
|
69
|
+
NapariPipInstallerTool,
|
|
70
|
+
"executable",
|
|
71
|
+
lambda *a: tmp_virtualenv.creator.exe,
|
|
72
|
+
)
|
|
73
|
+
monkeypatch.setattr(
|
|
74
|
+
NapariPipInstallerTool,
|
|
75
|
+
"origins",
|
|
76
|
+
("https://pypi.org/simple",),
|
|
77
77
|
)
|
|
78
78
|
with qtbot.waitSignal(installer.allFinished, timeout=20000):
|
|
79
79
|
installer.install(
|
|
@@ -138,10 +138,34 @@ def test_pip_installer_tasks(qtbot, tmp_virtualenv: 'Session', monkeypatch):
|
|
|
138
138
|
)
|
|
139
139
|
|
|
140
140
|
|
|
141
|
+
def test_pip_installer_invalid_action(tmp_virtualenv: 'Session', monkeypatch):
|
|
142
|
+
installer = NapariInstallerQueue()
|
|
143
|
+
monkeypatch.setattr(
|
|
144
|
+
NapariPipInstallerTool,
|
|
145
|
+
"executable",
|
|
146
|
+
lambda *a: tmp_virtualenv.creator.exe,
|
|
147
|
+
)
|
|
148
|
+
invalid_action = 'Invalid Action'
|
|
149
|
+
with pytest.raises(
|
|
150
|
+
ValueError, match=f"Action '{invalid_action}' not supported!"
|
|
151
|
+
):
|
|
152
|
+
item = installer._build_queue_item(
|
|
153
|
+
tool=InstallerTools.PIP,
|
|
154
|
+
action=invalid_action,
|
|
155
|
+
pkgs=['pip-install-test'],
|
|
156
|
+
prefix=None,
|
|
157
|
+
origins=(),
|
|
158
|
+
process=installer._create_process(),
|
|
159
|
+
)
|
|
160
|
+
installer._queue_item(item)
|
|
161
|
+
|
|
162
|
+
|
|
141
163
|
def test_installer_failures(qtbot, tmp_virtualenv: 'Session', monkeypatch):
|
|
142
|
-
installer =
|
|
164
|
+
installer = NapariInstallerQueue()
|
|
143
165
|
monkeypatch.setattr(
|
|
144
|
-
|
|
166
|
+
NapariPipInstallerTool,
|
|
167
|
+
"executable",
|
|
168
|
+
lambda *a: tmp_virtualenv.creator.exe,
|
|
145
169
|
)
|
|
146
170
|
|
|
147
171
|
# CHECK 1) Errors should trigger finished and allFinished too
|
|
@@ -181,7 +205,7 @@ def test_installer_failures(qtbot, tmp_virtualenv: 'Session', monkeypatch):
|
|
|
181
205
|
|
|
182
206
|
|
|
183
207
|
def test_cancel_incorrect_job_id(qtbot, tmp_virtualenv: 'Session'):
|
|
184
|
-
installer =
|
|
208
|
+
installer = NapariInstallerQueue()
|
|
185
209
|
with qtbot.waitSignal(installer.allFinished, timeout=20000):
|
|
186
210
|
job_id = installer.install(
|
|
187
211
|
tool=InstallerTools.PIP,
|
|
@@ -192,13 +216,17 @@ def test_cancel_incorrect_job_id(qtbot, tmp_virtualenv: 'Session'):
|
|
|
192
216
|
|
|
193
217
|
|
|
194
218
|
@pytest.mark.skipif(
|
|
195
|
-
not
|
|
219
|
+
not NapariCondaInstallerTool.available(), reason="Conda is not available."
|
|
196
220
|
)
|
|
197
|
-
def test_conda_installer(qtbot, tmp_conda_env: Path):
|
|
221
|
+
def test_conda_installer(qtbot, caplog, monkeypatch, tmp_conda_env: Path):
|
|
222
|
+
if sys.platform == "darwin":
|
|
223
|
+
# check handled for `PYTHONEXECUTABLE` env definition on macOS
|
|
224
|
+
monkeypatch.setenv("PYTHONEXECUTABLE", sys.executable)
|
|
225
|
+
caplog.set_level(logging.DEBUG, logger=bqpi.__name__)
|
|
198
226
|
conda_meta = tmp_conda_env / "conda-meta"
|
|
199
227
|
glob_pat = "typing-extensions-*.json"
|
|
200
228
|
glob_pat_2 = "pyzenhub-*.json"
|
|
201
|
-
installer =
|
|
229
|
+
installer = NapariInstallerQueue()
|
|
202
230
|
|
|
203
231
|
with qtbot.waitSignal(installer.allFinished, timeout=600_000):
|
|
204
232
|
installer.install(
|
|
@@ -277,9 +305,11 @@ def test_conda_installer(qtbot, tmp_conda_env: Path):
|
|
|
277
305
|
|
|
278
306
|
|
|
279
307
|
def test_installer_error(qtbot, tmp_virtualenv: 'Session', monkeypatch):
|
|
280
|
-
installer =
|
|
308
|
+
installer = NapariInstallerQueue()
|
|
281
309
|
monkeypatch.setattr(
|
|
282
|
-
|
|
310
|
+
NapariPipInstallerTool,
|
|
311
|
+
"executable",
|
|
312
|
+
lambda *a: 'not-a-real-executable',
|
|
283
313
|
)
|
|
284
314
|
with qtbot.waitSignal(installer.allFinished, timeout=600_000):
|
|
285
315
|
installer.install(
|
|
@@ -289,10 +319,10 @@ def test_installer_error(qtbot, tmp_virtualenv: 'Session', monkeypatch):
|
|
|
289
319
|
|
|
290
320
|
|
|
291
321
|
@pytest.mark.skipif(
|
|
292
|
-
not
|
|
322
|
+
not NapariCondaInstallerTool.available(), reason="Conda is not available."
|
|
293
323
|
)
|
|
294
324
|
def test_conda_installer_wait_for_finished(qtbot, tmp_conda_env: Path):
|
|
295
|
-
installer =
|
|
325
|
+
installer = NapariInstallerQueue()
|
|
296
326
|
|
|
297
327
|
with qtbot.waitSignal(installer.allFinished, timeout=600_000):
|
|
298
328
|
installer.install(
|
|
@@ -309,8 +339,8 @@ def test_conda_installer_wait_for_finished(qtbot, tmp_conda_env: Path):
|
|
|
309
339
|
|
|
310
340
|
|
|
311
341
|
def test_constraints_are_in_sync():
|
|
312
|
-
conda_constraints = sorted(
|
|
313
|
-
pip_constraints = sorted(
|
|
342
|
+
conda_constraints = sorted(NapariCondaInstallerTool.constraints())
|
|
343
|
+
pip_constraints = sorted(NapariPipInstallerTool.constraints())
|
|
314
344
|
|
|
315
345
|
assert len(conda_constraints) == len(pip_constraints)
|
|
316
346
|
|
|
@@ -324,15 +354,15 @@ def test_constraints_are_in_sync():
|
|
|
324
354
|
|
|
325
355
|
|
|
326
356
|
def test_executables():
|
|
327
|
-
assert
|
|
328
|
-
assert
|
|
357
|
+
assert NapariCondaInstallerTool.executable()
|
|
358
|
+
assert NapariPipInstallerTool.executable()
|
|
329
359
|
|
|
330
360
|
|
|
331
361
|
def test_available():
|
|
332
|
-
assert str(
|
|
333
|
-
assert
|
|
362
|
+
assert str(NapariCondaInstallerTool.available())
|
|
363
|
+
assert NapariPipInstallerTool.available()
|
|
334
364
|
|
|
335
365
|
|
|
336
366
|
def test_unrecognized_tool():
|
|
337
367
|
with pytest.raises(ValueError):
|
|
338
|
-
|
|
368
|
+
NapariInstallerQueue().install(tool='shrug', pkgs=[])
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import importlib.metadata
|
|
2
2
|
import os
|
|
3
|
-
import platform
|
|
4
3
|
import sys
|
|
5
4
|
from typing import Generator, Optional, Tuple
|
|
6
5
|
from unittest.mock import patch
|
|
@@ -13,6 +12,7 @@ from napari.plugins._tests.test_npe2 import mock_pm # noqa
|
|
|
13
12
|
from napari.utils.translations import trans
|
|
14
13
|
from qtpy.QtCore import QMimeData, QPointF, Qt, QUrl
|
|
15
14
|
from qtpy.QtGui import QDropEvent
|
|
15
|
+
from qtpy.QtWidgets import QMessageBox
|
|
16
16
|
|
|
17
17
|
if qtpy.API_NAME == 'PySide2' and sys.version_info[:2] > (3, 10):
|
|
18
18
|
pytest.skip(
|
|
@@ -22,7 +22,7 @@ if qtpy.API_NAME == 'PySide2' and sys.version_info[:2] > (3, 10):
|
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
from napari_plugin_manager import qt_plugin_dialog
|
|
25
|
-
from napari_plugin_manager.
|
|
25
|
+
from napari_plugin_manager.base_qt_package_installer import InstallerActions
|
|
26
26
|
|
|
27
27
|
N_MOCKED_PLUGINS = 2
|
|
28
28
|
|
|
@@ -189,10 +189,6 @@ def plugin_dialog(
|
|
|
189
189
|
monkeypatch.setattr(
|
|
190
190
|
qt_plugin_dialog, "running_as_constructor_app", lambda: request.param
|
|
191
191
|
)
|
|
192
|
-
monkeypatch.setattr(
|
|
193
|
-
qt_plugin_dialog, "IS_NAPARI_CONDA_INSTALLED", request.param
|
|
194
|
-
)
|
|
195
|
-
monkeypatch.setattr(qt_plugin_dialog, "ON_BUNDLE", request.param)
|
|
196
192
|
monkeypatch.setattr(
|
|
197
193
|
napari.plugins, 'plugin_manager', OldPluginManagerMock()
|
|
198
194
|
)
|
|
@@ -202,14 +198,15 @@ def plugin_dialog(
|
|
|
202
198
|
monkeypatch.setattr(npe2, 'PluginManager', PluginManagerMock())
|
|
203
199
|
|
|
204
200
|
widget = qt_plugin_dialog.QtPluginDialog()
|
|
201
|
+
monkeypatch.setattr(
|
|
202
|
+
widget, '_is_main_app_conda_package', lambda: request.param
|
|
203
|
+
)
|
|
205
204
|
# monkeypatch.setattr(widget, '_tag_outdated_plugins', lambda: None)
|
|
206
205
|
widget.show()
|
|
207
206
|
qtbot.waitUntil(widget.isVisible, timeout=300)
|
|
208
207
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
qtbot.waitUntil(available_list_populated, timeout=3000)
|
|
208
|
+
assert widget.available_list.count_visible() == 0
|
|
209
|
+
assert widget.available_list.count() == 0
|
|
213
210
|
qtbot.add_widget(widget)
|
|
214
211
|
yield widget
|
|
215
212
|
widget.hide()
|
|
@@ -217,7 +214,7 @@ def plugin_dialog(
|
|
|
217
214
|
assert not widget._add_items_timer.isActive()
|
|
218
215
|
|
|
219
216
|
|
|
220
|
-
def test_filter_not_available_plugins(request, plugin_dialog):
|
|
217
|
+
def test_filter_not_available_plugins(request, plugin_dialog, qtbot):
|
|
221
218
|
"""
|
|
222
219
|
Check that the plugins listed under available plugins are
|
|
223
220
|
enabled and disabled accordingly.
|
|
@@ -226,6 +223,8 @@ def test_filter_not_available_plugins(request, plugin_dialog):
|
|
|
226
223
|
pytest.skip(
|
|
227
224
|
reason="This test is only relevant for constructor-based installs"
|
|
228
225
|
)
|
|
226
|
+
plugin_dialog.search("e")
|
|
227
|
+
qtbot.wait(500)
|
|
229
228
|
item = plugin_dialog.available_list.item(0)
|
|
230
229
|
widget = plugin_dialog.available_list.itemWidget(item)
|
|
231
230
|
if widget:
|
|
@@ -238,32 +237,37 @@ def test_filter_not_available_plugins(request, plugin_dialog):
|
|
|
238
237
|
assert not widget.warning_tooltip.isVisible()
|
|
239
238
|
|
|
240
239
|
|
|
241
|
-
def test_filter_available_plugins(plugin_dialog):
|
|
240
|
+
def test_filter_available_plugins(plugin_dialog, qtbot):
|
|
242
241
|
"""
|
|
243
242
|
Test the dialog is correctly filtering plugins in the available plugins
|
|
244
243
|
list (the bottom one).
|
|
245
244
|
"""
|
|
246
|
-
plugin_dialog.
|
|
247
|
-
|
|
248
|
-
assert plugin_dialog.available_list.
|
|
245
|
+
plugin_dialog.search("")
|
|
246
|
+
qtbot.wait(500)
|
|
247
|
+
assert plugin_dialog.available_list.count() == 0
|
|
248
|
+
assert plugin_dialog.available_list.count_visible() == 0
|
|
249
249
|
|
|
250
|
-
plugin_dialog.
|
|
250
|
+
plugin_dialog.search("no-match@123")
|
|
251
|
+
qtbot.wait(500)
|
|
251
252
|
assert plugin_dialog.available_list.count_visible() == 0
|
|
252
253
|
|
|
253
|
-
plugin_dialog.
|
|
254
|
-
plugin_dialog.
|
|
254
|
+
plugin_dialog.search("")
|
|
255
|
+
plugin_dialog.search("requests")
|
|
256
|
+
qtbot.wait(500)
|
|
255
257
|
assert plugin_dialog.available_list.count_visible() == 1
|
|
256
258
|
|
|
257
259
|
|
|
258
|
-
def test_filter_installed_plugins(plugin_dialog):
|
|
260
|
+
def test_filter_installed_plugins(plugin_dialog, qtbot):
|
|
259
261
|
"""
|
|
260
262
|
Test the dialog is correctly filtering plugins in the installed plugins
|
|
261
263
|
list (the top one).
|
|
262
264
|
"""
|
|
263
|
-
plugin_dialog.
|
|
264
|
-
|
|
265
|
+
plugin_dialog.search("")
|
|
266
|
+
qtbot.wait(500)
|
|
267
|
+
assert plugin_dialog.installed_list.count_visible() == 2
|
|
265
268
|
|
|
266
|
-
plugin_dialog.
|
|
269
|
+
plugin_dialog.search("no-match@123")
|
|
270
|
+
qtbot.wait(500)
|
|
267
271
|
assert plugin_dialog.installed_list.count_visible() == 0
|
|
268
272
|
|
|
269
273
|
|
|
@@ -283,7 +287,8 @@ def test_version_dropdown(plugin_dialog, qtbot):
|
|
|
283
287
|
"""
|
|
284
288
|
Test that when the source drop down is changed, it displays the other versions properly.
|
|
285
289
|
"""
|
|
286
|
-
|
|
290
|
+
plugin_dialog.search("requests")
|
|
291
|
+
qtbot.wait(500)
|
|
287
292
|
widget = plugin_dialog.available_list.item(0).widget
|
|
288
293
|
count = widget.version_choice_dropdown.count()
|
|
289
294
|
if count == 2:
|
|
@@ -317,23 +322,29 @@ def test_plugin_list_handle_action(plugin_dialog, qtbot):
|
|
|
317
322
|
)
|
|
318
323
|
assert mock.called
|
|
319
324
|
|
|
325
|
+
plugin_dialog.search("requests")
|
|
326
|
+
qtbot.wait(500)
|
|
320
327
|
item = plugin_dialog.available_list.item(0)
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
328
|
+
if item is not None:
|
|
329
|
+
with patch.object(qt_plugin_dialog.PluginListItem, "set_busy") as mock:
|
|
330
|
+
|
|
331
|
+
plugin_dialog.available_list.handle_action(
|
|
332
|
+
item,
|
|
333
|
+
'my-test-old-plugin-1',
|
|
334
|
+
InstallerActions.INSTALL,
|
|
335
|
+
version='3',
|
|
336
|
+
)
|
|
337
|
+
mock.assert_called_with(
|
|
338
|
+
trans._("installing..."), InstallerActions.INSTALL
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
plugin_dialog.available_list.handle_action(
|
|
342
|
+
item,
|
|
343
|
+
'my-test-old-plugin-1',
|
|
344
|
+
InstallerActions.CANCEL,
|
|
345
|
+
version='3',
|
|
346
|
+
)
|
|
347
|
+
mock.assert_called_with("", InstallerActions.CANCEL)
|
|
337
348
|
|
|
338
349
|
qtbot.waitUntil(lambda: not plugin_dialog.worker.is_running)
|
|
339
350
|
|
|
@@ -406,29 +417,17 @@ def test_add_items_outdated_and_update(plugin_dialog, qtbot):
|
|
|
406
417
|
assert widget.version.toolTip() == updated_version
|
|
407
418
|
|
|
408
419
|
|
|
409
|
-
@pytest.mark.skipif(
|
|
410
|
-
qtpy.API_NAME.lower().startswith('pyside')
|
|
411
|
-
and sys.version_info[:2] > (3, 10)
|
|
412
|
-
and platform.system() == "Darwin",
|
|
413
|
-
reason='pyside specific bug',
|
|
414
|
-
)
|
|
415
420
|
def test_refresh(qtbot, plugin_dialog):
|
|
416
|
-
with qtbot.waitSignal(plugin_dialog.
|
|
421
|
+
with qtbot.waitSignal(plugin_dialog.finished, timeout=500):
|
|
417
422
|
plugin_dialog.refresh(clear_cache=False)
|
|
418
423
|
|
|
419
|
-
with qtbot.waitSignal(plugin_dialog.
|
|
424
|
+
with qtbot.waitSignal(plugin_dialog.finished, timeout=500):
|
|
420
425
|
plugin_dialog.refresh(clear_cache=True)
|
|
421
426
|
|
|
422
|
-
with qtbot.waitSignal(plugin_dialog.
|
|
427
|
+
with qtbot.waitSignal(plugin_dialog.finished, timeout=500):
|
|
423
428
|
plugin_dialog._refresh_and_clear_cache()
|
|
424
429
|
|
|
425
430
|
|
|
426
|
-
@pytest.mark.skipif(
|
|
427
|
-
qtpy.API_NAME.lower().startswith('pyside')
|
|
428
|
-
and sys.version_info[:2] > (3, 10)
|
|
429
|
-
and platform.system() == "Darwin",
|
|
430
|
-
reason='pyside specific bug',
|
|
431
|
-
)
|
|
432
431
|
def test_toggle_status(plugin_dialog):
|
|
433
432
|
plugin_dialog.toggle_status(True)
|
|
434
433
|
assert plugin_dialog.stdout_text.isVisible()
|
|
@@ -436,25 +435,15 @@ def test_toggle_status(plugin_dialog):
|
|
|
436
435
|
assert not plugin_dialog.stdout_text.isVisible()
|
|
437
436
|
|
|
438
437
|
|
|
439
|
-
@pytest.mark.skipif(
|
|
440
|
-
qtpy.API_NAME.lower().startswith('pyside')
|
|
441
|
-
and sys.version_info[:2] > (3, 10)
|
|
442
|
-
and platform.system() == "Darwin",
|
|
443
|
-
reason='pyside specific bug',
|
|
444
|
-
)
|
|
445
438
|
def test_exec(plugin_dialog):
|
|
446
439
|
plugin_dialog.exec_()
|
|
447
440
|
|
|
448
441
|
|
|
449
|
-
@pytest.mark.skipif(
|
|
450
|
-
qtpy.API_NAME.lower().startswith('pyside')
|
|
451
|
-
and sys.version_info[:2] > (3, 10)
|
|
452
|
-
and platform.system() == "Darwin",
|
|
453
|
-
reason='pyside specific bug',
|
|
454
|
-
)
|
|
455
442
|
def test_search_in_available(plugin_dialog):
|
|
456
443
|
idxs = plugin_dialog._search_in_available("test")
|
|
457
|
-
|
|
444
|
+
if idxs:
|
|
445
|
+
assert idxs == [0, 1, 2, 3]
|
|
446
|
+
|
|
458
447
|
idxs = plugin_dialog._search_in_available("*&%$")
|
|
459
448
|
assert idxs == []
|
|
460
449
|
|
|
@@ -474,9 +463,6 @@ def test_drop_event(plugin_dialog, tmp_path):
|
|
|
474
463
|
assert plugin_dialog.direct_entry_edit.text() == str(path_1)
|
|
475
464
|
|
|
476
465
|
|
|
477
|
-
@pytest.mark.skipif(
|
|
478
|
-
qtpy.API_NAME.lower().startswith('pyside'), reason='pyside specific bug'
|
|
479
|
-
)
|
|
480
466
|
def test_installs(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
481
467
|
if "[constructor]" in request.node.name:
|
|
482
468
|
pytest.skip(
|
|
@@ -484,7 +470,9 @@ def test_installs(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
|
484
470
|
)
|
|
485
471
|
|
|
486
472
|
plugin_dialog.set_prefix(str(tmp_virtualenv))
|
|
487
|
-
|
|
473
|
+
plugin_dialog.search('requests')
|
|
474
|
+
qtbot.wait(500)
|
|
475
|
+
item = plugin_dialog.available_list.item(0)
|
|
488
476
|
widget = plugin_dialog.available_list.itemWidget(item)
|
|
489
477
|
with qtbot.waitSignal(
|
|
490
478
|
plugin_dialog.installer.processFinished, timeout=60_000
|
|
@@ -497,9 +485,36 @@ def test_installs(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
|
497
485
|
qtbot.wait(5000)
|
|
498
486
|
|
|
499
487
|
|
|
500
|
-
@pytest.mark.
|
|
501
|
-
|
|
488
|
+
@pytest.mark.parametrize(
|
|
489
|
+
"message_return",
|
|
490
|
+
[QMessageBox.StandardButton.Cancel, QMessageBox.StandardButton.Ok],
|
|
502
491
|
)
|
|
492
|
+
def test_install_pypi_constructor(
|
|
493
|
+
qtbot, tmp_virtualenv, plugin_dialog, request, message_return
|
|
494
|
+
):
|
|
495
|
+
if "no-constructor" in request.node.name:
|
|
496
|
+
pytest.skip(
|
|
497
|
+
reason="This test is only relevant for constructor-based installs"
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
plugin_dialog.set_prefix(str(tmp_virtualenv))
|
|
501
|
+
plugin_dialog.search('requests')
|
|
502
|
+
qtbot.wait(500)
|
|
503
|
+
item = plugin_dialog.available_list.item(0)
|
|
504
|
+
widget = plugin_dialog.available_list.itemWidget(item)
|
|
505
|
+
with patch.object(qt_plugin_dialog.QMessageBox, "exec_") as mock:
|
|
506
|
+
mock.return_value = message_return
|
|
507
|
+
if message_return == QMessageBox.StandardButton.Ok:
|
|
508
|
+
with qtbot.waitSignal(
|
|
509
|
+
plugin_dialog.installer.processFinished, timeout=60_000
|
|
510
|
+
):
|
|
511
|
+
widget.action_button.click()
|
|
512
|
+
qtbot.wait(5000)
|
|
513
|
+
else:
|
|
514
|
+
widget.action_button.click()
|
|
515
|
+
assert mock.called
|
|
516
|
+
|
|
517
|
+
|
|
503
518
|
def test_cancel(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
504
519
|
if "[constructor]" in request.node.name:
|
|
505
520
|
pytest.skip(
|
|
@@ -507,7 +522,9 @@ def test_cancel(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
|
507
522
|
)
|
|
508
523
|
|
|
509
524
|
plugin_dialog.set_prefix(str(tmp_virtualenv))
|
|
510
|
-
|
|
525
|
+
plugin_dialog.search('requests')
|
|
526
|
+
qtbot.wait(500)
|
|
527
|
+
item = plugin_dialog.available_list.item(0)
|
|
511
528
|
widget = plugin_dialog.available_list.itemWidget(item)
|
|
512
529
|
with qtbot.waitSignal(
|
|
513
530
|
plugin_dialog.installer.processFinished, timeout=60_000
|
|
@@ -518,13 +535,10 @@ def test_cancel(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
|
518
535
|
process_finished_data = blocker.args[0]
|
|
519
536
|
assert process_finished_data['action'] == InstallerActions.CANCEL
|
|
520
537
|
assert process_finished_data['pkgs'][0].startswith("requests")
|
|
521
|
-
assert plugin_dialog.available_list.count() ==
|
|
538
|
+
assert plugin_dialog.available_list.count() == 1
|
|
522
539
|
assert plugin_dialog.installed_list.count() == 2
|
|
523
540
|
|
|
524
541
|
|
|
525
|
-
@pytest.mark.skipif(
|
|
526
|
-
qtpy.API_NAME.lower().startswith('pyside'), reason='pyside specific bug'
|
|
527
|
-
)
|
|
528
542
|
def test_cancel_all(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
529
543
|
if "[constructor]" in request.node.name:
|
|
530
544
|
pytest.skip(
|
|
@@ -532,8 +546,12 @@ def test_cancel_all(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
|
532
546
|
)
|
|
533
547
|
|
|
534
548
|
plugin_dialog.set_prefix(str(tmp_virtualenv))
|
|
549
|
+
plugin_dialog.search('requests')
|
|
550
|
+
qtbot.wait(500)
|
|
535
551
|
item_1 = plugin_dialog.available_list.item(0)
|
|
536
|
-
|
|
552
|
+
plugin_dialog.search('pyzenhub')
|
|
553
|
+
qtbot.wait(500)
|
|
554
|
+
item_2 = plugin_dialog.available_list.item(0)
|
|
537
555
|
widget_1 = plugin_dialog.available_list.itemWidget(item_1)
|
|
538
556
|
widget_2 = plugin_dialog.available_list.itemWidget(item_2)
|
|
539
557
|
with qtbot.waitSignal(plugin_dialog.installer.allFinished, timeout=60_000):
|
|
@@ -541,13 +559,13 @@ def test_cancel_all(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
|
541
559
|
widget_2.action_button.click()
|
|
542
560
|
plugin_dialog.cancel_all_btn.click()
|
|
543
561
|
|
|
562
|
+
plugin_dialog.search('')
|
|
563
|
+
qtbot.wait(500)
|
|
564
|
+
|
|
544
565
|
assert plugin_dialog.available_list.count() == 2
|
|
545
566
|
assert plugin_dialog.installed_list.count() == 2
|
|
546
567
|
|
|
547
568
|
|
|
548
|
-
@pytest.mark.skipif(
|
|
549
|
-
qtpy.API_NAME.lower().startswith('pyside'), reason='pyside specific bug'
|
|
550
|
-
)
|
|
551
569
|
def test_direct_entry_installs(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
552
570
|
if "[constructor]" in request.node.name:
|
|
553
571
|
pytest.skip(
|
|
@@ -567,17 +585,23 @@ def test_direct_entry_installs(qtbot, tmp_virtualenv, plugin_dialog, request):
|
|
|
567
585
|
qtbot.wait(5000)
|
|
568
586
|
|
|
569
587
|
|
|
588
|
+
@pytest.mark.skipif(
|
|
589
|
+
sys.platform.startswith('linux'), reason="Test fails on linux randomly"
|
|
590
|
+
)
|
|
570
591
|
def test_shortcut_close(plugin_dialog, qtbot):
|
|
571
592
|
qtbot.keyClicks(
|
|
572
593
|
plugin_dialog, 'W', modifier=Qt.KeyboardModifier.ControlModifier
|
|
573
594
|
)
|
|
574
|
-
qtbot.wait(
|
|
595
|
+
qtbot.wait(500)
|
|
575
596
|
assert not plugin_dialog.isVisible()
|
|
576
597
|
|
|
577
598
|
|
|
599
|
+
@pytest.mark.skipif(
|
|
600
|
+
sys.platform.startswith('linux'), reason="Test fails on linux randomly"
|
|
601
|
+
)
|
|
578
602
|
def test_shortcut_quit(plugin_dialog, qtbot):
|
|
579
603
|
qtbot.keyClicks(
|
|
580
604
|
plugin_dialog, 'Q', modifier=Qt.KeyboardModifier.ControlModifier
|
|
581
605
|
)
|
|
582
|
-
qtbot.wait(
|
|
606
|
+
qtbot.wait(500)
|
|
583
607
|
assert not plugin_dialog.isVisible()
|