gtk: Emit a signal when a specific test result is clicked

I only do this for failing tests that have text set in their stdout or
stderr properties. I also update the CSS for failed tests to give an
indication when users hover their mouse over them.

Signed-off-by: Anna Schumaker <anna@nowheycreamery.com>
This commit is contained in:
Anna Schumaker 2023-08-30 15:47:29 -04:00
parent 40b1d1789d
commit 5a25935fed
3 changed files with 73 additions and 8 deletions

View File

@ -229,45 +229,81 @@ class TestResultFactory(unittest.TestCase):
"""Test that the factory was initialized correctly."""
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.XunitFactory)
def test_setup_click(self):
"""Test that we setup a GestureClick on the child widget."""
self.factory.emit("setup", self.listitem)
child = self.listitem.get_child()
click = getattr(child, "click")
self.assertIsInstance(click, Gtk.GestureClick)
self.assertIn(click, child.observe_controllers())
self.factory.emit("teardown", self.listitem)
self.assertIsNone(getattr(child, "click"))
self.assertNotIn(click, child.observe_controllers())
def test_bind_passed(self):
"""Test binding to a passing test."""
show_messages = unittest.mock.Mock()
self.testcase.add_xunit("xunit-1", "passed", 3, "", None, None)
self.factory.connect("show-messages", show_messages)
self.factory.emit("setup", self.listitem)
child = self.listitem.get_child()
self.factory.emit("bind", self.listitem)
self.assertEqual(self.listitem.get_child().get_text(), "3 seconds")
self.assertIsNone(self.listitem.get_child().get_tooltip_text())
self.assertEqual(child.get_text(), "3 seconds")
self.assertIsNone(child.get_tooltip_text())
self.assertTrue(self.parent.has_css_class("passed"))
child.click.emit("released", 1, 0, 0)
show_messages.assert_not_called()
self.factory.emit("unbind", self.listitem)
self.assertFalse(self.parent.has_css_class("passed"))
def test_bind_skipped(self):
"""Test binding to a skipped test."""
show_messages = unittest.mock.Mock()
self.testcase.add_xunit("xunit-1", "skipped", 0,
"test skipped for ... reasons", None, None)
self.factory.connect("show-messages", show_messages)
self.factory.emit("setup", self.listitem)
child = self.listitem.get_child()
self.factory.emit("bind", self.listitem)
self.assertEqual(self.listitem.get_child().get_text(), "skipped")
self.assertEqual(self.listitem.get_child().get_tooltip_text(),
self.assertEqual(child.get_text(), "skipped")
self.assertEqual(child.get_tooltip_text(),
"test skipped for ... reasons")
self.assertTrue(self.parent.has_css_class("skipped"))
child.click.emit("released", 1, 0, 0)
show_messages.assert_not_called()
self.factory.emit("unbind", self.listitem)
self.assertFalse(self.parent.has_css_class("skipped"))
def test_bind_failed(self):
"""Test binding to a failed test."""
show_messages = unittest.mock.Mock()
self.testcase.add_xunit("xunit-1", "failure", 8,
"- failed. see output", None, None)
"- failed. see output", "stdout message",
"stderr message")
self.factory.connect("show-messages", show_messages)
self.factory.emit("setup", self.listitem)
child = self.listitem.get_child()
self.factory.emit("bind", self.listitem)
self.assertEqual(self.listitem.get_child().get_text(), "failure")
self.assertEqual(self.listitem.get_child().get_tooltip_text(),
"failed. see output")
self.assertEqual(child.get_text(), "failure")
self.assertEqual(child.get_tooltip_text(), "failed. see output")
self.assertTrue(self.parent.has_css_class("failure"))
child.click.emit("released", 1, 0, 0)
show_messages.assert_called_with(self.factory, "test/case", "xunit-1",
"stdout message", "stderr message")
self.factory.emit("unbind", self.listitem)
self.assertFalse(self.parent.has_css_class("failure"))
child.click.emit("released", 1, 0, 0)
show_messages.assert_called_once()
def test_bind_missing(self):
"""Test binding to a missing test."""

View File

@ -127,6 +127,18 @@ class PropertyFactory(XunitFactory):
class ResultFactory(XunitFactory):
"""Factory for making test result widgets."""
def __clicked(self, click: Gtk.GestureClick, n_press:
int, x: float, y: float, row: model.TestCase) -> None:
if (result := row[self.xunit]) is not None:
if len(result.stdout) > 0 or len(result.stderr) > 0:
self.emit("show-messages", row.name, self.xunit,
result.stdout, result.stderr)
def do_setup(self, child: Gtk.Inscription) -> None:
"""Set up click handling on the child widget."""
child.click = Gtk.GestureClick()
child.add_controller(child.click)
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:
@ -138,11 +150,23 @@ class ResultFactory(XunitFactory):
child.set_text(text)
child.set_tooltip_text(result.message.lstrip(" -"))
child.get_parent().add_css_class(result.status)
child.click.connect("released", self.__clicked, row)
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)
child.click.disconnect_by_func(self.__clicked)
def do_teardown(self, child: Gtk.Inscription) -> None:
"""Clean up the GestureClick."""
child.remove_controller(child.click)
setattr(child, "click", None)
@GObject.Signal(arg_types=(str, str, str, str))
def show_messages(self, testcase: str, xunit: str,
stdout: str, stderr: str) -> None:
"""Show the selected messages to the user."""
class SummaryFactory(XunitFactory):

View File

@ -26,3 +26,8 @@ cell.failure {
color: @error_fg_color;
background-color: @error_bg_color;
}
cell.failure:hover {
color: @error_fg_color;
background-color: shade(@error_bg_color, 1.1);
}