This applies to both the Table and child Playlists models. I'm doing my own idle handling already for searching, so we can rely on that instead of needing Gtk to do it. The benefit to this is that we can select playlists programmatically during startup, since we don't need to worry about the Table not being fully loaded yet. Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
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)
|