Moved the patched shuilils to the path module

This commit is contained in:
Philip Ridout 2017-09-20 21:44:57 +01:00
parent 92c6b9c09d
commit b440584cb5
11 changed files with 325 additions and 355 deletions

View File

@ -38,10 +38,9 @@ from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, OpenLPMixin, AppLocation, LanguageManager, Settings, UiStrings, \ from openlp.core.common import Registry, OpenLPMixin, AppLocation, LanguageManager, Settings, UiStrings, \
check_directory_exists, is_macosx, is_win, translate 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.common.versionchecker import VersionThread, get_application_version
from openlp.core.lib import ScreenList from openlp.core.lib import ScreenList
from openlp.core.lib.shutil import copytree
from openlp.core.resources import qInitResources from openlp.core.resources import qInitResources
from openlp.core.ui import SplashScreen from openlp.core.ui import SplashScreen
from openlp.core.ui.exceptionform import ExceptionForm from openlp.core.ui.exceptionform import ExceptionForm

View File

@ -19,6 +19,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
import shutil
from contextlib import suppress from contextlib import suppress
from openlp.core.common import is_win from openlp.core.common import is_win
@ -29,6 +30,121 @@ else:
from pathlib import PosixPath as PathVariant 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): def path_to_str(path=None):
""" """
A utility function to convert a Path object or NoneType to a string equivalent. A utility function to convert a Path object or NoneType to a string equivalent.
@ -98,3 +214,4 @@ class Path(PathVariant):
with suppress(ValueError): with suppress(ValueError):
path = path.relative_to(base_path) path = path.relative_to(base_path)
return {'__Path__': path.parts} return {'__Path__': path.parts}

View File

@ -611,35 +611,6 @@ def create_separated_list(string_list):
return list_to_string 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 .exceptions import ValidationError
from .screen import ScreenList from .screen import ScreenList
from .formattingtags import FormattingTags from .formattingtags import FormattingTags

View File

@ -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

View File

@ -22,8 +22,7 @@
""" Patch the QFileDialog so it accepts and returns Path objects""" """ Patch the QFileDialog so it accepts and returns Path objects"""
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
from openlp.core.common.path import Path, path_to_str, str_to_path from openlp.core.common.path import Path, path_to_str, replace_params, str_to_path
from openlp.core.lib import replace_params
class FileDialog(QtWidgets.QFileDialog): class FileDialog(QtWidgets.QFileDialog):

View File

@ -39,10 +39,9 @@ from openlp.core.api.http import server
from openlp.core.common import Registry, RegistryProperties, AppLocation, LanguageManager, Settings, UiStrings, \ from openlp.core.common import Registry, RegistryProperties, AppLocation, LanguageManager, Settings, UiStrings, \
check_directory_exists, translate, is_win, is_macosx, add_actions check_directory_exists, translate, is_win, is_macosx, add_actions
from openlp.core.common.actions import ActionList, CategoryOrder 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.common.versionchecker import get_application_version
from openlp.core.lib import Renderer, PluginManager, ImageManager, PluginStatus, ScreenList, build_icon 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.lib.ui import create_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, LiveController, PluginForm, \ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, LiveController, PluginForm, \
ShortcutListForm, FormattingTagForm, PreviewController ShortcutListForm, FormattingTagForm, PreviewController

View File

@ -27,9 +27,8 @@ from subprocess import check_output, CalledProcessError
from openlp.core.common import AppLocation, check_binary_exists from openlp.core.common import AppLocation, check_binary_exists
from openlp.core.common import Settings, is_win 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 import ScreenList
from openlp.core.lib.shutil import which
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
if is_win(): if is_win():

View File

@ -24,9 +24,8 @@ import logging
from PyQt5 import QtCore from PyQt5 import QtCore
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, md5_hash 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 import create_thumb, validate_thumb
from openlp.core.lib.shutil import rmtree
log = logging.getLogger(__name__) log = logging.getLogger(__name__)

View File

@ -24,8 +24,209 @@ Package to test the openlp.core.common.path package.
""" """
import os import os
from unittest import TestCase 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): class TestPath(TestCase):

View File

@ -32,7 +32,7 @@ from PyQt5 import QtCore, QtGui
from openlp.core.common.path import Path from openlp.core.common.path import Path
from openlp.core.lib import FormattingTags, build_icon, check_item_selected, clean_tags, compare_chord_lyric, \ 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, \ 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')) 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() thumb_path.stat.assert_called_once_with()
self.assertFalse(result, 'The result should be False') 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): def test_resize_thumb(self):
""" """
Test the resize_thumb() function Test the resize_thumb() function

View File

@ -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'))