Update the path edit component to use the pathlib module. Add a few utility methods

This commit is contained in:
Philip Ridout 2017-08-04 18:40:57 +01:00
parent cb451b88af
commit 03bcc194ea
17 changed files with 650 additions and 110 deletions

View File

@ -0,0 +1,61 @@
# -*- 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 #
###############################################################################
from pathlib import Path
def path_to_str(path):
"""
A utility function to convert a Path object or NoneType to a string equivalent.
:param path: The value to convert to a string
:type: pathlib.Path or None
:return: An empty string if :param:`path` is None, else a string representation of the :param:`path`
:rtype: str
"""
if not isinstance(path, Path) and path is not None:
raise TypeError('parameter \'path\' must be of type Path or NoneType')
if path is None:
return ''
else:
return str(path)
def str_to_path(string):
"""
A utility function to convert a str object to a Path or NoneType.
This function is of particular use because initating a Path object with an empty string causes the Path object to
point to the current working directory.
:param string: The string to convert
:type string: str
:return: None if :param:`string` is empty, or a Path object representation of :param:`string`
:rtype: pathlib.Path or None
"""
if not isinstance(string, str):
raise TypeError('parameter \'string\' must be of type str')
if string == '':
return None
return Path(string)

View File

@ -608,6 +608,41 @@ 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 args: Positional arguments
:type args: (,)
:param kwargs: Key Word arguments
:type kwargs: dict
:param params: A tuple of tuples with the position and the key word to replace.
:type params: ((int, str, path_to_str),)
:return: The modified positional and keyword arguments
:rtype: (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 .filedialog import FileDialog
from .screen import ScreenList

View File

@ -30,6 +30,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import AppLocation, Settings, SlideLimits, UiStrings, translate
from openlp.core.common.languagemanager import format_time
from openlp.core.common.path import path_to_str
from openlp.core.lib import SettingsTab, build_icon
from openlp.core.ui.lib import PathEdit, PathType
@ -156,7 +157,7 @@ class AdvancedTab(SettingsTab):
self.data_directory_new_label = QtWidgets.QLabel(self.data_directory_group_box)
self.data_directory_new_label.setObjectName('data_directory_current_label')
self.data_directory_path_edit = PathEdit(self.data_directory_group_box, path_type=PathType.Directories,
default_path=str(AppLocation.get_directory(AppLocation.DataDir)))
default_path=AppLocation.get_directory(AppLocation.DataDir))
self.data_directory_layout.addRow(self.data_directory_new_label, self.data_directory_path_edit)
self.new_data_directory_has_files_label = QtWidgets.QLabel(self.data_directory_group_box)
self.new_data_directory_has_files_label.setObjectName('new_data_directory_has_files_label')
@ -373,7 +374,7 @@ class AdvancedTab(SettingsTab):
self.new_data_directory_has_files_label.hide()
self.data_directory_cancel_button.hide()
# Since data location can be changed, make sure the path is present.
self.data_directory_path_edit.path = str(AppLocation.get_data_path())
self.data_directory_path_edit.path = AppLocation.get_data_path()
# Don't allow data directory move if running portable.
if settings.value('advanced/is portable'):
self.data_directory_group_box.hide()
@ -497,12 +498,12 @@ class AdvancedTab(SettingsTab):
'closed.').format(path=new_data_path),
defaultButton=QtWidgets.QMessageBox.No)
if answer != QtWidgets.QMessageBox.Yes:
self.data_directory_path_edit.path = str(AppLocation.get_data_path())
self.data_directory_path_edit.path = AppLocation.get_data_path()
return
# Check if data already exists here.
self.check_data_overwrite(new_data_path)
self.check_data_overwrite(path_to_str(new_data_path))
# Save the new location.
self.main_window.set_new_data_path(new_data_path)
self.main_window.set_new_data_path(path_to_str(new_data_path))
self.data_directory_cancel_button.show()
def on_data_directory_copy_check_box_toggled(self):
@ -550,7 +551,7 @@ class AdvancedTab(SettingsTab):
"""
Cancel the data directory location change
"""
self.data_directory_path_edit.path = str(AppLocation.get_data_path())
self.data_directory_path_edit.path = AppLocation.get_data_path()
self.data_directory_copy_check_box.setChecked(False)
self.main_window.set_new_data_path(None)
self.main_window.set_copy_data(False)

View File

@ -23,6 +23,7 @@
The general tab of the configuration dialog.
"""
import logging
from pathlib import Path
from PyQt5 import QtCore, QtGui, QtWidgets
@ -172,7 +173,8 @@ class GeneralTab(SettingsTab):
self.logo_layout.setObjectName('logo_layout')
self.logo_file_label = QtWidgets.QLabel(self.logo_group_box)
self.logo_file_label.setObjectName('logo_file_label')
self.logo_file_path_edit = PathEdit(self.logo_group_box, default_path=':/graphics/openlp-splash-screen.png')
self.logo_file_path_edit = PathEdit(self.logo_group_box,
default_path=Path(':/graphics/openlp-splash-screen.png'))
self.logo_layout.addRow(self.logo_file_label, self.logo_file_path_edit)
self.logo_color_label = QtWidgets.QLabel(self.logo_group_box)
self.logo_color_label.setObjectName('logo_color_label')
@ -266,7 +268,7 @@ class GeneralTab(SettingsTab):
self.audio_group_box.setTitle(translate('OpenLP.GeneralTab', 'Background Audio'))
self.start_paused_check_box.setText(translate('OpenLP.GeneralTab', 'Start background audio paused'))
self.repeat_list_check_box.setText(translate('OpenLP.GeneralTab', 'Repeat track list'))
self.logo_file_path_edit.dialog_caption = dialog_caption = translate('OpenLP.AdvancedTab', 'Select Logo File')
self.logo_file_path_edit.dialog_caption = translate('OpenLP.AdvancedTab', 'Select Logo File')
self.logo_file_path_edit.filters = '{text};;{names} (*)'.format(
text=get_images_filter(), names=UiStrings().AllFiles)
@ -325,7 +327,7 @@ class GeneralTab(SettingsTab):
settings.setValue('auto open', self.auto_open_check_box.isChecked())
settings.setValue('show splash', self.show_splash_check_box.isChecked())
settings.setValue('logo background color', self.logo_background_color)
settings.setValue('logo file', self.logo_file_path_edit.path)
settings.setValue('logo file', str(self.logo_file_path_edit.path))
settings.setValue('logo hide on startup', self.logo_hide_on_startup_check_box.isChecked())
settings.setValue('update check', self.check_for_updates_check_box.isChecked())
settings.setValue('save prompt', self.save_check_service_check_box.isChecked())

View File

@ -0,0 +1,118 @@
# -*- 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 QFileDialog so it accepts and returns Path objects"""
from functools import wraps
from pathlib import Path
from PyQt5 import QtWidgets
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.lib import replace_params
class PQFileDialog(QtWidgets.QFileDialog):
@classmethod
@wraps(QtWidgets.QFileDialog.getExistingDirectory)
def getExistingDirectory(cls, *args, **kwargs):
"""
Reimplement `getExistingDirectory` so that it can be called with, and return Path objects
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[Path, str]
"""
args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
return_value = super().getExistingDirectory(*args, **kwargs)
# getExistingDirectory returns a str that represents the path. The string is empty if the user cancels the
# dialog.
return str_to_path(return_value)
@classmethod
@wraps(QtWidgets.QFileDialog.getOpenFileName)
def getOpenFileName(cls, *args, **kwargs):
"""
Reimplement `getOpenFileName` so that it can be called with, and return Path objects
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[Path, str]
"""
args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
return_value = super().getOpenFileName(*args, **kwargs)
# getOpenFileName returns a tuple. The first item is a of str's that represents the path. The string is empty if
# the user cancels the dialog.
return str_to_path(return_value[0]), return_value[1]
@classmethod
def getOpenFileNames(cls, *args, **kwargs):
"""
Reimplement `getOpenFileNames` so that it can be called with, and return Path objects
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[list[Path], str]
"""
args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
return_value = super().getOpenFileNames(*args, **kwargs)
# getSaveFileName returns a tuple. The first item is a list of str's that represents the path. The list is
# empty if the user cancels the dialog.
paths = [str_to_path(path) for path in return_value[0]]
return paths, return_value[1]
@classmethod
def getSaveFileName(cls, *args, **kwargs):
"""
Reimplement `getSaveFileName` so that it can be called with, and return Path objects
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[Path or None, str]
"""
args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
return_value = super().getSaveFileName(*args, **kwargs)
# getSaveFileName returns a tuple. The first item represents the path as a str. The string is empty if the user
# cancels the dialog.
return str_to_path(return_value[0]), return_value[1]

View File

@ -20,12 +20,14 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from enum import Enum
import os.path
from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import UiStrings, translate
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.lib import build_icon
from openlp.core.ui.lib.filedialogpatches import PQFileDialog
class PathType(Enum):
@ -38,11 +40,12 @@ class PathEdit(QtWidgets.QWidget):
The :class:`~openlp.core.ui.lib.pathedit.PathEdit` class subclasses QWidget to create a custom widget for use when
a file or directory needs to be selected.
"""
pathChanged = QtCore.pyqtSignal(str)
pathChanged = QtCore.pyqtSignal(Path)
def __init__(self, parent=None, path_type=PathType.Files, default_path=None, dialog_caption=None, show_revert=True):
"""
Initalise the PathEdit widget
Initialise the PathEdit widget
:param parent: The parent of the widget. This is just passed to the super method.
:type parent: QWidget or None
@ -51,9 +54,9 @@ class PathEdit(QtWidgets.QWidget):
:type dialog_caption: str
:param default_path: The default path. This is set as the path when the revert button is clicked
:type default_path: str
:type default_path: pathlib.Path
:param show_revert: Used to determin if the 'revert button' should be visible.
:param show_revert: Used to determine if the 'revert button' should be visible.
:type show_revert: bool
:return: None
@ -79,7 +82,6 @@ class PathEdit(QtWidgets.QWidget):
widget_layout = QtWidgets.QHBoxLayout()
widget_layout.setContentsMargins(0, 0, 0, 0)
self.line_edit = QtWidgets.QLineEdit(self)
self.line_edit.setText(self._path)
widget_layout.addWidget(self.line_edit)
self.browse_button = QtWidgets.QToolButton(self)
self.browse_button.setIcon(build_icon(':/general/general_open.png'))
@ -101,7 +103,7 @@ class PathEdit(QtWidgets.QWidget):
A property getter method to return the selected path.
:return: The selected path
:rtype: str
:rtype: pathlib.Path
"""
return self._path
@ -111,11 +113,15 @@ class PathEdit(QtWidgets.QWidget):
A Property setter method to set the selected path
:param path: The path to set the widget to
:type path: str
:type path: pathlib.Path
:return: None
:rtype: None
"""
self._path = path
self.line_edit.setText(path)
self.line_edit.setToolTip(path)
text = path_to_str(path)
self.line_edit.setText(text)
self.line_edit.setToolTip(text)
@property
def path_type(self):
@ -124,7 +130,7 @@ class PathEdit(QtWidgets.QWidget):
selecting a file or directory.
:return: The type selected
:rtype: Enum of PathEdit
:rtype: PathType
"""
return self._path_type
@ -133,8 +139,11 @@ class PathEdit(QtWidgets.QWidget):
"""
A Property setter method to set the path type
:param path: The type of path to select
:type path: Enum of PathEdit
:param path_type: The type of path to select
:type path_type: PathType
:return: None
:rtype: None
"""
self._path_type = path_type
self.update_button_tool_tips()
@ -142,7 +151,9 @@ class PathEdit(QtWidgets.QWidget):
def update_button_tool_tips(self):
"""
Called to update the tooltips on the buttons. This is changing path types, and when the widget is initalised
:return: None
:rtype: None
"""
if self._path_type == PathType.Directories:
self.browse_button.setToolTip(translate('OpenLP.PathEdit', 'Browse for directory.'))
@ -156,21 +167,21 @@ class PathEdit(QtWidgets.QWidget):
A handler to handle a click on the browse button.
Show the QFileDialog and process the input from the user
:return: None
:rtype: None
"""
caption = self.dialog_caption
path = ''
path = None
if self._path_type == PathType.Directories:
if not caption:
caption = translate('OpenLP.PathEdit', 'Select Directory')
path = QtWidgets.QFileDialog.getExistingDirectory(self, caption,
self._path, QtWidgets.QFileDialog.ShowDirsOnly)
path = PQFileDialog.getExistingDirectory(self, caption, self._path, PQFileDialog.ShowDirsOnly)
elif self._path_type == PathType.Files:
if not caption:
caption = self.dialog_caption = translate('OpenLP.PathEdit', 'Select File')
path, filter_used = QtWidgets.QFileDialog.getOpenFileName(self, caption, self._path, self.filters)
path, filter_used = PQFileDialog.getOpenFileName(self, caption, self._path, self.filters)
if path:
path = os.path.normpath(path)
self.on_new_path(path)
def on_revert_button_clicked(self):
@ -178,16 +189,21 @@ class PathEdit(QtWidgets.QWidget):
A handler to handle a click on the revert button.
Set the new path to the value of the default_path instance variable.
:return: None
:rtype: None
"""
self.on_new_path(self.default_path)
def on_line_edit_editing_finished(self):
"""
A handler to handle when the line edit has finished being edited.
:return: None
:rtype: None
"""
self.on_new_path(self.line_edit.text())
path = str_to_path(self.line_edit.text())
self.on_new_path(path)
def on_new_path(self, path):
"""
@ -196,9 +212,10 @@ class PathEdit(QtWidgets.QWidget):
Emits the pathChanged Signal
:param path: The new path
:type path: str
:type path: pathlib.Path
:return: None
:rtype: None
"""
if self._path != path:
self.path = path

View File

@ -28,12 +28,15 @@ import os
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, UiStrings, translate, get_images_filter, is_not_image_file
from openlp.core.common.path import path_to_str
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui import ThemeLayoutForm
from openlp.core.ui.media.webkitplayer import VIDEO_EXT
from .themewizard import Ui_ThemeWizard
from pathlib import Path
log = logging.getLogger(__name__)
@ -316,11 +319,11 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
self.setField('background_type', 1)
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Image):
self.image_color_button.color = self.theme.background_border_color
self.image_path_edit.path = self.theme.background_filename
self.image_path_edit.path = path_to_str(self.theme.background_filename)
self.setField('background_type', 2)
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Video):
self.video_color_button.color = self.theme.background_border_color
self.video_path_edit.path = self.theme.background_filename
self.video_path_edit.path = path_to_str(self.theme.background_filename)
self.setField('background_type', 4)
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Transparent):
self.setField('background_type', 3)
@ -448,18 +451,18 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
"""
self.theme.background_end_color = color
def on_image_path_edit_path_changed(self, filename):
def on_image_path_edit_path_changed(self, file_path):
"""
Background Image button pushed.
"""
self.theme.background_filename = filename
self.theme.background_filename = path_to_str(file_path)
self.set_background_page_values()
def on_video_path_edit_path_changed(self, filename):
def on_video_path_edit_path_changed(self, file_path):
"""
Background video button pushed.
"""
self.theme.background_filename = filename
self.theme.background_filename = path_to_str(file_path)
self.set_background_page_values()
def on_main_color_changed(self, color):

View File

@ -30,6 +30,8 @@ from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGrad
from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets
from openlp.core.ui.lib import ColorButton, PathEdit
from pathlib import Path
class Ui_ThemeWizard(object):
"""

View File

@ -255,7 +255,7 @@ class BGExtract(RegistryProperties):
chapter=chapter,
version=version)
soup = get_soup_for_bible_ref(
'http://biblegateway.com/passage/?{url}'.format(url=url_params),
'http://www.biblegateway.com/passage/?{url}'.format(url=url_params),
pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='')
if not soup:
return None
@ -284,7 +284,7 @@ class BGExtract(RegistryProperties):
"""
log.debug('BGExtract.get_books_from_http("{version}")'.format(version=version))
url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '{version}'.format(version=version)})
reference_url = 'http://biblegateway.com/versions/?{url}#books'.format(url=url_params)
reference_url = 'http://www.biblegateway.com/versions/?{url}#books'.format(url=url_params)
page = get_web_page(reference_url)
if not page:
send_error_message('download')

View File

@ -20,10 +20,11 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt5 import QtGui, QtWidgets
from PyQt5 import QtWidgets
from openlp.core.common import Settings, UiStrings, translate
from openlp.core.lib import SettingsTab, build_icon
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.lib import SettingsTab
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.lib import PathEdit
from openlp.plugins.presentations.lib.pdfcontroller import PdfController
@ -156,7 +157,7 @@ class PresentationTab(SettingsTab):
self.program_path_edit.setEnabled(enable_pdf_program)
pdf_program = Settings().value(self.settings_section + '/pdf_program')
if pdf_program:
self.program_path_edit.path = pdf_program
self.program_path_edit.path = str_to_path(pdf_program)
def save(self):
"""
@ -192,7 +193,7 @@ class PresentationTab(SettingsTab):
Settings().setValue(setting_key, self.ppt_window_check_box.checkState())
changed = True
# Save pdf-settings
pdf_program = self.program_path_edit.path
pdf_program = path_to_str(self.program_path_edit.path)
enable_pdf_program = self.pdf_program_check_box.checkState()
# If the given program is blank disable using the program
if pdf_program == '':
@ -219,12 +220,12 @@ class PresentationTab(SettingsTab):
checkbox.setEnabled(controller.is_available())
self.set_controller_text(checkbox, controller)
def on_program_path_edit_path_changed(self, filename):
def on_program_path_edit_path_changed(self, new_path):
"""
Select the mudraw or ghostscript binary that should be used.
"""
if filename:
if not PdfController.process_check_binary(filename):
if new_path:
if not PdfController.process_check_binary(new_path):
critical_error_message_box(UiStrings().Error,
translate('PresentationPlugin.PresentationTab',
'The program is not ghostscript or mudraw which is required.'))

View File

@ -27,6 +27,7 @@ from PyQt5 import QtCore, QtWidgets
from sqlalchemy.sql import and_
from openlp.core.common import RegistryProperties, Settings, check_directory_exists, translate
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.songusage.lib.db import SongUsageItem
from .songusagedetaildialog import Ui_SongUsageDetailDialog
@ -55,20 +56,21 @@ class SongUsageDetailForm(QtWidgets.QDialog, Ui_SongUsageDetailDialog, RegistryP
"""
self.from_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/from date'))
self.to_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/to date'))
self.report_path_edit.path = Settings().value(self.plugin.settings_section + '/last directory export')
self.report_path_edit.path = str_to_path(
Settings().value(self.plugin.settings_section + '/last directory export'))
def on_report_path_edit_path_changed(self, file_path):
"""
Triggered when the Directory selection button is clicked
"""
Settings().setValue(self.plugin.settings_section + '/last directory export', file_path)
Settings().setValue(self.plugin.settings_section + '/last directory export', path_to_str(file_path))
def accept(self):
"""
Ok was triggered so lets save the data and run the report
"""
log.debug('accept')
path = self.report_path_edit.path
path = path_to_str(self.report_path_edit.path)
if not path:
self.main_window.error_message(
translate('SongUsagePlugin.SongUsageDetailForm', 'Output Path Not Selected'),

View File

@ -0,0 +1,88 @@
# -*- 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 #
###############################################################################
"""
Package to test the openlp.core.common.path package.
"""
import os
from pathlib import Path
from unittest import TestCase
from openlp.core.common.path import path_to_str, str_to_path
class TestPath(TestCase):
"""
Tests for the :mod:`openlp.core.common.path` module
"""
def test_path_to_str_type_error(self):
"""
Test that `path_to_str` raises a type error when called with an invalid type
"""
# GIVEN: The `path_to_str` function
# WHEN: Calling `path_to_str` with an invalid Type
# THEN: A TypeError should have been raised
with self.assertRaises(TypeError):
path_to_str(str())
def test_path_to_str_none(self):
"""
Test that `path_to_str` correctly converts the path parameter when passed with None
"""
# GIVEN: The `path_to_str` function
# WHEN: Calling the `path_to_str` function with None
result = path_to_str(None)
# THEN: `path_to_str` should return an empty string
self.assertEqual(result, '')
def test_path_to_str_path_object(self):
"""
Test that `path_to_str` correctly converts the path parameter when passed a Path object
"""
# GIVEN: The `path_to_str` function
# WHEN: Calling the `path_to_str` function with a Path object
result = path_to_str(Path('test/path'))
# THEN: `path_to_str` should return a string representation of the Path object
self.assertEqual(result, os.path.join('test', 'path'))
def test_str_to_path_type_error(self):
"""
Test that `str_to_path` raises a type error when called with an invalid type
"""
# GIVEN: The `str_to_path` function
# WHEN: Calling `str_to_path` with an invalid Type
# THEN: A TypeError should have been raised
with self.assertRaises(TypeError):
str_to_path(Path())
def test_str_to_path_empty_str(self):
"""
Test that `str_to_path` correctly converts the string parameter when passed with and empty string
"""
# GIVEN: The `str_to_path` function
# WHEN: Calling the `str_to_path` function with None
result = str_to_path('')
# THEN: `path_to_str` should return None
self.assertEqual(result, None)

View File

@ -29,10 +29,9 @@ from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtGui
from openlp.core.lib import FormattingTags, expand_chords_for_printing
from openlp.core.lib import build_icon, check_item_selected, clean_tags, create_thumb, create_separated_list, \
expand_tags, get_text_file_string, image_to_byte, resize_image, str_to_bool, validate_thumb, expand_chords, \
compare_chord_lyric, find_formatting_tags
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
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'resources'))
@ -652,6 +651,38 @@ class TestLib(TestCase):
mocked_os.stat.assert_any_call(thumb_path)
assert result is False, '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

@ -22,6 +22,7 @@
"""
Package to test the openlp.core.ui.themeform package.
"""
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
@ -45,7 +46,7 @@ class TestThemeManager(TestCase):
self.instance.theme = MagicMock()
# WHEN: `on_image_path_edit_path_changed` is clicked
self.instance.on_image_path_edit_path_changed('/new/pat.h')
self.instance.on_image_path_edit_path_changed(Path('/', 'new', 'pat.h'))
# THEN: The theme background file should be set and `set_background_page_values` should have been called
self.assertEqual(self.instance.theme.background_filename, '/new/pat.h')

View File

@ -0,0 +1,191 @@
import os
import sys
from unittest import TestCase
from unittest.mock import patch
from pathlib import Path
from PyQt5 import QtWidgets
from openlp.core.ui.lib.filedialogpatches import PQFileDialog
class TestFileDialogPatches(TestCase):
"""
Tests for the :mod:`openlp.core.ui.lib.filedialogpatches` module
"""
def test_pq_file_dialog(self):
"""
Test that the :class:`PQFileDialog` instantiates correctly
"""
#app = QtWidgets.QApplication(sys.argv)
# GIVEN: The PQFileDialog class
# WHEN: Creating an instance
instance = PQFileDialog()
# THEN: The instance should be an instance of QFileDialog
self.assertIsInstance(instance, QtWidgets.QFileDialog)
def test_get_existing_directory_user_abort(self):
"""
Test that `getExistingDirectory` handles the case when the user cancels the dialog
"""
# GIVEN: PQFileDialog with a mocked QDialog.getExistingDirectory method
# WHEN: Calling PQFileDialog.getExistingDirectory and the user cancels the dialog returns a empty string
with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=''):
result = PQFileDialog.getExistingDirectory()
# THEN: The result should be None
self.assertEqual(result, None)
def test_get_existing_directory_user_accepts(self):
"""
Test that `getExistingDirectory` handles the case when the user accepts the dialog
"""
# GIVEN: PQFileDialog with a mocked QDialog.getExistingDirectory method
# WHEN: Calling PQFileDialog.getExistingDirectory, the user chooses a file and accepts the dialog (it returns a
# string pointing to the directory)
with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=os.path.join('test', 'dir')):
result = PQFileDialog.getExistingDirectory()
# THEN: getExistingDirectory() should return a Path object pointing to the chosen file
self.assertEqual(result, Path('test', 'dir'))
def test_get_existing_directory_param_order(self):
"""
Test that `getExistingDirectory` passes the parameters to `QFileDialog.getExistingDirectory` in the correct
order
"""
# GIVEN: PQFileDialog
with patch('openlp.core.ui.lib.filedialogpatches.QtWidgets.QFileDialog.getExistingDirectory', return_value='') \
as mocked_get_existing_directory:
# WHEN: Calling the getExistingDirectory method with all parameters set
PQFileDialog.getExistingDirectory('Parent', 'Caption', Path('test', 'dir'), 'Options')
# THEN: The `QFileDialog.getExistingDirectory` should have been called with the parameters in the correct
# order
mocked_get_existing_directory.assert_called_once_with('Parent', 'Caption', os.path.join('test', 'dir'),
'Options')
def test_get_open_file_name_user_abort(self):
"""
Test that `getOpenFileName` handles the case when the user cancels the dialog
"""
# GIVEN: PQFileDialog with a mocked QDialog.getOpenFileName method
# WHEN: Calling PQFileDialog.getOpenFileName and the user cancels the dialog (it returns a tuple with the first
# value set as an empty string)
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')):
result = PQFileDialog.getOpenFileName()
# THEN: First value should be None
self.assertEqual(result[0], None)
def test_get_open_file_name_user_accepts(self):
"""
Test that `getOpenFileName` handles the case when the user accepts the dialog
"""
# GIVEN: PQFileDialog with a mocked QDialog.getOpenFileName method
# WHEN: Calling PQFileDialog.getOpenFileName, the user chooses a file and accepts the dialog (it returns a
# tuple with the first value set as an string pointing to the file)
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName',
return_value=(os.path.join('test', 'chosen.file'), '')):
result = PQFileDialog.getOpenFileName()
# THEN: getOpenFileName() should return a tuple with the first value set to a Path object pointing to the
# chosen file
self.assertEqual(result[0], Path('test', 'chosen.file'))
def test_get_open_file_name_selected_filter(self):
"""
Test that `getOpenFileName` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileName`
"""
# GIVEN: PQFileDialog with a mocked QDialog.get_save_file_name method
# WHEN: Calling PQFileDialog.getOpenFileName, and `QFileDialog.getOpenFileName` returns a known `selectedFilter`
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', 'selected filter')):
result = PQFileDialog.getOpenFileName()
# THEN: getOpenFileName() should return a tuple with the second value set to a the selected filter
self.assertEqual(result[1], 'selected filter')
def test_get_open_file_names_user_abort(self):
"""
Test that `getOpenFileNames` handles the case when the user cancels the dialog
"""
# GIVEN: PQFileDialog with a mocked QDialog.getOpenFileNames method
# WHEN: Calling PQFileDialog.getOpenFileNames and the user cancels the dialog (it returns a tuple with the first
# value set as an empty list)
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], '')):
result = PQFileDialog.getOpenFileNames()
# THEN: First value should be an empty list
self.assertEqual(result[0], [])
def test_get_open_file_names_user_accepts(self):
"""
Test that `getOpenFileNames` handles the case when the user accepts the dialog
"""
# GIVEN: PQFileDialog with a mocked QDialog.getOpenFileNames method
# WHEN: Calling PQFileDialog.getOpenFileNames, the user chooses some files and accepts the dialog (it returns a
# tuple with the first value set as a list of strings pointing to the file)
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames',
return_value=([os.path.join('test', 'chosen.file1'), os.path.join('test', 'chosen.file2')], '')):
result = PQFileDialog.getOpenFileNames()
# THEN: getOpenFileNames() should return a tuple with the first value set to a list of Path objects pointing
# to the chosen file
self.assertEqual(result[0], [Path('test', 'chosen.file1'), Path('test', 'chosen.file2')])
def test_get_open_file_names_selected_filter(self):
"""
Test that `getOpenFileNames` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileNames`
"""
# GIVEN: PQFileDialog with a mocked QDialog.getOpenFileNames method
# WHEN: Calling PQFileDialog.getOpenFileNames, and `QFileDialog.getOpenFileNames` returns a known
# `selectedFilter`
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], 'selected filter')):
result = PQFileDialog.getOpenFileNames()
# THEN: getOpenFileNames() should return a tuple with the second value set to a the selected filter
self.assertEqual(result[1], 'selected filter')
def test_get_save_file_name_user_abort(self):
"""
Test that `getSaveFileName` handles the case when the user cancels the dialog
"""
# GIVEN: PQFileDialog with a mocked QDialog.get_save_file_name method
# WHEN: Calling PQFileDialog.getSaveFileName and the user cancels the dialog (it returns a tuple with the first
# value set as an empty string)
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', '')):
result = PQFileDialog.getSaveFileName()
# THEN: First value should be None
self.assertEqual(result[0], None)
def test_get_save_file_name_user_accepts(self):
"""
Test that `getSaveFileName` handles the case when the user accepts the dialog
"""
# GIVEN: PQFileDialog with a mocked QDialog.getSaveFileName method
# WHEN: Calling PQFileDialog.getSaveFileName, the user chooses a file and accepts the dialog (it returns a
# tuple with the first value set as an string pointing to the file)
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName',
return_value=(os.path.join('test', 'chosen.file'), '')):
result = PQFileDialog.getSaveFileName()
# THEN: getSaveFileName() should return a tuple with the first value set to a Path object pointing to the
# chosen file
self.assertEqual(result[0], Path('test', 'chosen.file'))
def test_get_save_file_name_selected_filter(self):
"""
Test that `getSaveFileName` does not modify the selectedFilter as returned by `QFileDialog.getSaveFileName`
"""
# GIVEN: PQFileDialog with a mocked QDialog.get_save_file_name method
# WHEN: Calling PQFileDialog.getSaveFileName, and `QFileDialog.getSaveFileName` returns a known `selectedFilter`
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', 'selected filter')):
result = PQFileDialog.getSaveFileName()
# THEN: getSaveFileName() should return a tuple with the second value set to a the selected filter
self.assertEqual(result[1], 'selected filter')

View File

@ -22,12 +22,13 @@
"""
This module contains tests for the openlp.core.ui.lib.pathedit module
"""
import os
from pathlib import Path
from unittest import TestCase
from PyQt5 import QtWidgets
from unittest.mock import MagicMock, PropertyMock, patch
from openlp.core.ui.lib import PathEdit, PathType
from unittest.mock import MagicMock, PropertyMock, patch
from openlp.core.ui.lib.filedialogpatches import PQFileDialog
class TestPathEdit(TestCase):
@ -43,11 +44,11 @@ class TestPathEdit(TestCase):
Test the `path` property getter.
"""
# GIVEN: An instance of PathEdit with the `_path` instance variable set
self.widget._path = 'getter/test/pat.h'
self.widget._path = Path('getter', 'test', 'pat.h')
# WHEN: Reading the `path` property
# THEN: The value that we set should be returned
self.assertEqual(self.widget.path, 'getter/test/pat.h')
self.assertEqual(self.widget.path, Path('getter', 'test', 'pat.h'))
def test_path_setter(self):
"""
@ -57,13 +58,13 @@ class TestPathEdit(TestCase):
self.widget.line_edit = MagicMock()
# WHEN: Writing to the `path` property
self.widget.path = 'setter/test/pat.h'
self.widget.path = Path('setter', 'test', 'pat.h')
# THEN: The `_path` instance variable should be set with the test data. The `line_edit` text and tooltip
# should have also been set.
self.assertEqual(self.widget._path, 'setter/test/pat.h')
self.widget.line_edit.setToolTip.assert_called_once_with('setter/test/pat.h')
self.widget.line_edit.setText.assert_called_once_with('setter/test/pat.h')
self.assertEqual(self.widget._path, Path('setter', 'test', 'pat.h'))
self.widget.line_edit.setToolTip.assert_called_once_with(os.path.join('setter', 'test', 'pat.h'))
self.widget.line_edit.setText.assert_called_once_with(os.path.join('setter', 'test', 'pat.h'))
def test_path_type_getter(self):
"""
@ -125,22 +126,20 @@ class TestPathEdit(TestCase):
"""
# GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked
# QFileDialog.getExistingDirectory
with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory', return_value='') as \
with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getExistingDirectory', return_value=None) as \
mocked_get_existing_directory, \
patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName') as \
mocked_get_open_file_name, \
patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName') as mocked_get_open_file_name:
self.widget._path_type = PathType.Directories
self.widget._path = 'test/path/'
self.widget._path = Path('test', 'path')
# WHEN: Calling on_browse_button_clicked
self.widget.on_browse_button_clicked()
# THEN: The FileDialog.getExistingDirectory should have been called with the default caption
mocked_get_existing_directory.assert_called_once_with(self.widget, 'Select Directory', 'test/path/',
QtWidgets.QFileDialog.ShowDirsOnly)
mocked_get_existing_directory.assert_called_once_with(self.widget, 'Select Directory',
Path('test', 'path'),
PQFileDialog.ShowDirsOnly)
self.assertFalse(mocked_get_open_file_name.called)
self.assertFalse(mocked_normpath.called)
def test_on_browse_button_clicked_directory_custom_caption(self):
"""
@ -149,45 +148,40 @@ class TestPathEdit(TestCase):
"""
# GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked
# QFileDialog.getExistingDirectory with `default_caption` set.
with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory', return_value='') as \
with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getExistingDirectory', return_value=None) as \
mocked_get_existing_directory, \
patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName') as \
mocked_get_open_file_name, \
patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName') as mocked_get_open_file_name:
self.widget._path_type = PathType.Directories
self.widget._path = 'test/path/'
self.widget._path = Path('test', 'path')
self.widget.dialog_caption = 'Directory Caption'
# WHEN: Calling on_browse_button_clicked
self.widget.on_browse_button_clicked()
# THEN: The FileDialog.getExistingDirectory should have been called with the custom caption
mocked_get_existing_directory.assert_called_once_with(self.widget, 'Directory Caption', 'test/path/',
QtWidgets.QFileDialog.ShowDirsOnly)
mocked_get_existing_directory.assert_called_once_with(self.widget, 'Directory Caption',
Path('test', 'path'),
PQFileDialog.ShowDirsOnly)
self.assertFalse(mocked_get_open_file_name.called)
self.assertFalse(mocked_normpath.called)
def test_on_browse_button_clicked_file(self):
"""
Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files.
"""
# GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName
with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory') as \
mocked_get_existing_directory, \
patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')) as \
mocked_get_open_file_name, \
patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getExistingDirectory') as mocked_get_existing_directory, \
patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName', return_value=(None, '')) as \
mocked_get_open_file_name:
self.widget._path_type = PathType.Files
self.widget._path = 'test/pat.h'
self.widget._path = Path('test', 'pat.h')
# WHEN: Calling on_browse_button_clicked
self.widget.on_browse_button_clicked()
# THEN: The FileDialog.getOpenFileName should have been called with the default caption
mocked_get_open_file_name.assert_called_once_with(self.widget, 'Select File', 'test/pat.h',
mocked_get_open_file_name.assert_called_once_with(self.widget, 'Select File', Path('test', 'pat.h'),
self.widget.filters)
self.assertFalse(mocked_get_existing_directory.called)
self.assertFalse(mocked_normpath.called)
def test_on_browse_button_clicked_file_custom_caption(self):
"""
@ -196,23 +190,20 @@ class TestPathEdit(TestCase):
"""
# GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName
# with `default_caption` set.
with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getExistingDirectory') as \
mocked_get_existing_directory, \
patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')) as \
mocked_get_open_file_name, \
patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getExistingDirectory') as mocked_get_existing_directory, \
patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName', return_value=(None, '')) as \
mocked_get_open_file_name:
self.widget._path_type = PathType.Files
self.widget._path = 'test/pat.h'
self.widget._path = Path('test', 'pat.h')
self.widget.dialog_caption = 'File Caption'
# WHEN: Calling on_browse_button_clicked
self.widget.on_browse_button_clicked()
# THEN: The FileDialog.getOpenFileName should have been called with the custom caption
mocked_get_open_file_name.assert_called_once_with(self.widget, 'File Caption', 'test/pat.h',
mocked_get_open_file_name.assert_called_once_with(self.widget, 'File Caption', Path('test', 'pat.h'),
self.widget.filters)
self.assertFalse(mocked_get_existing_directory.called)
self.assertFalse(mocked_normpath.called)
def test_on_browse_button_clicked_user_cancels(self):
"""
@ -221,16 +212,14 @@ class TestPathEdit(TestCase):
"""
# GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns an empty str for the
# file path.
with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')) as \
mocked_get_open_file_name, \
patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath:
with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName', return_value=(None, '')) as \
mocked_get_open_file_name:
# WHEN: Calling on_browse_button_clicked
self.widget.on_browse_button_clicked()
# THEN: normpath should not have been called
self.assertTrue(mocked_get_open_file_name.called)
self.assertFalse(mocked_normpath.called)
def test_on_browse_button_clicked_user_accepts(self):
"""
@ -239,9 +228,8 @@ class TestPathEdit(TestCase):
"""
# GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns a str for the file
# path.
with patch('openlp.core.ui.lib.pathedit.QtWidgets.QFileDialog.getOpenFileName',
return_value=('/test/pat.h', '')) as mocked_get_open_file_name, \
patch('openlp.core.ui.lib.pathedit.os.path.normpath') as mocked_normpath, \
with patch('openlp.core.ui.lib.pathedit.PQFileDialog.getOpenFileName',
return_value=(Path('test', 'pat.h'), '')) as mocked_get_open_file_name, \
patch.object(self.widget, 'on_new_path'):
# WHEN: Calling on_browse_button_clicked
@ -249,7 +237,6 @@ class TestPathEdit(TestCase):
# THEN: normpath and `on_new_path` should have been called
self.assertTrue(mocked_get_open_file_name.called)
mocked_normpath.assert_called_once_with('/test/pat.h')
self.assertTrue(self.widget.on_new_path.called)
def test_on_revert_button_clicked(self):
@ -258,13 +245,13 @@ class TestPathEdit(TestCase):
"""
# GIVEN: An instance of PathEdit with a mocked `on_new_path`, and the `default_path` set.
with patch.object(self.widget, 'on_new_path') as mocked_on_new_path:
self.widget.default_path = '/default/pat.h'
self.widget.default_path = Path('default', 'pat.h')
# WHEN: Calling `on_revert_button_clicked`
self.widget.on_revert_button_clicked()
# THEN: on_new_path should have been called with the default path
mocked_on_new_path.assert_called_once_with('/default/pat.h')
mocked_on_new_path.assert_called_once_with(Path('default', 'pat.h'))
def test_on_line_edit_editing_finished(self):
"""
@ -272,13 +259,13 @@ class TestPathEdit(TestCase):
"""
# GIVEN: An instance of PathEdit with a mocked `line_edit` and `on_new_path`.
with patch.object(self.widget, 'on_new_path') as mocked_on_new_path:
self.widget.line_edit = MagicMock(**{'text.return_value': '/test/pat.h'})
self.widget.line_edit = MagicMock(**{'text.return_value': 'test/pat.h'})
# WHEN: Calling `on_line_edit_editing_finished`
self.widget.on_line_edit_editing_finished()
# THEN: on_new_path should have been called with the path enetered in `line_edit`
mocked_on_new_path.assert_called_once_with('/test/pat.h')
mocked_on_new_path.assert_called_once_with(Path('test', 'pat.h'))
def test_on_new_path_no_change(self):
"""
@ -286,11 +273,11 @@ class TestPathEdit(TestCase):
"""
# GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal
with patch('openlp.core.ui.lib.pathedit.PathEdit.path', new_callable=PropertyMock):
self.widget._path = '/old/test/pat.h'
self.widget._path = Path('/old', 'test', 'pat.h')
self.widget.pathChanged = MagicMock()
# WHEN: Calling `on_new_path` with the same path as the existing path
self.widget.on_new_path('/old/test/pat.h')
self.widget.on_new_path(Path('/old', 'test', 'pat.h'))
# THEN: The `pathChanged` signal should not be emitted
self.assertFalse(self.widget.pathChanged.emit.called)
@ -301,11 +288,11 @@ class TestPathEdit(TestCase):
"""
# GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal
with patch('openlp.core.ui.lib.pathedit.PathEdit.path', new_callable=PropertyMock):
self.widget._path = '/old/test/pat.h'
self.widget._path = Path('/old', 'test', 'pat.h')
self.widget.pathChanged = MagicMock()
# WHEN: Calling `on_new_path` with the a new path
self.widget.on_new_path('/new/test/pat.h')
self.widget.on_new_path(Path('/new', 'test', 'pat.h'))
# THEN: The `pathChanged` signal should be emitted
self.widget.pathChanged.emit.assert_called_once_with('/new/test/pat.h')
self.widget.pathChanged.emit.assert_called_once_with(Path('/new', 'test', 'pat.h'))