gui: native-backend session work + fix shim crashes; add page smoke test
Bundles the pending native-UI session (dark shell, style overhaul, audio page) with review fixes: - native Row: set_subtitle_lines + set_activatable_widget (store and online-accounts pages crashed with AttributeError under TANINUX_UI=native) - wine page routed through the ui seam (last direct Adw import removed) - console: delete no-op log_expander/collapsible_log and .clear() call sites - ui/__init__ docstring now states the actual default backend (native) - tests/test_pages_native.py builds every registered page under the native backend (29 pass; skips headless) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
"""Smoke test for the native (libadwaita-free) UI backend.
|
||||
|
||||
Under ``TANINUX_UI=native`` every registered page must ``build()`` without
|
||||
tripping over a gap in the native widget shims (``ui/native.py``). The point is
|
||||
to catch ``AttributeError`` / ``TypeError`` — a missing method or a wrong kwarg
|
||||
on a shim — the kind of runtime crash that only surfaces when a page is opened.
|
||||
|
||||
The test is deliberately tolerant of *environmental* failures: several pages
|
||||
call system tools (pacman, nmcli, gsettings, …) inside ``build()``. When such a
|
||||
call blows up we skip that page rather than fail — those are not shim gaps.
|
||||
|
||||
Needs a display. If GTK cannot initialise (headless CI), the whole module is
|
||||
skipped at import time.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
# Must be set before taninux.gui.ui is imported so the native backend is chosen.
|
||||
os.environ.setdefault("TANINUX_UI", "native")
|
||||
|
||||
import pytest
|
||||
|
||||
# --- GTK availability gate (module-level skip when there is no display) --------
|
||||
try:
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "4.0")
|
||||
from gi.repository import Gtk
|
||||
|
||||
_res = Gtk.init_check()
|
||||
_gtk_ok = _res[0] if isinstance(_res, tuple) else bool(_res)
|
||||
except Exception as exc: # noqa: BLE001 — any import/version error means no GTK
|
||||
pytest.skip(f"GTK 4 unavailable: {exc}", allow_module_level=True)
|
||||
else:
|
||||
if not _gtk_ok:
|
||||
pytest.skip("GTK could not initialise (no display)", allow_module_level=True)
|
||||
|
||||
from taninux.gui import ui # noqa: E402
|
||||
from taninux.gui.pages import PAGES # noqa: E402
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def window():
|
||||
"""An off-screen GTK root so built pages have a real window to parent into.
|
||||
|
||||
Deliberately never presented and never destroyed: realising/tearing down a
|
||||
window here (while pages have spawned worker threads that post idle
|
||||
callbacks) can crash GTK at interpreter shutdown. Leaving it for the OS to
|
||||
reclaim keeps the smoke test stable.
|
||||
"""
|
||||
ui.ensure_css()
|
||||
win = Gtk.Window()
|
||||
ui.set_dark(win, False)
|
||||
yield win
|
||||
|
||||
|
||||
@pytest.mark.parametrize("page", PAGES, ids=lambda p: p.key)
|
||||
def test_page_builds(page, window):
|
||||
try:
|
||||
widget = page.build()
|
||||
except (AttributeError, TypeError):
|
||||
# A shim gap (missing method / wrong kwarg) — exactly what we hunt for.
|
||||
raise
|
||||
except Exception as exc: # noqa: BLE001 — a system tool the sandbox lacks
|
||||
pytest.skip(f"{page.key}: build() needs a live system resource: {exc!r}")
|
||||
|
||||
assert widget is not None, f"{page.key}.build() returned None"
|
||||
# Parent it (unrealised) so the native container measure paths are exercised.
|
||||
holder = Gtk.Box()
|
||||
holder.append(widget)
|
||||
Reference in New Issue
Block a user