gtk: Create a MessagesView
The MessagesView combines two MessageViews into a split-pane card. This lets us display stdout and stderr side-by-side to the user so they can see what is going on. I also add a 'back' button that the user can click to signal that they are done reviewing the output. Signed-off-by: Anna Schumaker <anna@nowheycreamery.com>
This commit is contained in:
parent
5fb9bd6221
commit
ea2913429c
|
@ -4,6 +4,7 @@ import unittest
|
|||
import tests.xunit
|
||||
import xfstestsdb.gtk.view
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Adw
|
||||
|
||||
|
||||
class TestXunitView(unittest.TestCase):
|
||||
|
@ -352,6 +353,85 @@ class TestMessageView(unittest.TestCase):
|
|||
self.assertEqual(self.view.text, "\n".join(diff))
|
||||
|
||||
|
||||
class MessagesView(unittest.TestCase):
|
||||
"""Test the MessagesView."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.view = xfstestsdb.gtk.view.MessagesView()
|
||||
|
||||
def test_init(self):
|
||||
"""Check that the MessagesView was set up correctly."""
|
||||
self.assertIsInstance(self.view, Gtk.Box)
|
||||
self.assertIsInstance(self.view.get_first_child(), Gtk.CenterBox)
|
||||
self.assertIsInstance(self.view.get_last_child(), Gtk.Paned)
|
||||
|
||||
self.assertTrue(self.view.get_first_child().has_css_class("toolbar"))
|
||||
self.assertTrue(self.view.has_css_class("card"))
|
||||
|
||||
self.assertEqual(self.view.props.orientation, Gtk.Orientation.VERTICAL)
|
||||
self.assertEqual(self.view.props.margin_start, 24)
|
||||
self.assertEqual(self.view.props.margin_end, 24)
|
||||
self.assertEqual(self.view.props.margin_top, 24)
|
||||
self.assertEqual(self.view.props.margin_bottom, 24)
|
||||
|
||||
def test_back_button(self):
|
||||
"""Check that the back button was set up correctly."""
|
||||
self.assertIsInstance(self.view._back, Gtk.Button)
|
||||
self.assertIsInstance(self.view._back.props.child, Adw.ButtonContent)
|
||||
self.assertEqual(self.view.get_first_child().props.start_widget,
|
||||
self.view._back)
|
||||
|
||||
self.assertEqual(self.view._back.props.child.props.icon_name,
|
||||
"go-previous-symbolic")
|
||||
self.assertEqual(self.view._back.props.child.props.label, "back")
|
||||
self.assertTrue(self.view._back.has_css_class("suggested-action"))
|
||||
self.assertTrue(self.view._back.has_css_class("pill"))
|
||||
|
||||
go_back = unittest.mock.Mock()
|
||||
self.view.connect("go-back", go_back)
|
||||
self.view._back.emit("clicked")
|
||||
go_back.assert_called()
|
||||
|
||||
def test_title(self):
|
||||
"""Check that the view title was set up correctly."""
|
||||
self.assertIsInstance(self.view._title, Adw.WindowTitle)
|
||||
self.assertEqual(self.view.get_first_child().props.center_widget,
|
||||
self.view._title)
|
||||
|
||||
self.assertEqual(self.view.testcase, "")
|
||||
self.view.testcase = "test/case"
|
||||
self.assertEqual(self.view._title.props.title, "test/case")
|
||||
|
||||
self.assertEqual(self.view.xunit, "")
|
||||
self.view.xunit = "xunit-1"
|
||||
self.assertEqual(self.view._title.props.subtitle, "xunit-1")
|
||||
|
||||
def test_stdout(self):
|
||||
"""Check that the stdout window was set up properly."""
|
||||
self.assertIsInstance(self.view._stdout,
|
||||
xfstestsdb.gtk.view.MessageView)
|
||||
self.assertEqual(self.view.get_last_child().props.start_child,
|
||||
self.view._stdout)
|
||||
self.assertEqual(self.view._stdout.title, "stdout")
|
||||
|
||||
self.assertEqual(self.view.stdout, "")
|
||||
self.view.stdout = "stdout text"
|
||||
self.assertEqual(self.view._stdout.text, "stdout text")
|
||||
|
||||
def test_stderr(self):
|
||||
"""Check that the stderr window was set up properly."""
|
||||
self.assertIsInstance(self.view._stderr,
|
||||
xfstestsdb.gtk.view.MessageView)
|
||||
self.assertEqual(self.view.get_last_child().props.end_child,
|
||||
self.view._stderr)
|
||||
self.assertEqual(self.view._stderr.title, "stderr")
|
||||
|
||||
self.assertEqual(self.view.stderr, "")
|
||||
self.view.stderr = "stderr text"
|
||||
self.assertEqual(self.view._stderr.text, "stderr text")
|
||||
|
||||
|
||||
class TestSummaryView(unittest.TestCase):
|
||||
"""Tests the SummaryView."""
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import re
|
|||
from gi.repository import GObject
|
||||
from gi.repository import Gio
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Adw
|
||||
from .model import PropertyList
|
||||
from .model import PropertyFilter
|
||||
from .model import TestCaseList
|
||||
|
@ -231,6 +232,50 @@ class MessageView(Gtk.Box):
|
|||
buffer.set_text(new_text)
|
||||
|
||||
|
||||
class MessagesView(Gtk.Box):
|
||||
"""A view for displaying stdout and stderr messages."""
|
||||
|
||||
testcase = GObject.Property(type=str)
|
||||
xunit = GObject.Property(type=str)
|
||||
stdout = GObject.Property(type=str)
|
||||
stderr = GObject.Property(type=str)
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize a MessagesView."""
|
||||
icon = "go-previous-symbolic"
|
||||
super().__init__(orientation=Gtk.Orientation.VERTICAL, margin_top=24,
|
||||
margin_start=24, margin_end=24, margin_bottom=24)
|
||||
self._back = Gtk.Button(child=Adw.ButtonContent(icon_name=icon,
|
||||
label="back"))
|
||||
self._title = Adw.WindowTitle()
|
||||
self._stdout = MessageView("stdout")
|
||||
self._stderr = MessageView("stderr")
|
||||
|
||||
self.bind_property("testcase", self._title, "title")
|
||||
self.bind_property("xunit", self._title, "subtitle")
|
||||
self.bind_property("stdout", self._stdout, "text")
|
||||
self.bind_property("stderr", self._stderr, "text")
|
||||
|
||||
self._back.connect("clicked", self.__back_clicked)
|
||||
|
||||
self.append(Gtk.CenterBox(start_widget=self._back,
|
||||
center_widget=self._title))
|
||||
self.append(Gtk.Paned(start_child=self._stdout,
|
||||
end_child=self._stderr, vexpand=True))
|
||||
|
||||
self.get_first_child().add_css_class("toolbar")
|
||||
self._back.add_css_class("suggested-action")
|
||||
self._back.add_css_class("pill")
|
||||
self.add_css_class("card")
|
||||
|
||||
def __back_clicked(self, button: Gtk.Button) -> None:
|
||||
self.emit("go-back")
|
||||
|
||||
@GObject.Signal
|
||||
def go_back(self) -> None:
|
||||
"""Signal that the user wants to go back."""
|
||||
|
||||
|
||||
class SummaryView(XunitView):
|
||||
"""Displays our SummaryList model to the user."""
|
||||
|
||||
|
|
Loading…
Reference in New Issue