591 lines
23 KiB
Python
591 lines
23 KiB
Python
# Copyright 2022 (c) Anna Schumaker
|
|
"""Tests our database object base classes."""
|
|
import unittest
|
|
import unittest.mock
|
|
import emmental.db.table
|
|
import emmental.store
|
|
import tests.util.table
|
|
from gi.repository import GObject
|
|
from gi.repository import Gio
|
|
from gi.repository import Gtk
|
|
|
|
|
|
class TestRow(unittest.TestCase):
|
|
"""Tests our common database Row object."""
|
|
|
|
def setUp(self):
|
|
"""Set up common variables."""
|
|
self.table = Gio.ListStore()
|
|
self.table.delete = unittest.mock.Mock(return_value=True)
|
|
self.table.update = unittest.mock.Mock(return_value=True)
|
|
self.row = tests.util.table.MockRow(table=self.table)
|
|
|
|
def test_init(self):
|
|
"""Test that the database Row is configured correctly."""
|
|
self.assertIsInstance(self.row, emmental.db.table.Row)
|
|
self.assertIsInstance(self.row, GObject.GObject)
|
|
self.assertEqual(self.row.table, self.table)
|
|
|
|
def test_primary_key(self):
|
|
"""Test the primary_key property."""
|
|
with self.assertRaises(NotImplementedError):
|
|
emmental.db.table.Row(self.table).primary_key
|
|
|
|
self.row.number = 2
|
|
self.assertEqual(self.row.primary_key, 2)
|
|
|
|
def test_do_update(self):
|
|
"""Test updating a Row attribute."""
|
|
self.row.number = 1
|
|
self.table.update.assert_called_with(self.row, "number", 1)
|
|
|
|
self.table.update.reset_mock()
|
|
self.row.table = None
|
|
self.table.update.assert_not_called()
|
|
|
|
def test_delete(self):
|
|
"""Test deleting a Row."""
|
|
self.assertTrue(self.row.delete())
|
|
self.table.delete.assert_called_with(self.row)
|
|
|
|
|
|
@unittest.mock.patch("gi.repository.Gtk.Filter.changed")
|
|
class TestKeySet(unittest.TestCase):
|
|
"""Tests our KeySet for holding database Rows."""
|
|
|
|
def setUp(self):
|
|
"""Set up common variables."""
|
|
self.keyset = emmental.db.table.KeySet()
|
|
self.table = Gio.ListStore()
|
|
self.row1 = tests.util.table.MockRow(number=1, table=self.table)
|
|
self.row2 = tests.util.table.MockRow(number=2, table=self.table)
|
|
|
|
def test_init(self, mock_changed: unittest.mock.Mock):
|
|
"""Test that the KeySet is created correctly."""
|
|
self.assertIsInstance(self.keyset, Gtk.Filter)
|
|
self.assertIsNone(self.keyset._keys, None)
|
|
self.assertEqual(self.keyset.n_keys, -1)
|
|
|
|
keyset2 = emmental.db.table.KeySet(keys={1, 2, 3})
|
|
self.assertSetEqual(keyset2._keys, {1, 2, 3})
|
|
self.assertEqual(keyset2.n_keys, 3)
|
|
|
|
def test_subtract(self, mock_changed: unittest.mock.Mock):
|
|
"""Test subtracting two KeySets."""
|
|
keyset2 = emmental.db.table.KeySet(keys={2, 3})
|
|
self.assertIsNone(self.keyset - self.keyset)
|
|
self.assertIsNone(self.keyset - keyset2)
|
|
self.assertSetEqual(keyset2 - self.keyset, {2, 3})
|
|
|
|
self.keyset.keys = {1, 2, 3, 4, 5}
|
|
self.assertSetEqual(self.keyset - keyset2, {1, 4, 5})
|
|
self.assertSetEqual(keyset2 - self.keyset, set())
|
|
|
|
def test_strictness(self, mock_changed: unittest.mock.Mock):
|
|
"""Test checking strictness."""
|
|
self.assertEqual(self.keyset.get_strictness(), Gtk.FilterMatch.ALL)
|
|
self.keyset._keys = set()
|
|
self.assertEqual(self.keyset.get_strictness(), Gtk.FilterMatch.NONE)
|
|
self.keyset._keys = {1, 2, 3}
|
|
self.assertEqual(self.keyset.get_strictness(), Gtk.FilterMatch.SOME)
|
|
|
|
def test_add_row(self, mock_changed: unittest.mock.Mock):
|
|
"""Test adding Rows to the KeySet."""
|
|
mock_added = unittest.mock.Mock()
|
|
self.keyset.connect("key-added", mock_added)
|
|
|
|
self.keyset.add_row(self.row1)
|
|
self.assertIsNone(self.keyset.keys)
|
|
mock_added.assert_not_called()
|
|
|
|
self.keyset.keys = set()
|
|
self.keyset.add_row(self.row1)
|
|
self.assertSetEqual(self.keyset.keys, {1})
|
|
self.assertEqual(self.keyset.n_keys, 1)
|
|
mock_changed.assert_called_with(Gtk.FilterChange.LESS_STRICT)
|
|
mock_added.assert_called_with(self.keyset, 1)
|
|
|
|
self.keyset.add_row(self.row2)
|
|
self.assertSetEqual(self.keyset.keys, {1, 2})
|
|
self.assertEqual(self.keyset.n_keys, 2)
|
|
mock_changed.assert_called_with(Gtk.FilterChange.LESS_STRICT)
|
|
mock_added.assert_called_with(self.keyset, 2)
|
|
|
|
mock_changed.reset_mock()
|
|
mock_added.reset_mock()
|
|
self.keyset.add_row(self.row2)
|
|
self.assertSetEqual(self.keyset.keys, {1, 2})
|
|
mock_changed.assert_not_called()
|
|
mock_added.assert_not_called()
|
|
|
|
def test_remove_row(self, mock_changed: unittest.mock.Mock):
|
|
"""Test removing Rows from the KeySet."""
|
|
mock_removed = unittest.mock.Mock()
|
|
self.keyset.connect("key-removed", mock_removed)
|
|
|
|
self.keyset.remove_row(self.row1)
|
|
mock_changed.assert_not_called()
|
|
mock_removed.assert_not_called()
|
|
|
|
self.keyset.keys = {1, 2}
|
|
self.keyset.remove_row(self.row1)
|
|
self.assertSetEqual(self.keyset._keys, {2})
|
|
self.assertEqual(self.keyset.n_keys, 1)
|
|
mock_changed.assert_called_with(Gtk.FilterChange.MORE_STRICT)
|
|
mock_removed.assert_called_with(self.keyset, 1)
|
|
|
|
mock_changed.reset_mock()
|
|
mock_removed.reset_mock()
|
|
self.keyset.remove_row(self.row1)
|
|
self.assertSetEqual(self.keyset.keys, {2})
|
|
self.assertEqual(self.keyset.n_keys, 1)
|
|
mock_changed.assert_not_called()
|
|
mock_removed.assert_not_called()
|
|
|
|
self.keyset.remove_row(self.row2)
|
|
self.assertSetEqual(self.keyset._keys, set())
|
|
self.assertEqual(self.keyset.n_keys, 0)
|
|
mock_changed.assert_called_with(Gtk.FilterChange.MORE_STRICT)
|
|
mock_removed.assert_called_with(self.keyset, 2)
|
|
|
|
def test_keys(self, mock_changed: unittest.mock.Mock):
|
|
"""Test getting and setting the KeySet.keys property."""
|
|
mock_keys_changed = unittest.mock.Mock()
|
|
self.keyset.connect("keys-changed", mock_keys_changed)
|
|
|
|
self.assertIsNone(self.keyset.keys)
|
|
self.keyset.keys = None
|
|
self.assertIsNone(self.keyset.keys)
|
|
mock_changed.assert_not_called()
|
|
mock_keys_changed.assert_not_called()
|
|
|
|
self.keyset.keys = {1, 2, 3}
|
|
self.assertSetEqual(self.keyset._keys, {1, 2, 3})
|
|
self.assertEqual(self.keyset.n_keys, 3)
|
|
mock_changed.assert_called_with(Gtk.FilterChange.MORE_STRICT)
|
|
mock_keys_changed.assert_called_with(self.keyset, set(), {1, 2, 3})
|
|
|
|
mock_changed.reset_mock()
|
|
self.keyset.keys = {1, 2}
|
|
self.assertSetEqual(self.keyset.keys, {1, 2})
|
|
self.assertEqual(self.keyset.n_keys, 2)
|
|
mock_changed.assert_called_with(Gtk.FilterChange.MORE_STRICT)
|
|
mock_keys_changed.assert_called_with(self.keyset, {3}, set())
|
|
|
|
mock_changed.reset_mock()
|
|
mock_keys_changed.reset_mock()
|
|
self.keyset.keys = {1, 2}
|
|
mock_changed.assert_not_called()
|
|
mock_keys_changed.assert_not_called()
|
|
|
|
self.keyset.keys = {1, 2, 3}
|
|
self.assertSetEqual(self.keyset.keys, {1, 2, 3})
|
|
mock_changed.assert_called_with(Gtk.FilterChange.LESS_STRICT)
|
|
mock_keys_changed.assert_called_with(self.keyset, set(), {3})
|
|
|
|
self.keyset.keys = {4, 5, 6}
|
|
self.assertSetEqual(self.keyset._keys, {4, 5, 6})
|
|
mock_changed.assert_called_with(Gtk.FilterChange.DIFFERENT)
|
|
mock_keys_changed.assert_called_with(self.keyset, {1, 2, 3}, {4, 5, 6})
|
|
|
|
self.keyset.keys = None
|
|
self.assertIsNone(self.keyset._keys)
|
|
self.assertEqual(self.keyset.n_keys, -1)
|
|
mock_changed.assert_called_with(Gtk.FilterChange.LESS_STRICT)
|
|
mock_keys_changed.assert_called_with(self.keyset, {4, 5, 6}, set())
|
|
|
|
def test_match_contains(self, mock_changed: unittest.mock.Mock):
|
|
"""Test matching Rows and the __contains__() magic method."""
|
|
self.assertTrue(self.keyset.match(self.row1))
|
|
self.assertTrue(self.row1 in self.keyset)
|
|
|
|
self.keyset.keys = {1, 2, 3}
|
|
self.assertTrue(self.keyset.match(self.row1))
|
|
self.assertTrue(self.row1 in self.keyset)
|
|
|
|
self.keyset.keys = {4, 5, 6}
|
|
self.assertFalse(self.keyset.match(self.row1))
|
|
self.assertFalse(self.row1 in self.keyset)
|
|
|
|
self.keyset.keys = set()
|
|
self.assertFalse(self.keyset.match(self.row1))
|
|
self.assertFalse(self.row1 in self.keyset)
|
|
|
|
|
|
class TestTable(tests.util.TestCase):
|
|
"""Tests the base Table object."""
|
|
|
|
def setUp(self):
|
|
"""Set up common variables."""
|
|
super().setUp()
|
|
self.table = emmental.db.table.Table(self.sql)
|
|
|
|
def test_init(self):
|
|
"""Test that the table is set up properly."""
|
|
self.assertIsInstance(self.table, Gtk.FilterListModel)
|
|
self.assertIsInstance(self.table.queue, emmental.db.idle.Queue)
|
|
self.assertIsInstance(self.table.get_filter(),
|
|
emmental.db.table.KeySet)
|
|
self.assertIsInstance(self.table.store, emmental.store.SortedList)
|
|
self.assertIsInstance(self.table.rows, dict)
|
|
|
|
self.assertEqual(self.table.sql, self.sql)
|
|
self.assertEqual(self.table.get_model(), self.table.store)
|
|
self.assertEqual(self.table.store.key_func, self.table.get_sort_key)
|
|
self.assertDictEqual(self.table.rows, {})
|
|
self.assertFalse(self.table.get_incremental())
|
|
|
|
filter2 = emmental.db.table.KeySet()
|
|
queue2 = emmental.db.idle.Queue()
|
|
table2 = emmental.db.table.Table(self.sql, filter=filter2,
|
|
queue=queue2)
|
|
self.assertEqual(table2.get_filter(), filter2)
|
|
self.assertEqual(table2.queue, queue2)
|
|
|
|
def test_clear(self):
|
|
"""Test clearing a table."""
|
|
row = tests.util.table.MockRow(number=1, table=self.table)
|
|
self.table.store.append(row)
|
|
self.table.loaded = True
|
|
self.table.queue.running = True
|
|
|
|
self.table.clear()
|
|
self.assertEqual(self.table.store.n_items, 0)
|
|
self.assertDictEqual(self.table.rows, dict())
|
|
self.assertFalse(self.table.queue.running)
|
|
self.assertFalse(self.table.loaded)
|
|
|
|
def test_contains(self):
|
|
"""Test checking if a Row is already in this Table."""
|
|
row1 = tests.util.table.MockRow(number=1, table=self.table)
|
|
row2 = tests.util.table.MockRow(number=2, table=self.table)
|
|
self.table.insert(row1)
|
|
self.assertTrue(row1 in self.table)
|
|
self.assertFalse(row2 in self.table)
|
|
|
|
def test_get_sort_key(self):
|
|
"""Test getting a sort key for a row."""
|
|
row = tests.util.table.MockRow(number=1, table=self.table)
|
|
self.table.insert(row)
|
|
self.assertEqual(self.table.get_sort_key(row), 1)
|
|
|
|
def test_index(self):
|
|
"""Test finding the index of rows in the table."""
|
|
row1 = tests.util.table.MockRow(number=1, table=self.table)
|
|
row2 = tests.util.table.MockRow(number=2, table=self.table)
|
|
row3 = tests.util.table.MockRow(number=3, table=self.table)
|
|
self.table.insert(row1)
|
|
self.table.rows[row3.primary_key] = row3
|
|
self.assertEqual(self.table.index(row1), 0)
|
|
self.assertIsNone(self.table.index(row2))
|
|
self.assertIsNone(self.table.index(row3))
|
|
|
|
def test_insert(self):
|
|
"""Test inserting rows into the table in sorted position."""
|
|
row1 = tests.util.table.MockRow(number=1, table=self.table)
|
|
row2 = tests.util.table.MockRow(number=2, table=self.table)
|
|
row3 = tests.util.table.MockRow(number=3, table=self.table)
|
|
|
|
self.assertEqual(self.table.insert(row1), row1)
|
|
self.assertEqual(self.table.store.get_item(0), row1)
|
|
self.assertDictEqual(self.table.rows, {1: row1})
|
|
|
|
self.assertEqual(self.table.insert(row3), row3)
|
|
self.assertEqual(self.table.store.get_item(0), row1)
|
|
self.assertEqual(self.table.store.get_item(1), row3)
|
|
self.assertDictEqual(self.table.rows, {1: row1, 3: row3})
|
|
|
|
self.assertEqual(self.table.insert(row2), row2)
|
|
self.assertEqual(self.table.store.get_item(0), row1)
|
|
self.assertEqual(self.table.store.get_item(1), row2)
|
|
self.assertEqual(self.table.store.get_item(2), row3)
|
|
self.assertDictEqual(self.table.rows, {1: row1, 2: row2, 3: row3})
|
|
|
|
row1_again = tests.util.table.MockRow(number=1, table=self.table)
|
|
self.assertIsNone(self.table.insert(row1_again))
|
|
self.assertIsNone(self.table.insert(row1))
|
|
self.assertIsNone(self.table.insert(None))
|
|
|
|
def test_interface(self):
|
|
"""Test that calling interface functions raises an exception."""
|
|
with self.assertRaises(NotImplementedError):
|
|
self.table.construct(rowid=1)
|
|
with self.assertRaises(NotImplementedError):
|
|
self.table.create(rowid=1)
|
|
with self.assertRaises(NotImplementedError):
|
|
self.table.do_sql_delete(None)
|
|
with self.assertRaises(NotImplementedError):
|
|
self.table.filter("*text*")
|
|
self.table.queue.complete()
|
|
with self.assertRaises(NotImplementedError):
|
|
self.table.load()
|
|
self.table.queue.complete()
|
|
with self.assertRaises(NotImplementedError):
|
|
self.table.lookup(1)
|
|
with self.assertRaises(NotImplementedError):
|
|
self.table.update(None, "column", 12345)
|
|
|
|
|
|
class TestTableFunctions(tests.util.TestCase):
|
|
"""Tests Table functions with a Mock implementation."""
|
|
|
|
def setUp(self):
|
|
"""Set up common variables."""
|
|
super().setUp()
|
|
self.table = tests.util.table.MockTable(self.sql)
|
|
|
|
def test_construct(self):
|
|
"""Test constructing a new Row object."""
|
|
row = self.table.construct(number=1)
|
|
self.assertIsInstance(row, tests.util.table.MockRow)
|
|
self.assertIsInstance(row, emmental.db.table.Row)
|
|
self.assertEqual(row.table, self.table)
|
|
self.assertEqual(row.number, 1)
|
|
|
|
def test_create(self):
|
|
"""Test creating new rows."""
|
|
row = self.table.create(number=1)
|
|
self.assertIsInstance(row, tests.util.table.MockRow)
|
|
self.assertEqual(self.table.index(row), 0)
|
|
self.assertEqual(row.number, 1)
|
|
self.assertDictEqual(self.table.rows, {1: row})
|
|
|
|
self.assertIsNone(self.table.create(number=1))
|
|
|
|
def test_delete(self):
|
|
"""Test deleting rows."""
|
|
row = self.table.create(number=1)
|
|
|
|
with unittest.mock.patch.object(self.sql, "commit") as mock_commit:
|
|
self.assertTrue(row.delete())
|
|
self.assertEqual(len(self.table), 0)
|
|
self.assertDictEqual(self.table.rows, dict())
|
|
mock_commit.assert_called()
|
|
|
|
self.assertFalse(row.delete())
|
|
|
|
def test_filter(self):
|
|
"""Test filtering Rows in the table."""
|
|
for n in [1, 121, 212, 333]:
|
|
self.table.create(number=n)
|
|
self.table.queue.push(unittest.mock.Mock())
|
|
|
|
self.table.filter("*3*")
|
|
self.assertIsNone(self.table.get_filter().keys)
|
|
self.assertEqual(self.table.queue[0], (self.table._filter_idle, "*3*"))
|
|
|
|
self.table.filter("*2*")
|
|
self.assertEqual(self.table.queue[0], (self.table._filter_idle, "*2*"))
|
|
|
|
self.table.queue.complete()
|
|
self.assertSetEqual(self.table.get_filter().keys, {121, 212})
|
|
|
|
self.table.filter("*1*", now=True)
|
|
self.assertSetEqual(self.table.get_filter().keys, {1, 121, 212})
|
|
|
|
self.table.filter(None)
|
|
self.assertIsNone(self.table.queue[0])
|
|
self.assertIsNone(self.table.get_filter().keys)
|
|
|
|
def test_get_sort_key(self):
|
|
"""Test getting a sort key for a row."""
|
|
row = self.table.create(number=42)
|
|
self.assertTupleEqual(self.table.get_sort_key(row), (42, 42))
|
|
|
|
def test_load(self):
|
|
"""Test loading rows from the database."""
|
|
self.assertFalse(self.table.loaded)
|
|
|
|
table_loaded = unittest.mock.Mock()
|
|
self.sql.connect("table-loaded", table_loaded)
|
|
self.sql("INSERT INTO mock_table (number) VALUES (?)", 1)
|
|
self.sql("INSERT INTO mock_table (number) VALUES (?)", 2)
|
|
|
|
self.table.load()
|
|
self.assertFalse(self.table.loaded)
|
|
self.assertEqual(len(self.table), 0)
|
|
self.assertEqual(self.table.queue[0], (self.table._load_idle,))
|
|
|
|
self.table.queue.complete()
|
|
self.assertTrue(self.table.loaded)
|
|
self.assertEqual(len(self.table), 2)
|
|
table_loaded.assert_called_with(self.sql, self.table)
|
|
|
|
row1 = self.table[0]
|
|
row2 = self.table[1]
|
|
|
|
for row, n in [(row1, 1), (row2, 2)]:
|
|
with self.subTest(n=n):
|
|
self.assertEqual(row.number, n)
|
|
|
|
self.assertEqual(self.table.rows, {1: row1, 2: row2})
|
|
|
|
self.table.load(now=True)
|
|
self.assertNotEqual(self.table[0], row1)
|
|
self.assertNotEqual(self.table[1], row2)
|
|
|
|
def test_lookup(self):
|
|
"""Test looking up rows in the table."""
|
|
row = self.table.create(number=1)
|
|
self.assertEqual(self.table.lookup(1), row)
|
|
self.assertIsNone(self.table.lookup(2))
|
|
|
|
def test_stop(self):
|
|
"""Test the table.stop() function."""
|
|
with unittest.mock.patch.object(self.table.queue, "cancel") as cancel:
|
|
self.table.stop()
|
|
cancel.assert_called()
|
|
|
|
def test_update(self):
|
|
"""Test updating a Row."""
|
|
row = self.table.create(number=1)
|
|
self.assertTrue(self.table.update(row, "number", 2))
|
|
row.number = 2
|
|
|
|
self.table.create(number=3)
|
|
self.assertFalse(self.table.update(row, "number", 3))
|
|
|
|
|
|
class TestTableSubset(tests.util.TestCase):
|
|
"""Tests the TableSubset."""
|
|
|
|
def setUp(self):
|
|
"""Set up common variables."""
|
|
super().setUp()
|
|
self.table = tests.util.table.MockTable(self.sql)
|
|
self.subset = emmental.db.table.TableSubset(self.table)
|
|
self.rows = [self.table.create(number=i) for i in range(5)]
|
|
|
|
def test_init(self):
|
|
"""Test that the TableSubset was set up properly."""
|
|
self.assertIsInstance(self.subset, Gio.ListModel)
|
|
self.assertIsInstance(self.subset, GObject.GObject)
|
|
self.assertIsInstance(self.subset.keyset, emmental.db.table.KeySet)
|
|
self.assertSetEqual(self.subset.keyset.keys, set())
|
|
self.assertEqual(self.subset.table, self.table)
|
|
|
|
subset2 = emmental.db.table.TableSubset(self.table, keys={1, 2, 3})
|
|
self.assertSetEqual(subset2.keyset.keys, {1, 2, 3})
|
|
|
|
def test_get_item_type(self):
|
|
"""Test the Gio.ListModel.get_item_type() function."""
|
|
self.assertEqual(self.subset.get_item_type(),
|
|
emmental.db.table.Row.__gtype__)
|
|
|
|
def test_get_n_items(self):
|
|
"""Test the Gio.ListModel.get_n_items() function."""
|
|
self.assertEqual(self.subset.get_n_items(), 0)
|
|
self.assertEqual(self.subset.n_rows, 0)
|
|
|
|
self.subset.add_row(self.rows[0])
|
|
self.assertEqual(self.subset.get_n_items(), 0)
|
|
self.assertEqual(self.subset.n_rows, 0)
|
|
|
|
self.table.loaded = True
|
|
self.assertEqual(self.subset.get_n_items(), 1)
|
|
self.assertEqual(self.subset.n_rows, 1)
|
|
|
|
self.table.loaded = False
|
|
self.assertEqual(self.subset.get_n_items(), 0)
|
|
self.assertEqual(self.subset.n_rows, 0)
|
|
|
|
def test_get_item(self):
|
|
"""Test the Gio.ListModel.get_item() function."""
|
|
for row in self.rows:
|
|
self.subset.add_row(row)
|
|
|
|
self.assertListEqual(self.subset._items, [])
|
|
|
|
for i, row in enumerate(self.rows):
|
|
with self.subTest(i=i, row=row.number):
|
|
self.assertIsNone(self.subset.get_item(i))
|
|
|
|
self.table.loaded = True
|
|
self.assertEqual(self.subset.get_item(i), row)
|
|
self.assertEqual(self.subset._items[i], row)
|
|
|
|
self.table.loaded = False
|
|
self.assertIsNone(self.subset.get_item(i))
|
|
|
|
def test_add_row(self):
|
|
"""Test adding a row to the TableSubset."""
|
|
expected = set()
|
|
self.table.loaded = True
|
|
self.assertListEqual(self.subset._items, [])
|
|
|
|
changed = unittest.mock.Mock()
|
|
self.subset.connect("items-changed", changed)
|
|
|
|
for n, i in enumerate([2, 0, 4, 1, 3], start=1):
|
|
row = self.rows[i]
|
|
with self.subTest(i=i, row=row.number):
|
|
expected.add(i)
|
|
self.subset.add_row(row)
|
|
self.assertSetEqual(self.subset.keyset.keys, expected)
|
|
self.assertEqual(self.subset.n_rows, n)
|
|
changed.assert_called_with(self.subset,
|
|
sorted(expected).index(i), 0, 1)
|
|
|
|
self.assertListEqual(self.subset._items, self.rows)
|
|
self.assertListEqual(list(self.subset), self.rows)
|
|
|
|
def test_remove_row(self):
|
|
"""Test removing a row from the TableSubset."""
|
|
self.table.loaded = True
|
|
[self.subset.add_row(row) for row in self.rows]
|
|
expected = {row.number for row in self.rows}
|
|
|
|
changed = unittest.mock.Mock()
|
|
self.subset.connect("items-changed", changed)
|
|
|
|
for n, i in enumerate([2, 0, 4, 1, 3], start=1):
|
|
row = self.rows[i]
|
|
rm = sorted(expected).index(i)
|
|
with self.subTest(i=i, row=row.number):
|
|
expected.discard(i)
|
|
self.subset.remove_row(row)
|
|
self.assertSetEqual(self.subset.keyset.keys, expected)
|
|
self.assertEqual(self.subset.n_rows, 5 - n)
|
|
changed.assert_called_with(self.subset, rm, 1, 0)
|
|
|
|
self.assertEqual(self.subset.n_rows, 0)
|
|
|
|
def test_contains(self):
|
|
"""Test the __contains__() magic method."""
|
|
self.table.loaded = True
|
|
self.assertFalse(self.rows[0] in self.subset)
|
|
self.subset.add_row(self.rows[0])
|
|
self.assertTrue(self.rows[0] in self.subset)
|
|
|
|
def test_table_not_loaded(self):
|
|
"""Test operations when the table hasn't been loaded."""
|
|
self.subset.add_row(self.rows[0])
|
|
self.assertListEqual(self.subset._items, [])
|
|
self.assertEqual(self.subset.n_rows, 0)
|
|
self.assertIsNone(self.subset.get_item(0))
|
|
|
|
self.subset.remove_row(self.rows[0])
|
|
self.assertListEqual(self.subset._items, [])
|
|
self.assertEqual(self.subset.n_rows, 0)
|
|
|
|
def test_table_loaded(self):
|
|
"""Test changing the value of Table.loaded."""
|
|
changed = unittest.mock.Mock()
|
|
self.subset.connect("items-changed", changed)
|
|
|
|
self.table.loaded = True
|
|
changed.assert_not_called()
|
|
self.table.loaded = False
|
|
changed.assert_not_called()
|
|
|
|
self.subset.add_row(self.rows[0])
|
|
self.subset.add_row(self.rows[1])
|
|
|
|
self.table.loaded = True
|
|
self.assertEqual(self.subset.n_rows, 2)
|
|
changed.assert_called_with(self.subset, 0, 0, 2)
|
|
|
|
self.table.loaded = False
|
|
self.assertEqual(self.subset.n_rows, 0)
|
|
changed.assert_called_with(self.subset, 0, 2, 0)
|