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, \
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

View File

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

View File

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

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"""
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):

View File

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

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 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():

View File

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

View File

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

View File

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

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