Source code for seriesmarker.test.gui.sorting_test

# ==============================================================================
# -*- coding: utf-8 -*-
#
# Copyright (C) 2013 - 2016 Tobias Röttger <toroettg@gmail.com>
#
# This file is part of SeriesMarker.
#
# SeriesMarker is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# SeriesMarker is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with SeriesMarker.  If not, see <http://www.gnu.org/licenses/>.
# ==============================================================================

import random
import unittest
from unittest.mock import MagicMock

from PySide.QtCore import Qt, QModelIndex, QCoreApplication
from pytvdbapi.api import Show

from seriesmarker.persistence.database import db_get_series
from seriesmarker.gui.search_dialog import SearchDialog
from seriesmarker.test.database.base.persitent_db_test_case import \
    PersistentDBTestCase
from seriesmarker.test.gui.base.main_window_test import MainWindowTest
from seriesmarker.test.util.example_data_factory import ExampleDataFactory


[docs]class SortingTest(MainWindowTest, PersistentDBTestCase): """Performs tests of the application's main window's features related to sorting. .. note:: Cases in this test depend on a specific execution order. Therefore, case names are numbered. .. todo:: Might be merged with :class:`.StoryTest` in separate test-class to reduce boilerplate code (setUpClass, setUp). """ @classmethod
[docs] def setUpClass(cls): MainWindowTest.setUpClass() PersistentDBTestCase.setUpClass() from seriesmarker.persistence.database import db_init db_init()
[docs] def setUp(self): super().setUp() for series in db_get_series(): self.window.model.add_item(series) QCoreApplication.processEvents();
[docs] def test_01_sort_on_add(self): Show.update = MagicMock() series = [] series_names = ["HIMYM", "DRWHO", "BUFFY", "MADLOVE", "ROMEPG", "WONDERYEARS", "DEFIANCE"] random.shuffle(series_names) for name in series_names: series.append(ExampleDataFactory.new_pytvdb_show(name)) SearchDialog.exec_ = MagicMock(return_value=SearchDialog.Accepted) SearchDialog.result_value = MagicMock(side_effect=series) self.assertEqual(self.window.model.rowCount(), 0, "Default model is not empty") self.click_add_button(times=len(series)) self.assertEqual(self.window.model.rowCount(), 7, "Selected series were not added") def prepare_next_test(): # Create progress by marking specific episodes watched model = self.window.model for series_number in range(0, model.rowCount()): series_index = model.index(series_number, 0) series_node = model.node_at(series_index) name = series_node.name() if name == "How I Met Your Mother": select = 6 elif name == "Rome: Power & Glory": select = 2 else: select = 1 episodes = [] for season_node in series_node.children: season_index = model.index(season_node.child_index(), 0, series_index) for episode_node in season_node.children: episode_index = model.index(episode_node.child_index(), 0, season_index) episodes.append(episode_index) for index in range(0, select): model.setData(episodes[index], Qt.Checked, role=Qt.CheckStateRole) result = [ ("Buffy the Vampire Slayer", " 1 / 1 ", "100.0%"), ("Defiance", " 1 / 3 ", "33.3%"), ("Doctor Who", " 1 / 12 ", "8.3%"), ("How I Met Your Mother", " 6 / 7 ", "85.7%"), ("Mad Love", " 1 / 2 ", "50.0%"), ("Rome: Power & Glory", " 2 / 4 ", "50.0%"), ("The Wonder Years", " 1 / 1 ", "100.0%") ] self._check_displayed_data(0, Qt.AscendingOrder, result, "Sort view after adding a series") prepare_next_test()
[docs] def test_02_sort_on_load(self): result = [ ("Buffy the Vampire Slayer", " 1 / 1 ", "100.0%"), ("Defiance", " 1 / 3 ", "33.3%"), ("Doctor Who", " 1 / 12 ", "8.3%"), ("How I Met Your Mother", " 6 / 7 ", "85.7%"), ("Mad Love", " 1 / 2 ", "50.0%"), ("Rome: Power & Glory", " 2 / 4 ", "50.0%"), ("The Wonder Years", " 1 / 1 ", "100.0%") ] self._check_displayed_data(0, Qt.AscendingOrder, result, "Sort view after loading from data base")
[docs] def test_03_sort_series_by_name(self): target = self.header_center(self.tree_view.header(), 0) result = [ ("Buffy the Vampire Slayer", " 1 / 1 ", "100.0%"), ("Defiance", " 1 / 3 ", "33.3%"), ("Doctor Who", " 1 / 12 ", "8.3%"), ("How I Met Your Mother", " 6 / 7 ", "85.7%"), ("Mad Love", " 1 / 2 ", "50.0%"), ("Rome: Power & Glory", " 2 / 4 ", "50.0%"), ("The Wonder Years", " 1 / 1 ", "100.0%") ] self._check_displayed_data(0, Qt.AscendingOrder, result, "Sort view after loading from data base") self.click(self.tree_view.header().viewport(), target) self._check_displayed_data(0, Qt.DescendingOrder, list(reversed(result)), "Sort view after descending sort by name")
[docs] def test_04_sort_season_by_name(self):
# Expand series viewport = self.tree_view.viewport() series_node_index = self.tree_view.model().index(2, 0) item_rect = self.tree_view.visualRect(series_node_index) target = item_rect.center() self.click(viewport, target) self.click(viewport, target, double_click=True) result = [ ("Season 0", 1, "100.0%"), ("Season 1", 6, "0.0%"), ("Season 2", 1, "0.0%"), ("Season 10", 1, "0.0%"), ("Season 11", 1, "0.0%"), ("Season 20", 1, "0.0%"), ("Season 21", 1, "0.0%") ] self._check_displayed_data(0, Qt.AscendingOrder, result, "Sort season after loading from data base", parent=series_node_index) target = self.header_center(self.tree_view.header(), 0) self.click(self.tree_view.header().viewport(), target) series_node_index = self.tree_view.model().index(4, 0) # change of order changed index too self._check_displayed_data(0, Qt.DescendingOrder, result, "Changing sort order should not alter season order", parent=series_node_index)
[docs] def test_05_sort_series_by_episodes(self): target = self.header_center(self.tree_view.header(), 1) result_asc = [ ("Buffy the Vampire Slayer", " 1 / 1 ", "100.0%"), ("Defiance", " 1 / 3 ", "33.3%"), ("Doctor Who", " 1 / 12 ", "8.3%"), ("Mad Love", " 1 / 2 ", "50.0%"), ("The Wonder Years", " 1 / 1 ", "100.0%"), ("Rome: Power & Glory", " 2 / 4 ", "50.0%"), ("How I Met Your Mother", " 6 / 7 ", "85.7%") ] result_dsc = list(reversed(result_asc[-2:])) + result_asc[0:-2] self.click(self.tree_view.header().viewport(), target) self._check_displayed_data(1, Qt.AscendingOrder, result_asc, "Sort view after ascending sort by episodes") self.click(self.tree_view.header().viewport(), target) self._check_displayed_data(1, Qt.DescendingOrder, result_dsc, "Sort view after descending sort by episodes")
[docs] def test_06_sort_series_by_progress(self): """Tests 'intelligent' sorting by progress. .. seealso:: :meth:`.SortFilterProxyModel.lessThan` """ target = self.header_center(self.tree_view.header(), 2) result_asc = [ ("Doctor Who", " 1 / 12 ", "8.3%"), ("Defiance", " 1 / 3 ", "33.3%"), ("Mad Love", " 1 / 2 ", "50.0%"), ("Rome: Power & Glory", " 2 / 4 ", "50.0%"), ("How I Met Your Mother", " 6 / 7 ", "85.7%"), ("Buffy the Vampire Slayer", " 1 / 1 ", "100.0%"), ("The Wonder Years", " 1 / 1 ", "100.0%") ] result_dsc = list(reversed(result_asc[0:5])) + result_asc[5:] self.click(self.tree_view.header().viewport(), target) self._check_displayed_data(2, Qt.AscendingOrder, result_asc, "Sort view after ascending sort by progress") self.click(self.tree_view.header().viewport(), target) self._check_displayed_data(2, Qt.DescendingOrder, result_dsc, "Sort view after descending sort by progress")
[docs] def test_07_secondary_sorting(self): """Checks if entries with equal primary sort value are correctly being sorted by series name.""" target = self.header_center(self.tree_view.header(), 2) result_pre = [ ("How I Met Your Mother", " 6 / 7 ", "85.7%"), ("Rome: Power & Glory", " 2 / 4 ", "50.0%"), ("Mad Love", " 1 / 2 ", "50.0%"), ("Defiance", " 1 / 3 ", "33.3%"), ("Doctor Who", " 1 / 12 ", "8.3%"), ("Buffy the Vampire Slayer", " 1 / 1 ", "100.0%"), ("The Wonder Years", " 1 / 1 ", "100.0%") ] result = [ ("Buffy the Vampire Slayer", " 1 / 1 ", "100.0%"), ("Defiance", " 1 / 3 ", "33.3%"), ("Doctor Who", " 1 / 12 ", "8.3%"), ("Mad Love", " 1 / 2 ", "50.0%"), ("The Wonder Years", " 1 / 1 ", "100.0%"), ("Rome: Power & Glory", " 2 / 4 ", "50.0%"), ("How I Met Your Mother", " 6 / 7 ", "85.7%") ] self.click(self.tree_view.header().viewport(), target) self.click(self.tree_view.header().viewport(), target) self._check_displayed_data(2, Qt.DescendingOrder, result_pre, "Sort view after descending sort by progress") target = self.header_center(self.tree_view.header(), 1) self.click(self.tree_view.header().viewport(), target) self._check_displayed_data(1, Qt.AscendingOrder, result, "Sort view after ascending sort by episodes")
[docs] def _check_displayed_data(self, expected_section, expected_order, expected_result, msg, parent=QModelIndex()): header = self.tree_view.header() self.assertEqual(header.isSortIndicatorShown(), True, "No column seems to be sorted.") self.assertEqual(header.sortIndicatorSection(), expected_section, "Not sorted by correct column.") self.assertEqual(header.sortIndicatorOrder(), expected_order, "Not sorted by correct order.") # @formatter:off model = self.tree_view.model() for column in range(0, 3): self.assertEqual( [model.data(model.index(index, column, parent)) for index in range(0, 7)], [elem[column] for elem in expected_result], "Column '{}' not sorted correctly in case: {}.".format( self.tree_view.model().headerData(column, Qt.Horizontal, Qt.DisplayRole), msg ) )
#@formatter:on
[docs]def get_suit(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(SortingTest)) return suite
if __name__ == "__main__": unittest.TextTestRunner(verbosity=2).run(get_suit())