# Copyright 2022 (c) Anna Schumaker. """Tests our Playlist Sorter.""" import emmental.tracklist.sorter import unittest from gi.repository import GObject from gi.repository import Gio class TestSortConstants(unittest.TestCase): """Test case for Sort Order constants.""" def test_flags(self): """Test flags passed to the sort_order property.""" self.assertEqual(emmental.tracklist.sorter.SORT_ORDER_FLAGS, GObject.ParamFlags.READWRITE | GObject.ParamFlags.EXPLICIT_NOTIFY) def test_sort_fields(self): """Test the sort fields definition dictionary.""" self.assertDictEqual(emmental.tracklist.sorter.SORT_FIELDS, {"Album": ["album"], "Artist": ["artist"], "Album Artist": ["albumartist"], "Filepath": ["filepath"], "Length": ["length"], "Last Played Date": ["lastplayed"], "Last Started Date": ["laststarted"], "Play Count": ["playcount"], "Release Date": ["release"], "Title": ["title"], "Track Number": ["mediumno", "number"]}) def test_reverse_lookup(self): """Test the sort field reverse lookup dictionary.""" self.assertDictEqual(emmental.tracklist.sorter.REVERSE_LOOKUP, {"album": "Album", "artist": "Artist", "albumartist": "Album Artist", "filepath": "Filepath", "length": "Length", "lastplayed": "Last Played Date", "laststarted": "Last Started Date", "playcount": "Play Count", "release": "Release Date", "title": "Title", "mediumno": "Track Number", "number": "Track Number"}) class TestSortField(unittest.TestCase): """Test case for our SortField object.""" def setUp(self): """Set up common variables.""" self.model = Gio.ListStore() self.field = emmental.tracklist.sorter.SortField(self.model, "Album") def test_init(self): """Test that the Sort Field is initialized correctly.""" self.assertIsInstance(self.field, GObject.GObject) self.assertEqual(self.field.name, "Album") self.assertEqual(self.field.model, self.model) self.assertFalse(self.field.enabled) self.assertFalse(self.field.reversed) with self.assertRaises(KeyError): emmental.tracklist.sorter.SortField(self.model, "Invalid Field") def test_str(self): """Test converting a Sort Field to a string.""" for (field, cols) in emmental.tracklist.sorter.SORT_FIELDS.items(): expected = ", ".join(cols) reversed = ", ".join([f"{c} DESC" for c in cols]) with self.subTest(field=field, expected=(expected, reversed)): self.field.name = field self.field.reversed = False self.assertEqual(str(self.field), expected) self.field.reversed = True self.assertEqual(str(self.field), reversed) def test_disable(self): """Test disabling a Sort Field.""" self.model.disable = unittest.mock.Mock() self.field.disable() self.model.disable.assert_called_with(self.field) def test_enable(self): """Test enabling a Sort Field.""" self.model.enable = unittest.mock.Mock() self.field.enable() self.model.enable.assert_called_with(self.field) def test_move_down(self): """Test moving a Sort Field down.""" self.model.move_down = unittest.mock.Mock() self.field.move_down() self.model.move_down.assert_called_with(self.field) def test_move_up(self): """Test moving a Sort Field up.""" self.model.move_up = unittest.mock.Mock() self.field.move_up() self.model.move_up.assert_called_with(self.field) def test_reverse(self): """Test reversing a Sort Field.""" self.model.reverse = unittest.mock.Mock() self.field.reverse() self.model.reverse.assert_called_with(self.field) class TestSortOrderModel(unittest.TestCase): """Test case for our Sort Order Model.""" def setUp(self): """Set up common variables.""" self.sort_fields = emmental.tracklist.sorter.SORT_FIELDS self.model = emmental.tracklist.sorter.SortOrderModel() def test_init(self): """Test that the model is initialized properly.""" self.assertIsInstance(self.model, Gio.ListStore) self.assertEqual(self.model.n_enabled, 0) self.assertEqual(self.model.get_item_type(), emmental.tracklist.sorter.SortField.__gtype__) self.assertEqual(self.model.sort_order, "") for i, name in enumerate(self.sort_fields.keys()): with self.subTest(i=i, name=name): self.assertIsInstance(self.model[i], emmental.tracklist.sorter.SortField) self.assertEqual(self.model[i].name, name) def test_index(self): """Test the Sort Order Model index() function.""" for i, name in enumerate(emmental.tracklist.sorter.SORT_FIELDS.keys()): with self.subTest(i=i, name=name): self.assertEqual(self.model.index(self.model[i]), i) field2 = emmental.tracklist.sorter.SortField(self.model, "Album") self.assertIsNone(self.model.index(field2)) def test_lookup(self): """Test looping up sort fields by name.""" for name in emmental.tracklist.sorter.SORT_FIELDS.keys(): with self.subTest(name=name): self.assertEqual(self.model.lookup(name).name, name) self.assertIsNone(self.model.lookup("Invalid Name")) def test_disable(self): """Test disabling a sort field.""" (field_0 := self.model[0]).enable() (field_1 := self.model[1]).enable() (field_2 := self.model[2]).enable() field_2.reversed = True self.assertTrue(self.model.disable(field_2)) self.assertFalse(field_2.enabled) self.assertFalse(field_2.reversed) self.assertEqual(self.model.n_enabled, 2) self.assertEqual(self.model.index(field_2), 2) self.assertEqual(self.model.sort_order, f"{str(field_0)}, {str(field_1)}") self.assertFalse(self.model.disable(field_2)) self.assertEqual(self.model.n_enabled, 2) self.assertTrue(self.model.disable(field_0)) self.assertFalse(field_0.enabled) self.assertEqual(self.model.n_enabled, 1) self.assertEqual(self.model.index(field_0), 1) self.assertEqual(self.model.sort_order, str(field_1)) def test_enable(self): """Test enabling a sort field.""" field_0 = self.model[0] self.assertTrue(self.model.enable(field_0)) self.assertTrue(field_0.enabled) self.assertEqual(self.model.n_enabled, 1) self.assertEqual(self.model.index(field_0), 0) self.assertEqual(self.model.sort_order, str(field_0)) self.assertFalse(self.model.enable(field_0)) self.assertEqual(self.model.n_enabled, 1) field_3 = self.model[3] self.assertTrue(self.model.enable(field_3)) self.assertTrue(field_3.enabled) self.assertEqual(self.model.n_enabled, 2) self.assertEqual(self.model.index(field_3), 1) self.assertEqual(self.model.sort_order, f"{str(field_0)}, {str(field_3)}") def test_move_down(self): """Test moving a sort field down in the list.""" (field_0 := self.model[0]).enable() (field_1 := self.model[1]).enable() for res in [True, False]: with self.subTest(res=res): self.assertEqual(self.model.move_down(field_0), res) self.assertEqual(self.model[0], field_1) self.assertEqual(self.model[1], field_0) self.assertEqual(self.model.sort_order, f"{str(field_1)}, {str(field_0)}") def test_move_up(self): """Test moving a sort field down in the list.""" (field_0 := self.model[0]).enable() (field_1 := self.model[1]).enable() for res in [True, False]: with self.subTest(res=res): self.assertEqual(self.model.move_up(field_1), res) self.assertEqual(self.model[0], field_1) self.assertEqual(self.model[1], field_0) self.assertEqual(self.model.sort_order, f"{str(field_1)}, {str(field_0)}") def test_reverse(self): """Test reversing a sort field.""" (field_0 := self.model[0]).enable() self.model.reverse(field_0) self.assertTrue(field_0.reversed) self.assertEqual(self.model.sort_order, str(field_0)) self.model.reverse(field_0) self.assertFalse(field_0.reversed) self.assertEqual(self.model.sort_order, str(field_0)) def test_set_sort_order_artist(self): """Test setting the Sort Order property to "artist".""" self.model.set_sort_order("artist") self.assertEqual(self.model.n_enabled, 1) self.assertEqual(self.model.sort_order, "artist") self.assertEqual(self.model[0].name, "Artist") self.assertTrue(self.model[0].enabled) self.assertFalse(self.model[0].reversed) self.assertFalse(self.model[1].enabled) def test_set_sort_order_album_title(self): """Test setting the Sort Order property to "album DESC, title".""" self.model[1].enable() self.model[1].reverse() self.model.set_sort_order("album DESC, title") self.assertEqual(self.model.n_enabled, 2) self.assertEqual(self.model.sort_order, "album DESC, title") self.assertEqual(self.model[0].name, "Album") self.assertTrue(self.model[0].enabled) self.assertTrue(self.model[0].reversed) self.assertEqual(self.model[1].name, "Title") self.assertTrue(self.model[1].enabled) self.assertFalse(self.model[1].reversed) self.assertFalse(self.model[2].enabled) self.assertFalse(self.model[2].reversed) def test_set_sort_order_trackno_playcount(self): """Test setting the Sort Order property to "album DESC, title".""" self.model.set_sort_order("mediumno, number, playcount") self.assertEqual(self.model.n_enabled, 2) self.assertEqual(self.model.sort_order, "mediumno, number, playcount") self.assertEqual(self.model[0].name, "Track Number") self.assertTrue(self.model[0].enabled) self.assertFalse(self.model[0].reversed) self.assertEqual(self.model[1].name, "Play Count") self.assertTrue(self.model[1].enabled) self.assertFalse(self.model[1].reversed) self.assertFalse(self.model[2].enabled) self.assertFalse(self.model[2].reversed) def test_set_sort_order_user(self): """Test setting the Sort Order property to "user".""" self.model[0].enable() self.model.set_sort_order("user") self.assertEqual(self.model.n_enabled, 0) self.assertEqual(self.model.sort_order, "user") self.assertFalse(self.model[0].enabled) def test_set_sort_order_same(self): """Test setting the Sort Order property to the same value.""" self.model.set_sort_order("user") notify = unittest.mock.Mock() self.model.connect("notify::sort-order", notify) self.model.set_sort_order("user") notify.assert_not_called() def test_set_sort_order_none(self): """Test setting the Sort Order property to 'None'.""" notify = unittest.mock.Mock() self.model.connect("notify::sort-order", notify) self.model.set_sort_order(None) notify.assert_not_called()