From b440584cb54a68200bd1d5bd53eea313c9a5b834 Mon Sep 17 00:00:00 2001 From: Philip Ridout Date: Wed, 20 Sep 2017 21:44:57 +0100 Subject: [PATCH] Moved the patched shuilils to the path module --- openlp/core/__init__.py | 3 +- openlp/core/common/path.py | 117 ++++++++++ openlp/core/lib/__init__.py | 29 --- openlp/core/lib/shutil.py | 112 ---------- openlp/core/ui/lib/filedialog.py | 3 +- openlp/core/ui/mainwindow.py | 3 +- .../presentations/lib/pdfcontroller.py | 3 +- .../lib/presentationcontroller.py | 3 +- .../openlp_core_common/test_path.py | 203 +++++++++++++++++- tests/functional/openlp_core_lib/test_lib.py | 34 +-- .../functional/openlp_core_lib/test_shutil.py | 170 --------------- 11 files changed, 325 insertions(+), 355 deletions(-) delete mode 100755 openlp/core/lib/shutil.py delete mode 100755 tests/functional/openlp_core_lib/test_shutil.py diff --git a/openlp/core/__init__.py b/openlp/core/__init__.py index 0fcea2d1a..8cd62a97f 100644 --- a/openlp/core/__init__.py +++ b/openlp/core/__init__.py @@ -38,10 +38,9 @@ from PyQt5 import QtCore, QtGui, QtWidgets from openlp.core.common import Registry, OpenLPMixin, AppLocation, LanguageManager, Settings, UiStrings, \ check_directory_exists, is_macosx, is_win, translate -from openlp.core.common.path import Path +from openlp.core.common.path import Path, copytree from openlp.core.common.versionchecker import VersionThread, get_application_version from openlp.core.lib import ScreenList -from openlp.core.lib.shutil import copytree from openlp.core.resources import qInitResources from openlp.core.ui import SplashScreen from openlp.core.ui.exceptionform import ExceptionForm diff --git a/openlp/core/common/path.py b/openlp/core/common/path.py index 3c4dd93c9..f11c4bb9f 100644 --- a/openlp/core/common/path.py +++ b/openlp/core/common/path.py @@ -19,6 +19,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### +import shutil from contextlib import suppress from openlp.core.common import is_win @@ -29,6 +30,121 @@ else: from pathlib import PosixPath as PathVariant +def replace_params(args, kwargs, params): + """ + Apply a transformation function to the specified args or kwargs + + :param tuple args: Positional arguments + :param dict kwargs: Key Word arguments + :param params: A tuple of tuples with the position and the key word to replace. + :return: The modified positional and keyword arguments + :rtype: tuple[tuple, dict] + + + Usage: + Take a method with the following signature, and assume we which to apply the str function to arg2: + def method(arg1=None, arg2=None, arg3=None) + + As arg2 can be specified postitionally as the second argument (1 with a zero index) or as a keyword, the we + would call this function as follows: + + replace_params(args, kwargs, ((1, 'arg2', str),)) + """ + args = list(args) + for position, key_word, transform in params: + if len(args) > position: + args[position] = transform(args[position]) + elif key_word in kwargs: + kwargs[key_word] = transform(kwargs[key_word]) + return tuple(args), kwargs + + +def copy(*args, **kwargs): + """ + Wraps :func:`shutil.copy` so that we can accept Path objects. + + :param src openlp.core.common.path.Path: Takes a Path object which is then converted to a str object + :param dst openlp.core.common.path.Path: Takes a Path object which is then converted to a str object + :return: Converts the str object received from :func:`shutil.copy` to a Path or NoneType object + :rtype: openlp.core.common.path.Path | None + + See the following link for more information on the other parameters: + https://docs.python.org/3/library/shutil.html#shutil.copy + """ + + args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str))) + + return str_to_path(shutil.copy(*args, **kwargs)) + + +def copyfile(*args, **kwargs): + """ + Wraps :func:`shutil.copyfile` so that we can accept Path objects. + + :param openlp.core.common.path.Path src: Takes a Path object which is then converted to a str object + :param openlp.core.common.path.Path dst: Takes a Path object which is then converted to a str object + :return: Converts the str object received from :func:`shutil.copyfile` to a Path or NoneType object + :rtype: openlp.core.common.path.Path | None + + See the following link for more information on the other parameters: + https://docs.python.org/3/library/shutil.html#shutil.copyfile + """ + + args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str))) + + return str_to_path(shutil.copyfile(*args, **kwargs)) + + +def copytree(*args, **kwargs): + """ + Wraps :func:shutil.copytree` so that we can accept Path objects. + + :param openlp.core.common.path.Path src : Takes a Path object which is then converted to a str object + :param openlp.core.common.path.Path dst: Takes a Path object which is then converted to a str object + :return: Converts the str object received from :func:`shutil.copytree` to a Path or NoneType object + :rtype: openlp.core.common.path.Path | None + + See the following link for more information on the other parameters: + https://docs.python.org/3/library/shutil.html#shutil.copytree + """ + + args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str))) + + return str_to_path(shutil.copytree(*args, **kwargs)) + + +def rmtree(*args, **kwargs): + """ + Wraps :func:shutil.rmtree` so that we can accept Path objects. + + :param openlp.core.common.path.Path path: Takes a Path object which is then converted to a str object + :return: Passes the return from :func:`shutil.rmtree` back + :rtype: None + + See the following link for more information on the other parameters: + https://docs.python.org/3/library/shutil.html#shutil.rmtree + """ + + args, kwargs = replace_params(args, kwargs, ((0, 'path', path_to_str),)) + + return shutil.rmtree(*args, **kwargs) + + +def which(*args, **kwargs): + """ + Wraps :func:shutil.which` so that it return a Path objects. + + :rtype: openlp.core.common.Path + + See the following link for more information on the other parameters: + https://docs.python.org/3/library/shutil.html#shutil.which + """ + file_name = shutil.which(*args, **kwargs) + if file_name: + return str_to_path(file_name) + return None + + def path_to_str(path=None): """ A utility function to convert a Path object or NoneType to a string equivalent. @@ -98,3 +214,4 @@ class Path(PathVariant): with suppress(ValueError): path = path.relative_to(base_path) return {'__Path__': path.parts} + diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 1d55df497..4602fee2c 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -611,35 +611,6 @@ def create_separated_list(string_list): return list_to_string -def replace_params(args, kwargs, params): - """ - Apply a transformation function to the specified args or kwargs - - :param tuple args: Positional arguments - :param dict kwargs: Key Word arguments - :param params: A tuple of tuples with the position and the key word to replace. - :return: The modified positional and keyword arguments - :rtype: tuple[tuple, dict] - - - Usage: - Take a method with the following signature, and assume we which to apply the str function to arg2: - def method(arg1=None, arg2=None, arg3=None) - - As arg2 can be specified postitionally as the second argument (1 with a zero index) or as a keyword, the we - would call this function as follows: - - replace_params(args, kwargs, ((1, 'arg2', str),)) - """ - args = list(args) - for position, key_word, transform in params: - if len(args) > position: - args[position] = transform(args[position]) - elif key_word in kwargs: - kwargs[key_word] = transform(kwargs[key_word]) - return tuple(args), kwargs - - from .exceptions import ValidationError from .screen import ScreenList from .formattingtags import FormattingTags diff --git a/openlp/core/lib/shutil.py b/openlp/core/lib/shutil.py deleted file mode 100755 index 1c7a9a393..000000000 --- a/openlp/core/lib/shutil.py +++ /dev/null @@ -1,112 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2017 OpenLP Developers # -# --------------------------------------------------------------------------- # -# This program is free software; you can redistribute it and/or modify it # -# under the terms of the GNU General Public License as published by the Free # -# Software Foundation; version 2 of the License. # -# # -# This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### -""" Patch the shutil methods we use so they accept and return Path objects""" -import shutil - -from openlp.core.common.path import path_to_str, str_to_path -from openlp.core.lib import replace_params - - -def copy(*args, **kwargs): - """ - Wraps :func:`shutil.copy` so that we can accept Path objects. - - :param src openlp.core.common.path.Path: Takes a Path object which is then converted to a str object - :param dst openlp.core.common.path.Path: Takes a Path object which is then converted to a str object - :return: Converts the str object received from :func:`shutil.copy` to a Path or NoneType object - :rtype: openlp.core.common.path.Path | None - - See the following link for more information on the other parameters: - https://docs.python.org/3/library/shutil.html#shutil.copy - """ - - args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str))) - - return str_to_path(shutil.copy(*args, **kwargs)) - - -def copyfile(*args, **kwargs): - """ - Wraps :func:`shutil.copyfile` so that we can accept Path objects. - - :param openlp.core.common.path.Path src: Takes a Path object which is then converted to a str object - :param openlp.core.common.path.Path dst: Takes a Path object which is then converted to a str object - :return: Converts the str object received from :func:`shutil.copyfile` to a Path or NoneType object - :rtype: openlp.core.common.path.Path | None - - See the following link for more information on the other parameters: - https://docs.python.org/3/library/shutil.html#shutil.copyfile - """ - - args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str))) - - return str_to_path(shutil.copyfile(*args, **kwargs)) - - -def copytree(*args, **kwargs): - """ - Wraps :func:shutil.copytree` so that we can accept Path objects. - - :param openlp.core.common.path.Path src : Takes a Path object which is then converted to a str object - :param openlp.core.common.path.Path dst: Takes a Path object which is then converted to a str object - :return: Converts the str object received from :func:`shutil.copytree` to a Path or NoneType object - :rtype: openlp.core.common.path.Path | None - - See the following link for more information on the other parameters: - https://docs.python.org/3/library/shutil.html#shutil.copytree - """ - - args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str))) - - return str_to_path(shutil.copytree(*args, **kwargs)) - - -def rmtree(*args, **kwargs): - """ - Wraps :func:shutil.rmtree` so that we can accept Path objects. - - :param openlp.core.common.path.Path path: Takes a Path object which is then converted to a str object - :return: Passes the return from :func:`shutil.rmtree` back - :rtype: None - - See the following link for more information on the other parameters: - https://docs.python.org/3/library/shutil.html#shutil.rmtree - """ - - args, kwargs = replace_params(args, kwargs, ((0, 'path', path_to_str),)) - - return shutil.rmtree(*args, **kwargs) - - -def which(*args, **kwargs): - """ - Wraps :func:shutil.which` so that it return a Path objects. - - :rtype: openlp.core.common.Path - - See the following link for more information on the other parameters: - https://docs.python.org/3/library/shutil.html#shutil.which - """ - file_name = shutil.which(*args, **kwargs) - if file_name: - return str_to_path(file_name) - return None diff --git a/openlp/core/ui/lib/filedialog.py b/openlp/core/ui/lib/filedialog.py index d4a702e83..0f3ef4058 100755 --- a/openlp/core/ui/lib/filedialog.py +++ b/openlp/core/ui/lib/filedialog.py @@ -22,8 +22,7 @@ """ Patch the QFileDialog so it accepts and returns Path objects""" from PyQt5 import QtWidgets -from openlp.core.common.path import Path, path_to_str, str_to_path -from openlp.core.lib import replace_params +from openlp.core.common.path import Path, path_to_str, replace_params, str_to_path class FileDialog(QtWidgets.QFileDialog): diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 88799b060..4b505b807 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -39,10 +39,9 @@ from openlp.core.api.http import server from openlp.core.common import Registry, RegistryProperties, AppLocation, LanguageManager, Settings, UiStrings, \ check_directory_exists, translate, is_win, is_macosx, add_actions from openlp.core.common.actions import ActionList, CategoryOrder -from openlp.core.common.path import Path, path_to_str, str_to_path +from openlp.core.common.path import Path, copyfile, path_to_str, str_to_path from openlp.core.common.versionchecker import get_application_version from openlp.core.lib import Renderer, PluginManager, ImageManager, PluginStatus, ScreenList, build_icon -from openlp.core.lib.shutil import copyfile from openlp.core.lib.ui import create_action from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, LiveController, PluginForm, \ ShortcutListForm, FormattingTagForm, PreviewController diff --git a/openlp/plugins/presentations/lib/pdfcontroller.py b/openlp/plugins/presentations/lib/pdfcontroller.py index a39cce36c..81fa3994a 100644 --- a/openlp/plugins/presentations/lib/pdfcontroller.py +++ b/openlp/plugins/presentations/lib/pdfcontroller.py @@ -27,9 +27,8 @@ from subprocess import check_output, CalledProcessError from openlp.core.common import AppLocation, check_binary_exists from openlp.core.common import Settings, is_win -from openlp.core.common.path import Path, path_to_str +from openlp.core.common.path import which from openlp.core.lib import ScreenList -from openlp.core.lib.shutil import which from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument if is_win(): diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py index 3225eac24..304d70833 100644 --- a/openlp/plugins/presentations/lib/presentationcontroller.py +++ b/openlp/plugins/presentations/lib/presentationcontroller.py @@ -24,9 +24,8 @@ import logging from PyQt5 import QtCore from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, md5_hash -from openlp.core.common.path import Path +from openlp.core.common.path import Path, rmtree from openlp.core.lib import create_thumb, validate_thumb -from openlp.core.lib.shutil import rmtree log = logging.getLogger(__name__) diff --git a/tests/functional/openlp_core_common/test_path.py b/tests/functional/openlp_core_common/test_path.py index f5abcffd5..0f35319c9 100644 --- a/tests/functional/openlp_core_common/test_path.py +++ b/tests/functional/openlp_core_common/test_path.py @@ -24,8 +24,209 @@ Package to test the openlp.core.common.path package. """ import os from unittest import TestCase +from unittest.mock import ANY, MagicMock, patch -from openlp.core.common.path import Path, path_to_str, str_to_path +from openlp.core.common.path import Path, copy, copyfile, copytree, path_to_str, replace_params, rmtree, str_to_path, \ + which + + +class TestShutil(TestCase): + """ + Tests for the :mod:`openlp.core.common.path` module + """ + def test_replace_params_no_params(self): + """ + Test replace_params when called with and empty tuple instead of parameters to replace + """ + # GIVEN: Some test data + test_args = (1, 2) + test_kwargs = {'arg3': 3, 'arg4': 4} + test_params = tuple() + + # WHEN: Calling replace_params + result_args, result_kwargs = replace_params(test_args, test_kwargs, test_params) + + # THEN: The positional and keyword args should not have changed + self.assertEqual(test_args, result_args) + self.assertEqual(test_kwargs, result_kwargs) + + def test_replace_params_params(self): + """ + Test replace_params when given a positional and a keyword argument to change + """ + # GIVEN: Some test data + test_args = (1, 2) + test_kwargs = {'arg3': 3, 'arg4': 4} + test_params = ((1, 'arg2', str), (2, 'arg3', str)) + + # WHEN: Calling replace_params + result_args, result_kwargs = replace_params(test_args, test_kwargs, test_params) + + # THEN: The positional and keyword args should have have changed + self.assertEqual(result_args, (1, '2')) + self.assertEqual(result_kwargs, {'arg3': '3', 'arg4': 4}) + + def test_copy(self): + """ + Test :func:`openlp.core.common.path.copy` + """ + # GIVEN: A mocked `shutil.copy` which returns a test path as a string + with patch('openlp.core.common.path.shutil.copy', return_value=os.path.join('destination', 'test', 'path')) \ + as mocked_shutil_copy: + + # WHEN: Calling :func:`openlp.core.common.path.copy` with the src and dst parameters as Path object types + result = copy(Path('source', 'test', 'path'), Path('destination', 'test', 'path')) + + # THEN: :func:`shutil.copy` should have been called with the str equivalents of the Path objects. + # :func:`openlp.core.common.path.copy` should return the str type result of calling + # :func:`shutil.copy` as a Path object. + mocked_shutil_copy.assert_called_once_with(os.path.join('source', 'test', 'path'), + os.path.join('destination', 'test', 'path')) + self.assertEqual(result, Path('destination', 'test', 'path')) + + def test_copy_follow_optional_params(self): + """ + Test :func:`openlp.core.common.path.copy` when follow_symlinks is set to false + """ + # GIVEN: A mocked `shutil.copy` + with patch('openlp.core.common.path.shutil.copy', return_value='') as mocked_shutil_copy: + + # WHEN: Calling :func:`openlp.core.common.path.copy` with :param:`follow_symlinks` set to False + copy(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), follow_symlinks=False) + + # THEN: :func:`shutil.copy` should have been called with :param:`follow_symlinks` set to false + mocked_shutil_copy.assert_called_once_with(ANY, ANY, follow_symlinks=False) + + def test_copyfile(self): + """ + Test :func:`openlp.core.common.path.copyfile` + """ + # GIVEN: A mocked :func:`shutil.copyfile` which returns a test path as a string + with patch('openlp.core.common.path.shutil.copyfile', + return_value=os.path.join('destination', 'test', 'path')) as mocked_shutil_copyfile: + + # WHEN: Calling :func:`openlp.core.common.path.copyfile` with the src and dst parameters as Path object + # types + result = copyfile(Path('source', 'test', 'path'), Path('destination', 'test', 'path')) + + # THEN: :func:`shutil.copyfile` should have been called with the str equivalents of the Path objects. + # :func:`openlp.core.common.path.copyfile` should return the str type result of calling + # :func:`shutil.copyfile` as a Path object. + mocked_shutil_copyfile.assert_called_once_with(os.path.join('source', 'test', 'path'), + os.path.join('destination', 'test', 'path')) + self.assertEqual(result, Path('destination', 'test', 'path')) + + def test_copyfile_optional_params(self): + """ + Test :func:`openlp.core.common.path.copyfile` when follow_symlinks is set to false + """ + # GIVEN: A mocked :func:`shutil.copyfile` + with patch('openlp.core.common.path.shutil.copyfile', return_value='') as mocked_shutil_copyfile: + + # WHEN: Calling :func:`openlp.core.common.path.copyfile` with :param:`follow_symlinks` set to False + copyfile(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), follow_symlinks=False) + + # THEN: :func:`shutil.copyfile` should have been called with the optional parameters, with out any of the + # values being modified + mocked_shutil_copyfile.assert_called_once_with(ANY, ANY, follow_symlinks=False) + + def test_copytree(self): + """ + Test :func:`openlp.core.common.path.copytree` + """ + # GIVEN: A mocked :func:`shutil.copytree` which returns a test path as a string + with patch('openlp.core.common.path.shutil.copytree', + return_value=os.path.join('destination', 'test', 'path')) as mocked_shutil_copytree: + + # WHEN: Calling :func:`openlp.core.common.path.copytree` with the src and dst parameters as Path object + # types + result = copytree(Path('source', 'test', 'path'), Path('destination', 'test', 'path')) + + # THEN: :func:`shutil.copytree` should have been called with the str equivalents of the Path objects. + # :func:`openlp.core.common.path.copytree` should return the str type result of calling + # :func:`shutil.copytree` as a Path object. + mocked_shutil_copytree.assert_called_once_with(os.path.join('source', 'test', 'path'), + os.path.join('destination', 'test', 'path')) + self.assertEqual(result, Path('destination', 'test', 'path')) + + def test_copytree_optional_params(self): + """ + Test :func:`openlp.core.common.path.copytree` when optional parameters are passed + """ + # GIVEN: A mocked :func:`shutil.copytree` + with patch('openlp.core.common.path.shutil.copytree', return_value='') as mocked_shutil_copytree: + mocked_ignore = MagicMock() + mocked_copy_function = MagicMock() + + # WHEN: Calling :func:`openlp.core.common.path.copytree` with the optional parameters set + copytree(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), symlinks=True, + ignore=mocked_ignore, copy_function=mocked_copy_function, ignore_dangling_symlinks=True) + + # THEN: :func:`shutil.copytree` should have been called with the optional parameters, with out any of the + # values being modified + mocked_shutil_copytree.assert_called_once_with(ANY, ANY, symlinks=True, ignore=mocked_ignore, + copy_function=mocked_copy_function, + ignore_dangling_symlinks=True) + + def test_rmtree(self): + """ + Test :func:`rmtree` + """ + # GIVEN: A mocked :func:`shutil.rmtree` + with patch('openlp.core.common.path.shutil.rmtree', return_value=None) as mocked_shutil_rmtree: + + # WHEN: Calling :func:`openlp.core.common.path.rmtree` with the path parameter as Path object type + result = rmtree(Path('test', 'path')) + + # THEN: :func:`shutil.rmtree` should have been called with the str equivalents of the Path object. + mocked_shutil_rmtree.assert_called_once_with(os.path.join('test', 'path')) + self.assertIsNone(result) + + def test_rmtree_optional_params(self): + """ + Test :func:`openlp.core.common.path.rmtree` when optional parameters are passed + """ + # GIVEN: A mocked :func:`shutil.rmtree` + with patch('openlp.core.common.path.shutil.rmtree', return_value='') as mocked_shutil_rmtree: + mocked_on_error = MagicMock() + + # WHEN: Calling :func:`openlp.core.common.path.rmtree` with :param:`ignore_errors` set to True and + # :param:`onerror` set to a mocked object + rmtree(Path('test', 'path'), ignore_errors=True, onerror=mocked_on_error) + + # THEN: :func:`shutil.rmtree` should have been called with the optional parameters, with out any of the + # values being modified + mocked_shutil_rmtree.assert_called_once_with(ANY, ignore_errors=True, onerror=mocked_on_error) + + def test_which_no_command(self): + """ + Test :func:`openlp.core.common.path.which` when the command is not found. + """ + # GIVEN: A mocked :func:`shutil.which` when the command is not found. + with patch('openlp.core.common.path.shutil.which', return_value=None) as mocked_shutil_which: + + # WHEN: Calling :func:`openlp.core.common.path.which` with a command that does not exist. + result = which('no_command') + + # THEN: :func:`shutil.which` should have been called with the command, and :func:`which` should return None. + mocked_shutil_which.assert_called_once_with('no_command') + self.assertIsNone(result) + + def test_which_command(self): + """ + Test :func:`openlp.core.common.path.which` when a command has been found. + """ + # GIVEN: A mocked :func:`shutil.which` when the command is found. + with patch('openlp.core.common.path.shutil.which', + return_value=os.path.join('path', 'to', 'command')) as mocked_shutil_which: + + # WHEN: Calling :func:`openlp.core.common.path.which` with a command that exists. + result = which('command') + + # THEN: :func:`shutil.which` should have been called with the command, and :func:`which` should return a + # Path object equivalent of the command path. + mocked_shutil_which.assert_called_once_with('command') + self.assertEqual(result, Path('path', 'to', 'command')) class TestPath(TestCase): diff --git a/tests/functional/openlp_core_lib/test_lib.py b/tests/functional/openlp_core_lib/test_lib.py index 8b46e99c3..96e78e351 100644 --- a/tests/functional/openlp_core_lib/test_lib.py +++ b/tests/functional/openlp_core_lib/test_lib.py @@ -32,7 +32,7 @@ from PyQt5 import QtCore, QtGui from openlp.core.common.path import Path from openlp.core.lib import FormattingTags, build_icon, check_item_selected, clean_tags, compare_chord_lyric, \ create_separated_list, create_thumb, expand_chords, expand_chords_for_printing, expand_tags, find_formatting_tags, \ - get_text_file_string, image_to_byte, replace_params, resize_image, str_to_bool, validate_thumb + get_text_file_string, image_to_byte, resize_image, str_to_bool, validate_thumb TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'resources')) @@ -636,38 +636,6 @@ class TestLib(TestCase): thumb_path.stat.assert_called_once_with() self.assertFalse(result, 'The result should be False') - def test_replace_params_no_params(self): - """ - Test replace_params when called with and empty tuple instead of parameters to replace - """ - # GIVEN: Some test data - test_args = (1, 2) - test_kwargs = {'arg3': 3, 'arg4': 4} - test_params = tuple() - - # WHEN: Calling replace_params - result_args, result_kwargs = replace_params(test_args, test_kwargs, test_params) - - # THEN: The positional and keyword args should not have changed - self.assertEqual(test_args, result_args) - self.assertEqual(test_kwargs, result_kwargs) - - def test_replace_params_params(self): - """ - Test replace_params when given a positional and a keyword argument to change - """ - # GIVEN: Some test data - test_args = (1, 2) - test_kwargs = {'arg3': 3, 'arg4': 4} - test_params = ((1, 'arg2', str), (2, 'arg3', str)) - - # WHEN: Calling replace_params - result_args, result_kwargs = replace_params(test_args, test_kwargs, test_params) - - # THEN: The positional and keyword args should have have changed - self.assertEqual(result_args, (1, '2')) - self.assertEqual(result_kwargs, {'arg3': '3', 'arg4': 4}) - def test_resize_thumb(self): """ Test the resize_thumb() function diff --git a/tests/functional/openlp_core_lib/test_shutil.py b/tests/functional/openlp_core_lib/test_shutil.py deleted file mode 100755 index 737f7ce00..000000000 --- a/tests/functional/openlp_core_lib/test_shutil.py +++ /dev/null @@ -1,170 +0,0 @@ -import os -from unittest import TestCase -from unittest.mock import ANY, MagicMock, patch - -from openlp.core.common.path import Path -from openlp.core.lib.shutil import copy, copyfile, copytree, rmtree, which - - -class TestShutil(TestCase): - """ - Tests for the :mod:`openlp.core.lib.shutil` module - """ - - def test_copy(self): - """ - Test :func:`copy` - """ - # GIVEN: A mocked `shutil.copy` which returns a test path as a string - with patch('openlp.core.lib.shutil.shutil.copy', return_value=os.path.join('destination', 'test', 'path')) \ - as mocked_shutil_copy: - - # WHEN: Calling :func:`copy` with the src and dst parameters as Path object types - result = copy(Path('source', 'test', 'path'), Path('destination', 'test', 'path')) - - # THEN: :func:`shutil.copy` should have been called with the str equivalents of the Path objects. - # :func:`copy` should return the str type result of calling :func:`shutil.copy` as a Path object. - mocked_shutil_copy.assert_called_once_with(os.path.join('source', 'test', 'path'), - os.path.join('destination', 'test', 'path')) - self.assertEqual(result, Path('destination', 'test', 'path')) - - def test_copy_follow_optional_params(self): - """ - Test :func:`copy` when follow_symlinks is set to false - """ - # GIVEN: A mocked `shutil.copy` - with patch('openlp.core.lib.shutil.shutil.copy', return_value='') as mocked_shutil_copy: - - # WHEN: Calling :func:`copy` with :param:`follow_symlinks` set to False - copy(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), follow_symlinks=False) - - # THEN: :func:`shutil.copy` should have been called with :param:`follow_symlinks` set to false - mocked_shutil_copy.assert_called_once_with(ANY, ANY, follow_symlinks=False) - - def test_copyfile(self): - """ - Test :func:`copyfile` - """ - # GIVEN: A mocked :func:`shutil.copyfile` which returns a test path as a string - with patch('openlp.core.lib.shutil.shutil.copyfile', - return_value=os.path.join('destination', 'test', 'path')) as mocked_shutil_copyfile: - - # WHEN: Calling :func:`copyfile` with the src and dst parameters as Path object types - result = copyfile(Path('source', 'test', 'path'), Path('destination', 'test', 'path')) - - # THEN: :func:`shutil.copyfile` should have been called with the str equivalents of the Path objects. - # :func:`copyfile` should return the str type result of calling :func:`shutil.copyfile` as a Path - # object. - mocked_shutil_copyfile.assert_called_once_with(os.path.join('source', 'test', 'path'), - os.path.join('destination', 'test', 'path')) - self.assertEqual(result, Path('destination', 'test', 'path')) - - def test_copyfile_optional_params(self): - """ - Test :func:`copyfile` when follow_symlinks is set to false - """ - # GIVEN: A mocked :func:`shutil.copyfile` - with patch('openlp.core.lib.shutil.shutil.copyfile', return_value='') as mocked_shutil_copyfile: - - # WHEN: Calling :func:`copyfile` with :param:`follow_symlinks` set to False - copyfile(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), follow_symlinks=False) - - # THEN: :func:`shutil.copyfile` should have been called with the optional parameters, with out any of the - # values being modified - mocked_shutil_copyfile.assert_called_once_with(ANY, ANY, follow_symlinks=False) - - def test_copytree(self): - """ - Test :func:`copytree` - """ - # GIVEN: A mocked :func:`shutil.copytree` which returns a test path as a string - with patch('openlp.core.lib.shutil.shutil.copytree', - return_value=os.path.join('destination', 'test', 'path')) as mocked_shutil_copytree: - - # WHEN: Calling :func:`copytree` with the src and dst parameters as Path object types - result = copytree(Path('source', 'test', 'path'), Path('destination', 'test', 'path')) - - # THEN: :func:`shutil.copytree` should have been called with the str equivalents of the Path objects. - # :func:`patches.copytree` should return the str type result of calling :func:`shutil.copytree` as a - # Path object. - mocked_shutil_copytree.assert_called_once_with(os.path.join('source', 'test', 'path'), - os.path.join('destination', 'test', 'path')) - self.assertEqual(result, Path('destination', 'test', 'path')) - - def test_copytree_optional_params(self): - """ - Test :func:`copytree` when optional parameters are passed - """ - # GIVEN: A mocked :func:`shutil.copytree` - with patch('openlp.core.lib.shutil.shutil.copytree', return_value='') as mocked_shutil_copytree: - mocked_ignore = MagicMock() - mocked_copy_function = MagicMock() - - # WHEN: Calling :func:`copytree` with the optional parameters set - copytree(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), symlinks=True, - ignore=mocked_ignore, copy_function=mocked_copy_function, ignore_dangling_symlinks=True) - - # THEN: :func:`shutil.copytree` should have been called with the optional parameters, with out any of the - # values being modified - mocked_shutil_copytree.assert_called_once_with(ANY, ANY, symlinks=True, ignore=mocked_ignore, - copy_function=mocked_copy_function, - ignore_dangling_symlinks=True) - - def test_rmtree(self): - """ - Test :func:`rmtree` - """ - # GIVEN: A mocked :func:`shutil.rmtree` - with patch('openlp.core.lib.shutil.shutil.rmtree', return_value=None) as mocked_shutil_rmtree: - - # WHEN: Calling :func:`rmtree` with the path parameter as Path object type - result = rmtree(Path('test', 'path')) - - # THEN: :func:`shutil.rmtree` should have been called with the str equivalents of the Path object. - mocked_shutil_rmtree.assert_called_once_with(os.path.join('test', 'path')) - self.assertIsNone(result) - - def test_rmtree_optional_params(self): - """ - Test :func:`rmtree` when optional parameters are passed - """ - # GIVEN: A mocked :func:`shutil.rmtree` - with patch('openlp.core.lib.shutil.shutil.rmtree', return_value='') as mocked_shutil_rmtree: - mocked_on_error = MagicMock() - - # WHEN: Calling :func:`rmtree` with :param:`ignore_errors` set to True and `onerror` set to a mocked object - rmtree(Path('test', 'path'), ignore_errors=True, onerror=mocked_on_error) - - # THEN: :func:`shutil.rmtree` should have been called with the optional parameters, with out any of the - # values being modified - mocked_shutil_rmtree.assert_called_once_with(ANY, ignore_errors=True, onerror=mocked_on_error) - - def test_which_no_command(self): - """ - Test :func:`which` when the command is not found. - """ - # GIVEN: A mocked :func:``shutil.which` when the command is not found. - with patch('openlp.core.lib.shutil.shutil.which', return_value=None) as mocked_shutil_which: - - # WHEN: Calling :func:`which` with a command that does not exist. - result = which('no_command') - - # THEN: :func:`shutil.which` should have been called with the command, and :func:`which` should return None. - mocked_shutil_which.assert_called_once_with('no_command') - self.assertIsNone(result) - - def test_which_command(self): - """ - Test :func:`which` when a command has been found. - """ - # GIVEN: A mocked :func:`shutil.which` when the command is found. - with patch('openlp.core.lib.shutil.shutil.which', - return_value=os.path.join('path', 'to', 'command')) as mocked_shutil_which: - - # WHEN: Calling :func:`which` with a command that exists. - result = which('command') - - # THEN: :func:`shutil.which` should have been called with the command, and :func:`which` should return a - # Path object equivalent of the command path. - mocked_shutil_which.assert_called_once_with('command') - self.assertEqual(result, Path('path', 'to', 'command'))