Compare commits
10 Commits
4d3425bb57
...
2deb484754
Author | SHA1 | Date |
---|---|---|
Anna Schumaker | 2deb484754 | |
Anna Schumaker | af1ab81ea2 | |
Anna Schumaker | 3dc8179624 | |
Anna Schumaker | c145a67ae6 | |
Anna Schumaker | 7ae246677b | |
Anna Schumaker | 59cb699bd9 | |
Anna Schumaker | 4838889c56 | |
Anna Schumaker | 5dc7735ba7 | |
Anna Schumaker | c45ec1909e | |
Anna Schumaker | ad08357121 |
|
@ -9,23 +9,213 @@ from gi.repository import Gio
|
|||
from gi.repository import Gtk
|
||||
|
||||
|
||||
class TestXunitResult(unittest.TestCase):
|
||||
class TestXunitCell(unittest.TestCase):
|
||||
"""Test case for our base XunitCell object."""
|
||||
|
||||
def test_cell(self):
|
||||
"""Test creating a Cell instance."""
|
||||
cell = xfstestsdb.gtk.model.XunitCell(name="my xunit name")
|
||||
self.assertIsInstance(cell, GObject.GObject)
|
||||
self.assertEqual(cell.name, "my xunit name")
|
||||
self.assertEqual(str(cell), "my xunit name")
|
||||
|
||||
|
||||
class TestXunitRow(unittest.TestCase):
|
||||
"""Test case for our base XunitRow object."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.row = xfstestsdb.gtk.model.XunitRow(name="row-name")
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the XunitRow is set up properly."""
|
||||
self.assertIsInstance(self.row, GObject.GObject)
|
||||
self.assertEqual(self.row.name, "row-name")
|
||||
|
||||
def test_compare(self):
|
||||
"""Test the less-than operator on XunitRows."""
|
||||
row2 = xfstestsdb.gtk.model.XunitRow(name="row-name-2")
|
||||
self.assertTrue(self.row < row2)
|
||||
self.assertFalse(row2 < self.row)
|
||||
self.assertFalse(self.row < self.row)
|
||||
|
||||
def test_xunits(self):
|
||||
"""Test adding xunits to a XunitRow."""
|
||||
self.assertIsNone(self.row["xunit-1"])
|
||||
|
||||
self.row.add_xunit("xunit-1")
|
||||
self.assertSetEqual(self.row.get_results(), {"xunit-1"})
|
||||
|
||||
xunit = self.row["xunit-1"]
|
||||
self.assertIsInstance(xunit, xfstestsdb.gtk.model.XunitCell)
|
||||
self.assertEqual(xunit.name, "xunit-1")
|
||||
|
||||
self.row.add_xunit("xunit-2")
|
||||
self.assertSetEqual(self.row.get_results(), {"xunit-1", "xunit-2"})
|
||||
|
||||
xunit = self.row["xunit-2"]
|
||||
self.assertIsInstance(xunit, xfstestsdb.gtk.model.XunitCell)
|
||||
self.assertEqual(xunit.name, "xunit-2")
|
||||
|
||||
|
||||
class TestXunitList(unittest.TestCase):
|
||||
"""Test case for our base XunitList object."""
|
||||
|
||||
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.xulist = xfstestsdb.gtk.model.XunitList(self.xfstestsdb.sql, 1)
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the XunitList was set up properly."""
|
||||
self.assertIsInstance(self.xulist, GObject.GObject)
|
||||
self.assertIsInstance(self.xulist, Gio.ListModel)
|
||||
self.assertEqual(self.xulist.runid, 1)
|
||||
|
||||
def test_get_item_type(self):
|
||||
"""Test the get_item_type() function."""
|
||||
self.assertEqual(self.xulist.get_item_type(),
|
||||
xfstestsdb.gtk.model.XunitRow.__gtype__)
|
||||
|
||||
def test_get_n_items(self):
|
||||
"""Test the get_n_items() function."""
|
||||
self.assertEqual(self.xulist.get_n_items(), 0)
|
||||
self.assertEqual(self.xulist.n_items, 0)
|
||||
|
||||
self.xulist.n_items = 2
|
||||
self.assertEqual(self.xulist.get_n_items(), 2)
|
||||
|
||||
def test_get_item(self):
|
||||
"""Test the get_item() function."""
|
||||
self.assertIsNone(self.xulist.get_item(0))
|
||||
|
||||
def test_get_xunits(self):
|
||||
"""Test the get_xunits() function."""
|
||||
self.assertListEqual(self.xulist.get_xunits(), ["xunit-1", "xunit-2"])
|
||||
|
||||
|
||||
class TestPropertyValue(unittest.TestCase):
|
||||
"""Tests a single Xunit Property instance."""
|
||||
|
||||
def test_xunit_property(self):
|
||||
"""Test creating an xunit property instance."""
|
||||
property = xfstestsdb.gtk.model.PropertyValue(name="my xunit name",
|
||||
key="key", value="123")
|
||||
self.assertIsInstance(property, xfstestsdb.gtk.model.XunitCell)
|
||||
self.assertEqual(property.name, "my xunit name")
|
||||
self.assertEqual(property.key, "key")
|
||||
self.assertEqual(property.value, "123")
|
||||
self.assertEqual(str(property), "key = 123")
|
||||
|
||||
|
||||
class TestProperty(unittest.TestCase):
|
||||
"""Tests our Property GObject."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.property = xfstestsdb.gtk.model.Property(name="property")
|
||||
|
||||
def test_init(self):
|
||||
"""Check that the Property is set up properly."""
|
||||
self.assertIsInstance(self.property, xfstestsdb.gtk.model.XunitRow)
|
||||
self.assertEqual(self.property.name, "property")
|
||||
|
||||
def test_xunits(self):
|
||||
"""Test adding xunits to a Property."""
|
||||
self.assertIsNone(self.property["xunit-1"])
|
||||
|
||||
self.property.add_xunit("xunit-1", "PLATFORM", "linux-123")
|
||||
property = self.property["xunit-1"]
|
||||
self.assertIsInstance(property, xfstestsdb.gtk.model.PropertyValue)
|
||||
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.property.add_xunit("xunit-2", "PLATFORM", "linux-123")
|
||||
property = self.property["xunit-2"]
|
||||
self.assertIsInstance(property, xfstestsdb.gtk.model.PropertyValue)
|
||||
self.assertEqual(property.name, "xunit-2")
|
||||
self.assertEqual(property.key, "PLATFORM")
|
||||
self.assertEqual(property.value, "linux-123")
|
||||
self.assertTrue(self.property.all_same_value())
|
||||
|
||||
self.property.add_xunit("xunit-3", "PLATFORM", "linux-456")
|
||||
self.assertFalse(self.property.all_same_value())
|
||||
|
||||
|
||||
class TestPropertyList(unittest.TestCase):
|
||||
"""Tests our PropertyList GObject."""
|
||||
|
||||
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_2)])
|
||||
|
||||
self.prlist = xfstestsdb.gtk.model.PropertyList(self.xfstestsdb.sql, 1)
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the PropertyList was set up properly."""
|
||||
self.assertIsInstance(self.prlist, xfstestsdb.gtk.model.XunitList)
|
||||
self.assertEqual(self.prlist.runid, 1)
|
||||
self.assertEqual(self.prlist.n_items, 15)
|
||||
|
||||
|
||||
class TestPropertyFilter(unittest.TestCase):
|
||||
"""Tests our Gtk.Filter customized for filtering Properties."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.filter = xfstestsdb.gtk.model.PropertyFilter()
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the TestCaseFilter is set up properly."""
|
||||
self.assertIsInstance(self.filter, Gtk.Filter)
|
||||
self.assertEqual(self.filter.get_strictness(), Gtk.FilterMatch.SOME)
|
||||
|
||||
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"]:
|
||||
with self.subTest(property=prop):
|
||||
property.name = prop
|
||||
self.assertFalse(self.filter.match(property))
|
||||
|
||||
|
||||
class TestTestResult(unittest.TestCase):
|
||||
"""Tests a single TestCase Xunit instance."""
|
||||
|
||||
def test_xunit_result(self):
|
||||
"""Test creating an xunit instance."""
|
||||
xunit = xfstestsdb.gtk.model.XunitResult(name="my xunit name",
|
||||
status="passed", time=123,
|
||||
message="my message",
|
||||
stdout="my stdout",
|
||||
stderr="my stderr")
|
||||
self.assertIsInstance(xunit, GObject.GObject)
|
||||
xunit = xfstestsdb.gtk.model.TestResult(name="my xunit name",
|
||||
status="passed", time=123,
|
||||
message="my message",
|
||||
stdout="my stdout",
|
||||
stderr="my stderr")
|
||||
self.assertIsInstance(xunit, xfstestsdb.gtk.model.XunitCell)
|
||||
self.assertEqual(xunit.name, "my xunit name")
|
||||
self.assertEqual(xunit.status, "passed")
|
||||
self.assertEqual(xunit.time, 123)
|
||||
self.assertEqual(xunit.message, "my message")
|
||||
self.assertEqual(xunit.stdout, "my stdout")
|
||||
self.assertEqual(xunit.stderr, "my stderr")
|
||||
self.assertEqual(str(xunit), "passed")
|
||||
|
||||
|
||||
class TestTestCase(unittest.TestCase):
|
||||
|
@ -37,16 +227,9 @@ class TestTestCase(unittest.TestCase):
|
|||
|
||||
def test_init(self):
|
||||
"""Check that the TestCase is set up properly."""
|
||||
self.assertIsInstance(self.testcase, GObject.GObject)
|
||||
self.assertIsInstance(self.testcase, xfstestsdb.gtk.model.XunitRow)
|
||||
self.assertEqual(self.testcase.name, "test-case")
|
||||
|
||||
def test_compare(self):
|
||||
"""Test the less-than operator on TestCases."""
|
||||
testcase2 = xfstestsdb.gtk.model.TestCase(name="test-case-2")
|
||||
self.assertTrue(self.testcase < testcase2)
|
||||
self.assertFalse(testcase2 < self.testcase)
|
||||
self.assertFalse(self.testcase < self.testcase)
|
||||
|
||||
def test_xunits(self):
|
||||
"""Test adding xunits to a TestCase."""
|
||||
self.assertIsNone(self.testcase["xunit-1"])
|
||||
|
@ -54,7 +237,7 @@ class TestTestCase(unittest.TestCase):
|
|||
self.testcase.add_xunit("xunit-1", "passed", 123, "message",
|
||||
"stdout", "stderr")
|
||||
xunit = self.testcase["xunit-1"]
|
||||
self.assertIsInstance(xunit, xfstestsdb.gtk.model.XunitResult)
|
||||
self.assertIsInstance(xunit, xfstestsdb.gtk.model.TestResult)
|
||||
self.assertEqual(xunit.name, "xunit-1")
|
||||
self.assertEqual(xunit.status, "passed")
|
||||
self.assertEqual(xunit.time, 123)
|
||||
|
@ -64,7 +247,7 @@ class TestTestCase(unittest.TestCase):
|
|||
|
||||
self.testcase.add_xunit("xunit-2", "failed", 456, None, None, None)
|
||||
xunit = self.testcase["xunit-2"]
|
||||
self.assertIsInstance(xunit, xfstestsdb.gtk.model.XunitResult)
|
||||
self.assertIsInstance(xunit, xfstestsdb.gtk.model.TestResult)
|
||||
self.assertEqual(xunit.name, "xunit-2")
|
||||
self.assertEqual(xunit.status, "failed")
|
||||
self.assertEqual(xunit.time, 456)
|
||||
|
@ -72,18 +255,6 @@ class TestTestCase(unittest.TestCase):
|
|||
self.assertEqual(xunit.stdout, "")
|
||||
self.assertEqual(xunit.stderr, "")
|
||||
|
||||
def test_get_results(self):
|
||||
"""Test getting a set of results for this test case."""
|
||||
self.testcase.add_xunit("xunit-1", "passed", 123, "", "", "")
|
||||
self.assertSetEqual(self.testcase.get_results(), {"passed"})
|
||||
self.testcase.add_xunit("xunit-2", "passed", 123, "", "", "")
|
||||
self.assertSetEqual(self.testcase.get_results(), {"passed"})
|
||||
self.testcase.add_xunit("xunit-3", "skipped", 123, "", "", "")
|
||||
self.assertSetEqual(self.testcase.get_results(), {"passed", "skipped"})
|
||||
self.testcase.add_xunit("xunit-4", "failure", 123, "", "", "")
|
||||
self.assertSetEqual(self.testcase.get_results(),
|
||||
{"passed", "skipped", "failure"})
|
||||
|
||||
|
||||
class TestCaseList(unittest.TestCase):
|
||||
"""Tests our TestCaseList Gio.ListModel."""
|
||||
|
@ -102,18 +273,8 @@ class TestCaseList(unittest.TestCase):
|
|||
|
||||
def test_init(self):
|
||||
"""Test that the TestCaseList was set up properly."""
|
||||
self.assertIsInstance(self.tclist, GObject.GObject)
|
||||
self.assertIsInstance(self.tclist, Gio.ListModel)
|
||||
self.assertIsInstance(self.tclist, xfstestsdb.gtk.model.XunitList)
|
||||
self.assertEqual(self.tclist.runid, 1)
|
||||
|
||||
def test_get_item_type(self):
|
||||
"""Test the get_item_type() function."""
|
||||
self.assertEqual(self.tclist.get_item_type(),
|
||||
xfstestsdb.gtk.model.TestCase.__gtype__)
|
||||
|
||||
def test_get_n_items(self):
|
||||
"""Test the get_n_items() function."""
|
||||
self.assertEqual(self.tclist.get_n_items(), 10)
|
||||
self.assertEqual(self.tclist.n_items, 10)
|
||||
|
||||
def test_get_item(self):
|
||||
|
@ -132,10 +293,6 @@ class TestCaseList(unittest.TestCase):
|
|||
|
||||
self.assertIsNone(self.tclist.get_item(10))
|
||||
|
||||
def test_get_xunits(self):
|
||||
"""Test the get_xunits() function."""
|
||||
self.assertListEqual(self.tclist.get_xunits(), ["xunit-1", "xunit-2"])
|
||||
|
||||
|
||||
class TestCaseFilter(unittest.TestCase):
|
||||
"""Tests our Gtk.Filter customized for filtering TestCases."""
|
||||
|
@ -214,7 +371,7 @@ class TestSummaryValue(unittest.TestCase):
|
|||
value = xfstestsdb.gtk.model.SummaryValue(name="my xunit name",
|
||||
value=12345,
|
||||
unit="testcase")
|
||||
self.assertIsInstance(value, GObject.GObject)
|
||||
self.assertIsInstance(value, xfstestsdb.gtk.model.XunitCell)
|
||||
self.assertEqual(value.name, "my xunit name")
|
||||
self.assertEqual(value.unit, "testcase")
|
||||
self.assertEqual(value.value, 12345)
|
||||
|
@ -238,7 +395,7 @@ class TestSummary(unittest.TestCase):
|
|||
|
||||
def test_init(self):
|
||||
"""Check that the Summary is set up properly."""
|
||||
self.assertIsInstance(self.summary, GObject.GObject)
|
||||
self.assertIsInstance(self.summary, xfstestsdb.gtk.model.XunitRow)
|
||||
self.assertEqual(self.summary.name, "passed")
|
||||
|
||||
def test_compare(self):
|
||||
|
@ -265,13 +422,6 @@ class TestSummary(unittest.TestCase):
|
|||
self.assertEqual(xunit.value, 123)
|
||||
self.assertEqual(xunit.unit, "unit")
|
||||
|
||||
def test_get_results(self):
|
||||
"""Test getting a set of results for this summary."""
|
||||
self.summary.add_xunit("xunit-1", 1, "unit")
|
||||
self.assertSetEqual(self.summary.get_results(), {"1 unit"})
|
||||
self.summary.add_xunit("xunit-2", 2, "unit")
|
||||
self.assertSetEqual(self.summary.get_results(), {"1 unit", "2 units"})
|
||||
|
||||
|
||||
class TestSummaryList(unittest.TestCase):
|
||||
"""Test case for our summary list."""
|
||||
|
@ -290,18 +440,8 @@ class TestSummaryList(unittest.TestCase):
|
|||
|
||||
def test_init(self):
|
||||
"""Test that the SummaryList was set up properly."""
|
||||
self.assertIsInstance(self.summary, GObject.GObject)
|
||||
self.assertIsInstance(self.summary, Gio.ListModel)
|
||||
self.assertIsInstance(self.summary, xfstestsdb.gtk.model.XunitList)
|
||||
self.assertEqual(self.summary.runid, 1)
|
||||
|
||||
def test_get_item_type(self):
|
||||
"""Test the get_item_type() function."""
|
||||
self.assertEqual(self.summary.get_item_type(),
|
||||
xfstestsdb.gtk.model.Summary.__gtype__)
|
||||
|
||||
def test_get_n_items(self):
|
||||
"""Test the get_n_items() function."""
|
||||
self.assertEqual(self.summary.get_n_items(), 4)
|
||||
self.assertEqual(self.summary.n_items, 4)
|
||||
|
||||
def test_get_item(self):
|
||||
|
@ -318,7 +458,3 @@ class TestSummaryList(unittest.TestCase):
|
|||
case "skipped": expected = {"3 testcases"}
|
||||
case "time": expected = {"43 seconds"}
|
||||
self.assertSetEqual(summary.get_results(), expected)
|
||||
|
||||
def test_get_xunits(self):
|
||||
"""Test the get_xunits() function."""
|
||||
self.assertListEqual(self.summary.get_xunits(), ["xunit-1", "xunit-2"])
|
||||
|
|
|
@ -6,6 +6,66 @@ from gi.repository import Gtk
|
|||
from gi.repository import Adw
|
||||
|
||||
|
||||
class TestFactory(unittest.TestCase):
|
||||
"""Tests our base Gtk.Factory to make Gtk.Inscriptions."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.xunitrow = xfstestsdb.gtk.model.XunitRow("xunit/row")
|
||||
self.listitem = Gtk.ListItem()
|
||||
self.listitem.get_item = unittest.mock.Mock(return_value=self.xunitrow)
|
||||
|
||||
self.factory = xfstestsdb.gtk.row.Factory()
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the Factory was initialized correctly."""
|
||||
self.assertIsInstance(self.factory, Gtk.SignalListItemFactory)
|
||||
|
||||
def test_setup(self):
|
||||
"""Test that the factory implements the 'setup' signal."""
|
||||
with unittest.mock.patch.object(self.factory,
|
||||
"do_setup") as mock_setup:
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.assertIsInstance(self.listitem.get_child(), Gtk.Inscription)
|
||||
self.assertEqual(self.listitem.get_child().props.xalign, 0.5)
|
||||
self.assertEqual(self.listitem.get_child().props.nat_chars, 18)
|
||||
self.assertEqual(self.listitem.get_child().props.text_overflow,
|
||||
Gtk.InscriptionOverflow.ELLIPSIZE_END)
|
||||
self.assertTrue(self.listitem.get_child().has_css_class("numeric"))
|
||||
mock_setup.assert_called_with(self.listitem.get_child())
|
||||
|
||||
def test_bind(self):
|
||||
"""Test that the factory implements the 'bind' signal."""
|
||||
with unittest.mock.patch.object(self.factory, "do_bind") as mock_bind:
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.factory.emit("bind", self.listitem)
|
||||
mock_bind.assert_called_with(self.xunitrow,
|
||||
self.listitem.get_child())
|
||||
|
||||
def test_unbind(self):
|
||||
"""Test that the factory implements the 'unbind' signal."""
|
||||
with unittest.mock.patch.object(self.factory,
|
||||
"do_unbind") as mock_unbind:
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.factory.emit("bind", self.listitem)
|
||||
self.listitem.get_child().set_text("text")
|
||||
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
self.assertIsNone(self.listitem.get_child().get_text())
|
||||
mock_unbind.assert_called_with(self.xunitrow,
|
||||
self.listitem.get_child())
|
||||
|
||||
def test_teardown(self):
|
||||
"""Test that the factory implements the 'teardown' signal."""
|
||||
with unittest.mock.patch.object(self.factory,
|
||||
"do_teardown") as mock_teardown:
|
||||
self.factory.emit("setup", self.listitem)
|
||||
child = self.listitem.get_child()
|
||||
self.factory.emit("teardown", self.listitem)
|
||||
self.assertIsNone(self.listitem.get_child())
|
||||
mock_teardown.assert_called_with(child)
|
||||
|
||||
|
||||
class TestLabelFactory(unittest.TestCase):
|
||||
"""Tests our Gtk.Factory to make Gtk.Labels."""
|
||||
|
||||
|
@ -15,12 +75,12 @@ class TestLabelFactory(unittest.TestCase):
|
|||
self.listitem = Gtk.ListItem()
|
||||
self.listitem.get_item = unittest.mock.Mock(return_value=self.testcase)
|
||||
|
||||
self.factory = xfstestsdb.gtk.row.LabelFactory("name")
|
||||
self.factory = xfstestsdb.gtk.row.LabelFactory(property="name")
|
||||
self.group = xfstestsdb.gtk.row.LabelFactory.group
|
||||
|
||||
def test_init(self):
|
||||
"""Test that the factory was initialized correctly."""
|
||||
self.assertIsInstance(self.factory, Gtk.SignalListItemFactory)
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.Factory)
|
||||
self.assertEqual(self.factory.property, "name")
|
||||
|
||||
def test_size_group(self):
|
||||
|
@ -33,8 +93,6 @@ class TestLabelFactory(unittest.TestCase):
|
|||
def test_setup(self):
|
||||
"""Test that the factory implements the 'setup' signal."""
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.assertIsInstance(self.listitem.get_child(), Gtk.Label)
|
||||
self.assertTrue(self.listitem.get_child().has_css_class("numeric"))
|
||||
self.assertIn(self.listitem.get_child(), self.group.get_widgets())
|
||||
|
||||
def test_bind(self):
|
||||
|
@ -50,14 +108,13 @@ class TestLabelFactory(unittest.TestCase):
|
|||
self.factory.emit("setup", self.listitem)
|
||||
self.factory.emit("bind", self.listitem)
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "")
|
||||
self.assertIsNone(self.listitem.get_child().get_text())
|
||||
|
||||
def test_teardown(self):
|
||||
"""Test that the factory implements the 'teardown' signal."""
|
||||
self.factory.emit("setup", self.listitem)
|
||||
child = self.listitem.get_child()
|
||||
self.factory.emit("teardown", self.listitem)
|
||||
self.assertIsNone(self.listitem.get_child())
|
||||
self.assertNotIn(child, self.group.get_widgets())
|
||||
|
||||
def test_styles(self):
|
||||
|
@ -79,6 +136,31 @@ class TestLabelFactory(unittest.TestCase):
|
|||
self.assertFalse(child.has_css_class(expected))
|
||||
|
||||
|
||||
class TestPropertyFactory(unittest.TestCase):
|
||||
"""Tests our Gtk.Factory to show xunit properties."""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up common variables."""
|
||||
self.property = xfstestsdb.gtk.model.Property("property")
|
||||
self.listitem = Gtk.ListItem()
|
||||
self.listitem.get_item = unittest.mock.Mock(return_value=self.property)
|
||||
|
||||
self.factory = xfstestsdb.gtk.row.PropertyFactory("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")
|
||||
|
||||
def test_bind_different(self):
|
||||
"""Test binding to the a property when all values are different."""
|
||||
self.property.add_xunit("xunit-1", "property", "value")
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.factory.emit("bind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "value")
|
||||
self.assertEqual(self.listitem.get_child().get_tooltip_text(), "value")
|
||||
|
||||
|
||||
class TestResultFactory(unittest.TestCase):
|
||||
"""Tests our Gtk.Factory to show test results."""
|
||||
|
||||
|
@ -99,16 +181,9 @@ class TestResultFactory(unittest.TestCase):
|
|||
|
||||
def test_init(self):
|
||||
"""Test that the factory was initialized correctly."""
|
||||
self.assertIsInstance(self.factory, Gtk.SignalListItemFactory)
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.Factory)
|
||||
self.assertEqual(self.factory.xunit, "xunit-1")
|
||||
|
||||
def test_setup(self):
|
||||
"""Test that the factory implements the 'setup' signal."""
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.assertIsInstance(self.listitem.get_child(), Gtk.Label)
|
||||
self.assertTrue(self.listitem.get_child().has_css_class("numeric"))
|
||||
self.assertEqual(self.parent.get_child(), self.listitem.get_child())
|
||||
|
||||
def test_bind_passed(self):
|
||||
"""Test binding to a passing test."""
|
||||
self.testcase.add_xunit("xunit-1", "passed", 3, "", None, None)
|
||||
|
@ -119,7 +194,6 @@ class TestResultFactory(unittest.TestCase):
|
|||
self.assertTrue(self.parent.has_css_class("passed"))
|
||||
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "")
|
||||
self.assertFalse(self.parent.has_css_class("passed"))
|
||||
|
||||
def test_bind_skipped(self):
|
||||
|
@ -134,7 +208,6 @@ class TestResultFactory(unittest.TestCase):
|
|||
self.assertTrue(self.parent.has_css_class("skipped"))
|
||||
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "")
|
||||
self.assertFalse(self.parent.has_css_class("skipped"))
|
||||
|
||||
def test_bind_failed(self):
|
||||
|
@ -149,23 +222,16 @@ class TestResultFactory(unittest.TestCase):
|
|||
self.assertTrue(self.parent.has_css_class("failure"))
|
||||
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "")
|
||||
self.assertFalse(self.parent.has_css_class("failure"))
|
||||
|
||||
def test_bind_missing(self):
|
||||
"""Test binding to a missing test."""
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.factory.emit("bind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "")
|
||||
self.assertIsNone(self.listitem.get_child().get_text())
|
||||
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
|
||||
def test_teardown(self):
|
||||
"""Test that the factory implements the 'teardown' signal."""
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.factory.emit("teardown", self.listitem)
|
||||
self.assertIsNone(self.listitem.get_child())
|
||||
|
||||
|
||||
class TestSummaryFactory(unittest.TestCase):
|
||||
"""Tests our Gtk.Factory to show Xfstests results summaries."""
|
||||
|
@ -180,15 +246,9 @@ class TestSummaryFactory(unittest.TestCase):
|
|||
|
||||
def test_init(self):
|
||||
"""Test that the factory was initialized correctly."""
|
||||
self.assertIsInstance(self.factory, Gtk.SignalListItemFactory)
|
||||
self.assertIsInstance(self.factory, xfstestsdb.gtk.row.Factory)
|
||||
self.assertEqual(self.factory.xunit, "xunit-1")
|
||||
|
||||
def test_setup(self):
|
||||
"""Test that the factory implements the 'setup' signal."""
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.assertIsInstance(self.listitem.get_child(), Gtk.Label)
|
||||
self.assertTrue(self.listitem.get_child().has_css_class("numeric"))
|
||||
|
||||
def test_bind_passed(self):
|
||||
"""Test binding to the passed tests summary."""
|
||||
self.summary.add_xunit("xunit-1", 1, "testcase")
|
||||
|
@ -198,7 +258,6 @@ class TestSummaryFactory(unittest.TestCase):
|
|||
self.assertTrue(self.listitem.get_child().has_css_class("success"))
|
||||
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "")
|
||||
self.assertFalse(self.listitem.get_child().has_css_class("success"))
|
||||
|
||||
def test_bind_failed(self):
|
||||
|
@ -211,7 +270,6 @@ class TestSummaryFactory(unittest.TestCase):
|
|||
self.assertTrue(self.listitem.get_child().has_css_class("error"))
|
||||
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "")
|
||||
self.assertFalse(self.listitem.get_child().has_css_class("error"))
|
||||
|
||||
def test_bind_skipped(self):
|
||||
|
@ -224,7 +282,6 @@ class TestSummaryFactory(unittest.TestCase):
|
|||
self.assertTrue(self.listitem.get_child().has_css_class("warning"))
|
||||
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "")
|
||||
self.assertFalse(self.listitem.get_child().has_css_class("warning"))
|
||||
|
||||
def test_bind_time(self):
|
||||
|
@ -237,11 +294,4 @@ class TestSummaryFactory(unittest.TestCase):
|
|||
self.assertTrue(self.listitem.get_child().has_css_class("accent"))
|
||||
|
||||
self.factory.emit("unbind", self.listitem)
|
||||
self.assertEqual(self.listitem.get_child().get_text(), "")
|
||||
self.assertFalse(self.listitem.get_child().has_css_class("accent"))
|
||||
|
||||
def test_teardown(self):
|
||||
"""Test that the factory implements the 'teardown' signal."""
|
||||
self.factory.emit("setup", self.listitem)
|
||||
self.factory.emit("teardown", self.listitem)
|
||||
self.assertIsNone(self.listitem.get_child())
|
||||
|
|
|
@ -6,6 +6,86 @@ import xfstestsdb.gtk.view
|
|||
from gi.repository import Gtk
|
||||
|
||||
|
||||
class TestPropertyView(unittest.TestCase):
|
||||
"""Tests the PropertyView."""
|
||||
|
||||
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.PropertyList(self.xfstestsdb.sql, 1)
|
||||
self.view = xfstestsdb.gtk.view.PropertyView()
|
||||
|
||||
def test_init(self):
|
||||
"""Test that we created the ProeprtyView 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."""
|
||||
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.assertTrue(self.view.props.child.has_css_class("data-table"))
|
||||
|
||||
def test_filter(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.assertEqual(self.view.props.child.get_model().get_model(),
|
||||
self.view._filtermodel)
|
||||
self.assertEqual(self.view._filtermodel.props.filter,
|
||||
self.view._propfilter)
|
||||
|
||||
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,
|
||||
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)
|
||||
|
||||
def test_model(self):
|
||||
"""Test setting the model property."""
|
||||
self.view.model = self.model
|
||||
self.assertEqual(self.view._filtermodel.props.model, self.model)
|
||||
|
||||
columns = self.view.props.child.get_columns()
|
||||
self.assertEqual(len(columns), 3)
|
||||
self.assertEqual(columns[0], self.view._property)
|
||||
|
||||
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)
|
||||
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._property)
|
||||
|
||||
|
||||
class TestFilterButtons(unittest.TestCase):
|
||||
"""Test case for our TestCaseView FilterButtons."""
|
||||
|
||||
|
@ -237,6 +317,7 @@ class TestXfstestsView(unittest.TestCase):
|
|||
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 = xfstestsdb.gtk.model.TestCaseList(self.xfstestsdb.sql, 1)
|
||||
self.summary = xfstestsdb.gtk.model.SummaryList(self.xfstestsdb.sql, 1)
|
||||
self.view = xfstestsdb.gtk.view.XfstestsView()
|
||||
|
@ -246,11 +327,19 @@ class TestXfstestsView(unittest.TestCase):
|
|||
self.assertIsInstance(self.view, Gtk.Box)
|
||||
self.assertEqual(self.view.props.orientation, Gtk.Orientation.VERTICAL)
|
||||
|
||||
def test_property_view(self):
|
||||
"""Check that the XfstestsView sets up a PropertyView correctly."""
|
||||
self.assertIsInstance(self.view._propertyview,
|
||||
xfstestsdb.gtk.view.PropertyView)
|
||||
self.assertEqual(self.view.get_first_child(), self.view._propertyview)
|
||||
|
||||
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(self.view.get_first_child(), self.view._testcaseview)
|
||||
self.assertEqual(sep.get_next_sibling(), self.view._testcaseview)
|
||||
|
||||
def test_summary_view(self):
|
||||
"""Check that the XfstestsView sets up a SummaryView correctly."""
|
||||
|
@ -260,6 +349,12 @@ class TestXfstestsView(unittest.TestCase):
|
|||
xfstestsdb.gtk.view.SummaryView)
|
||||
self.assertEqual(sep.get_next_sibling(), self.view._summaryview)
|
||||
|
||||
def test_properties(self):
|
||||
"""Test the XfstestsView 'properties' property."""
|
||||
self.assertIsNone(self.view.properties)
|
||||
self.view.properties = self.props
|
||||
self.assertEqual(self.view._propertyview.model, self.props)
|
||||
|
||||
def test_model(self):
|
||||
"""Test the XfstestsView 'model' property."""
|
||||
self.assertIsNone(self.view.model)
|
||||
|
|
|
@ -16,8 +16,8 @@ class TestWindow(unittest.TestCase):
|
|||
def test_init(self):
|
||||
"""Check that the Window is set up correctly."""
|
||||
self.assertIsInstance(self.window, Adw.Window)
|
||||
self.assertEqual(self.window.props.default_height, 800)
|
||||
self.assertEqual(self.window.props.default_width, 1200)
|
||||
self.assertEqual(self.window.props.default_height, 1000)
|
||||
self.assertEqual(self.window.props.default_width, 1600)
|
||||
self.assertTrue(self.window.has_css_class("devel"))
|
||||
|
||||
self.assertIsInstance(self.window.props.content, Gtk.Box)
|
||||
|
|
|
@ -27,6 +27,7 @@ class TestApplication(unittest.TestCase):
|
|||
self.assertEqual(self.application.get_resource_base_path(),
|
||||
xfstestsdb.gtk.gsetup.RESOURCE_PATH)
|
||||
self.assertEqual(self.application.runid, 0)
|
||||
self.assertIsNone(self.application.properties)
|
||||
self.assertIsNone(self.application.model)
|
||||
self.assertIsNone(self.application.summary)
|
||||
|
||||
|
@ -43,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.properties)
|
||||
self.assertIsNone(self.application.model)
|
||||
self.assertIsNone(self.application.summary)
|
||||
|
||||
|
@ -56,6 +58,8 @@ class TestApplication(unittest.TestCase):
|
|||
mock_cmd.get_arguments.assert_called()
|
||||
mock_activate.assert_called()
|
||||
self.assertEqual(self.application.runid, 42)
|
||||
self.assertIsInstance(self.application.properties,
|
||||
xfstestsdb.gtk.model.PropertyList)
|
||||
self.assertIsInstance(self.application.model,
|
||||
xfstestsdb.gtk.model.TestCaseList)
|
||||
self.assertIsInstance(self.application.summary,
|
||||
|
@ -86,6 +90,10 @@ class TestApplication(unittest.TestCase):
|
|||
self.application.runid = 42
|
||||
self.assertEqual(self.application.win.runid, 42)
|
||||
|
||||
properties = xfstestsdb.gtk.model.PropertyList(self.xfstestsdb.sql, 42)
|
||||
self.application.properties = properties
|
||||
self.assertEqual(self.application.view.properties, properties)
|
||||
|
||||
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, 3)
|
||||
self.assertEqual(xfstestsdb.MINOR, 4)
|
||||
|
||||
self.xfstestsdb.run(["--version"])
|
||||
self.assertEqual(mock_stdout.getvalue(), "xfstestsdb v1.3-debug\n")
|
||||
self.assertEqual(mock_stdout.getvalue(), "xfstestsdb v1.4-debug\n")
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
import pathlib
|
||||
|
||||
XUNIT_1 = pathlib.Path(__file__).parent / "test-1.xunit"
|
||||
XUNIT_2 = pathlib.Path(__file__).parent / "test-2.xunit"
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuite
|
||||
xmlns="https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/tree/doc/xunit.xsd"
|
||||
|
||||
name="xfstests"
|
||||
failures="1" skipped="3" tests="10" time="43"
|
||||
hostname="myhost"
|
||||
start_timestamp="2023-01-31T14:14:14-05:00"
|
||||
timestamp="2023-01-31T14:14:55-05:00"
|
||||
report_timestamp="2023-01-31T14:14:57-05:00"
|
||||
>
|
||||
<properties>
|
||||
<property name="SECTION" value="-no-sections-"/>
|
||||
<property name="FSTYP" value="myfs"/>
|
||||
<property name="PLATFORM" value="Linux/x86_64 myhost 6.1.8-arch1"/>
|
||||
<property name="MOUNT_OPTIONS" value="-o mountopt1,mountopt3"/>
|
||||
<property name="HOST_OPTIONS" value="local.config"/>
|
||||
<property name="CHECK_OPTIONS" value="-r -R xunit -g quick"/>
|
||||
<property name="TIME_FACTOR" value="1"/>
|
||||
<property name="LOAD_FACTOR" value="1"/>
|
||||
<property name="TEST_DIR" value="/mnt/test2"/>
|
||||
<property name="TEST_DEV" value="/dev/vdb3"/>
|
||||
<property name="SCRATCH_DEV" value="/dev/vdb4"/>
|
||||
<property name="SCRATCH_MNT" value="/mnt/scratch2"/>
|
||||
<property name="OVL_UPPER" value="ovl-upper"/>
|
||||
<property name="OVL_LOWER" value="ovl-lower"/>
|
||||
<property name="OVL_WORK" value="ovl-work"/>
|
||||
</properties>
|
||||
<testcase classname="xfstests.global" name="test/01" time="1">
|
||||
</testcase>
|
||||
<testcase classname="xfstests.global" name="test/02" time="0">
|
||||
<skipped message="skipped on /dev/vdb1" />
|
||||
</testcase>
|
||||
<testcase classname="xfstests.global" name="test/03" time="0">
|
||||
<skipped message="skipped on /mnt/test too" />
|
||||
</testcase>
|
||||
<testcase classname="xfstests.global" name="test/04" time="4">
|
||||
</testcase>
|
||||
<testcase classname="xfstests.global" name="test/05" time="5">
|
||||
</testcase>
|
||||
<testcase classname="xfstests.global" name="test/06" time="6">
|
||||
</testcase>
|
||||
<testcase classname="xfstests.global" name="test/07" time="0">
|
||||
<skipped message="fstype "myfs" gets skipped" />
|
||||
</testcase>
|
||||
<testcase classname="xfstests.global" name="test/08" time="8">
|
||||
</testcase>
|
||||
<testcase classname="xfstests.global" name="test/09" time="9">
|
||||
<failure message="- output mismatch (see somefile)" type="TestFail" />
|
||||
<system-out>
|
||||
<![CDATA[
|
||||
there was a problem with '/dev/vdb2'
|
||||
]]>
|
||||
</system-out>
|
||||
<system-err>
|
||||
<![CDATA[
|
||||
--- test/09.out 2023-01-31 14:14:14.141414 -1414
|
||||
+++ results/some/sub/dir/test/09.out.bad 2023-02-02 16:16:16.161616 -1616
|
||||
there was a problem with '/mnt/scratch'
|
||||
]]>
|
||||
</system-err>
|
||||
|
||||
</testcase>
|
||||
<testcase classname="xfstests.global" name="test/10" time="10">
|
||||
</testcase>
|
||||
</testsuite>
|
|
@ -15,7 +15,7 @@ from . import untag
|
|||
from . import xunit
|
||||
|
||||
MAJOR = 1
|
||||
MINOR = 3
|
||||
MINOR = 4
|
||||
|
||||
|
||||
class Command:
|
||||
|
|
|
@ -18,6 +18,7 @@ class Application(Adw.Application):
|
|||
"""Our Adw.Application for displaying xfstests results."""
|
||||
|
||||
runid = GObject.Property(type=int)
|
||||
properties = GObject.Property(type=model.PropertyList)
|
||||
summary = GObject.Property(type=model.SummaryList)
|
||||
model = GObject.Property(type=model.TestCaseList)
|
||||
win = GObject.Property(type=window.Window)
|
||||
|
@ -40,6 +41,7 @@ class Application(Adw.Application):
|
|||
match split[0]:
|
||||
case "runid":
|
||||
self.runid = int(split[1])
|
||||
self.properties = model.PropertyList(self.sql, self.runid)
|
||||
self.model = model.TestCaseList(self.sql, self.runid)
|
||||
self.summary = model.SummaryList(self.sql, self.runid)
|
||||
|
||||
|
@ -56,6 +58,7 @@ class Application(Adw.Application):
|
|||
self.win.headerbar.pack_end(self.view.filterbuttons)
|
||||
|
||||
self.bind_property("runid", self.win, "runid")
|
||||
self.bind_property("properties", self.view, "properties")
|
||||
self.bind_property("model", self.view, "model")
|
||||
self.bind_property("summary", self.view, "summary")
|
||||
self.add_window(self.win)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Copyright 2023 (c) Anna Schumaker.
|
||||
"""Our Testcase Gio.ListModel."""
|
||||
import sqlite3
|
||||
import typing
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gio
|
||||
|
@ -7,91 +8,184 @@ from gi.repository import Gtk
|
|||
from .. import sqlite
|
||||
|
||||
|
||||
class XunitResult(GObject.GObject):
|
||||
"""The results for a single TestCase with a specific Xunit."""
|
||||
class XunitCell(GObject.GObject):
|
||||
"""Holds a single value for a single Xunit."""
|
||||
|
||||
name = GObject.Property(type=str)
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Get a string representation of this XunitCell."""
|
||||
return self.name
|
||||
|
||||
|
||||
class XunitRow(GObject.GObject):
|
||||
"""Collects results for a single row across multiple Xunits."""
|
||||
|
||||
name = GObject.Property(type=str)
|
||||
|
||||
def __init__(self, name: str) -> None:
|
||||
"""Initialize an XunitRow."""
|
||||
super().__init__(name=name)
|
||||
self.__xunits = {}
|
||||
|
||||
def __getitem__(self, xunit: str) -> XunitCell | None:
|
||||
"""Get the value of a specific Xunit."""
|
||||
return self.__xunits.get(xunit)
|
||||
|
||||
def __lt__(self, rhs: typing.Self) -> bool:
|
||||
"""Compare the names of two XunitRows."""
|
||||
return self.name < rhs.name
|
||||
|
||||
def add_xunit(self, name: str, *args, **kwargs) -> None:
|
||||
"""Add an XunitCell to the XunitRow."""
|
||||
self.__xunits[name] = self.do_make_xunit(name, *args, **kwargs)
|
||||
|
||||
def do_make_xunit(self, name: str) -> XunitCell:
|
||||
"""Create and return a new XunitCell."""
|
||||
return XunitCell(name=name)
|
||||
|
||||
def get_results(self) -> set[str]:
|
||||
"""Get a set of results for each added xunit."""
|
||||
return {str(xunit) for xunit in self.__xunits.values()}
|
||||
|
||||
|
||||
class XunitList(GObject.GObject, Gio.ListModel):
|
||||
"""A list of XunitRows for a specific Xfstests Run."""
|
||||
|
||||
runid = GObject.Property(type=int)
|
||||
n_items = GObject.Property(type=int)
|
||||
|
||||
def __init__(self, sql: sqlite.Connection, runid: int) -> None:
|
||||
"""Initialize an XunitList."""
|
||||
super().__init__(runid=runid)
|
||||
self.__xunits = set()
|
||||
|
||||
rows = {}
|
||||
for row in self.do_query(sql).fetchall():
|
||||
self.do_parse(rows, row)
|
||||
self.__xunits.add(row["xunit"])
|
||||
|
||||
self.__items = sorted(rows.values())
|
||||
self.n_items = len(self.__items)
|
||||
|
||||
def do_get_item_type(self) -> GObject.GType:
|
||||
"""Get the type of the objects in the list."""
|
||||
return XunitRow.__gtype__
|
||||
|
||||
def do_get_n_items(self) -> int:
|
||||
"""Get the number of items in the list."""
|
||||
return self.n_items
|
||||
|
||||
def do_get_item(self, n: int) -> XunitRow | None:
|
||||
"""Get a specific item on the list."""
|
||||
return self.__items[n] if n < self.n_items else None
|
||||
|
||||
def do_parse(self, rows: dict[XunitRow], row: sqlite3.Row) -> None:
|
||||
"""Parse a sqlite3.Row and add it to the rows dict."""
|
||||
|
||||
def do_query(self, sql: sqlite.Connection) -> sqlite3.Cursor:
|
||||
"""Query the database."""
|
||||
return sql("SELECT name AS xunit FROM xunits WHERE runid=?",
|
||||
self.runid)
|
||||
|
||||
def get_xunits(self) -> list[str]:
|
||||
"""Get a list of xunits attached to this xfstests run."""
|
||||
return sorted(self.__xunits)
|
||||
|
||||
|
||||
class PropertyValue(XunitCell):
|
||||
"""A single Property for a specific Xunit."""
|
||||
|
||||
key = GObject.Property(type=str)
|
||||
value = GObject.Property(type=str)
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Get a string representation of this Property."""
|
||||
return f"{self.key} = {self.value}"
|
||||
|
||||
|
||||
class Property(XunitRow):
|
||||
"""Collects one property across multiple xunits."""
|
||||
|
||||
def do_make_xunit(self, name: str, key: str, value: str) -> PropertyValue:
|
||||
"""Add a PropertyValue to the Property."""
|
||||
return PropertyValue(name=name, key=key, value=value)
|
||||
|
||||
def all_same_value(self) -> bool:
|
||||
"""Check if all the xunits have the same value."""
|
||||
return len(self.get_results()) == 1
|
||||
|
||||
|
||||
class PropertyList(XunitList):
|
||||
"""A list of Properties for a specific Xfstests Run."""
|
||||
|
||||
def do_query(self, sql: sqlite.Connection) -> sqlite3.Cursor:
|
||||
"""Query the database for properties."""
|
||||
return sql("""SELECT xunit, key, value FROM xunit_properties_view
|
||||
WHERE runid=?""", self.runid)
|
||||
|
||||
def do_parse(self, rows: dict[Property], row: sqlite3.Cursor) -> None:
|
||||
"""Parse the data in the row and add it to the rows dict."""
|
||||
property = rows.setdefault(row["key"], Property(row["key"]))
|
||||
property.add_xunit(row["xunit"], row["key"], row["value"])
|
||||
|
||||
|
||||
class PropertyFilter(Gtk.Filter):
|
||||
"""A filter for Properties."""
|
||||
|
||||
def do_get_strictness(self) -> Gtk.FilterMatch:
|
||||
"""Get the strictness of the filter."""
|
||||
return Gtk.FilterMatch.SOME
|
||||
|
||||
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
|
||||
|
||||
|
||||
class TestResult(XunitCell):
|
||||
"""The results for a single TestCase with a specific Xunit."""
|
||||
|
||||
status = GObject.Property(type=str)
|
||||
time = GObject.Property(type=int)
|
||||
message = GObject.Property(type=str)
|
||||
stdout = GObject.Property(type=str)
|
||||
stderr = GObject.Property(type=str)
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Get a string representation of this TestResult."""
|
||||
return self.status
|
||||
|
||||
class TestCase(GObject.GObject):
|
||||
|
||||
class TestCase(XunitRow):
|
||||
"""Collects results for a single TestCase with multiple Xunits."""
|
||||
|
||||
name = GObject.Property(type=str)
|
||||
|
||||
def __init__(self, name: str) -> None:
|
||||
"""Initialize a TestCase object."""
|
||||
super().__init__(name=name)
|
||||
self.__xunits = {}
|
||||
|
||||
def __getitem__(self, xunit: str) -> XunitResult | None:
|
||||
"""Get the results for a specific Xunit."""
|
||||
return self.__xunits.get(xunit)
|
||||
|
||||
def __lt__(self, rhs: typing.Self) -> bool:
|
||||
"""Compare the names of two TestCases."""
|
||||
return self.name < rhs.name
|
||||
|
||||
def add_xunit(self, name: str, status: str, time: int,
|
||||
message: str | None, stdout: str | None,
|
||||
stderr: str | None) -> None:
|
||||
def do_make_xunit(self, name: str, status: str, time: int,
|
||||
message: str | None, stdout: str | None,
|
||||
stderr: str | None) -> TestResult:
|
||||
"""Add an xunit result to the TestCase."""
|
||||
message = "" if message is None else message
|
||||
stdout = "" if stdout is None else stdout
|
||||
stderr = "" if stderr is None else stderr
|
||||
self.__xunits[name] = XunitResult(name=name, status=status, time=time,
|
||||
message=message, stdout=stdout,
|
||||
stderr=stderr)
|
||||
|
||||
def get_results(self) -> set[str]:
|
||||
"""Get a set of results for each added xunit."""
|
||||
return {xunit.status for xunit in self.__xunits.values()}
|
||||
return TestResult(name=name, status=status, time=time,
|
||||
message=("" if message is None else message),
|
||||
stdout=("" if stdout is None else stdout),
|
||||
stderr=("" if stderr is None else stderr))
|
||||
|
||||
|
||||
class TestCaseList(GObject.GObject, Gio.ListModel):
|
||||
class TestCaseList(XunitList):
|
||||
"""A list of TestCases for a specific Xfstests Run."""
|
||||
|
||||
runid = GObject.Property(type=int)
|
||||
n_items = GObject.Property(type=int)
|
||||
def do_query(self, sql: sqlite.Connection) -> sqlite3.Cursor:
|
||||
"""Query the database for testcase results."""
|
||||
return sql("""SELECT testcase, xunit, status, time,
|
||||
message, stdout, stderr
|
||||
FROM testcases_view WHERE runid=?""", self.runid)
|
||||
|
||||
def __init__(self, sql: sqlite.Connection, runid: int) -> None:
|
||||
"""Initialize a TestCaseList."""
|
||||
super().__init__(runid=runid)
|
||||
self.__xunits = set()
|
||||
|
||||
cases = {}
|
||||
cur = sql("""SELECT testcase, xunit, status,
|
||||
time, message, stdout, stderr
|
||||
FROM testcases_view WHERE runid=?""", runid)
|
||||
for row in cur.fetchall():
|
||||
testcase = cases.setdefault(row["testcase"],
|
||||
TestCase(row["testcase"]))
|
||||
testcase.add_xunit(row["xunit"], row["status"], row["time"],
|
||||
row["message"], row["stdout"], row["stderr"])
|
||||
self.__xunits.add(row["xunit"])
|
||||
|
||||
self.__items = sorted(cases.values())
|
||||
self.n_items = len(self.__items)
|
||||
|
||||
def do_get_item_type(self) -> GObject.GType:
|
||||
"""Get the type of the objects in the list."""
|
||||
return TestCase.__gtype__
|
||||
|
||||
def do_get_n_items(self) -> int:
|
||||
"""Get the number of items in the list."""
|
||||
return self.n_items
|
||||
|
||||
def do_get_item(self, n: int) -> TestCase | None:
|
||||
"""Get a specific item on the list."""
|
||||
return self.__items[n] if n < self.n_items else None
|
||||
|
||||
def get_xunits(self) -> list[str]:
|
||||
"""Get a list of xunits attached to this xfstests run."""
|
||||
return sorted(self.__xunits)
|
||||
def do_parse(self, rows: dict[TestCase], row: sqlite3.Cursor) -> None:
|
||||
"""Parse the data in the row and add it to the rows dict."""
|
||||
testcase = rows.setdefault(row["testcase"], TestCase(row["testcase"]))
|
||||
testcase.add_xunit(row["xunit"], row["status"], row["time"],
|
||||
row["message"], row["stdout"], row["stderr"])
|
||||
|
||||
|
||||
class TestCaseFilter(Gtk.Filter):
|
||||
|
@ -134,7 +228,7 @@ class TestCaseFilter(Gtk.Filter):
|
|||
return False
|
||||
|
||||
|
||||
class SummaryValue(GObject.GObject):
|
||||
class SummaryValue(XunitCell):
|
||||
"""The summary of a single Xfstests xunit field."""
|
||||
|
||||
name = GObject.Property(type=str)
|
||||
|
@ -147,70 +241,30 @@ class SummaryValue(GObject.GObject):
|
|||
return f"{self.value} {self.unit}{s}"
|
||||
|
||||
|
||||
class Summary(GObject.GObject):
|
||||
class Summary(XunitRow):
|
||||
"""Collects values for each summary field with multiple Xunits."""
|
||||
|
||||
name = GObject.Property(type=str)
|
||||
|
||||
def __init__(self, name: str) -> None:
|
||||
"""Initialize a Summary object."""
|
||||
super().__init__(name=name)
|
||||
self.__xunits = {}
|
||||
|
||||
def __getitem__(self, xunit: str) -> SummaryValue | None:
|
||||
"""Get the summary for a specific Xunit."""
|
||||
return self.__xunits.get(xunit)
|
||||
|
||||
def __lt__(self, rhs: typing.Self) -> bool:
|
||||
"""Compare the fields of two Summaries."""
|
||||
order = ["passed", "failed", "skipped", "time"]
|
||||
return order.index(self.name) < order.index(rhs.name)
|
||||
|
||||
def add_xunit(self, name: str, value: int, unit: str) -> None:
|
||||
def do_make_xunit(self, name: str, value: int, unit: str) -> SummaryValue:
|
||||
"""Add an xunit summary to the Summary."""
|
||||
self.__xunits[name] = SummaryValue(name=name, value=value, unit=unit)
|
||||
|
||||
def get_results(self) -> set[str]:
|
||||
"""Get a set of results for each added xunit."""
|
||||
return {str(value) for value in self.__xunits.values()}
|
||||
return SummaryValue(name=name, value=value, unit=unit)
|
||||
|
||||
|
||||
class SummaryList(GObject.GObject, Gio.ListModel):
|
||||
class SummaryList(XunitList):
|
||||
"""A list summarizing the results of a specific Xfstests Run."""
|
||||
|
||||
runid = GObject.Property(type=int)
|
||||
n_items = GObject.Property(type=int)
|
||||
def do_query(self, sql: sqlite.Connection) -> sqlite3.Cursor:
|
||||
"""Query the database for xunit summaries."""
|
||||
return sql("""SELECT name AS xunit, passed, failed, skipped, time
|
||||
FROM xunits_view WHERE runid=?""", self.runid)
|
||||
|
||||
def __init__(self, sql: sqlite.Connection, runid: int) -> None:
|
||||
"""Initialize a SummaryList."""
|
||||
super().__init__(runid=runid)
|
||||
self.__xunits = set()
|
||||
|
||||
results = {}
|
||||
cur = sql("""SELECT name AS xunit, passed, failed, skipped, time
|
||||
FROM xunits_view WHERE runid=?""", runid)
|
||||
for row in cur.fetchall():
|
||||
for field in ["passed", "failed", "skipped", "time"]:
|
||||
summary = results.setdefault(field, Summary(field))
|
||||
summary.add_xunit(row["xunit"], row[field],
|
||||
"second" if field == "time" else "testcase")
|
||||
self.__xunits.add(row["xunit"])
|
||||
|
||||
self.__items = sorted(results.values())
|
||||
self.n_items = len(self.__items)
|
||||
|
||||
def do_get_item_type(self) -> GObject.GType:
|
||||
"""Get the type of the objects in the list."""
|
||||
return Summary.__gtype__
|
||||
|
||||
def do_get_n_items(self) -> int:
|
||||
"""Get the number of items in the list."""
|
||||
return self.n_items
|
||||
|
||||
def do_get_item(self, n: int) -> Summary | None:
|
||||
"""Get a specific item on the list."""
|
||||
return self.__items[n] if n < self.n_items else None
|
||||
|
||||
def get_xunits(self) -> list[str]:
|
||||
"""Get a list of xunits attached to this xfstests run."""
|
||||
return sorted(self.__xunits)
|
||||
def do_parse(self, rows: dict[Summary], row: sqlite3.Row) -> None:
|
||||
"""Parse the data in the row and add it to the rows dict."""
|
||||
for field in ["passed", "failed", "skipped", "time"]:
|
||||
summary = rows.setdefault(field, Summary(field))
|
||||
summary.add_xunit(row["xunit"], row[field],
|
||||
"second" if field == "time" else "testcase")
|
||||
|
|
|
@ -3,13 +3,59 @@
|
|||
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 LabelFactory(Gtk.SignalListItemFactory):
|
||||
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)
|
||||
|
@ -18,42 +64,46 @@ class LabelFactory(Gtk.SignalListItemFactory):
|
|||
def __init__(self, property: str):
|
||||
"""Initialize our InscriptionFactory."""
|
||||
super().__init__(property=property)
|
||||
self.connect("setup", self.do_setup)
|
||||
self.connect("bind", self.do_bind)
|
||||
self.connect("unbind", self.do_unbind)
|
||||
self.connect("teardown", self.do_teardown)
|
||||
|
||||
def do_setup(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
||||
def do_setup(self, child: Gtk.Inscription) -> None:
|
||||
"""Set up a ListItem child widget."""
|
||||
child = Gtk.Label()
|
||||
child.add_css_class("numeric")
|
||||
listitem.set_child(child)
|
||||
LabelFactory.group.add_widget(child)
|
||||
|
||||
def do_bind(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
||||
def do_bind(self, row: model.XunitRow, child: Gtk.Inscription) -> None:
|
||||
"""Bind a ListItem to the child widget."""
|
||||
text = listitem.get_item().get_property(self.property)
|
||||
child = listitem.get_child()
|
||||
text = row.get_property(self.property)
|
||||
if style := STYLES.get(text):
|
||||
child.add_css_class(style)
|
||||
child.set_text(text)
|
||||
|
||||
def do_unbind(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
||||
def do_unbind(self, row: model.XunitRow, child: Gtk.Inscription) -> None:
|
||||
"""Unbind a ListItem from the child widget."""
|
||||
child = listitem.get_child()
|
||||
for style in STYLES.values():
|
||||
child.remove_css_class(style)
|
||||
child.set_text("")
|
||||
|
||||
def do_teardown(self, factory: typing.Self,
|
||||
listitem: Gtk.ListItem) -> None:
|
||||
def do_teardown(self, child: Gtk.Inscription) -> None:
|
||||
"""Clean up a ListItem child widget."""
|
||||
if (child := listitem.get_child()) is not None:
|
||||
if child is not None:
|
||||
LabelFactory.group.remove_widget(child)
|
||||
listitem.set_child(None)
|
||||
|
||||
|
||||
class ResultFactory(Gtk.SignalListItemFactory):
|
||||
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)
|
||||
|
@ -61,43 +111,26 @@ class ResultFactory(Gtk.SignalListItemFactory):
|
|||
def __init__(self, xunit: str):
|
||||
"""Initialize our ResultFactory."""
|
||||
super().__init__(xunit=xunit)
|
||||
self.connect("setup", self.do_setup)
|
||||
self.connect("bind", self.do_bind)
|
||||
self.connect("unbind", self.do_unbind)
|
||||
self.connect("teardown", self.do_teardown)
|
||||
|
||||
def do_setup(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
||||
"""Set up a ListItem child widget."""
|
||||
listitem.set_child(Gtk.Label())
|
||||
listitem.get_child().add_css_class("numeric")
|
||||
|
||||
def do_bind(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
||||
def do_bind(self, row: model.TestCase, child: Gtk.Inscription) -> None:
|
||||
"""Bind a ListItem to the child widget."""
|
||||
if (result := listitem.get_item()[self.xunit]) is None:
|
||||
if (result := row[self.xunit]) is None:
|
||||
return
|
||||
|
||||
if (text := result.status) == "passed":
|
||||
text = f"{result.time} seconds"
|
||||
|
||||
child = listitem.get_child()
|
||||
child.set_text(text)
|
||||
child.set_tooltip_text(result.message.lstrip(" -"))
|
||||
child.get_parent().add_css_class(result.status)
|
||||
|
||||
def do_unbind(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
||||
def do_unbind(self, row: model.TestCase, child: Gtk.Inscription) -> None:
|
||||
"""Unbind a ListItem from the child widget."""
|
||||
if (result := listitem.get_item()[self.xunit]) is not None:
|
||||
child = listitem.get_child()
|
||||
child.set_text("")
|
||||
if (result := row[self.xunit]) is not None:
|
||||
child.get_parent().remove_css_class(result.status)
|
||||
|
||||
def do_teardown(self, factory: typing.Self,
|
||||
listitem: Gtk.ListItem) -> None:
|
||||
"""Clean up a ListItem child widget."""
|
||||
listitem.set_child(None)
|
||||
|
||||
|
||||
class SummaryFactory(Gtk.SignalListItemFactory):
|
||||
class SummaryFactory(Factory):
|
||||
"""Factory for making test summary widgets."""
|
||||
|
||||
xunit = GObject.Property(type=str)
|
||||
|
@ -105,31 +138,13 @@ class SummaryFactory(Gtk.SignalListItemFactory):
|
|||
def __init__(self, xunit: str):
|
||||
"""Initialize our ResultFactory."""
|
||||
super().__init__(xunit=xunit)
|
||||
self.connect("setup", self.do_setup)
|
||||
self.connect("bind", self.do_bind)
|
||||
self.connect("unbind", self.do_unbind)
|
||||
self.connect("teardown", self.do_teardown)
|
||||
|
||||
def do_setup(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
||||
"""Set up a ListItem child widget."""
|
||||
listitem.set_child(Gtk.Label())
|
||||
listitem.get_child().add_css_class("numeric")
|
||||
|
||||
def do_bind(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
||||
def do_bind(self, row: model.Summary, child: Gtk.Inscription) -> None:
|
||||
"""Bind a ListItem to the child widget."""
|
||||
summary = listitem.get_item()
|
||||
result = summary[self.xunit]
|
||||
child = listitem.get_child()
|
||||
result = row[self.xunit]
|
||||
child.set_text(str(result))
|
||||
child.add_css_class(STYLES[summary.name])
|
||||
child.add_css_class(STYLES[row.name])
|
||||
|
||||
def do_unbind(self, factory: typing.Self, listitem: Gtk.ListItem) -> None:
|
||||
def do_unbind(self, row: model.TestCase, child: Gtk.Inscription) -> None:
|
||||
"""Unbind a ListItem from the child widget."""
|
||||
child = listitem.get_child()
|
||||
child.set_text("")
|
||||
child.remove_css_class(STYLES[listitem.get_item().name])
|
||||
|
||||
def do_teardown(self, factory: typing.Self,
|
||||
listitem: Gtk.ListItem) -> None:
|
||||
"""Clean up a ListItem child widget."""
|
||||
listitem.set_child(None)
|
||||
child.remove_css_class(STYLES[row.name])
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
"""A view widget used to display our TestCaseModel."""
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gtk
|
||||
from .model import PropertyList
|
||||
from .model import PropertyFilter
|
||||
from .model import TestCaseList
|
||||
from .model import TestCaseFilter
|
||||
from .model import SummaryList
|
||||
|
@ -9,6 +11,48 @@ from . import button
|
|||
from . import row
|
||||
|
||||
|
||||
class PropertyView(Gtk.ScrolledWindow):
|
||||
"""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)
|
||||
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))
|
||||
|
||||
|
||||
class FilterButtons(Gtk.Box):
|
||||
"""Buttons for controlling the TestCaseFilter."""
|
||||
|
||||
|
@ -124,18 +168,23 @@ class SummaryView(Gtk.ScrolledWindow):
|
|||
class XfstestsView(Gtk.Box):
|
||||
"""A widget to display the results of an Xfstests runs."""
|
||||
|
||||
properties = GObject.Property(type=PropertyList)
|
||||
model = GObject.Property(type=TestCaseList)
|
||||
summary = GObject.Property(type=SummaryList)
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize an XfstestsView."""
|
||||
super().__init__(orientation=Gtk.Orientation.VERTICAL)
|
||||
self._propertyview = PropertyView()
|
||||
self._testcaseview = TestCaseView()
|
||||
self._summaryview = SummaryView()
|
||||
|
||||
self.bind_property("properties", self._propertyview, "model")
|
||||
self.bind_property("model", self._testcaseview, "model")
|
||||
self.bind_property("summary", self._summaryview, "model")
|
||||
|
||||
self.append(self._propertyview)
|
||||
self.append(Gtk.Separator())
|
||||
self.append(self._testcaseview)
|
||||
self.append(Gtk.Separator())
|
||||
self.append(self._summaryview)
|
||||
|
|
|
@ -16,7 +16,7 @@ class Window(Adw.Window):
|
|||
|
||||
def __init__(self, **kwargs):
|
||||
"""Set up our Window."""
|
||||
super().__init__(default_height=800, default_width=1200,
|
||||
super().__init__(default_height=1000, default_width=1600,
|
||||
content=Gtk.Box(orientation=Gtk.Orientation.VERTICAL),
|
||||
title=Adw.WindowTitle(title="xfstestsdb gtk"),
|
||||
headerbar=Adw.HeaderBar(), **kwargs)
|
||||
|
|
Loading…
Reference in New Issue