synodic-client 0.0.1.dev40__tar.gz → 0.0.1.dev41__tar.gz
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.
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/PKG-INFO +1 -1
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/pyproject.toml +1 -1
- synodic_client-0.0.1.dev41/synodic_client/_version.py +1 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/screen.py +59 -61
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_gather_packages.py +24 -44
- synodic_client-0.0.1.dev40/synodic_client/_version.py +0 -1
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/LICENSE.md +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/README.md +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/__init__.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/__main__.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/__init__.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/bootstrap.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/data.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/icon.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/instance.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/qt.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/__init__.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/action_card.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/card.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/install.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/log_panel.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/settings.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/sidebar.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/spinner.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/tray.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/update_banner.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/theme.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/uri.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/workers.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/cli.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/client.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/config.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/logging.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/protocol.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/py.typed +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/resolution.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/startup.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/updater.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/__init__.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/conftest.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/__init__.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/__init__.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/conftest.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_action_card.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_install_preview.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_log_panel.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_logging.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_preview_model.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_settings.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_sidebar.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_tray_window_show.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_update_banner.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_update_feedback.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_cli.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_client_updater.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_client_version.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_config.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_examples.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_install.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_resolution.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_updater.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_uri.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/test_workers.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/windows/__init__.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/windows/conftest.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/windows/test_protocol.py +0 -0
- {synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/windows/test_startup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.0.1.dev41'
|
|
@@ -8,6 +8,7 @@ from pathlib import Path
|
|
|
8
8
|
|
|
9
9
|
from porringer.api import API
|
|
10
10
|
from porringer.backend.builder import Builder
|
|
11
|
+
from porringer.backend.command.core.discovery import DiscoveredPlugins
|
|
11
12
|
from porringer.core.plugin_schema.plugin_manager import PluginManager
|
|
12
13
|
from porringer.core.plugin_schema.project_environment import ProjectEnvironment
|
|
13
14
|
from porringer.schema import (
|
|
@@ -1158,26 +1159,29 @@ class ToolsView(QWidget):
|
|
|
1158
1159
|
return None
|
|
1159
1160
|
return {name for name, chip in self._filter_chips.items() if chip.isChecked()}
|
|
1160
1161
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1162
|
+
@staticmethod
|
|
1163
|
+
def _is_plugin_active(plugin_name: str, active: set[str] | None) -> bool:
|
|
1164
|
+
"""Return whether *plugin_name* passes the chip filter."""
|
|
1165
|
+
return active is None or plugin_name in active
|
|
1163
1166
|
|
|
1164
|
-
|
|
1165
|
-
|
|
1167
|
+
@staticmethod
|
|
1168
|
+
def _finalise_provider(
|
|
1169
|
+
provider: PluginProviderHeader | None,
|
|
1170
|
+
has_visible: bool,
|
|
1171
|
+
) -> bool:
|
|
1172
|
+
"""Set provider visibility and return whether it had visible children."""
|
|
1173
|
+
if provider is not None:
|
|
1174
|
+
provider.setVisible(has_visible)
|
|
1175
|
+
return has_visible
|
|
1166
1176
|
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
search text.
|
|
1170
|
-
* **PluginRow** — visible when its plugin is active **and** its
|
|
1171
|
-
package name or plugin name contains the search text.
|
|
1172
|
-
* **ProjectChildRow** — follows its parent :class:`PluginRow`.
|
|
1173
|
-
* **PluginKindHeader** — visible when at least one child
|
|
1174
|
-
provider in its kind group is visible.
|
|
1177
|
+
def _apply_filter(self, _text: str | None = None) -> None:
|
|
1178
|
+
"""Show/hide section widgets based on search text and active chips.
|
|
1175
1179
|
|
|
1176
|
-
|
|
1180
|
+
Delegates to :meth:`_is_plugin_active` for chip matching and
|
|
1181
|
+
:meth:`_finalise_provider` for provider visibility bookkeeping.
|
|
1177
1182
|
"""
|
|
1178
1183
|
query = self._search_input.text().strip().lower()
|
|
1179
1184
|
active = self._active_chip_plugins()
|
|
1180
|
-
all_active = active is None # None → no chips yet, show all
|
|
1181
1185
|
|
|
1182
1186
|
current_kind_header: PluginKindHeader | None = None
|
|
1183
1187
|
kind_has_visible = False
|
|
@@ -1187,13 +1191,8 @@ class ToolsView(QWidget):
|
|
|
1187
1191
|
|
|
1188
1192
|
for widget in self._section_widgets:
|
|
1189
1193
|
if isinstance(widget, PluginKindHeader):
|
|
1190
|
-
|
|
1194
|
+
kind_has_visible |= self._finalise_provider(current_provider, provider_has_visible_child)
|
|
1191
1195
|
if current_kind_header is not None:
|
|
1192
|
-
# Finalise last provider of previous kind
|
|
1193
|
-
if current_provider is not None:
|
|
1194
|
-
current_provider.setVisible(provider_has_visible_child)
|
|
1195
|
-
if provider_has_visible_child:
|
|
1196
|
-
kind_has_visible = True
|
|
1197
1196
|
current_kind_header.setVisible(kind_has_visible)
|
|
1198
1197
|
|
|
1199
1198
|
current_kind_header = widget
|
|
@@ -1202,31 +1201,20 @@ class ToolsView(QWidget):
|
|
|
1202
1201
|
provider_has_visible_child = False
|
|
1203
1202
|
|
|
1204
1203
|
elif isinstance(widget, PluginProviderHeader):
|
|
1205
|
-
|
|
1206
|
-
if current_provider is not None:
|
|
1207
|
-
current_provider.setVisible(provider_has_visible_child)
|
|
1208
|
-
if provider_has_visible_child:
|
|
1209
|
-
kind_has_visible = True
|
|
1204
|
+
kind_has_visible |= self._finalise_provider(current_provider, provider_has_visible_child)
|
|
1210
1205
|
|
|
1211
1206
|
current_provider = widget
|
|
1212
1207
|
provider_has_visible_child = False
|
|
1213
|
-
|
|
1214
|
-
plugin_active = all_active or (active is not None and plugin_name in active)
|
|
1215
|
-
|
|
1216
|
-
if not plugin_active:
|
|
1217
|
-
# Entire provider hidden
|
|
1208
|
+
if not self._is_plugin_active(widget._plugin_name, active):
|
|
1218
1209
|
widget.setVisible(False)
|
|
1219
|
-
provider_has_visible_child = False
|
|
1220
1210
|
|
|
1221
1211
|
elif isinstance(widget, PluginRow):
|
|
1222
|
-
|
|
1223
|
-
plugin_active = all_active or (active is not None and plugin_name in active)
|
|
1224
|
-
if not plugin_active:
|
|
1212
|
+
if not self._is_plugin_active(widget._plugin_name, active):
|
|
1225
1213
|
widget.setVisible(False)
|
|
1226
1214
|
parent_row_visible = False
|
|
1227
1215
|
continue
|
|
1228
1216
|
|
|
1229
|
-
name_match = not query or query in widget._package_name.lower() or query in
|
|
1217
|
+
name_match = not query or query in widget._package_name.lower() or query in widget._plugin_name.lower()
|
|
1230
1218
|
widget.setVisible(name_match)
|
|
1231
1219
|
parent_row_visible = name_match
|
|
1232
1220
|
if name_match:
|
|
@@ -1236,10 +1224,7 @@ class ToolsView(QWidget):
|
|
|
1236
1224
|
widget.setVisible(parent_row_visible)
|
|
1237
1225
|
|
|
1238
1226
|
# Finalise last provider and kind
|
|
1239
|
-
|
|
1240
|
-
current_provider.setVisible(provider_has_visible_child)
|
|
1241
|
-
if provider_has_visible_child:
|
|
1242
|
-
kind_has_visible = True
|
|
1227
|
+
kind_has_visible |= self._finalise_provider(current_provider, provider_has_visible_child)
|
|
1243
1228
|
if current_kind_header is not None:
|
|
1244
1229
|
current_kind_header.setVisible(kind_has_visible)
|
|
1245
1230
|
|
|
@@ -1834,6 +1819,7 @@ class ProjectsView(QWidget):
|
|
|
1834
1819
|
if self._coordinator is not None:
|
|
1835
1820
|
snapshot = await self._coordinator.refresh()
|
|
1836
1821
|
results = snapshot.validated_directories
|
|
1822
|
+
discovered = snapshot.discovered
|
|
1837
1823
|
else:
|
|
1838
1824
|
loop = asyncio.get_running_loop()
|
|
1839
1825
|
results = await loop.run_in_executor(
|
|
@@ -1843,6 +1829,7 @@ class ProjectsView(QWidget):
|
|
|
1843
1829
|
check_manifest=True,
|
|
1844
1830
|
),
|
|
1845
1831
|
)
|
|
1832
|
+
discovered = None
|
|
1846
1833
|
|
|
1847
1834
|
directories: list[tuple[Path, str, bool]] = []
|
|
1848
1835
|
current_paths: set[Path] = set()
|
|
@@ -1854,32 +1841,12 @@ class ProjectsView(QWidget):
|
|
|
1854
1841
|
current_paths.add(path)
|
|
1855
1842
|
|
|
1856
1843
|
# Remove widgets for directories no longer in cache
|
|
1857
|
-
|
|
1858
|
-
if path not in current_paths:
|
|
1859
|
-
widget = self._widgets.pop(path)
|
|
1860
|
-
self._stack.removeWidget(widget)
|
|
1861
|
-
widget.reset()
|
|
1862
|
-
widget.deleteLater()
|
|
1844
|
+
self._remove_stale_widgets(current_paths)
|
|
1863
1845
|
|
|
1864
1846
|
# Grab pre-discovered plugins so each widget can skip redundant discovery
|
|
1865
|
-
discovered = snapshot.discovered if self._coordinator is not None else None
|
|
1866
1847
|
|
|
1867
1848
|
# Create new widgets for new directories
|
|
1868
|
-
|
|
1869
|
-
if path not in self._widgets and valid:
|
|
1870
|
-
widget = SetupPreviewWidget(
|
|
1871
|
-
self._porringer,
|
|
1872
|
-
self,
|
|
1873
|
-
show_close=False,
|
|
1874
|
-
config=self._config,
|
|
1875
|
-
)
|
|
1876
|
-
widget._discovered_plugins = discovered
|
|
1877
|
-
widget.install_finished.connect(self._on_install_finished)
|
|
1878
|
-
widget.phase_changed.connect(
|
|
1879
|
-
lambda phase, p=path: self._on_widget_phase_changed(p, phase),
|
|
1880
|
-
)
|
|
1881
|
-
self._widgets[path] = widget
|
|
1882
|
-
self._stack.addWidget(widget)
|
|
1849
|
+
self._create_directory_widgets(directories, discovered)
|
|
1883
1850
|
|
|
1884
1851
|
# Rebuild sidebar
|
|
1885
1852
|
self._sidebar.set_directories(directories)
|
|
@@ -1909,6 +1876,37 @@ class ProjectsView(QWidget):
|
|
|
1909
1876
|
|
|
1910
1877
|
# --- Event handlers ---
|
|
1911
1878
|
|
|
1879
|
+
def _remove_stale_widgets(self, current_paths: set[Path]) -> None:
|
|
1880
|
+
"""Remove stacked widgets for directories no longer in the cache."""
|
|
1881
|
+
for path in list(self._widgets):
|
|
1882
|
+
if path not in current_paths:
|
|
1883
|
+
widget = self._widgets.pop(path)
|
|
1884
|
+
self._stack.removeWidget(widget)
|
|
1885
|
+
widget.reset()
|
|
1886
|
+
widget.deleteLater()
|
|
1887
|
+
|
|
1888
|
+
def _create_directory_widgets(
|
|
1889
|
+
self,
|
|
1890
|
+
directories: list[tuple[Path, str, bool]],
|
|
1891
|
+
discovered: DiscoveredPlugins | None,
|
|
1892
|
+
) -> None:
|
|
1893
|
+
"""Create :class:`SetupPreviewWidget` instances for new valid directories."""
|
|
1894
|
+
for path, _name, valid in directories:
|
|
1895
|
+
if path not in self._widgets and valid:
|
|
1896
|
+
widget = SetupPreviewWidget(
|
|
1897
|
+
self._porringer,
|
|
1898
|
+
self,
|
|
1899
|
+
show_close=False,
|
|
1900
|
+
config=self._config,
|
|
1901
|
+
)
|
|
1902
|
+
widget._discovered_plugins = discovered
|
|
1903
|
+
widget.install_finished.connect(self._on_install_finished)
|
|
1904
|
+
widget.phase_changed.connect(
|
|
1905
|
+
lambda phase, p=path: self._on_widget_phase_changed(p, phase),
|
|
1906
|
+
)
|
|
1907
|
+
self._widgets[path] = widget
|
|
1908
|
+
self._stack.addWidget(widget)
|
|
1909
|
+
|
|
1912
1910
|
def _on_selection_changed(self, path: Path) -> None:
|
|
1913
1911
|
"""Handle sidebar selection — switch the stacked widget."""
|
|
1914
1912
|
widget = self._widgets.get(path)
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_gather_packages.py
RENAMED
|
@@ -6,12 +6,30 @@ import asyncio
|
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from unittest.mock import AsyncMock, MagicMock
|
|
8
8
|
|
|
9
|
+
from packaging.version import Version
|
|
9
10
|
from porringer.core.schema import Package, PackageRelation, PackageRelationKind
|
|
10
11
|
from porringer.schema import ManifestDirectory
|
|
11
|
-
|
|
12
|
-
from
|
|
12
|
+
from porringer.schema.plugin import PluginInfo, PluginKind
|
|
13
|
+
from PySide6.QtWidgets import QLabel, QPushButton
|
|
14
|
+
|
|
15
|
+
from synodic_client.application.screen.screen import (
|
|
16
|
+
FilterChip,
|
|
17
|
+
PackageEntry,
|
|
18
|
+
PluginKindHeader,
|
|
19
|
+
PluginProviderHeader,
|
|
20
|
+
PluginRow,
|
|
21
|
+
PluginRowData,
|
|
22
|
+
ProjectChildRow,
|
|
23
|
+
ProjectInstance,
|
|
24
|
+
ToolsView,
|
|
25
|
+
)
|
|
13
26
|
from synodic_client.resolution import ResolvedConfig
|
|
14
27
|
|
|
28
|
+
# Named constants for expected counts (avoids PLR2004)
|
|
29
|
+
_EXPECTED_PROJECT_INSTANCES = 2
|
|
30
|
+
_EXPECTED_VISIBLE_ROWS_ALL = 3
|
|
31
|
+
_EXPECTED_VISIBLE_ROWS_PIPX = 2
|
|
32
|
+
|
|
15
33
|
|
|
16
34
|
def _make_config() -> ResolvedConfig:
|
|
17
35
|
"""Build a minimal ResolvedConfig for tests."""
|
|
@@ -429,7 +447,7 @@ class TestBuildDisplayPackages:
|
|
|
429
447
|
|
|
430
448
|
assert len(result) == 1
|
|
431
449
|
pkg = result[0]
|
|
432
|
-
assert len(pkg.project_instances) ==
|
|
450
|
+
assert len(pkg.project_instances) == _EXPECTED_PROJECT_INSTANCES
|
|
433
451
|
labels = {pi.project_label for pi in pkg.project_instances}
|
|
434
452
|
assert labels == {'project-a', 'project-b'}
|
|
435
453
|
|
|
@@ -479,8 +497,6 @@ class TestProjectChildRow:
|
|
|
479
497
|
|
|
480
498
|
@staticmethod
|
|
481
499
|
def _make_instance(*, transitive: bool = False) -> ProjectChildRow:
|
|
482
|
-
from synodic_client.application.screen.screen import ProjectInstance
|
|
483
|
-
|
|
484
500
|
return ProjectChildRow(
|
|
485
501
|
ProjectInstance(
|
|
486
502
|
project_label='periapsis',
|
|
@@ -498,8 +514,6 @@ class TestProjectChildRow:
|
|
|
498
514
|
row.navigate_to_project.connect(spy)
|
|
499
515
|
|
|
500
516
|
# Find the navigate button (→)
|
|
501
|
-
from PySide6.QtWidgets import QPushButton
|
|
502
|
-
|
|
503
517
|
nav_btns = [w for w in row.findChildren(QPushButton) if w.text() == '\u2192']
|
|
504
518
|
assert len(nav_btns) == 1
|
|
505
519
|
nav_btns[0].click()
|
|
@@ -518,8 +532,6 @@ class TestProjectChildRow:
|
|
|
518
532
|
assert len(labels) == 0
|
|
519
533
|
|
|
520
534
|
|
|
521
|
-
from PySide6.QtWidgets import QLabel
|
|
522
|
-
|
|
523
535
|
# ---------------------------------------------------------------------------
|
|
524
536
|
# FilterChip
|
|
525
537
|
# ---------------------------------------------------------------------------
|
|
@@ -531,8 +543,6 @@ class TestFilterChip:
|
|
|
531
543
|
@staticmethod
|
|
532
544
|
def test_chip_starts_checked() -> None:
|
|
533
545
|
"""Filter chips start in the checked (active) state."""
|
|
534
|
-
from synodic_client.application.screen.screen import FilterChip
|
|
535
|
-
|
|
536
546
|
chip = FilterChip('pipx')
|
|
537
547
|
assert chip.isChecked()
|
|
538
548
|
assert chip.text() == 'pipx'
|
|
@@ -540,8 +550,6 @@ class TestFilterChip:
|
|
|
540
550
|
@staticmethod
|
|
541
551
|
def test_toggling_emits_signal() -> None:
|
|
542
552
|
"""Toggling a chip emits the plugin name and new state."""
|
|
543
|
-
from synodic_client.application.screen.screen import FilterChip
|
|
544
|
-
|
|
545
553
|
chip = FilterChip('uv')
|
|
546
554
|
spy = MagicMock()
|
|
547
555
|
chip.toggled_with_name.connect(spy)
|
|
@@ -552,8 +560,6 @@ class TestFilterChip:
|
|
|
552
560
|
@staticmethod
|
|
553
561
|
def test_recheck_emits_true() -> None:
|
|
554
562
|
"""Re-checking a chip emits True."""
|
|
555
|
-
from synodic_client.application.screen.screen import FilterChip
|
|
556
|
-
|
|
557
563
|
chip = FilterChip('pip')
|
|
558
564
|
spy = MagicMock()
|
|
559
565
|
chip.setChecked(False)
|
|
@@ -589,16 +595,6 @@ class TestSearchFilter:
|
|
|
589
595
|
ProviderHeader(uv)
|
|
590
596
|
PluginRow(mypy, plugin=uv)
|
|
591
597
|
"""
|
|
592
|
-
from packaging.version import Version
|
|
593
|
-
from porringer.schema.plugin import PluginInfo, PluginKind
|
|
594
|
-
|
|
595
|
-
from synodic_client.application.screen.screen import (
|
|
596
|
-
PluginKindHeader,
|
|
597
|
-
PluginProviderHeader,
|
|
598
|
-
PluginRow,
|
|
599
|
-
PluginRowData,
|
|
600
|
-
)
|
|
601
|
-
|
|
602
598
|
kind_hdr = PluginKindHeader(PluginKind.TOOL)
|
|
603
599
|
view._section_widgets.append(kind_hdr)
|
|
604
600
|
view._container_layout.insertWidget(0, kind_hdr)
|
|
@@ -639,8 +635,6 @@ class TestSearchFilter:
|
|
|
639
635
|
|
|
640
636
|
view._search_input.setText('ruff')
|
|
641
637
|
|
|
642
|
-
from synodic_client.application.screen.screen import PluginRow
|
|
643
|
-
|
|
644
638
|
visible_rows = [w for w in view._section_widgets if isinstance(w, PluginRow) and not w.isHidden()]
|
|
645
639
|
assert len(visible_rows) == 1
|
|
646
640
|
assert visible_rows[0]._package_name == 'ruff'
|
|
@@ -653,10 +647,8 @@ class TestSearchFilter:
|
|
|
653
647
|
view._search_input.setText('ruff')
|
|
654
648
|
view._search_input.setText('')
|
|
655
649
|
|
|
656
|
-
from synodic_client.application.screen.screen import PluginRow
|
|
657
|
-
|
|
658
650
|
visible_rows = [w for w in view._section_widgets if isinstance(w, PluginRow) and not w.isHidden()]
|
|
659
|
-
assert len(visible_rows) ==
|
|
651
|
+
assert len(visible_rows) == _EXPECTED_VISIBLE_ROWS_ALL
|
|
660
652
|
|
|
661
653
|
def test_chip_deselection_hides_plugin(self) -> None:
|
|
662
654
|
"""Deselecting a chip hides all rows from that plugin."""
|
|
@@ -665,8 +657,6 @@ class TestSearchFilter:
|
|
|
665
657
|
|
|
666
658
|
view._filter_chips['pipx'].setChecked(False)
|
|
667
659
|
|
|
668
|
-
from synodic_client.application.screen.screen import PluginRow
|
|
669
|
-
|
|
670
660
|
visible_rows = [w for w in view._section_widgets if isinstance(w, PluginRow) and not w.isHidden()]
|
|
671
661
|
assert len(visible_rows) == 1
|
|
672
662
|
assert visible_rows[0]._package_name == 'mypy'
|
|
@@ -679,10 +669,8 @@ class TestSearchFilter:
|
|
|
679
669
|
view._filter_chips['pipx'].setChecked(False)
|
|
680
670
|
view._filter_chips['pipx'].setChecked(True)
|
|
681
671
|
|
|
682
|
-
from synodic_client.application.screen.screen import PluginRow
|
|
683
|
-
|
|
684
672
|
visible_rows = [w for w in view._section_widgets if isinstance(w, PluginRow) and not w.isHidden()]
|
|
685
|
-
assert len(visible_rows) ==
|
|
673
|
+
assert len(visible_rows) == _EXPECTED_VISIBLE_ROWS_ALL
|
|
686
674
|
|
|
687
675
|
def test_search_plus_chip_filter(self) -> None:
|
|
688
676
|
"""Search and chip filtering compose — only matching rows in active plugins survive."""
|
|
@@ -692,8 +680,6 @@ class TestSearchFilter:
|
|
|
692
680
|
view._filter_chips['uv'].setChecked(False)
|
|
693
681
|
view._search_input.setText('pdm')
|
|
694
682
|
|
|
695
|
-
from synodic_client.application.screen.screen import PluginRow
|
|
696
|
-
|
|
697
683
|
visible_rows = [w for w in view._section_widgets if isinstance(w, PluginRow) and not w.isHidden()]
|
|
698
684
|
assert len(visible_rows) == 1
|
|
699
685
|
assert visible_rows[0]._package_name == 'pdm'
|
|
@@ -707,8 +693,6 @@ class TestSearchFilter:
|
|
|
707
693
|
view._filter_chips['pipx'].setChecked(False)
|
|
708
694
|
view._filter_chips['uv'].setChecked(False)
|
|
709
695
|
|
|
710
|
-
from synodic_client.application.screen.screen import PluginKindHeader
|
|
711
|
-
|
|
712
696
|
hidden_kinds = [w for w in view._section_widgets if isinstance(w, PluginKindHeader) and w.isHidden()]
|
|
713
697
|
assert len(hidden_kinds) == 1
|
|
714
698
|
|
|
@@ -719,8 +703,6 @@ class TestSearchFilter:
|
|
|
719
703
|
|
|
720
704
|
view._search_input.setText('mypy')
|
|
721
705
|
|
|
722
|
-
from synodic_client.application.screen.screen import PluginProviderHeader
|
|
723
|
-
|
|
724
706
|
visible_providers = [
|
|
725
707
|
w for w in view._section_widgets if isinstance(w, PluginProviderHeader) and not w.isHidden()
|
|
726
708
|
]
|
|
@@ -734,10 +716,8 @@ class TestSearchFilter:
|
|
|
734
716
|
|
|
735
717
|
view._search_input.setText('pipx')
|
|
736
718
|
|
|
737
|
-
from synodic_client.application.screen.screen import PluginRow
|
|
738
|
-
|
|
739
719
|
visible_rows = [w for w in view._section_widgets if isinstance(w, PluginRow) and not w.isHidden()]
|
|
740
|
-
assert len(visible_rows) ==
|
|
720
|
+
assert len(visible_rows) == _EXPECTED_VISIBLE_ROWS_PIPX
|
|
741
721
|
names = {w._package_name for w in visible_rows}
|
|
742
722
|
assert names == {'ruff', 'pdm'}
|
|
743
723
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.0.1.dev40'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/__init__.py
RENAMED
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/bootstrap.py
RENAMED
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/data.py
RENAMED
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/icon.py
RENAMED
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/instance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/card.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/screen/tray.py
RENAMED
|
File without changes
|
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/theme.py
RENAMED
|
File without changes
|
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/synodic_client/application/workers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_install_preview.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_preview_model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_tray_window_show.py
RENAMED
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_update_banner.py
RENAMED
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/qt/test_update_feedback.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/windows/test_protocol.py
RENAMED
|
File without changes
|
{synodic_client-0.0.1.dev40 → synodic_client-0.0.1.dev41}/tests/unit/windows/test_startup.py
RENAMED
|
File without changes
|