151 lines
5.3 KiB
Python
151 lines
5.3 KiB
Python
# Copyright 2023 (c) Anna Schumaker.
|
|
"""Our TestCase row widgets and factory."""
|
|
import typing
|
|
from gi.repository import GObject
|
|
from gi.repository import Gtk
|
|
from . import model
|
|
|
|
|
|
STYLES = {"passed": "success", "failed": "error",
|
|
"skipped": "warning", "time": "accent"}
|
|
|
|
|
|
class Factory(Gtk.SignalListItemFactory):
|
|
"""Create Gtk.Inscriptions for each Gtk.ListItem."""
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
"""Initialize our InscriptionFactory."""
|
|
super().__init__(*args, **kwargs)
|
|
self.connect("setup", self.__setup)
|
|
self.connect("bind", self.__bind)
|
|
self.connect("unbind", self.__unbind)
|
|
self.connect("teardown", self.__teardown)
|
|
|
|
def __setup(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
|
"""Set up a ListItem child widget."""
|
|
child = Gtk.Inscription(xalign=0.5, nat_chars=18)
|
|
child.props.text_overflow = Gtk.InscriptionOverflow.ELLIPSIZE_END
|
|
child.add_css_class("numeric")
|
|
self.do_setup(child)
|
|
listitem.set_child(child)
|
|
|
|
def __bind(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
|
"""Bind a ListItem to the child widget."""
|
|
self.do_bind(listitem.get_item(), listitem.get_child())
|
|
|
|
def __unbind(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
|
"""Unbind a ListItem from the child widget."""
|
|
self.do_unbind(listitem.get_item(), listitem.get_child())
|
|
listitem.get_child().set_text(None)
|
|
|
|
def __teardown(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
|
self.do_teardown(listitem.get_child())
|
|
listitem.set_child(None)
|
|
|
|
def do_setup(self, child: Gtk.Inscription) -> None:
|
|
"""Extra factory-specific setup for the child widget."""
|
|
|
|
def do_bind(self, row: model.XunitRow, child: Gtk.Inscription) -> None:
|
|
"""Extra factory-specific binding work for the child widget."""
|
|
|
|
def do_unbind(self, row: model.XunitRow, child: Gtk.Inscription) -> None:
|
|
"""Extra factory-specific unbinding work for the child widget."""
|
|
|
|
def do_teardown(self, child: Gtk.Inscription) -> None:
|
|
"""Extra factory-specific teardown for the child widget."""
|
|
|
|
|
|
class LabelFactory(Factory):
|
|
"""Create Gtk.Labels for each testcase."""
|
|
|
|
property = GObject.Property(type=str)
|
|
group = Gtk.SizeGroup()
|
|
|
|
def __init__(self, property: str):
|
|
"""Initialize our InscriptionFactory."""
|
|
super().__init__(property=property)
|
|
|
|
def do_setup(self, child: Gtk.Inscription) -> None:
|
|
"""Set up a ListItem child widget."""
|
|
LabelFactory.group.add_widget(child)
|
|
|
|
def do_bind(self, row: model.XunitRow, child: Gtk.Inscription) -> None:
|
|
"""Bind a ListItem to the child widget."""
|
|
text = row.get_property(self.property)
|
|
if style := STYLES.get(text):
|
|
child.add_css_class(style)
|
|
child.set_text(text)
|
|
|
|
def do_unbind(self, row: model.XunitRow, child: Gtk.Inscription) -> None:
|
|
"""Unbind a ListItem from the child widget."""
|
|
for style in STYLES.values():
|
|
child.remove_css_class(style)
|
|
|
|
def do_teardown(self, child: Gtk.Inscription) -> None:
|
|
"""Clean up a ListItem child widget."""
|
|
if child is not None:
|
|
LabelFactory.group.remove_widget(child)
|
|
|
|
|
|
class PropertyFactory(Factory):
|
|
"""Factory for making property widgets."""
|
|
|
|
xunit = GObject.Property(type=str)
|
|
|
|
def __init__(self, xunit: str):
|
|
"""Initialize our InscriptionFactory."""
|
|
super().__init__(xunit=xunit)
|
|
|
|
def do_bind(self, row: model.TestCase, child: Gtk.Inscription) -> None:
|
|
"""Bind a ListItem to the child widget."""
|
|
property = row[self.xunit]
|
|
child.set_text(property.value)
|
|
child.set_tooltip_text(property.value)
|
|
|
|
|
|
class ResultFactory(Factory):
|
|
"""Factory for making test result widgets."""
|
|
|
|
xunit = GObject.Property(type=str)
|
|
|
|
def __init__(self, xunit: str):
|
|
"""Initialize our ResultFactory."""
|
|
super().__init__(xunit=xunit)
|
|
|
|
def do_bind(self, row: model.TestCase, child: Gtk.Inscription) -> None:
|
|
"""Bind a ListItem to the child widget."""
|
|
if (result := row[self.xunit]) is None:
|
|
return
|
|
|
|
if (text := result.status) == "passed":
|
|
text = f"{result.time} seconds"
|
|
|
|
child.set_text(text)
|
|
child.set_tooltip_text(result.message.lstrip(" -"))
|
|
child.get_parent().add_css_class(result.status)
|
|
|
|
def do_unbind(self, row: model.TestCase, child: Gtk.Inscription) -> None:
|
|
"""Unbind a ListItem from the child widget."""
|
|
if (result := row[self.xunit]) is not None:
|
|
child.get_parent().remove_css_class(result.status)
|
|
|
|
|
|
class SummaryFactory(Factory):
|
|
"""Factory for making test summary widgets."""
|
|
|
|
xunit = GObject.Property(type=str)
|
|
|
|
def __init__(self, xunit: str):
|
|
"""Initialize our ResultFactory."""
|
|
super().__init__(xunit=xunit)
|
|
|
|
def do_bind(self, row: model.Summary, child: Gtk.Inscription) -> None:
|
|
"""Bind a ListItem to the child widget."""
|
|
result = row[self.xunit]
|
|
child.set_text(str(result))
|
|
child.add_css_class(STYLES[row.name])
|
|
|
|
def do_unbind(self, row: model.TestCase, child: Gtk.Inscription) -> None:
|
|
"""Unbind a ListItem from the child widget."""
|
|
child.remove_css_class(STYLES[row.name])
|