diff --git a/tests/gtk/test_row.py b/tests/gtk/test_row.py index d195b25..38a1af5 100644 --- a/tests/gtk/test_row.py +++ b/tests/gtk/test_row.py @@ -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.""" diff --git a/xfstestsdb/gtk/row.py b/xfstestsdb/gtk/row.py index f17dec7..a604294 100644 --- a/xfstestsdb/gtk/row.py +++ b/xfstestsdb/gtk/row.py @@ -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): diff --git a/xfstestsdb/gtk/xfstestsdb.css b/xfstestsdb/gtk/xfstestsdb.css index 4cc5914..fbcfaaa 100644 --- a/xfstestsdb/gtk/xfstestsdb.css +++ b/xfstestsdb/gtk/xfstestsdb.css @@ -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); +}