Compare commits
12 Commits
2deb484754
...
528444cab6
Author | SHA1 | Date |
---|---|---|
Anna Schumaker | 528444cab6 | |
Anna Schumaker | 952889687f | |
Anna Schumaker | ea2913429c | |
Anna Schumaker | 5fb9bd6221 | |
Anna Schumaker | 54be8f5ce3 | |
Anna Schumaker | 5a25935fed | |
Anna Schumaker | 40b1d1789d | |
Anna Schumaker | f44e064c89 | |
Anna Schumaker | 02452069da | |
Anna Schumaker | 7c7e279648 | |
Anna Schumaker | c861c49564 | |
Anna Schumaker | a5d1ae4607 |
|
@ -45,6 +45,7 @@ class TestXunitRow(unittest.TestCase):
|
|||
|
||||
self.row.add_xunit("xunit-1")
|
||||
self.assertSetEqual(self.row.get_results(), {"xunit-1"})
|
||||
self.assertListEqual(self.row.get_xunits(), ["xunit-1"])
|
||||
|
||||
xunit = self.row["xunit-1"]
|
||||
self.assertIsInstance(xunit, xfstestsdb.gtk.model.XunitCell)
|
||||
|
@ -52,6 +53,7 @@ class TestXunitRow(unittest.TestCase):
|
|||
|
||||
self.row.add_xunit("xunit-2")
|
||||
self.assertSetEqual(self.row.get_results(), {"xunit-1", "xunit-2"})
|
||||
self.assertListEqual(self.row.get_xunits(), ["xunit-1", "xunit-2"])
|
||||
|
||||
xunit = self.row["xunit-2"]
|
||||
self.assertIsInstance(xunit, xfstestsdb.gtk.model.XunitCell)
|
||||
|
@ -130,6 +132,8 @@ class TestProperty(unittest.TestCase):
|
|||
def test_xunits(self):
|
||||
"""Test adding xunits to a Property."""
|
||||
self.assertIsNone(self.property["xunit-1"])
|
||||
self.assertIsNone(self.property.get_value())
|
||||
self.assertFalse(self.property.all_same_value())
|
||||
|
||||
self.property.add_xunit("xunit-1", "PLATFORM", "linux-123")
|
||||
property = self.property["xunit-1"]
|
||||
|
@ -137,7 +141,8 @@ class TestProperty(unittest.TestCase):
|
|||
self.assertEqual(property.name, "xunit-1")
|
||||
self.assertEqual(property.key, "PLATFORM")
|
||||
self.assertEqual(property.value, "linux-123")
|
||||
self.assertTrue(self.property.all_same_value())
|
||||
self.assertFalse(self.property.all_same_value())
|
||||
self.assertIsNone(self.property.get_value())
|
||||
|
||||
self.property.add_xunit("xunit-2", "PLATFORM", "linux-123")
|
||||
property = self.property["xunit-2"]
|
||||
|
@ -146,9 +151,11 @@ class TestProperty(unittest.TestCase):
|
|||
self.assertEqual(property.key, "PLATFORM")
|
||||
self.assertEqual(property.value, "linux-123")
|
||||
self.assertTrue(self.property.all_same_value())
|
||||
self.assertEqual(self.property.get_value(), "linux-123")
|
||||
|
||||
self.property.add_xunit("xunit-3", "PLATFORM", "linux-456")
|
||||
self.assertFalse(self.property.all_same_value())
|
||||
self.assertIsNone(self.property.get_value())
|
||||
|
||||
|
||||
class TestPropertyList(unittest.TestCase):
|
||||
|
@ -172,6 +179,16 @@ class TestPropertyList(unittest.TestCase):
|
|||
self.assertEqual(self.prlist.runid, 1)
|
||||
self.assertEqual(self.prlist.n_items, 15)
|
||||
|
||||
def test_environment(self):
|
||||
"""Test environment handling."""
|
||||
self.assertIsInstance(self.prlist.environment, Gio.ListStore)
|
||||
self.assertEqual(len(self.prlist.environment), 1)
|
||||
self.assertEqual(self.prlist.environment[0], self.prlist)
|
||||
|
||||
env = self.prlist.get_environment()
|
||||
self.assertDictEqual(env, {"FSTYP": "myfs",
|
||||
"CHECK_OPTIONS": "-r -R xunit -g quick"})
|
||||
|
||||
|
||||
class TestPropertyFilter(unittest.TestCase):
|
||||
"""Tests our Gtk.Filter customized for filtering Properties."""
|
||||
|
@ -185,14 +202,27 @@ class TestPropertyFilter(unittest.TestCase):
|
|||
self.assertIsInstance(self.filter, Gtk.Filter)
|
||||
self.assertEqual(self.filter.get_strictness(), Gtk.FilterMatch.SOME)
|
||||
|
||||
def test_hidden_properties(self):
|
||||
"""Test the hidden properties global variable."""
|
||||
self.assertSetEqual(xfstestsdb.gtk.model.HIDDEN_PROPERTIES,
|
||||
{"CPUS", "HOST_OPTIONS", "LOAD_FACTOR",
|
||||
"MEM_KB", "NUMA_NODES", "OVL_LOWER",
|
||||
"OVL_UPPER", "OVL_WORK", "PLATFORM",
|
||||
"SECTION", "SWAP_KB", "TIME_FACTOR"})
|
||||
|
||||
def test_match(self):
|
||||
"""Test matching Properties with the Filter."""
|
||||
property = xfstestsdb.gtk.model.Property("name")
|
||||
self.assertTrue(self.filter.match(property))
|
||||
|
||||
for prop in ["CPUS", "HOST_OPTIONS", "MEM_KB", "LOAD_FACTOR",
|
||||
"NUMA_NODES", "OVL_LOWER", "OVL_UPPER", "OVL_WORK",
|
||||
"PLATFORM", "SECTION", "SWAP_KB", "TIME_FACTOR"]:
|
||||
property.add_xunit("xunit-1", "name", "my name")
|
||||
self.assertTrue(self.filter.match(property))
|
||||
property.add_xunit("xunit-2", "name", "my name")
|
||||
self.assertFalse(self.filter.match(property))
|
||||
property.add_xunit("xunit-3", "name", "my other name")
|
||||
self.assertTrue(self.filter.match(property))
|
||||
|
||||
for prop in xfstestsdb.gtk.model.HIDDEN_PROPERTIES:
|
||||
with self.subTest(property=prop):
|
||||
property.name = prop
|
||||
self.assertFalse(self.filter.match(property))
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"""Tests our row widgets and factories."""
|
||||
import unittest
|
||||
import xfstestsdb.gtk.row
|
||||
import tests.xunit
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Adw
|
||||
|
||||
|
@ -136,6 +137,52 @@ class TestLabelFactory(unittest.TestCase):
|
|||
self.assertFalse(child.has_css_class(expected))
|
||||
|
||||
|
||||
class TestEnvironmentFactory(unittest.TestCase):
|
||||
"""Tests our Gtk.Factory to show environment properties."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.xfstestsdb = xfstestsdb.Command()
|
||||
with unittest.mock.patch("sys.stdout"):
|
||||
self.xfstestsdb.run(["new", "/dev/vda1"])
|
||||
self.xfstestsdb.run(["xunit", "read", "--name", "xunit-1",
|
||||
"1", str(tests.xunit.XUNIT_1)])
|
||||
self.xfstestsdb.run(["xunit", "read", "--name", "xunit-2",
|
||||
"1", str(tests.xunit.XUNIT_1)])
|
||||
|
||||
self.props = xfstestsdb.gtk.model.PropertyList(self.xfstestsdb.sql, 1)
|
||||
self.listitem = Gtk.ListItem()
|
||||
self.listitem.get_item = unittest.mock.Mock(return_value=self.props)
|
||||
|
||||
self.factory = xfstestsdb.gtk.row.EnvironmentFactory(property="FSTYP")
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the factory was initialized correctly."""
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.Factory)
|
||||
self.assertEqual(self.factory.property, "FSTYP")
|
||||
|
||||
def test_bind(self):
|
||||
"""Test binding to a property."""
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.factory.emit("bind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_xalign(), 0)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "myfs")
|
||||
self.assertEqual(self.listitem.get_child().get_tooltip_text(), "myfs")
|
||||
|
||||
|
||||
class TestXunitFactory(unittest.TestCase):
|
||||
"""Tests our XunitFactory base class."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.factory = xfstestsdb.gtk.row.XunitFactory(xunit="xunit-1")
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the factory was initialized correctly."""
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.Factory)
|
||||
self.assertEqual(self.factory.xunit, "xunit-1")
|
||||
|
||||
|
||||
class TestPropertyFactory(unittest.TestCase):
|
||||
"""Tests our Gtk.Factory to show xunit properties."""
|
||||
|
||||
|
@ -145,15 +192,14 @@ class TestPropertyFactory(unittest.TestCase):
|
|||
self.listitem = Gtk.ListItem()
|
||||
self.listitem.get_item = unittest.mock.Mock(return_value=self.property)
|
||||
|
||||
self.factory = xfstestsdb.gtk.row.PropertyFactory("xunit-1")
|
||||
self.factory = xfstestsdb.gtk.row.PropertyFactory(xunit="xunit-1")
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the factory was initialized correctly."""
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.Factory)
|
||||
self.assertEqual(self.factory.xunit, "xunit-1")
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.XunitFactory)
|
||||
|
||||
def test_bind_different(self):
|
||||
"""Test binding to the a property when all values are different."""
|
||||
def test_bind(self):
|
||||
"""Test binding to a property."""
|
||||
self.property.add_xunit("xunit-1", "property", "value")
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.factory.emit("bind", self.listitem)
|
||||
|
@ -176,53 +222,88 @@ class TestResultFactory(unittest.TestCase):
|
|||
self.listitem = Gtk.ListItem()
|
||||
self.listitem.get_item = unittest.mock.Mock(return_value=self.testcase)
|
||||
|
||||
self.factory = xfstestsdb.gtk.row.ResultFactory("xunit-1")
|
||||
self.factory = xfstestsdb.gtk.row.ResultFactory(xunit="xunit-1")
|
||||
self.factory.connect("setup", self.setup_parent)
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the factory was initialized correctly."""
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.Factory)
|
||||
self.assertEqual(self.factory.xunit, "xunit-1")
|
||||
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."""
|
||||
|
@ -242,12 +323,11 @@ class TestSummaryFactory(unittest.TestCase):
|
|||
self.listitem = Gtk.ListItem()
|
||||
self.listitem.get_item = unittest.mock.Mock(return_value=self.summary)
|
||||
|
||||
self.factory = xfstestsdb.gtk.row.SummaryFactory("xunit-1")
|
||||
self.factory = xfstestsdb.gtk.row.SummaryFactory(xunit="xunit-1")
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the factory was initialized correctly."""
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.Factory)
|
||||
self.assertEqual(self.factory.xunit, "xunit-1")
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.XunitFactory)
|
||||
|
||||
def test_bind_passed(self):
|
||||
"""Test binding to the passed tests summary."""
|
||||
|
|
|
@ -4,10 +4,11 @@ import unittest
|
|||
import tests.xunit
|
||||
import xfstestsdb.gtk.view
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Adw
|
||||
|
||||
|
||||
class TestPropertyView(unittest.TestCase):
|
||||
"""Tests the PropertyView."""
|
||||
class TestXunitView(unittest.TestCase):
|
||||
"""Tests the XunitView base class."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
|
@ -19,19 +20,16 @@ class TestPropertyView(unittest.TestCase):
|
|||
self.xfstestsdb.run(["xunit", "read", "--name", "xunit-2",
|
||||
"1", str(tests.xunit.XUNIT_1)])
|
||||
|
||||
self.model = xfstestsdb.gtk.model.PropertyList(self.xfstestsdb.sql, 1)
|
||||
self.view = xfstestsdb.gtk.view.PropertyView()
|
||||
self.model = xfstestsdb.gtk.model.XunitList(self.xfstestsdb.sql, 1)
|
||||
self.view = xfstestsdb.gtk.view.XunitView("title")
|
||||
|
||||
def test_init(self):
|
||||
"""Test that we created the ProeprtyView correctly."""
|
||||
"""Test that we created the XunitView correctly."""
|
||||
self.assertIsInstance(self.view, Gtk.ScrolledWindow)
|
||||
self.assertEqual(self.view.props.vscrollbar_policy,
|
||||
Gtk.PolicyType.NEVER)
|
||||
self.assertTrue(self.view.has_css_class("card"))
|
||||
self.assertIsNone(self.view.model)
|
||||
|
||||
def test_columnview(self):
|
||||
"""Test that we set up the Columnview correctly."""
|
||||
"""Test that we set up the ColumnView child correctly."""
|
||||
self.assertIsInstance(self.view.props.child, Gtk.ColumnView)
|
||||
self.assertIsInstance(self.view.props.child.get_model(),
|
||||
Gtk.NoSelection)
|
||||
|
@ -39,51 +37,120 @@ class TestPropertyView(unittest.TestCase):
|
|||
self.assertTrue(self.view.props.child.get_show_column_separators())
|
||||
self.assertTrue(self.view.props.child.get_show_row_separators())
|
||||
self.assertTrue(self.view.props.child.get_hexpand())
|
||||
self.assertTrue(self.view.props.child.has_css_class("data-table"))
|
||||
|
||||
def test_filter(self):
|
||||
def test_filtermodel(self):
|
||||
"""Test that we set up the Gtk.FilterModel correctly."""
|
||||
self.assertIsInstance(self.view._filtermodel, Gtk.FilterListModel)
|
||||
self.assertIsInstance(self.view._propfilter,
|
||||
xfstestsdb.gtk.model.PropertyFilter)
|
||||
self.assertIsInstance(self.view.filtermodel, Gtk.FilterListModel)
|
||||
self.assertIsNone(self.view.filtermodel.props.filter)
|
||||
|
||||
self.assertEqual(self.view.props.child.get_model().get_model(),
|
||||
self.view._filtermodel)
|
||||
self.assertEqual(self.view._filtermodel.props.filter,
|
||||
self.view._propfilter)
|
||||
self.view.filtermodel)
|
||||
|
||||
def test_property_column(self):
|
||||
"""Test that we set up the 'property' column correctly."""
|
||||
self.assertIsInstance(self.view._property, Gtk.ColumnViewColumn)
|
||||
self.assertIsInstance(self.view._property.props.factory,
|
||||
def test_firstcol(self):
|
||||
"""Test that we set up the first column correctly."""
|
||||
self.assertIsInstance(self.view.firstcol, Gtk.ColumnViewColumn)
|
||||
self.assertIsInstance(self.view.firstcol.props.factory,
|
||||
xfstestsdb.gtk.row.LabelFactory)
|
||||
self.assertEqual(self.view._property.props.factory.property, "name")
|
||||
self.assertEqual(self.view._property.props.title, "property")
|
||||
self.assertFalse(self.view._property.props.expand)
|
||||
self.assertEqual(self.view.firstcol.props.factory.property, "name")
|
||||
self.assertEqual(self.view.firstcol.props.title, "title")
|
||||
self.assertFalse(self.view.firstcol.props.expand)
|
||||
|
||||
def test_model(self):
|
||||
"""Test setting the model property."""
|
||||
self.view.model = self.model
|
||||
self.assertEqual(self.view._filtermodel.props.model, self.model)
|
||||
|
||||
"""Test the model property."""
|
||||
columns = self.view.props.child.get_columns()
|
||||
self.assertIsNone(self.view.model)
|
||||
self.assertEqual(len(columns), 0)
|
||||
|
||||
self.view.model = self.model
|
||||
self.assertEqual(self.view.filtermodel.props.model, self.model)
|
||||
self.assertEqual(len(columns), 3)
|
||||
self.assertEqual(columns[0], self.view._property)
|
||||
self.assertEqual(columns[0], self.view.firstcol)
|
||||
|
||||
for i, title in enumerate(["xunit-1", "xunit-2"], start=1):
|
||||
with self.subTest(i=i, title=title):
|
||||
self.assertIsInstance(columns[i].props.factory,
|
||||
xfstestsdb.gtk.row.PropertyFactory)
|
||||
xfstestsdb.gtk.row.XunitFactory)
|
||||
self.assertEqual(columns[i].props.factory.xunit, title)
|
||||
self.assertEqual(columns[i].props.title, title)
|
||||
self.assertTrue(columns[i].props.expand)
|
||||
|
||||
self.view.model = None
|
||||
self.assertEqual(len(self.view.props.child.get_columns()), 0)
|
||||
self.assertEqual(len(columns), 0)
|
||||
|
||||
|
||||
class EnvironmentView(unittest.TestCase):
|
||||
"""Tests the EnvironmentView."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.xfstestsdb = xfstestsdb.Command()
|
||||
with unittest.mock.patch("sys.stdout"):
|
||||
self.xfstestsdb.run(["new", "/dev/vda1"])
|
||||
self.xfstestsdb.run(["xunit", "read", "--name", "xunit-1",
|
||||
"1", str(tests.xunit.XUNIT_1)])
|
||||
self.xfstestsdb.run(["xunit", "read", "--name", "xunit-2",
|
||||
"1", str(tests.xunit.XUNIT_1)])
|
||||
|
||||
self.props = xfstestsdb.gtk.model.PropertyList(self.xfstestsdb.sql, 1)
|
||||
self.model = self.props.environment
|
||||
self.view = xfstestsdb.gtk.view.EnvironmentView()
|
||||
|
||||
def test_init(self):
|
||||
"""Test that we created the EnvironmentView correctly."""
|
||||
self.assertIsInstance(self.view, xfstestsdb.gtk.view.XunitView)
|
||||
self.assertIsNone(self.view.filtermodel.props.filter)
|
||||
self.assertIsNone(self.view.firstcol)
|
||||
self.assertIsNone(self.view.model)
|
||||
|
||||
self.assertTrue(self.view.props.child.has_css_class("data-table"))
|
||||
|
||||
def test_make_factory(self):
|
||||
"""Test the do_make_factory() implementation."""
|
||||
factory = self.view.do_make_factory("property")
|
||||
self.assertIsInstance(factory, xfstestsdb.gtk.row.EnvironmentFactory)
|
||||
self.assertEqual(factory.property, "property")
|
||||
|
||||
def test_model(self):
|
||||
"""Test the model property."""
|
||||
columns = self.view.props.child.get_columns()
|
||||
self.assertIsNone(self.view.model)
|
||||
self.assertEqual(len(columns), 0)
|
||||
self.assertFalse(self.view.props.visible)
|
||||
|
||||
self.view.model = self.model
|
||||
self.assertEqual(self.view.props.child.get_columns()[0],
|
||||
self.view._property)
|
||||
self.assertEqual(self.view.filtermodel.props.model, self.model)
|
||||
self.assertEqual(len(columns), 7)
|
||||
self.assertTrue(self.view.props.visible)
|
||||
|
||||
self.view.model = None
|
||||
self.assertEqual(len(columns), 0)
|
||||
self.assertFalse(self.view.props.visible)
|
||||
|
||||
|
||||
class TestPropertyView(unittest.TestCase):
|
||||
"""Tests the PropertyView."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.view = xfstestsdb.gtk.view.PropertyView()
|
||||
|
||||
def test_init(self):
|
||||
"""Test that we created the ProeprtyView correctly."""
|
||||
self.assertIsInstance(self.view, xfstestsdb.gtk.view.XunitView)
|
||||
self.assertIsInstance(self.view.filtermodel.props.filter,
|
||||
xfstestsdb.gtk.model.PropertyFilter)
|
||||
self.assertIsNone(self.view.model)
|
||||
|
||||
self.assertEqual(self.view.props.vscrollbar_policy,
|
||||
Gtk.PolicyType.NEVER)
|
||||
self.assertEqual(self.view.firstcol.props.title, "property")
|
||||
self.assertTrue(self.view.props.child.has_css_class("data-table"))
|
||||
|
||||
def test_make_factory(self):
|
||||
"""Test the do_make_factory() implementation."""
|
||||
factory = self.view.do_make_factory("xunit-1")
|
||||
self.assertIsInstance(factory, xfstestsdb.gtk.row.PropertyFactory)
|
||||
self.assertEqual(factory.xunit, "xunit-1")
|
||||
|
||||
|
||||
class TestFilterButtons(unittest.TestCase):
|
||||
|
@ -148,91 +215,221 @@ class TestTestCaseView(unittest.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.xfstestsdb = xfstestsdb.Command()
|
||||
with unittest.mock.patch("sys.stdout"):
|
||||
self.xfstestsdb.run(["new", "/dev/vda1"])
|
||||
self.xfstestsdb.run(["xunit", "read", "--name", "xunit-1",
|
||||
"1", str(tests.xunit.XUNIT_1)])
|
||||
self.xfstestsdb.run(["xunit", "read", "--name", "xunit-2",
|
||||
"1", str(tests.xunit.XUNIT_1)])
|
||||
|
||||
self.model = xfstestsdb.gtk.model.TestCaseList(self.xfstestsdb.sql, 1)
|
||||
self.view = xfstestsdb.gtk.view.TestCaseView()
|
||||
|
||||
def test_init(self):
|
||||
"""Test that we create the TestCaseView correctly."""
|
||||
self.assertIsInstance(self.view, Gtk.ScrolledWindow)
|
||||
self.assertTrue(self.view.has_css_class("card"))
|
||||
self.assertIsInstance(self.view, xfstestsdb.gtk.view.XunitView)
|
||||
self.assertIsInstance(self.view.filtermodel.props.filter,
|
||||
xfstestsdb.gtk.model.TestCaseFilter)
|
||||
self.assertIsNone(self.view.model)
|
||||
|
||||
def test_columnview(self):
|
||||
"""Test that we set up the Columnview correctly."""
|
||||
self.assertIsInstance(self.view.props.child, Gtk.ColumnView)
|
||||
self.assertIsInstance(self.view.props.child.get_model(),
|
||||
Gtk.NoSelection)
|
||||
self.assertEqual(len(self.view.props.child.get_columns()), 0)
|
||||
self.assertTrue(self.view.props.child.get_show_column_separators())
|
||||
self.assertTrue(self.view.props.child.get_show_row_separators())
|
||||
self.assertTrue(self.view.props.child.get_hexpand())
|
||||
self.assertEqual(self.view.firstcol.props.title, "testcase")
|
||||
self.assertTrue(self.view.props.child.get_vexpand())
|
||||
|
||||
def test_filter(self):
|
||||
"""Test that we set up the Gtk.FilterModel and Buttons correctly."""
|
||||
self.assertIsInstance(self.view._filtermodel, Gtk.FilterListModel)
|
||||
self.assertIsInstance(self.view._testfilter,
|
||||
xfstestsdb.gtk.model.TestCaseFilter)
|
||||
self.assertIsInstance(self.view.filterbuttons,
|
||||
xfstestsdb.gtk.view.FilterButtons)
|
||||
|
||||
self.assertEqual(self.view.props.child.get_model().get_model(),
|
||||
self.view._filtermodel)
|
||||
self.assertEqual(self.view._filtermodel.props.filter,
|
||||
self.view._testfilter)
|
||||
|
||||
self.assertFalse(self.view._testfilter.passed)
|
||||
self.assertFalse(self.view.filtermodel.props.filter.passed)
|
||||
self.view.filterbuttons.passed = True
|
||||
self.assertTrue(self.view._testfilter.passed)
|
||||
self.assertTrue(self.view.filtermodel.props.filter.passed)
|
||||
|
||||
self.assertFalse(self.view._testfilter.skipped)
|
||||
self.assertFalse(self.view.filtermodel.props.filter.skipped)
|
||||
self.view.filterbuttons.skipped = True
|
||||
self.assertTrue(self.view._testfilter.skipped)
|
||||
self.assertTrue(self.view.filtermodel.props.filter.skipped)
|
||||
|
||||
self.assertTrue(self.view._testfilter.failure)
|
||||
self.assertTrue(self.view.filtermodel.props.filter.failure)
|
||||
self.view.filterbuttons.failure = False
|
||||
self.assertFalse(self.view._testfilter.failure)
|
||||
self.assertFalse(self.view.filtermodel.props.filter.failure)
|
||||
|
||||
def test_testcase_column(self):
|
||||
"""Test that we set up the 'testcase' column correctly."""
|
||||
self.assertIsInstance(self.view._testcase, Gtk.ColumnViewColumn)
|
||||
self.assertIsInstance(self.view._testcase.props.factory,
|
||||
xfstestsdb.gtk.row.LabelFactory)
|
||||
self.assertEqual(self.view._testcase.props.factory.property, "name")
|
||||
self.assertEqual(self.view._testcase.props.title, "testcase")
|
||||
self.assertFalse(self.view._testcase.props.expand)
|
||||
def test_make_factory(self):
|
||||
"""Test the do_make_factory() implementation."""
|
||||
show_messages = unittest.mock.Mock()
|
||||
self.view.connect("show-messages", show_messages)
|
||||
|
||||
def test_model(self):
|
||||
"""Test setting the model property."""
|
||||
self.view.model = self.model
|
||||
self.assertEqual(self.view._filtermodel.props.model, self.model)
|
||||
factory = self.view.do_make_factory("xunit-1")
|
||||
self.assertIsInstance(factory, xfstestsdb.gtk.row.ResultFactory)
|
||||
self.assertEqual(factory.xunit, "xunit-1")
|
||||
|
||||
columns = self.view.props.child.get_columns()
|
||||
self.assertEqual(len(columns), 3)
|
||||
self.assertEqual(columns[0], self.view._testcase)
|
||||
factory.emit("show-messages", "testcase", "xunit", "stdout", "stderr")
|
||||
show_messages.assert_called_with(self.view, "testcase", "xunit",
|
||||
"stdout", "stderr")
|
||||
|
||||
for i, title in enumerate(["xunit-1", "xunit-2"], start=1):
|
||||
with self.subTest(i=i, title=title):
|
||||
self.assertIsInstance(columns[i].props.factory,
|
||||
xfstestsdb.gtk.row.ResultFactory)
|
||||
self.assertEqual(columns[i].props.factory.xunit, title)
|
||||
self.assertEqual(columns[i].props.title, title)
|
||||
self.assertTrue(columns[i].props.expand)
|
||||
|
||||
self.view.model = None
|
||||
self.assertEqual(len(self.view.props.child.get_columns()), 0)
|
||||
class TestMessageView(unittest.TestCase):
|
||||
"""Test the MessageView."""
|
||||
|
||||
self.view.model = self.model
|
||||
self.assertEqual(self.view.props.child.get_columns()[0],
|
||||
self.view._testcase)
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.view = xfstestsdb.gtk.view.MessageView("title")
|
||||
|
||||
def test_init(self):
|
||||
"""Check that the MessageView was set up correctly."""
|
||||
self.assertIsInstance(self.view, Gtk.Box)
|
||||
self.assertEqual(self.view.props.orientation, Gtk.Orientation.VERTICAL)
|
||||
self.assertTrue(self.view.has_css_class("view"))
|
||||
|
||||
def test_detect_diff(self):
|
||||
"""Check detecting if input test looks like a diff."""
|
||||
self.assertFalse(self.view.detect_diff("not a diff"))
|
||||
lines = ["+++ /some/file"]
|
||||
self.assertFalse(self.view.detect_diff("\n".join(lines)))
|
||||
lines.append("--- /some/other/file")
|
||||
self.assertFalse(self.view.detect_diff("\n".join(lines)))
|
||||
lines.append("@@ 12,34,5 @@")
|
||||
self.assertFalse(self.view.detect_diff("\n".join(lines)))
|
||||
lines.append(" some context line")
|
||||
self.assertTrue(self.view.detect_diff("\n".join(lines)))
|
||||
lines[-1] = "+an added line"
|
||||
self.assertTrue(self.view.detect_diff("\n".join(lines)))
|
||||
lines[-1] = "-a removed line"
|
||||
self.assertTrue(self.view.detect_diff("\n".join(lines)))
|
||||
|
||||
def test_markup_diff(self):
|
||||
"""Check colorizing lines with diff colors."""
|
||||
self.assertEqual(self.view.markup_diff("abcde"), "abcde")
|
||||
self.assertEqual(self.view.markup_diff("+++ /some/file"),
|
||||
"<span color='#26a269'>+++ /some/file</span>")
|
||||
self.assertEqual(self.view.markup_diff("--- /some/other/file"),
|
||||
"<span color='#c01c28'>--- /some/other/file</span>")
|
||||
self.assertEqual(self.view.markup_diff("@@ 12,34,5 @@"),
|
||||
"<span color='#1c71d8'>@@ 12,34,5 @@</span>")
|
||||
self.assertEqual(self.view.markup_diff(" a context line"),
|
||||
"<span color='#77767b'> a context line</span>")
|
||||
self.assertEqual(self.view.markup_diff("+an added line"),
|
||||
"<span color='#26a269'>+an added line</span>")
|
||||
self.assertEqual(self.view.markup_diff("-a removed line"),
|
||||
"<span color='#c01c28'>-a removed line</span>")
|
||||
|
||||
def test_title(self):
|
||||
"""Test the title widgets."""
|
||||
self.assertIsInstance(self.view._label, Gtk.Label)
|
||||
self.assertIsInstance(self.view._label.get_next_sibling(),
|
||||
Gtk.Separator)
|
||||
self.assertEqual(self.view.get_first_child(), self.view._label)
|
||||
|
||||
self.assertEqual(self.view.title, "title")
|
||||
self.assertEqual(self.view._label.props.label, "title")
|
||||
self.assertEqual(self.view._label.props.margin_top, 6)
|
||||
self.assertTrue(self.view._label.has_css_class("large-title"))
|
||||
|
||||
def test_text(self):
|
||||
"""Test the text property."""
|
||||
win = self.view.get_last_child()
|
||||
self.assertIsInstance(win, Gtk.ScrolledWindow)
|
||||
self.assertIsInstance(self.view._textview, Gtk.TextView)
|
||||
self.assertEqual(win.props.child, self.view._textview)
|
||||
self.assertTrue(win.props.vexpand)
|
||||
|
||||
self.assertFalse(self.view._textview.props.editable)
|
||||
self.assertTrue(self.view._textview.props.monospace)
|
||||
|
||||
buffer = self.view._textview.get_buffer()
|
||||
self.assertEqual(self.view.text, "")
|
||||
with unittest.mock.patch.object(buffer, "set_text",
|
||||
wraps=buffer.set_text) as mock_set:
|
||||
self.view.text = "text"
|
||||
self.assertEqual(buffer.get_text(buffer.get_start_iter(),
|
||||
buffer.get_end_iter(), True),
|
||||
"text")
|
||||
mock_set.assert_called_with("text")
|
||||
self.assertEqual(self.view.text, "text")
|
||||
|
||||
def test_text_diff(self):
|
||||
"""Test setting the text property to a diff string."""
|
||||
buffer = self.view._textview.get_buffer()
|
||||
diff = ["+++ /some/file", "--- /some/other/file", "@@ 12,34,5 @@",
|
||||
" context line", "-removed line", "+added line"]
|
||||
|
||||
with unittest.mock.patch.object(buffer, "set_text",
|
||||
wraps=buffer.set_text) as mock_set:
|
||||
self.view.text = "\n".join(diff)
|
||||
mock_set.assert_not_called()
|
||||
self.assertEqual(self.view.text, "\n".join(diff))
|
||||
|
||||
self.view.text = "\n".join(diff)
|
||||
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):
|
||||
|
@ -240,68 +437,24 @@ class TestSummaryView(unittest.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.xfstestsdb = xfstestsdb.Command()
|
||||
with unittest.mock.patch("sys.stdout"):
|
||||
self.xfstestsdb.run(["new", "/dev/vda1"])
|
||||
self.xfstestsdb.run(["xunit", "read", "--name", "xunit-1",
|
||||
"1", str(tests.xunit.XUNIT_1)])
|
||||
self.xfstestsdb.run(["xunit", "read", "--name", "xunit-2",
|
||||
"1", str(tests.xunit.XUNIT_1)])
|
||||
|
||||
self.model = xfstestsdb.gtk.model.SummaryList(self.xfstestsdb.sql, 1)
|
||||
self.view = xfstestsdb.gtk.view.SummaryView()
|
||||
|
||||
def test_init(self):
|
||||
"""Test that we created the SummaryView correctly."""
|
||||
self.assertIsInstance(self.view, Gtk.ScrolledWindow)
|
||||
self.assertEqual(self.view.props.vscrollbar_policy,
|
||||
Gtk.PolicyType.NEVER)
|
||||
self.assertTrue(self.view.has_css_class("card"))
|
||||
self.assertIsInstance(self.view, xfstestsdb.gtk.view.XunitView)
|
||||
self.assertIsNone(self.view.filtermodel.props.filter)
|
||||
self.assertIsNone(self.view.model)
|
||||
|
||||
def test_columnview(self):
|
||||
"""Test that we set up the Columnview correctly."""
|
||||
self.assertIsInstance(self.view.props.child, Gtk.ColumnView)
|
||||
self.assertIsInstance(self.view.props.child.get_model(),
|
||||
Gtk.NoSelection)
|
||||
self.assertEqual(len(self.view.props.child.get_columns()), 0)
|
||||
self.assertTrue(self.view.props.child.get_show_column_separators())
|
||||
self.assertTrue(self.view.props.child.get_show_row_separators())
|
||||
self.assertTrue(self.view.props.child.get_hexpand())
|
||||
self.assertEqual(self.view.props.vscrollbar_policy,
|
||||
Gtk.PolicyType.NEVER)
|
||||
self.assertEqual(self.view.firstcol.props.title, "summary")
|
||||
self.assertTrue(self.view.props.child.has_css_class("data-table"))
|
||||
|
||||
def test_summary_column(self):
|
||||
"""Test that we set up the 'summary' column correctly."""
|
||||
self.assertIsInstance(self.view._summary, Gtk.ColumnViewColumn)
|
||||
self.assertIsInstance(self.view._summary.props.factory,
|
||||
xfstestsdb.gtk.row.LabelFactory)
|
||||
self.assertEqual(self.view._summary.props.factory.property, "name")
|
||||
self.assertEqual(self.view._summary.props.title, "summary")
|
||||
self.assertFalse(self.view._summary.props.expand)
|
||||
|
||||
def test_model(self):
|
||||
"""Test setting the model property."""
|
||||
self.view.model = self.model
|
||||
self.assertEqual(self.view.props.child.get_model().get_model(),
|
||||
self.model)
|
||||
|
||||
columns = self.view.props.child.get_columns()
|
||||
self.assertEqual(len(columns), 3)
|
||||
self.assertEqual(columns[0], self.view._summary)
|
||||
|
||||
for i, title in enumerate(["xunit-1", "xunit-2"], start=1):
|
||||
with self.subTest(i=i, title=title):
|
||||
self.assertIsInstance(columns[i].props.factory,
|
||||
xfstestsdb.gtk.row.SummaryFactory)
|
||||
self.assertEqual(columns[i].props.factory.xunit, title)
|
||||
self.assertEqual(columns[i].props.title, title)
|
||||
self.assertTrue(columns[i].props.expand)
|
||||
|
||||
self.view.model = None
|
||||
self.assertEqual(len(self.view.props.child.get_columns()), 0)
|
||||
|
||||
self.view.model = self.model
|
||||
self.assertEqual(self.view.props.child.get_columns()[0],
|
||||
self.view._summary)
|
||||
def test_make_factory(self):
|
||||
"""Test the do_make_factory() implementation."""
|
||||
factory = self.view.do_make_factory("xunit-1")
|
||||
self.assertIsInstance(factory, xfstestsdb.gtk.row.SummaryFactory)
|
||||
self.assertEqual(factory.xunit, "xunit-1")
|
||||
|
||||
|
||||
class TestXfstestsView(unittest.TestCase):
|
||||
|
@ -327,28 +480,57 @@ class TestXfstestsView(unittest.TestCase):
|
|||
self.assertIsInstance(self.view, Gtk.Box)
|
||||
self.assertEqual(self.view.props.orientation, Gtk.Orientation.VERTICAL)
|
||||
|
||||
def test_environment_view(self):
|
||||
"""Check that the XfstestsView sets up an EnvironmentView correctly."""
|
||||
self.assertIsInstance(self.view._environview,
|
||||
xfstestsdb.gtk.view.EnvironmentView)
|
||||
self.assertEqual(self.view.get_first_child(), self.view._environview)
|
||||
|
||||
def test_property_view(self):
|
||||
"""Check that the XfstestsView sets up a PropertyView correctly."""
|
||||
sep = self.view._environview.get_next_sibling()
|
||||
self.assertIsInstance(sep, Gtk.Separator)
|
||||
self.assertIsInstance(self.view._propertyview,
|
||||
xfstestsdb.gtk.view.PropertyView)
|
||||
self.assertEqual(self.view.get_first_child(), self.view._propertyview)
|
||||
self.assertEqual(sep.get_next_sibling(), self.view._propertyview)
|
||||
|
||||
def test_stack(self):
|
||||
"""Check that the XfstestsView sets u a Gtk.Stack correctly."""
|
||||
sep = self.view._propertyview.get_next_sibling()
|
||||
self.assertIsInstance(sep, Gtk.Separator)
|
||||
self.assertIsInstance(self.view._stack, Gtk.Stack)
|
||||
self.assertEqual(self.view._stack.props.transition_type,
|
||||
Gtk.StackTransitionType.OVER_LEFT_RIGHT)
|
||||
self.assertEqual(sep.get_next_sibling(), self.view._stack)
|
||||
|
||||
def test_testcase_view(self):
|
||||
"""Check that the XfstestsView sets up a TestCaseView correctly."""
|
||||
sep = self.view._propertyview.get_next_sibling()
|
||||
self.assertIsInstance(sep, Gtk.Separator)
|
||||
self.assertIsInstance(self.view._testcaseview,
|
||||
xfstestsdb.gtk.view.TestCaseView)
|
||||
self.assertEqual(sep.get_next_sibling(), self.view._testcaseview)
|
||||
self.assertEqual(self.view._stack.get_child_by_name("testcases"),
|
||||
self.view._testcaseview)
|
||||
|
||||
def test_messages_view(self):
|
||||
"""Check that the XfstestsView sets up a MessagesView correctly."""
|
||||
self.assertIsInstance(self.view._messagesview,
|
||||
xfstestsdb.gtk.view.MessagesView)
|
||||
self.assertEqual(self.view._stack.get_child_by_name("messages"),
|
||||
self.view._messagesview)
|
||||
|
||||
def test_summary_view(self):
|
||||
"""Check that the XfstestsView sets up a SummaryView correctly."""
|
||||
sep = self.view._testcaseview.get_next_sibling()
|
||||
sep = self.view._stack.get_next_sibling()
|
||||
self.assertIsInstance(sep, Gtk.Separator)
|
||||
self.assertIsInstance(self.view._summaryview,
|
||||
xfstestsdb.gtk.view.SummaryView)
|
||||
self.assertEqual(sep.get_next_sibling(), self.view._summaryview)
|
||||
|
||||
def test_environment(self):
|
||||
"""Test the XfstestsView 'environment' property."""
|
||||
self.assertIsNone(self.view.environment)
|
||||
self.view.environment = self.props.environment
|
||||
self.assertEqual(self.view._environview.model, self.props.environment)
|
||||
|
||||
def test_properties(self):
|
||||
"""Test the XfstestsView 'properties' property."""
|
||||
self.assertIsNone(self.view.properties)
|
||||
|
@ -371,3 +553,21 @@ class TestXfstestsView(unittest.TestCase):
|
|||
"""Test the XfstestsView 'filterbuttons' property."""
|
||||
self.assertEqual(self.view.filterbuttons,
|
||||
self.view._testcaseview.filterbuttons)
|
||||
|
||||
def test_messages(self):
|
||||
"""Test displaying messages to the user."""
|
||||
self.assertEqual(self.view._stack.get_visible_child_name(),
|
||||
"testcases")
|
||||
|
||||
self.view._testcaseview.emit("show-messages", "testcase",
|
||||
"xunit", "stdout", "stderr")
|
||||
self.assertEqual(self.view._stack.get_visible_child_name(),
|
||||
"messages")
|
||||
self.assertEqual(self.view._messagesview.testcase, "testcase")
|
||||
self.assertEqual(self.view._messagesview.xunit, "xunit")
|
||||
self.assertEqual(self.view._messagesview.stdout, "stdout")
|
||||
self.assertEqual(self.view._messagesview.stderr, "stderr")
|
||||
|
||||
self.view._messagesview.emit("go-back")
|
||||
self.assertEqual(self.view._stack.get_visible_child_name(),
|
||||
"testcases")
|
||||
|
|
|
@ -44,6 +44,7 @@ class TestApplication(unittest.TestCase):
|
|||
mock_cmd.get_arguments.assert_called()
|
||||
mock_activate.assert_called()
|
||||
self.assertEqual(self.application.runid, 0)
|
||||
self.assertIsNone(self.application.environment)
|
||||
self.assertIsNone(self.application.properties)
|
||||
self.assertIsNone(self.application.model)
|
||||
self.assertIsNone(self.application.summary)
|
||||
|
@ -64,6 +65,8 @@ class TestApplication(unittest.TestCase):
|
|||
xfstestsdb.gtk.model.TestCaseList)
|
||||
self.assertIsInstance(self.application.summary,
|
||||
xfstestsdb.gtk.model.SummaryList)
|
||||
self.assertEqual(self.application.environment,
|
||||
self.application.properties.environment)
|
||||
self.assertEqual(self.application.model.runid, 42)
|
||||
|
||||
@unittest.mock.patch("xfstestsdb.gtk.gsetup.add_style")
|
||||
|
@ -94,6 +97,10 @@ class TestApplication(unittest.TestCase):
|
|||
self.application.properties = properties
|
||||
self.assertEqual(self.application.view.properties, properties)
|
||||
|
||||
self.application.environment = properties.environment
|
||||
self.assertEqual(self.application.view.environment,
|
||||
properties.environment)
|
||||
|
||||
model = xfstestsdb.gtk.model.TestCaseList(self.xfstestsdb.sql, 42)
|
||||
self.application.model = model
|
||||
self.assertEqual(self.application.view.model, model)
|
||||
|
|
|
@ -52,7 +52,7 @@ class TestXfstestsdb(unittest.TestCase):
|
|||
def test_version(self, mock_stdout: io.StringIO):
|
||||
"""Test printing version information."""
|
||||
self.assertEqual(xfstestsdb.MAJOR, 1)
|
||||
self.assertEqual(xfstestsdb.MINOR, 4)
|
||||
self.assertEqual(xfstestsdb.MINOR, 5)
|
||||
|
||||
self.xfstestsdb.run(["--version"])
|
||||
self.assertEqual(mock_stdout.getvalue(), "xfstestsdb v1.4-debug\n")
|
||||
self.assertEqual(mock_stdout.getvalue(), "xfstestsdb v1.5-debug\n")
|
||||
|
|
|
@ -15,7 +15,7 @@ from . import untag
|
|||
from . import xunit
|
||||
|
||||
MAJOR = 1
|
||||
MINOR = 4
|
||||
MINOR = 5
|
||||
|
||||
|
||||
class Command:
|
||||
|
|
|
@ -18,6 +18,7 @@ class Application(Adw.Application):
|
|||
"""Our Adw.Application for displaying xfstests results."""
|
||||
|
||||
runid = GObject.Property(type=int)
|
||||
environment = GObject.Property(type=Gio.ListStore)
|
||||
properties = GObject.Property(type=model.PropertyList)
|
||||
summary = GObject.Property(type=model.SummaryList)
|
||||
model = GObject.Property(type=model.TestCaseList)
|
||||
|
@ -42,6 +43,7 @@ class Application(Adw.Application):
|
|||
case "runid":
|
||||
self.runid = int(split[1])
|
||||
self.properties = model.PropertyList(self.sql, self.runid)
|
||||
self.environment = self.properties.environment
|
||||
self.model = model.TestCaseList(self.sql, self.runid)
|
||||
self.summary = model.SummaryList(self.sql, self.runid)
|
||||
|
||||
|
@ -58,6 +60,7 @@ class Application(Adw.Application):
|
|||
self.win.headerbar.pack_end(self.view.filterbuttons)
|
||||
|
||||
self.bind_property("runid", self.win, "runid")
|
||||
self.bind_property("environment", self.view, "environment")
|
||||
self.bind_property("properties", self.view, "properties")
|
||||
self.bind_property("model", self.view, "model")
|
||||
self.bind_property("summary", self.view, "summary")
|
||||
|
|
|
@ -48,6 +48,10 @@ class XunitRow(GObject.GObject):
|
|||
"""Get a set of results for each added xunit."""
|
||||
return {str(xunit) for xunit in self.__xunits.values()}
|
||||
|
||||
def get_xunits(self) -> set[str]:
|
||||
"""Get a set of xunits added to this row."""
|
||||
return list(sorted(self.__xunits.keys()))
|
||||
|
||||
|
||||
class XunitList(GObject.GObject, Gio.ListModel):
|
||||
"""A list of XunitRows for a specific Xfstests Run."""
|
||||
|
@ -93,6 +97,11 @@ class XunitList(GObject.GObject, Gio.ListModel):
|
|||
return sorted(self.__xunits)
|
||||
|
||||
|
||||
HIDDEN_PROPERTIES = {"CPUS", "HOST_OPTIONS", "LOAD_FACTOR", "MEM_KB",
|
||||
"NUMA_NODES", "OVL_LOWER", "OVL_UPPER", "OVL_WORK",
|
||||
"PLATFORM", "SECTION", "SWAP_KB", "TIME_FACTOR"}
|
||||
|
||||
|
||||
class PropertyValue(XunitCell):
|
||||
"""A single Property for a specific Xunit."""
|
||||
|
||||
|
@ -113,12 +122,25 @@ class Property(XunitRow):
|
|||
|
||||
def all_same_value(self) -> bool:
|
||||
"""Check if all the xunits have the same value."""
|
||||
return len(self.get_results()) == 1
|
||||
return len(self.get_results()) == 1 and len(self.get_xunits()) > 1
|
||||
|
||||
def get_value(self) -> str | None:
|
||||
"""Get the value of this row if all xunits have the same value."""
|
||||
if self.all_same_value():
|
||||
return self[self.get_xunits()[0]].value
|
||||
|
||||
|
||||
class PropertyList(XunitList):
|
||||
"""A list of Properties for a specific Xfstests Run."""
|
||||
|
||||
environment = GObject.Property(type=Gio.ListStore)
|
||||
|
||||
def __init__(self, sql: sqlite.Connection, runid: int) -> None:
|
||||
"""Initialize an XunitList."""
|
||||
super().__init__(sql=sql, runid=runid)
|
||||
self.environment = Gio.ListStore()
|
||||
self.environment.append(self)
|
||||
|
||||
def do_query(self, sql: sqlite.Connection) -> sqlite3.Cursor:
|
||||
"""Query the database for properties."""
|
||||
return sql("""SELECT xunit, key, value FROM xunit_properties_view
|
||||
|
@ -129,6 +151,11 @@ class PropertyList(XunitList):
|
|||
property = rows.setdefault(row["key"], Property(row["key"]))
|
||||
property.add_xunit(row["xunit"], row["key"], row["value"])
|
||||
|
||||
def get_environment(self) -> dict[str, str]:
|
||||
"""Get a dictionary of 'environment' properties."""
|
||||
return {row.name: row.get_value() for row in self
|
||||
if row.name not in HIDDEN_PROPERTIES and row.all_same_value()}
|
||||
|
||||
|
||||
class PropertyFilter(Gtk.Filter):
|
||||
"""A filter for Properties."""
|
||||
|
@ -139,10 +166,8 @@ class PropertyFilter(Gtk.Filter):
|
|||
|
||||
def do_match(self, property: Property) -> bool:
|
||||
"""Check if a property matches the filter."""
|
||||
hidden = {"CPUS", "HOST_OPTIONS", "LOAD_FACTOR", "MEM_KB",
|
||||
"NUMA_NODES", "OVL_LOWER", "OVL_UPPER", "OVL_WORK",
|
||||
"PLATFORM", "SECTION", "SWAP_KB", "TIME_FACTOR"}
|
||||
return property.name not in hidden
|
||||
return property.name not in HIDDEN_PROPERTIES \
|
||||
and not property.all_same_value()
|
||||
|
||||
|
||||
class TestResult(XunitCell):
|
||||
|
|
|
@ -87,15 +87,36 @@ class LabelFactory(Factory):
|
|||
LabelFactory.group.remove_widget(child)
|
||||
|
||||
|
||||
class PropertyFactory(Factory):
|
||||
"""Factory for making property widgets."""
|
||||
class EnvironmentFactory(Factory):
|
||||
"""Factory for Environment property columns."""
|
||||
|
||||
property = GObject.Property(type=str)
|
||||
|
||||
def __init__(self, *, property: str):
|
||||
"""Initialize our Environment Factory."""
|
||||
super().__init__(property=property)
|
||||
|
||||
def do_bind(self, row: model.PropertyList, child: Gtk.Inscription) -> None:
|
||||
"""Bind an Environment property to the child widget."""
|
||||
text = row.get_environment()[self.property]
|
||||
child.set_xalign(0)
|
||||
child.set_text(text)
|
||||
child.set_tooltip_text(text)
|
||||
|
||||
|
||||
class XunitFactory(Factory):
|
||||
"""Factory base class for Xunit columns."""
|
||||
|
||||
xunit = GObject.Property(type=str)
|
||||
|
||||
def __init__(self, xunit: str):
|
||||
"""Initialize our InscriptionFactory."""
|
||||
def __init__(self, *, xunit: str):
|
||||
"""Initialize our Xunit Factory."""
|
||||
super().__init__(xunit=xunit)
|
||||
|
||||
|
||||
class PropertyFactory(XunitFactory):
|
||||
"""Factory for making property widgets."""
|
||||
|
||||
def do_bind(self, row: model.TestCase, child: Gtk.Inscription) -> None:
|
||||
"""Bind a ListItem to the child widget."""
|
||||
property = row[self.xunit]
|
||||
|
@ -103,14 +124,20 @@ class PropertyFactory(Factory):
|
|||
child.set_tooltip_text(property.value)
|
||||
|
||||
|
||||
class ResultFactory(Factory):
|
||||
class ResultFactory(XunitFactory):
|
||||
"""Factory for making test result widgets."""
|
||||
|
||||
xunit = GObject.Property(type=str)
|
||||
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 __init__(self, xunit: str):
|
||||
"""Initialize our ResultFactory."""
|
||||
super().__init__(xunit=xunit)
|
||||
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."""
|
||||
|
@ -123,22 +150,28 @@ class ResultFactory(Factory):
|
|||
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(Factory):
|
||||
class SummaryFactory(XunitFactory):
|
||||
"""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]
|
||||
|
|
|
@ -1,56 +1,110 @@
|
|||
# Copyright 2023 (c) Anna Schumaker.
|
||||
"""A view widget used to display our TestCaseModel."""
|
||||
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
|
||||
from .model import TestCaseFilter
|
||||
from .model import SummaryList
|
||||
from .model import XunitList
|
||||
from . import button
|
||||
from . import row
|
||||
|
||||
|
||||
class PropertyView(Gtk.ScrolledWindow):
|
||||
class XunitView(Gtk.ScrolledWindow):
|
||||
"""Our XunitView base class."""
|
||||
|
||||
filtermodel = GObject.Property(type=Gtk.FilterListModel)
|
||||
firstcol = GObject.Property(type=Gtk.ColumnViewColumn)
|
||||
|
||||
def __init__(self, title: str, **kwargs):
|
||||
"""Initialize an XunitView."""
|
||||
factory = row.LabelFactory("name")
|
||||
super().__init__(filtermodel=Gtk.FilterListModel(),
|
||||
firstcol=Gtk.ColumnViewColumn(title=title,
|
||||
factory=factory),
|
||||
child=Gtk.ColumnView(model=Gtk.NoSelection(),
|
||||
show_row_separators=True,
|
||||
show_column_separators=True,
|
||||
hexpand=True),
|
||||
**kwargs)
|
||||
self.props.child.get_model().set_model(self.filtermodel)
|
||||
self.add_css_class("card")
|
||||
|
||||
def do_make_factory(self, xunit: str) -> row.XunitFactory:
|
||||
"""Make an XunitFactory for the given xunit."""
|
||||
return row.XunitFactory(xunit=xunit)
|
||||
|
||||
@GObject.Property(type=XunitList)
|
||||
def model(self) -> XunitList | None:
|
||||
"""Get the XunitList shown by the XunitView."""
|
||||
return self.filtermodel.props.model
|
||||
|
||||
@model.setter
|
||||
def model(self, new: XunitList) -> None:
|
||||
for col in list(self.props.child.get_columns()):
|
||||
self.props.child.remove_column(col)
|
||||
|
||||
self.filtermodel.props.model = new
|
||||
|
||||
if new is not None:
|
||||
self.props.child.append_column(self.firstcol)
|
||||
for xunit in new.get_xunits():
|
||||
col = Gtk.ColumnViewColumn(title=xunit, expand=True,
|
||||
factory=self.do_make_factory(xunit))
|
||||
self.props.child.append_column(col)
|
||||
|
||||
|
||||
class EnvironmentView(XunitView):
|
||||
"""Displays our Environment properties to the user."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize an EnvironmentView."""
|
||||
super().__init__("environment", visible=False)
|
||||
self.firstcol = None
|
||||
self.props.child.add_css_class("data-table")
|
||||
|
||||
def do_make_factory(self, property: str) -> row.EnvironmentFactory:
|
||||
"""Make a new EnvironmentFactory instance."""
|
||||
return row.EnvironmentFactory(property=property)
|
||||
|
||||
@GObject.Property(type=Gio.ListModel)
|
||||
def model(self) -> Gio.ListModel | None:
|
||||
"""Get the ListModel shown by the EnvironmentView."""
|
||||
return self.filtermodel.props.model
|
||||
|
||||
@model.setter
|
||||
def model(self, new: Gio.ListModel) -> None:
|
||||
for col in list(self.props.child.get_columns()):
|
||||
self.props.child.remove_column(col)
|
||||
|
||||
self.filtermodel.props.model = new
|
||||
self.props.visible = new is not None
|
||||
|
||||
if new is not None:
|
||||
environ = new[0].get_environment()
|
||||
for prop in environ.keys():
|
||||
col = Gtk.ColumnViewColumn(title=prop, expand=True,
|
||||
factory=self.do_make_factory(prop))
|
||||
self.props.child.append_column(col)
|
||||
|
||||
|
||||
class PropertyView(XunitView):
|
||||
"""Displays our PropertyList model to the user."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize a PropertyView."""
|
||||
super().__init__(child=Gtk.ColumnView(model=Gtk.NoSelection(),
|
||||
show_row_separators=True,
|
||||
show_column_separators=True,
|
||||
hexpand=True),
|
||||
vscrollbar_policy=Gtk.PolicyType.NEVER)
|
||||
self._property = Gtk.ColumnViewColumn(title="property",
|
||||
factory=row.LabelFactory("name"))
|
||||
|
||||
self._propfilter = PropertyFilter()
|
||||
self._filtermodel = Gtk.FilterListModel(filter=self._propfilter)
|
||||
|
||||
self.props.child.get_model().set_model(self._filtermodel)
|
||||
super().__init__("property", vscrollbar_policy=Gtk.PolicyType.NEVER)
|
||||
self.filtermodel.set_filter(PropertyFilter())
|
||||
self.props.child.add_css_class("data-table")
|
||||
self.add_css_class("card")
|
||||
|
||||
def __property_column(self, xunit: str) -> None:
|
||||
return Gtk.ColumnViewColumn(title=xunit, expand=True,
|
||||
factory=row.PropertyFactory(xunit))
|
||||
|
||||
@GObject.Property(type=PropertyList)
|
||||
def model(self) -> PropertyList:
|
||||
"""Get the PropertyList shown by the View."""
|
||||
return self._filtermodel.props.model
|
||||
|
||||
@model.setter
|
||||
def model(self, new: PropertyList) -> None:
|
||||
for col in [col for col in self.props.child.get_columns()]:
|
||||
self.props.child.remove_column(col)
|
||||
|
||||
self._filtermodel.props.model = new
|
||||
|
||||
if new is not None:
|
||||
self.props.child.append_column(self._property)
|
||||
for xunit in new.get_xunits():
|
||||
self.props.child.append_column(self.__property_column(xunit))
|
||||
def do_make_factory(self, xunit: str) -> row.PropertyFactory:
|
||||
"""Make a new PropertyFactory instance."""
|
||||
return row.PropertyFactory(xunit=xunit)
|
||||
|
||||
|
||||
class FilterButtons(Gtk.Box):
|
||||
|
@ -79,116 +133,211 @@ class FilterButtons(Gtk.Box):
|
|||
self.append(self._failure)
|
||||
|
||||
|
||||
class TestCaseView(Gtk.ScrolledWindow):
|
||||
class TestCaseView(XunitView):
|
||||
"""Displays our TestCaseList model to the user."""
|
||||
|
||||
filterbuttons = GObject.Property(type=FilterButtons)
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize a TestCaseView."""
|
||||
super().__init__(child=Gtk.ColumnView(model=Gtk.NoSelection(),
|
||||
show_row_separators=True,
|
||||
show_column_separators=True,
|
||||
hexpand=True, vexpand=True),
|
||||
filterbuttons=FilterButtons())
|
||||
self._testcase = Gtk.ColumnViewColumn(title="testcase",
|
||||
factory=row.LabelFactory("name"))
|
||||
|
||||
self._testfilter = TestCaseFilter()
|
||||
self._filtermodel = Gtk.FilterListModel(filter=self._testfilter)
|
||||
super().__init__("testcase", filterbuttons=FilterButtons())
|
||||
self.filtermodel.props.filter = TestCaseFilter()
|
||||
|
||||
for prop in ["passed", "skipped", "failure"]:
|
||||
self.filterbuttons.bind_property(prop, self._testfilter, prop)
|
||||
self.filterbuttons.bind_property(prop,
|
||||
self.filtermodel.props.filter,
|
||||
prop)
|
||||
|
||||
self.props.child.get_model().set_model(self._filtermodel)
|
||||
self.props.child.set_vexpand(True)
|
||||
|
||||
def __show_messages(self, factory: row.ResultFactory, testcase: str,
|
||||
xunit: str, stdout: str, stderr: str) -> None:
|
||||
self.emit("show-messages", testcase, xunit, stdout, stderr)
|
||||
|
||||
def do_make_factory(self, xunit: str) -> row.ResultFactory:
|
||||
"""Make a new ResultFactory instance."""
|
||||
factory = row.ResultFactory(xunit=xunit)
|
||||
factory.connect("show-messages", self.__show_messages)
|
||||
return factory
|
||||
|
||||
@GObject.Signal(arg_types=(str, str, str, str))
|
||||
def show_messages(self, testcase: str, xunit: str,
|
||||
stdout: str, stderr: str) -> None:
|
||||
"""Signal that the user wants to inspect stdout and stderr messages."""
|
||||
|
||||
|
||||
class MessageView(Gtk.Box):
|
||||
"""A view for displaying a multiline test result message."""
|
||||
|
||||
title = GObject.Property(type=str)
|
||||
|
||||
def __init__(self, title: str):
|
||||
"""Initialize a MessageView."""
|
||||
super().__init__(title=title, orientation=Gtk.Orientation.VERTICAL)
|
||||
self._label = Gtk.Label(label=self.title, margin_top=6)
|
||||
self._textview = Gtk.TextView(monospace=True, editable=False)
|
||||
|
||||
self.append(self._label)
|
||||
self.append(Gtk.Separator())
|
||||
self.append(Gtk.ScrolledWindow(child=self._textview, vexpand=True))
|
||||
|
||||
self._label.add_css_class("large-title")
|
||||
self.add_css_class("view")
|
||||
|
||||
def detect_diff(self, text: str) -> bool:
|
||||
"""Detect if the given text looks like a diff."""
|
||||
in_file = out_file = counts = changed = False
|
||||
|
||||
for line in text.split("\n"):
|
||||
if re.match(r"^\+\+\+", line):
|
||||
in_file = True
|
||||
elif re.match(r"^---", line):
|
||||
out_file = True
|
||||
elif re.match(r"^@@(.*?)@@", line):
|
||||
counts = True
|
||||
elif re.match(r"^[\+| |-](.*?)", line):
|
||||
changed = True
|
||||
|
||||
return in_file and out_file and counts and changed
|
||||
|
||||
def markup_diff(self, text: str) -> str:
|
||||
"""Add Pango markup to the input string."""
|
||||
if re.match(r"^\++(.*?)", text):
|
||||
return f"<span color='#26a269'>{text}</span>"
|
||||
elif re.match(r"^-+(.*?)", text):
|
||||
return f"<span color='#c01c28'>{text}</span>"
|
||||
elif re.match(r"^@@(.*?)@@", text):
|
||||
return f"<span color='#1c71d8'>{text}</span>"
|
||||
elif re.match(r"^ (.*?)", text):
|
||||
return f"<span color='#77767b'>{text}</span>"
|
||||
return text
|
||||
|
||||
@GObject.Property(type=str)
|
||||
def text(self) -> str:
|
||||
"""Get the text displayed in the view."""
|
||||
buffer = self._textview.props.buffer
|
||||
return buffer.get_text(buffer.get_start_iter(),
|
||||
buffer.get_end_iter(), True)
|
||||
|
||||
@text.setter
|
||||
def text(self, new_text: str) -> None:
|
||||
buffer = self._textview.props.buffer
|
||||
if self.detect_diff(new_text):
|
||||
buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
|
||||
for i, line in enumerate(new_text.split("\n")):
|
||||
text = self.markup_diff(line)
|
||||
text = f"\n{text}" if i > 0 else text
|
||||
buffer.insert_markup(buffer.get_end_iter(), text, len(text))
|
||||
else:
|
||||
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 __xunit_column(self, xunit: str) -> None:
|
||||
return Gtk.ColumnViewColumn(title=xunit, expand=True,
|
||||
factory=row.ResultFactory(xunit))
|
||||
def __back_clicked(self, button: Gtk.Button) -> None:
|
||||
self.emit("go-back")
|
||||
|
||||
def make_buttons(self) -> FilterButtons:
|
||||
"""Make a new FilterButtons instance connected to this View."""
|
||||
return FilterButtons()
|
||||
|
||||
@GObject.Property(type=TestCaseList)
|
||||
def model(self) -> TestCaseList:
|
||||
"""Get the TestCaseList shown by the View."""
|
||||
return self._filtermodel.props.model
|
||||
|
||||
@model.setter
|
||||
def model(self, new: TestCaseList) -> None:
|
||||
for col in [col for col in self.props.child.get_columns()]:
|
||||
self.props.child.remove_column(col)
|
||||
|
||||
self._filtermodel.props.model = new
|
||||
|
||||
if new is not None:
|
||||
self.props.child.append_column(self._testcase)
|
||||
for xunit in new.get_xunits():
|
||||
self.props.child.append_column(self.__xunit_column(xunit))
|
||||
@GObject.Signal
|
||||
def go_back(self) -> None:
|
||||
"""Signal that the user wants to go back."""
|
||||
|
||||
|
||||
class SummaryView(Gtk.ScrolledWindow):
|
||||
class SummaryView(XunitView):
|
||||
"""Displays our SummaryList model to the user."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize a SummaryView."""
|
||||
super().__init__(child=Gtk.ColumnView(model=Gtk.NoSelection(),
|
||||
show_row_separators=True,
|
||||
show_column_separators=True,
|
||||
hexpand=True),
|
||||
vscrollbar_policy=Gtk.PolicyType.NEVER)
|
||||
self._summary = Gtk.ColumnViewColumn(title="summary",
|
||||
factory=row.LabelFactory("name"))
|
||||
self.add_css_class("card")
|
||||
super().__init__("summary", vscrollbar_policy=Gtk.PolicyType.NEVER)
|
||||
self.props.child.add_css_class("data-table")
|
||||
|
||||
def __summary_column(self, xunit: str) -> None:
|
||||
return Gtk.ColumnViewColumn(title=xunit, expand=True,
|
||||
factory=row.SummaryFactory(xunit))
|
||||
|
||||
@GObject.Property(type=SummaryList)
|
||||
def model(self) -> SummaryList:
|
||||
"""Get the SummaryList shown by the View."""
|
||||
return self.props.child.get_model().get_model()
|
||||
|
||||
@model.setter
|
||||
def model(self, new: SummaryList) -> None:
|
||||
for col in [col for col in self.props.child.get_columns()]:
|
||||
self.props.child.remove_column(col)
|
||||
|
||||
self.props.child.get_model().set_model(new)
|
||||
|
||||
if new is not None:
|
||||
self.props.child.append_column(self._summary)
|
||||
for xunit in new.get_xunits():
|
||||
self.props.child.append_column(self.__summary_column(xunit))
|
||||
def do_make_factory(self, xunit: str) -> row.SummaryFactory:
|
||||
"""Make a new SummaryFactory instance."""
|
||||
return row.SummaryFactory(xunit=xunit)
|
||||
|
||||
|
||||
class XfstestsView(Gtk.Box):
|
||||
"""A widget to display the results of an Xfstests runs."""
|
||||
|
||||
environment = GObject.Property(type=Gio.ListModel)
|
||||
properties = GObject.Property(type=PropertyList)
|
||||
model = GObject.Property(type=TestCaseList)
|
||||
summary = GObject.Property(type=SummaryList)
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize an XfstestsView."""
|
||||
animation = Gtk.StackTransitionType.OVER_LEFT_RIGHT
|
||||
super().__init__(orientation=Gtk.Orientation.VERTICAL)
|
||||
self._environview = EnvironmentView()
|
||||
self._propertyview = PropertyView()
|
||||
self._testcaseview = TestCaseView()
|
||||
self._messagesview = MessagesView()
|
||||
self._stack = Gtk.Stack(transition_type=animation)
|
||||
self._summaryview = SummaryView()
|
||||
|
||||
self.bind_property("environment", self._environview, "model")
|
||||
self.bind_property("properties", self._propertyview, "model")
|
||||
self.bind_property("model", self._testcaseview, "model")
|
||||
self.bind_property("summary", self._summaryview, "model")
|
||||
|
||||
self._testcaseview.connect("show-messages", self.__show_messages)
|
||||
self._messagesview.connect("go-back", self.__show_testcases)
|
||||
|
||||
self._stack.add_named(self._testcaseview, "testcases")
|
||||
self._stack.add_named(self._messagesview, "messages")
|
||||
|
||||
self.append(self._environview)
|
||||
self.append(Gtk.Separator())
|
||||
self.append(self._propertyview)
|
||||
self.append(Gtk.Separator())
|
||||
self.append(self._testcaseview)
|
||||
self.append(self._stack)
|
||||
self.append(Gtk.Separator())
|
||||
self.append(self._summaryview)
|
||||
|
||||
def __show_messages(self, view: TestCaseView, testcase: str,
|
||||
xunit: str, stdout: str, stderr: str) -> None:
|
||||
self._messagesview.testcase = testcase
|
||||
self._messagesview.xunit = xunit
|
||||
self._messagesview.stdout = stdout
|
||||
self._messagesview.stderr = stderr
|
||||
self._stack.set_visible_child_name("messages")
|
||||
|
||||
def __show_testcases(self, view: MessagesView) -> None:
|
||||
self._stack.set_visible_child_name("testcases")
|
||||
|
||||
@GObject.Property(type=FilterButtons)
|
||||
def filterbuttons(self) -> FilterButtons:
|
||||
"""Get the FilterButtons attached to the child TestCaseView."""
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue