diff --git a/tests/gtk/test_sidebar.py b/tests/gtk/test_sidebar.py
index 45abfd8..42aad28 100644
--- a/tests/gtk/test_sidebar.py
+++ b/tests/gtk/test_sidebar.py
@@ -166,3 +166,67 @@ class TestCalendarView(unittest.TestCase):
self.assertEqual(self.sidebar.runid, 0)
self.sidebar._view.runid = 42
self.assertEqual(self.sidebar.runid, 42)
+
+
+class TestSidebar(unittest.TestCase):
+ """Test the Sidebar class."""
+
+ def setUp(self):
+ """Set up common variables."""
+ self.xfstestsdb = xfstestsdb.Command()
+ self.sidebar = xfstestsdb.gtk.sidebar.Sidebar(self.xfstestsdb.sql)
+
+ def test_init(self):
+ """Test taht the sidebar was set up properly."""
+ self.assertIsInstance(self.sidebar, Gtk.Box)
+ self.assertEqual(self.sidebar.props.orientation,
+ Gtk.Orientation.VERTICAL)
+ self.assertEqual(self.sidebar.sql, self.xfstestsdb.sql)
+
+ def test_stack_switcher(self):
+ """Test the Gtk.StackSwitcher."""
+ self.assertIsInstance(self.sidebar._switcher, Gtk.StackSwitcher)
+ self.assertEqual(self.sidebar._switcher.props.stack,
+ self.sidebar._stack)
+ self.assertTrue(self.sidebar._switcher.has_css_class("large-icons"))
+
+ self.assertEqual(self.sidebar._switcher.props.margin_top, 6)
+ self.assertEqual(self.sidebar._switcher.props.margin_bottom, 6)
+ self.assertEqual(self.sidebar._switcher.props.margin_start, 80)
+ self.assertEqual(self.sidebar._switcher.props.margin_end, 80)
+
+ self.assertEqual(self.sidebar.get_first_child(),
+ self.sidebar._switcher)
+
+ def test_separator(self):
+ """Test the Gtk.Separator between sidebar widgets."""
+ sep = self.sidebar._switcher.get_next_sibling()
+ self.assertIsInstance(sep, Gtk.Separator)
+ self.assertEqual(sep.props.orientation, Gtk.Orientation.HORIZONTAL)
+ self.assertEqual(sep.get_next_sibling(), self.sidebar._stack)
+
+ def test_stack(self):
+ """Test the Gtk.Stack."""
+ self.assertIsInstance(self.sidebar._stack, Gtk.Stack)
+ self.assertEqual(self.sidebar._stack.props.transition_type,
+ Gtk.StackTransitionType.OVER_LEFT_RIGHT)
+ self.assertEqual(self.sidebar.get_last_child(), self.sidebar._stack)
+
+ def test_calendar_page(self):
+ """Test the Sidebar calendar view page."""
+ self.assertIsInstance(self.sidebar._calendar,
+ xfstestsdb.gtk.sidebar.CalendarView)
+ self.assertEqual(self.sidebar._calendar.sql, self.xfstestsdb.sql)
+
+ self.assertEqual(self.sidebar._stack.get_child_by_name("calendar"),
+ self.sidebar._calendar)
+ page = self.sidebar._stack.get_page(self.sidebar._calendar)
+ self.assertEqual(page.props.title, "Calendar")
+ self.assertEqual(page.props.icon_name, "month-symbolic")
+
+ def test_runid(self):
+ """Test the runid property."""
+ self.assertEqual(self.sidebar.runid, 0)
+
+ self.sidebar._calendar.runid = 1
+ self.assertEqual(self.sidebar.runid, 1)
diff --git a/xfstestsdb/gtk/icons/month-symbolic.svg b/xfstestsdb/gtk/icons/month-symbolic.svg
new file mode 100644
index 0000000..be3e123
--- /dev/null
+++ b/xfstestsdb/gtk/icons/month-symbolic.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/xfstestsdb/gtk/icons/xfstestsdb.gresource b/xfstestsdb/gtk/icons/xfstestsdb.gresource
index edc96a6..fef1f97 100644
Binary files a/xfstestsdb/gtk/icons/xfstestsdb.gresource and b/xfstestsdb/gtk/icons/xfstestsdb.gresource differ
diff --git a/xfstestsdb/gtk/icons/xfstestsdb.gresource.xml b/xfstestsdb/gtk/icons/xfstestsdb.gresource.xml
index ebd5bc9..ccdc2ac 100644
--- a/xfstestsdb/gtk/icons/xfstestsdb.gresource.xml
+++ b/xfstestsdb/gtk/icons/xfstestsdb.gresource.xml
@@ -5,5 +5,6 @@
test-skip-symbolic.svg
test-fail-symbolic.svg
down-large-symbolic.svg
+ month-symbolic.svg
diff --git a/xfstestsdb/gtk/sidebar.py b/xfstestsdb/gtk/sidebar.py
index daebff5..12cb98c 100644
--- a/xfstestsdb/gtk/sidebar.py
+++ b/xfstestsdb/gtk/sidebar.py
@@ -95,3 +95,34 @@ class CalendarView(Gtk.Box):
min, max).fetchall():
ts = datetime.datetime.fromisoformat(stamp['timestamp'])
self._calendar.mark_day(ts.day)
+
+
+class Sidebar(Gtk.Box):
+ """Our sidebar for seleting an xfstests run."""
+
+ runid = GObject.Property(type=int)
+ sql = GObject.Property(type=GObject.TYPE_PYOBJECT)
+
+ def __init__(self, sql: sqlite.Connection) -> None:
+ """Initialize a CalendarView instance."""
+ animation = Gtk.StackTransitionType.OVER_LEFT_RIGHT
+ super().__init__(sql=sql, orientation=Gtk.Orientation.VERTICAL)
+ self._stack = Gtk.Stack(transition_type=animation)
+ self._switcher = Gtk.StackSwitcher(stack=self._stack,
+ margin_top=6, margin_bottom=6,
+ margin_start=80, margin_end=80)
+ self._calendar = CalendarView(sql)
+
+ self._calendar.bind_property("runid", self, "runid")
+
+ self.__add_page(self._calendar, "Calendar", "month-symbolic")
+
+ self._switcher.add_css_class("large-icons")
+
+ self.append(self._switcher)
+ self.append(Gtk.Separator())
+ self.append(self._stack)
+
+ def __add_page(self, page: Gtk.Widget, title: str, icon: str) -> None:
+ pg = self._stack.add_titled(page, title.lower(), title)
+ pg.set_icon_name(icon)