emmental/tests/tracklist/test_buttons.py

389 lines
16 KiB
Python

# Copyright 2022 (c) Anna Schumaker
"""Tests extra buttons for the TrackList."""
import unittest
import unittest.mock
import emmental.tracklist.buttons
from gi.repository import Gio
from gi.repository import Gtk
class TestVisibleColumnRow(unittest.TestCase):
"""Test the Visible Column ListBoxRow."""
def setUp(self):
"""Set up common variables."""
self.row = emmental.tracklist.buttons.VisibleRow("title", True)
def test_init(self):
"""Test that the VisibleRow was set up properly."""
self.assertIsInstance(self.row, Gtk.ListBoxRow)
self.assertIsInstance(self.row.props.child, Gtk.Box)
self.assertEqual(self.row.title, "title")
self.assertTrue(self.row.active)
self.assertEqual(self.row.props.child.props.margin_start, 6)
self.assertEqual(self.row.props.child.props.margin_end, 6)
self.assertEqual(self.row.props.child.props.margin_top, 6)
self.assertEqual(self.row.props.child.props.margin_bottom, 6)
self.assertEqual(self.row.props.child.props.spacing, 6)
row2 = emmental.tracklist.buttons.VisibleRow("title2", False)
self.assertEqual(row2.title, "title2")
self.assertFalse(row2.active)
def test_switch(self):
"""Test the VisibleRow switch."""
self.assertIsInstance(self.row._switch, Gtk.Switch)
self.assertEqual(self.row._switch.props.parent, self.row.props.child)
self.assertTrue(self.row._switch.props.active)
self.row.active = False
self.assertFalse(self.row._switch.props.active)
self.row._switch.props.active = True
self.assertTrue(self.row.active)
row2 = emmental.tracklist.buttons.VisibleRow("title2", False)
self.assertFalse(row2._switch.props.active)
def test_label(self):
"""Test the VisibleRow title label."""
self.assertIsInstance(self.row._label, Gtk.Label)
self.assertEqual(self.row._label.props.label, "title")
self.assertEqual(self.row._switch.get_next_sibling(),
self.row._label)
class TestVisibleColumns(unittest.TestCase):
"""Test the Visible Columns button."""
def setUp(self):
"""Set up common variables."""
self.columns = Gio.ListStore()
self.columns.append(Gtk.ColumnViewColumn(title="title", visible=True))
self.columns.append(Gtk.ColumnViewColumn(title="title2",
visible=False))
self.button = emmental.tracklist.buttons.VisibleColumns(self.columns)
def test_init(self):
"""Test that the Visible Columns button is set up properly."""
self.assertIsInstance(self.button, emmental.buttons.PopoverButton)
self.assertFalse(self.button.get_has_frame())
self.assertEqual(self.button.get_icon_name(), "columns-symbolic")
self.assertEqual(self.button.get_tooltip_text(),
"configure visible columns")
self.assertEqual(self.button.columns, self.columns)
def test_popover_child(self):
"""Test that the popover_child was set up properly."""
self.assertIsInstance(self.button.popover_child, Gtk.ListBox)
self.assertEqual(self.button.popover_child.props.selection_mode,
Gtk.SelectionMode.NONE)
self.assertTrue(self.button.popover_child.has_css_class("boxed-list"))
def test_create_func(self):
"""Test that the Gtk.ListBox creates VisibleRows correctly."""
row = self.button.popover_child.get_row_at_index(0)
self.assertIsInstance(row, emmental.tracklist.buttons.VisibleRow)
self.assertEqual(row.title, "title")
self.assertTrue(row.active)
row.active = False
self.assertFalse(self.columns[0].get_visible())
row.active = True
self.assertTrue(self.columns[0].get_visible())
self.columns[0].set_visible(False)
self.assertFalse(row.active)
row = self.button.popover_child.get_row_at_index(1)
self.assertIsInstance(row, emmental.tracklist.buttons.VisibleRow)
self.assertEqual(row.title, "title2")
self.assertFalse(row.active)
def test_activate(self):
"""Test activating a Gtk.ListBox row."""
row = self.button.popover_child.get_row_at_index(0)
self.button.popover_child.emit("row-activated", row)
self.assertFalse(row.active)
self.button.popover_child.emit("row-activated", row)
self.assertTrue(row.active)
class TestLoopButton(unittest.TestCase):
"""Test the LoopButton."""
def setUp(self):
"""Set up common variables."""
self.loop = emmental.tracklist.buttons.LoopButton()
def test_init(self):
"""Test that the loop button is set up properly."""
self.assertIsInstance(self.loop, emmental.buttons.ImageToggle)
self.assertEqual(self.loop.active_icon_name,
"media-playlist-repeat-song")
self.assertEqual(self.loop.active_tooltip_text, "loop: track")
self.assertEqual(self.loop.inactive_icon_name, "media-playlist-repeat")
self.assertEqual(self.loop.inactive_tooltip_text, "loop: disabled")
self.assertFalse(self.loop.large_icon)
self.assertFalse(self.loop.get_has_frame())
def test_state(self):
"""Test changing the state property."""
self.assertTrue(self.loop.can_disable)
self.assertEqual(self.loop.state, "None")
self.assertAlmostEqual(self.loop.icon_opacity, 0.5, delta=0.005)
self.assertEqual(self.loop.props.tooltip_text, "loop: disabled")
self.assertFalse(self.loop.active)
self.loop.state = "Playlist"
self.assertEqual(self.loop.state, "Playlist")
self.assertEqual(self.loop.icon_opacity, 1.0)
self.assertEqual(self.loop.props.tooltip_text, "loop: playlist")
self.assertFalse(self.loop.active)
self.loop.state = "Track"
self.assertEqual(self.loop.state, "Track")
self.assertEqual(self.loop.icon_opacity, 1.0)
self.assertEqual(self.loop.props.tooltip_text, "loop: track")
self.assertTrue(self.loop.active)
self.loop.can_disable = False
self.loop.state = "None"
self.assertEqual(self.loop.state, "Track")
self.assertEqual(self.loop.props.tooltip_text, "loop: track")
self.assertTrue(self.loop.active)
self.loop.can_disable = True
self.loop.state = "None"
self.assertAlmostEqual(self.loop.icon_opacity, 0.5, delta=0.005)
self.assertEqual(self.loop.inactive_tooltip_text, "loop: disabled")
self.assertFalse(self.loop.active)
def test_click(self):
"""Test cycling through states when clicked."""
self.assertEqual(self.loop.state, "None")
self.loop.emit("clicked")
self.assertEqual(self.loop.state, "Playlist")
self.loop.emit("clicked")
self.assertEqual(self.loop.state, "Track")
self.loop.emit("clicked")
self.assertEqual(self.loop.state, "None")
self.loop.state = "Playlist"
self.loop.can_disable = False
self.loop.emit("clicked")
self.assertEqual(self.loop.state, "Track")
self.loop.emit("clicked")
self.assertEqual(self.loop.state, "Playlist")
class TestShuffleButtons(unittest.TestCase):
"""Test the Shuffle button."""
def setUp(self):
"""Set up common variables."""
self.shuffle = emmental.tracklist.buttons.ShuffleButton()
def test_init(self):
"""Test that the shuffle button is configured correctly."""
self.assertIsInstance(self.shuffle, emmental.buttons.ImageToggle)
self.assertFalse(self.shuffle.large_icon)
self.assertFalse(self.shuffle.get_has_frame())
self.assertEqual(self.shuffle.active_icon_name,
"media-playlist-shuffle")
self.assertEqual(self.shuffle.active_tooltip_text, "shuffle: enabled")
self.assertEqual(self.shuffle.inactive_icon_name,
"media-playlist-consecutive")
self.assertEqual(self.shuffle.inactive_tooltip_text,
"shuffle: disabled")
self.assertAlmostEqual(self.shuffle.icon_opacity, 0.5, delta=0.005)
def test_opacity(self):
"""Test adjusting the opacity based on active state."""
self.shuffle.active = True
self.assertEqual(self.shuffle.icon_opacity, 1.0)
self.shuffle.active = False
self.assertEqual(self.shuffle.icon_opacity, 0.5)
class TestSortRow(unittest.TestCase):
"""Test the Sort Row ListBoxRow."""
def setUp(self):
"""Set up common variables."""
self.model = emmental.tracklist.sorter.SortOrderModel()
self.model[0].enable()
self.model[1].reverse()
self.row1 = emmental.tracklist.buttons.SortRow(self.model[0])
self.row2 = emmental.tracklist.buttons.SortRow(self.model[1])
def test_init(self):
"""Test that the Sort Field Widget is configured correctly."""
self.assertIsInstance(self.row1, Gtk.ListBoxRow)
self.assertIsInstance(self.row1.props.child, Gtk.Box)
self.assertEqual(self.row1.props.child.props.margin_start, 6)
self.assertEqual(self.row1.props.child.props.margin_end, 6)
self.assertEqual(self.row1.props.child.props.margin_top, 6)
self.assertEqual(self.row1.props.child.props.margin_bottom, 6)
self.assertEqual(self.row1.props.child.props.spacing, 6)
self.assertEqual(self.row1.sort_field, self.model[0])
self.assertTrue(self.row1.active)
self.assertEqual(self.row2.sort_field, self.model[1])
self.assertFalse(self.row2.active)
def test_switch(self):
"""Test the SortRow switch."""
self.assertIsInstance(self.row1._switch, Gtk.Switch)
self.assertEqual(self.row1._switch.props.valign, Gtk.Align.CENTER)
self.assertEqual(self.row1._switch.props.parent, self.row1.props.child)
self.assertTrue(self.row1._switch.props.active)
self.assertFalse(self.row2._switch.props.active)
with unittest.mock.patch.object(self.model[0],
"disable") as mock_disable:
self.row1._switch.props.active = False
mock_disable.assert_called()
with unittest.mock.patch.object(self.model[0],
"enable") as mock_enable:
self.row1._switch.props.active = True
mock_enable.assert_called()
def test_label(self):
"""Test the SortRow title label."""
self.assertIsInstance(self.row1._label, Gtk.Label)
self.assertEqual(self.row1._switch.get_next_sibling(),
self.row1._label)
self.assertEqual(self.row1._label.props.label, self.model[0].name)
self.assertEqual(self.row1._label.props.xalign, 0.0)
self.assertTrue(self.row1._label.props.hexpand)
self.assertTrue(self.row1._label.props.sensitive)
self.assertFalse(self.row2._label.props.sensitive)
def test_reverse(self):
"""Test the SortRow reverse button."""
self.assertIsInstance(self.row1._reverse, emmental.buttons.ImageToggle)
self.assertEqual(self.row1._label.get_next_sibling(),
self.row1._reverse)
self.assertEqual(self.row1._reverse.active_icon_name, "arrow1-up")
self.assertEqual(self.row1._reverse.inactive_icon_name, "arrow1-down")
self.assertFalse(self.row1._reverse.props.has_frame)
self.assertFalse(self.row1._reverse.large_icon)
self.assertFalse(self.row1._reverse.props.active)
self.assertTrue(self.row1._reverse.props.sensitive)
self.assertTrue(self.row2._reverse.props.active)
self.assertFalse(self.row2._reverse.props.sensitive)
with unittest.mock.patch.object(self.model[0],
"reverse") as mock_reverse:
self.row1._reverse.emit("toggled")
mock_reverse.assert_called()
def test_move_box(self):
"""Test the box containing the move up & down buttons."""
self.assertIsInstance(self.row1._move_box, Gtk.Box)
self.assertEqual(self.row1._reverse.get_next_sibling(),
self.row1._move_box)
self.assertTrue(self.row1._move_box.has_css_class("linked"))
self.assertTrue(self.row1._move_box.props.sensitive)
self.assertFalse(self.row2._move_box.props.sensitive)
def test_move_up(self):
"""Test the move up button."""
self.assertIsInstance(self.row1._move_up, Gtk.Button)
self.assertEqual(self.row1._move_up.get_icon_name(),
"go-up-symbolic")
self.assertEqual(self.row1._move_up.props.parent,
self.row1._move_box)
with unittest.mock.patch.object(self.model[0],
"move_up") as mock_move_up:
self.row1._move_up.emit("clicked")
mock_move_up.assert_called()
def test_move_down(self):
"""Test the move down button."""
self.assertIsInstance(self.row1._move_down, Gtk.Button)
self.assertEqual(self.row1._move_down.get_icon_name(),
"go-down-symbolic")
self.assertEqual(self.row1._move_up.get_next_sibling(),
self.row1._move_down)
with unittest.mock.patch.object(self.model[0],
"move_down") as mock_move_down:
self.row1._move_down.emit("clicked")
mock_move_down.assert_called()
class TestSortButton(unittest.TestCase):
"""Test the Sort button."""
def setUp(self):
"""Set up common variables."""
self.sort = emmental.tracklist.buttons.SortButton()
def test_init(self):
"""Test that the Sort button is configured correctly."""
self.assertIsInstance(self.sort, emmental.buttons.PopoverButton)
self.assertEqual(self.sort.get_icon_name(),
"list-compact-symbolic")
self.assertEqual(self.sort.get_tooltip_text(),
"configure playlist sort order")
self.assertFalse(self.sort.get_has_frame())
def test_popover_child(self):
"""Test that the popover_child is configured correctly."""
self.assertIsInstance(self.sort.popover_child, Gtk.ListBox)
self.assertEqual(self.sort.popover_child.props.selection_mode,
Gtk.SelectionMode.NONE)
self.assertTrue(self.sort.popover_child.has_css_class("boxed-list"))
def test_create_func(self):
"""Test that the Gtk.ListBox creates SortRows correctly."""
row = self.sort.popover_child.get_row_at_index(0)
self.assertIsInstance(row, emmental.tracklist.buttons.SortRow)
self.assertEqual(row.sort_field, self.sort.model[0])
def test_activate(self):
"""Test activating a Gtk.ListBox sort row."""
row = self.sort.popover_child.get_row_at_index(0)
field = row.sort_field
self.assertFalse(field.enabled)
self.assertFalse(field.reversed)
with unittest.mock.patch.object(field, "enable") as mock_enable:
self.sort.popover_child.emit("row-activated", row)
mock_enable.assert_called()
mock_enable.reset_mock()
row.active = True
with unittest.mock.patch.object(field, "reverse") as mock_reverse:
self.sort.popover_child.emit("row-activated", row)
self.assertTrue(row._reverse.active)
mock_enable.assert_not_called()
mock_reverse.assert_called()
def test_sort_order(self):
"""Test the sort-order property."""
self.assertEqual(self.sort.sort_order, "")
self.sort.model[0].enable()
self.assertEqual(self.sort.sort_order, self.sort.model.sort_order)
self.sort.set_sort_order("artist")
self.assertEqual(self.sort.model.sort_order, "artist")