30899de5a3
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>
72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
"""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)
|