From bac99c9c546a607b962a91d2dca7bfd63c158712 Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Fri, 3 Nov 2023 11:35:21 -0400 Subject: [PATCH] gtk: Add a RunidView widget This will be placed in the sidebar to display our tree of potential runs to view. I do this as its own widget so we can reuse it for different sidebar views. Signed-off-by: Anna Schumaker --- tests/gtk/test_sidebar.py | 86 +++++++++++++++++++++++++++++++++++++++ xfstestsdb/gtk/sidebar.py | 46 +++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 tests/gtk/test_sidebar.py create mode 100644 xfstestsdb/gtk/sidebar.py diff --git a/tests/gtk/test_sidebar.py b/tests/gtk/test_sidebar.py new file mode 100644 index 0000000..320bdeb --- /dev/null +++ b/tests/gtk/test_sidebar.py @@ -0,0 +1,86 @@ +# Copyright 2023 (c) Anna Schumaker. +"""Tests our sidebar test selector.""" +import datetime +import unittest +import xfstestsdb.gtk.sidebar +from gi.repository import Gtk + + +class TestRunidView(unittest.TestCase): + """Test the RunidView class.""" + + def setUp(self): + """Set up common variables.""" + self.xfstestsdb = xfstestsdb.Command() + with unittest.mock.patch("sys.stdout"): + self.xfstestsdb.run(["new", "/dev/vda2"]) + self.xfstestsdb.run(["new", "/dev/vda1"]) + self.xfstestsdb.run(["new", "/dev/vda1"]) + self.xfstestsdb.run(["new", "/dev/vda3"]) + + self.today = datetime.date.today() + self.devlist = xfstestsdb.gtk.tree.DateDeviceList(self.xfstestsdb.sql, + self.today) + self.view = xfstestsdb.gtk.sidebar.RunidView(self.devlist) + + def test_init(self): + """Test that the RunidView was set up properly.""" + self.assertIsInstance(self.view, Gtk.ScrolledWindow) + self.assertEqual(self.view.props.vexpand, True) + + def test_listview(self): + """Test that the listview child is set up properly.""" + self.assertIsInstance(self.view._view, Gtk.ListView) + self.assertIsInstance(self.view._selection, Gtk.SingleSelection) + self.assertIsInstance(self.view._view.props.factory, + xfstestsdb.gtk.row.SidebarFactory) + + self.assertTrue(self.view._view.props.single_click_activate) + self.assertTrue(self.view._view.has_css_class("navigation-sidebar")) + self.assertTrue(self.view._view.has_css_class("background")) + + self.assertEqual(self.view._view.props.model, + self.view._selection) + self.assertEqual(self.view.props.child, self.view._view) + + def test_model_property(self): + """Test the model property.""" + self.assertEqual(self.view.model, self.devlist) + self.assertEqual(self.view._selection.props.model, + self.devlist.treemodel) + + self.view.model = None + self.assertIsNone(self.view._selection.props.model) + + self.view.model = self.devlist + self.assertEqual(self.view._selection.props.model, + self.devlist.treemodel) + + def test_runid_property(self): + """Test the runid property.""" + self.view.model = self.devlist + self.assertEqual(self.view.runid, 0) + + self.view._view.emit("activate", 1) + self.assertEqual(self.view.runid, 2) + self.view._view.emit("activate", 2) + self.assertEqual(self.view.runid, 3) + self.view._view.emit("activate", 4) + self.assertEqual(self.view.runid, 1) + self.view._view.emit("activate", 6) + self.assertEqual(self.view.runid, 4) + + def test_expand_collapse(self): + """Test expanding and collapsing child rows.""" + self.view.model = self.devlist + + self.assertTrue(self.view._selection[0].get_expanded()) + self.assertEqual(self.view.runid, 0) + + self.view._view.emit("activate", 0) + self.assertFalse(self.view._selection[0].get_expanded()) + self.assertEqual(self.view.runid, 0) + + self.view._view.emit("activate", 0) + self.assertTrue(self.view._selection[0].get_expanded()) + self.assertEqual(self.view.runid, 2) diff --git a/xfstestsdb/gtk/sidebar.py b/xfstestsdb/gtk/sidebar.py new file mode 100644 index 0000000..91efa30 --- /dev/null +++ b/xfstestsdb/gtk/sidebar.py @@ -0,0 +1,46 @@ +# Copyright 2023 (c) Anna Schumaker. +"""Our sidebar for selecting a specific xfstests run to view.""" +import typing +from gi.repository import GObject +from gi.repository import Gio +from gi.repository import Gtk +from . import row +from . import tree + + +class RunidView(Gtk.ScrolledWindow): + """Our RunidView class.""" + + runid = GObject.Property(type=int) + model = GObject.Property(type=Gio.ListModel) + + def __init__(self, model: tree.DateDeviceList) -> None: + """Initialize a RunidView instance.""" + super().__init__(model=model, vexpand=True) + self._selection = Gtk.SingleSelection(model=model.treemodel) + self._view = Gtk.ListView(model=self._selection, + factory=row.SidebarFactory(), + single_click_activate=True) + + self._view.connect("activate", self.__activate) + self.connect("notify::model", self.__notify_model) + + self._view.add_css_class("navigation-sidebar") + self._view.add_css_class("background") + self.set_child(self._view) + + def __activate(self, view: Gtk.ListView, position: int) -> None: + treeitem = self._selection[position] + item = treeitem.get_item() + if isinstance(item, tree.XfstestsRun): + self.runid = item.runid + elif treeitem.props.expanded: + treeitem.props.expanded = False + else: + treeitem.props.expanded = True + self.runid = item.get_earliest_run().runid + + def __notify_model(self, sidebar: typing.Self, + param: GObject.ParamSpec) -> None: + model = None if self.model is None else self.model.treemodel + self._selection.props.model = model