This commit is contained in:
Andreas Preikschat 2013-02-16 12:46:12 +01:00
commit a40defdeab
20 changed files with 415 additions and 44 deletions

View File

@ -30,6 +30,7 @@
The :mod:`lib` module contains most of the components and libraries that make The :mod:`lib` module contains most of the components and libraries that make
OpenLP work. OpenLP work.
""" """
from distutils.version import LooseVersion
import logging import logging
import os import os
@ -366,23 +367,23 @@ def create_separated_list(stringlist):
``stringlist`` ``stringlist``
List of unicode strings List of unicode strings
""" """
if Qt.PYQT_VERSION_STR >= u'4.9' and Qt.qVersion() >= u'4.8': if LooseVersion(Qt.PYQT_VERSION_STR) >= LooseVersion(u'4.9') and \
LooseVersion(Qt.qVersion()) >= LooseVersion(u'4.8'):
return QtCore.QLocale().createSeparatedList(stringlist) return QtCore.QLocale().createSeparatedList(stringlist)
if not stringlist: if not stringlist:
return u'' return u''
elif len(stringlist) == 1: elif len(stringlist) == 1:
return stringlist[0] return stringlist[0]
elif len(stringlist) == 2: elif len(stringlist) == 2:
return translate('OpenLP.core.lib', '%1 and %2', return translate('OpenLP.core.lib', '%s and %s',
'Locale list separator: 2 items') % (stringlist[0], stringlist[1]) 'Locale list separator: 2 items') % (stringlist[0], stringlist[1])
else: else:
merged = translate('OpenLP.core.lib', '%1, and %2', merged = translate('OpenLP.core.lib', '%s, and %s',
u'Locale list separator: end') % (stringlist[-2], stringlist[-1]) u'Locale list separator: end') % (stringlist[-2], stringlist[-1])
for index in reversed(range(1, len(stringlist) - 2)): for index in reversed(range(1, len(stringlist) - 2)):
merged = translate('OpenLP.core.lib', '%1, %2', merged = translate('OpenLP.core.lib', '%s, %s',
u'Locale list separator: middle') % (stringlist[index], merged) u'Locale list separator: middle') % (stringlist[index], merged)
return translate('OpenLP.core.lib', '%1, %2', return translate('OpenLP.core.lib', '%s, %s', u'Locale list separator: start') % (stringlist[0], merged)
u'Locale list separator: start') % (stringlist[0], merged)
from registry import Registry from registry import Registry

View File

@ -34,18 +34,18 @@ from PyQt4 import QtGui
from filerenamedialog import Ui_FileRenameDialog from filerenamedialog import Ui_FileRenameDialog
from openlp.core.lib import translate from openlp.core.lib import translate, Registry
class FileRenameForm(QtGui.QDialog, Ui_FileRenameDialog): class FileRenameForm(QtGui.QDialog, Ui_FileRenameDialog):
""" """
The file rename dialog The file rename dialog
""" """
def __init__(self, parent): def __init__(self):
""" """
Constructor Constructor
""" """
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, self.main_window)
self.setupUi(self) self.setupUi(self)
def exec_(self, copy=False): def exec_(self, copy=False):
@ -56,4 +56,15 @@ class FileRenameForm(QtGui.QDialog, Ui_FileRenameDialog):
self.setWindowTitle(translate('OpenLP.FileRenameForm', 'File Copy')) self.setWindowTitle(translate('OpenLP.FileRenameForm', 'File Copy'))
else: else:
self.setWindowTitle(translate('OpenLP.FileRenameForm', 'File Rename')) self.setWindowTitle(translate('OpenLP.FileRenameForm', 'File Rename'))
self.fileNameEdit.setFocus()
return QtGui.QDialog.exec_(self) return QtGui.QDialog.exec_(self)
def _get_main_window(self):
"""
Adds the main window to the class dynamically
"""
if not hasattr(self, u'_main_window'):
self._main_window = Registry().get(u'main_window')
return self._main_window
main_window = property(_get_main_window)

View File

@ -62,7 +62,7 @@ class ThemeManager(QtGui.QWidget):
Registry().register(u'theme_manager', self) Registry().register(u'theme_manager', self)
self.settingsSection = u'themes' self.settingsSection = u'themes'
self.themeForm = ThemeForm(self) self.themeForm = ThemeForm(self)
self.fileRenameForm = FileRenameForm(self) self.fileRenameForm = FileRenameForm()
# start with the layout # start with the layout
self.layout = QtGui.QVBoxLayout(self) self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0) self.layout.setSpacing(0)

View File

@ -199,7 +199,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
self.parameterEdit.setFocus() self.parameterEdit.setFocus()
return False return False
text = text.replace(u'<>', self.parameterEdit.text()) text = text.replace(u'<>', self.parameterEdit.text())
self.plugin.alertsmanager.displayAlert(text) self.plugin.alertsmanager.display_alert(text)
return True return True
def onCurrentRowChanged(self, row): def onCurrentRowChanged(self, row):

View File

@ -37,8 +37,10 @@ from PyQt4 import QtCore
from openlp.core.lib import Registry, translate from openlp.core.lib import Registry, translate
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class AlertsManager(QtCore.QObject): class AlertsManager(QtCore.QObject):
""" """
AlertsManager manages the settings of Alerts. AlertsManager manages the settings of Alerts.
@ -87,7 +89,7 @@ class AlertsManager(QtCore.QObject):
return return
text = self.alert_list.pop(0) text = self.alert_list.pop(0)
alertTab = self.parent().settingsTab alertTab = self.parent().settingsTab
self.parent().liveController.display.alert(text, alertTab.location) self.live_controller.display.alert(text, alertTab.location)
# Check to see if we have a timer running. # Check to see if we have a timer running.
if self.timer_id == 0: if self.timer_id == 0:
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000) self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
@ -103,11 +105,21 @@ class AlertsManager(QtCore.QObject):
log.debug(u'timer event') log.debug(u'timer event')
if event.timerId() == self.timer_id: if event.timerId() == self.timer_id:
alertTab = self.parent().settingsTab alertTab = self.parent().settingsTab
self.parent().liveController.display.alert(u'', alertTab.location) self.live_controller.display.alert(u'', alertTab.location)
self.killTimer(self.timer_id) self.killTimer(self.timer_id)
self.timer_id = 0 self.timer_id = 0
self.generate_alert() self.generate_alert()
def _get_live_controller(self):
"""
Adds the live controller to the class dynamically
"""
if not hasattr(self, u'_live_controller'):
self._live_controller = Registry().get(u'live_controller')
return self._live_controller
live_controller = property(_get_live_controller)
def _get_main_window(self): def _get_main_window(self):
""" """
Adds the main window to the class dynamically Adds the main window to the class dynamically
@ -116,4 +128,4 @@ class AlertsManager(QtCore.QObject):
self._main_window = Registry().get(u'main_window') self._main_window = Registry().get(u'main_window')
return self._main_window return self._main_window
main_window = property(_get_main_window) main_window = property(_get_main_window)

View File

@ -27,7 +27,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from PyQt4 import QtCore, QtGui from PyQt4 import QtGui
import logging import logging
@ -98,4 +98,14 @@ class ImagePlugin(Plugin):
last part of saving the config. last part of saving the config.
""" """
background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color')) background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color'))
self.liveController.imageManager.update_images_border(ImageSource.ImagePlugin, background) self.image_manager.update_images_border(ImageSource.ImagePlugin, background)
def _get_image_manager(self):
"""
Adds the image manager to the class dynamically
"""
if not hasattr(self, u'_image_manager'):
self._image_manager = Registry().get(u'image_manager')
return self._image_manager
image_manager = property(_get_image_manager)

View File

@ -124,6 +124,7 @@ from PyQt4 import QtCore, QtNetwork
from mako.template import Template from mako.template import Template
from openlp.core.lib import Registry, Settings, PluginStatus, StringContent from openlp.core.lib import Registry, Settings, PluginStatus, StringContent
from openlp.core.utils import AppLocation, translate from openlp.core.utils import AppLocation, translate
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -250,12 +251,11 @@ class HttpConnection(object):
def _get_service_items(self): def _get_service_items(self):
service_items = [] service_items = []
service_manager = self.parent.plugin.serviceManager
if self.parent.current_item: if self.parent.current_item:
current_unique_identifier = self.parent.current_item.unique_identifier current_unique_identifier = self.parent.current_item.unique_identifier
else: else:
current_unique_identifier = None current_unique_identifier = None
for item in service_manager.serviceItems: for item in self.service_manager.serviceItems:
service_item = item[u'service_item'] service_item = item[u'service_item']
service_items.append({ service_items.append({
u'id': unicode(service_item.unique_identifier), u'id': unicode(service_item.unique_identifier),
@ -386,13 +386,13 @@ class HttpConnection(object):
Poll OpenLP to determine the current slide number and item name. Poll OpenLP to determine the current slide number and item name.
""" """
result = { result = {
u'service': self.parent.plugin.serviceManager.service_id, u'service': self.service_manager.service_id,
u'slide': self.parent.current_slide or 0, u'slide': self.parent.current_slide or 0,
u'item': self.parent.current_item.unique_identifier if self.parent.current_item else u'', u'item': self.parent.current_item.unique_identifier if self.parent.current_item else u'',
u'twelve':Settings().value(u'remotes/twelve hour'), u'twelve':Settings().value(u'remotes/twelve hour'),
u'blank': self.parent.plugin.liveController.blankScreen.isChecked(), u'blank': self.live_controller.blankScreen.isChecked(),
u'theme': self.parent.plugin.liveController.themeScreen.isChecked(), u'theme': self.live_controller.themeScreen.isChecked(),
u'display': self.parent.plugin.liveController.desktopScreen.isChecked() u'display': self.live_controller.desktopScreen.isChecked()
} }
return HttpResponse(json.dumps({u'results': result}), return HttpResponse(json.dumps({u'results': result}),
{u'Content-Type': u'application/json'}) {u'Content-Type': u'application/json'})
@ -412,7 +412,7 @@ class HttpConnection(object):
""" """
Send an alert. Send an alert.
""" """
plugin = self.parent.plugin.pluginManager.get_plugin_by_name("alerts") plugin = self.plugin_manager.get_plugin_by_name("alerts")
if plugin.status == PluginStatus.Active: if plugin.status == PluginStatus.Active:
try: try:
text = json.loads(self.url_params[u'data'][0])[u'request'][u'text'] text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
@ -504,7 +504,7 @@ class HttpConnection(object):
""" """
if action == u'search': if action == u'search':
searches = [] searches = []
for plugin in self.parent.plugin.pluginManager.plugins: for plugin in self.plugin_manager.plugins:
if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch: if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch:
searches.append([plugin.name, unicode(plugin.textStrings[StringContent.Name][u'plural'])]) searches.append([plugin.name, unicode(plugin.textStrings[StringContent.Name][u'plural'])])
return HttpResponse( return HttpResponse(
@ -523,7 +523,7 @@ class HttpConnection(object):
except KeyError, ValueError: except KeyError, ValueError:
return HttpResponse(code=u'400 Bad Request') return HttpResponse(code=u'400 Bad Request')
text = urllib.unquote(text) text = urllib.unquote(text)
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type) plugin = self.plugin_manager.get_plugin_by_name(type)
if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch: if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch:
results = plugin.mediaItem.search(text, False) results = plugin.mediaItem.search(text, False)
else: else:
@ -539,7 +539,7 @@ class HttpConnection(object):
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id'] id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
except KeyError, ValueError: except KeyError, ValueError:
return HttpResponse(code=u'400 Bad Request') return HttpResponse(code=u'400 Bad Request')
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type) plugin = self.plugin_manager.get_plugin_by_name(type)
if plugin.status == PluginStatus.Active and plugin.mediaItem: if plugin.status == PluginStatus.Active and plugin.mediaItem:
plugin.mediaItem.goLive(id, remote=True) plugin.mediaItem.goLive(id, remote=True)
return HttpResponse(code=u'200 OK') return HttpResponse(code=u'200 OK')
@ -552,7 +552,7 @@ class HttpConnection(object):
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id'] id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
except KeyError, ValueError: except KeyError, ValueError:
return HttpResponse(code=u'400 Bad Request') return HttpResponse(code=u'400 Bad Request')
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type) plugin = self.plugin_manager.get_plugin_by_name(type)
if plugin.status == PluginStatus.Active and plugin.mediaItem: if plugin.status == PluginStatus.Active and plugin.mediaItem:
item_id = plugin.mediaItem.createItemFromId(id) item_id = plugin.mediaItem.createItemFromId(id)
plugin.mediaItem.addToService(item_id, remote=True) plugin.mediaItem.addToService(item_id, remote=True)
@ -583,3 +583,33 @@ class HttpConnection(object):
self.socket.close() self.socket.close()
self.socket = None self.socket = None
self.parent.close_connection(self) self.parent.close_connection(self)
def _get_service_manager(self):
"""
Adds the service manager to the class dynamically
"""
if not hasattr(self, u'_service_manager'):
self._service_manager = Registry().get(u'service_manager')
return self._service_manager
service_manager = property(_get_service_manager)
def _get_live_controller(self):
"""
Adds the live controller to the class dynamically
"""
if not hasattr(self, u'_live_controller'):
self._live_controller = Registry().get(u'live_controller')
return self._live_controller
live_controller = property(_get_live_controller)
def _get_plugin_manager(self):
"""
Adds the plugin manager to the class dynamically
"""
if not hasattr(self, u'_plugin_manager'):
self._plugin_manager = Registry().get(u'plugin_manager')
return self._plugin_manager
plugin_manager = property(_get_plugin_manager)

View File

@ -116,6 +116,23 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.findVerseSplit = re.compile(u'---\[\]---\n', re.UNICODE) self.findVerseSplit = re.compile(u'---\[\]---\n', re.UNICODE)
self.whitespace = re.compile(r'\W+', re.UNICODE) self.whitespace = re.compile(r'\W+', re.UNICODE)
def keyPressEvent(self, event):
"""
Reimplement the keyPressEvent to react on Return/Enter keys. When some combo boxes have focus we do not want
dialog's default action be triggered but instead our own.
``event``
A QtGui.QKeyEvent event.
"""
if event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
if self.authorsComboBox.hasFocus() and self.authorsComboBox.currentText():
self.onAuthorAddButtonClicked()
return
if self.topicsComboBox.hasFocus() and self.topicsComboBox.currentText():
self.onTopicAddButtonClicked()
return
QtGui.QDialog.keyPressEvent(self, event)
def initialise(self): def initialise(self):
""" """
Set up the form for when it is displayed. Set up the form for when it is displayed.

View File

@ -40,7 +40,13 @@ import os
import sys import sys
from distutils.version import LooseVersion from distutils.version import LooseVersion
is_win = sys.platform.startswith('win') # If we try to import uno before nose this will greate a warning. Just try to import nose first to supress the warning.
try:
import nose
except ImportError:
pass
IS_WIN = sys.platform.startswith('win')
VERS = { VERS = {
'Python': '2.6', 'Python': '2.6',
@ -48,7 +54,7 @@ VERS = {
'Qt4': '4.6', 'Qt4': '4.6',
'sqlalchemy': '0.5', 'sqlalchemy': '0.5',
# pyenchant 1.6 required on Windows # pyenchant 1.6 required on Windows
'enchant': '1.6' if is_win else '1.3' 'enchant': '1.6' if IS_WIN else '1.3'
} }
# pywin32 # pywin32
@ -84,7 +90,7 @@ OPTIONAL_MODULES = [
('sqlite', ' (SQLite 2 support)'), ('sqlite', ' (SQLite 2 support)'),
('MySQLdb', ' (MySQL support)'), ('MySQLdb', ' (MySQL support)'),
('psycopg2', ' (PostgreSQL support)'), ('psycopg2', ' (PostgreSQL support)'),
('pytest', ' (testing framework)'), ('nose', ' (testing framework)'),
] ]
w = sys.stdout.write w = sys.stdout.write
@ -176,7 +182,7 @@ def main():
for m in OPTIONAL_MODULES: for m in OPTIONAL_MODULES:
check_module(m[0], text=m[1]) check_module(m[0], text=m[1])
if is_win: if IS_WIN:
print('Checking for Windows specific modules...') print('Checking for Windows specific modules...')
for m in WIN32_MODULES: for m in WIN32_MODULES:
check_module(m) check_module(m)

View File

@ -0,0 +1,8 @@
import sip
sip.setapi(u'QDate', 2)
sip.setapi(u'QDateTime', 2)
sip.setapi(u'QString', 2)
sip.setapi(u'QTextStream', 2)
sip.setapi(u'QTime', 2)
sip.setapi(u'QUrl', 2)
sip.setapi(u'QVariant', 2)

View File

@ -0,0 +1,50 @@
"""
Package to test the openlp.core.ui package.
"""
import os
from unittest import TestCase
from PyQt4 import QtGui
from openlp.core.lib import Registry, ImageManager, ScreenList
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources'))
class TestImageManager(TestCase):
def setUp(self):
"""
Create the UI
"""
Registry.create()
self.app = QtGui.QApplication([])
ScreenList.create(self.app.desktop())
self.image_manager = ImageManager()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.app
def basic_image_manager_test(self):
"""
Test the Image Manager setup basic functionality
"""
# GIVEN: the an image add to the image manager
self.image_manager.add_image(TEST_PATH, u'church.jpg', None)
# WHEN the image is retrieved
image = self.image_manager.get_image(TEST_PATH, u'church.jpg')
# THEN returned record is a type of image
self.assertEqual(isinstance(image, QtGui.QImage), True, u'The returned object should be a QImage')
# WHEN the image is retrieved has not been loaded
# THEN a KeyError is thrown
with self.assertRaises(KeyError) as context:
self.image_manager.get_image(TEST_PATH, u'church1.jpg')
self.assertNotEquals(context.exception[0], u'', u'KeyError exception should have been thrown for missing image')

View File

@ -7,7 +7,7 @@ from datetime import datetime, timedelta
from mock import MagicMock, patch from mock import MagicMock, patch
from openlp.core.lib import str_to_bool, translate, check_directory_exists, get_text_file_string, build_icon, \ from openlp.core.lib import str_to_bool, translate, check_directory_exists, get_text_file_string, build_icon, \
image_to_byte, check_item_selected, validate_thumb image_to_byte, check_item_selected, validate_thumb, create_separated_list
class TestLib(TestCase): class TestLib(TestCase):
@ -308,14 +308,14 @@ class TestLib(TestCase):
file_path = u'path/to/file' file_path = u'path/to/file'
thumb_path = u'path/to/thumb' thumb_path = u'path/to/thumb'
mocked_os.path.exists.return_value = False mocked_os.path.exists.return_value = False
# WHEN: we run the validate_thumb() function # WHEN: we run the validate_thumb() function
result = validate_thumb(file_path, thumb_path) result = validate_thumb(file_path, thumb_path)
# THEN: we should have called a few functions, and the result should be False # THEN: we should have called a few functions, and the result should be False
mocked_os.path.exists.assert_called_with(thumb_path) mocked_os.path.exists.assert_called_with(thumb_path)
assert result is False, u'The result should be False' assert result is False, u'The result should be False'
def validate_thumb_file_exists_and_newer_test(self): def validate_thumb_file_exists_and_newer_test(self):
""" """
Test the validate_thumb() function when the thumbnail exists and has a newer timestamp than the file Test the validate_thumb() function when the thumbnail exists and has a newer timestamp than the file
@ -350,7 +350,7 @@ class TestLib(TestCase):
thumb_mocked_stat.st_mtime = datetime.now() - timedelta(seconds=10) thumb_mocked_stat.st_mtime = datetime.now() - timedelta(seconds=10)
mocked_os.path.exists.return_value = True mocked_os.path.exists.return_value = True
mocked_os.stat.side_effect = lambda fname: file_mocked_stat if fname == file_path else thumb_mocked_stat mocked_os.stat.side_effect = lambda fname: file_mocked_stat if fname == file_path else thumb_mocked_stat
# WHEN: we run the validate_thumb() function # WHEN: we run the validate_thumb() function
result = validate_thumb(file_path, thumb_path) result = validate_thumb(file_path, thumb_path)
@ -359,3 +359,90 @@ class TestLib(TestCase):
mocked_os.stat.assert_any_call(file_path) mocked_os.stat.assert_any_call(file_path)
mocked_os.stat.assert_any_call(thumb_path) mocked_os.stat.assert_any_call(thumb_path)
assert result is False, u'The result should be False' assert result is False, u'The result should be False'
def create_separated_list_qlocate_test(self):
"""
Test the create_separated_list function using the Qt provided method.
"""
with patch(u'openlp.core.lib.Qt') as mocked_qt, \
patch(u'openlp.core.lib.QtCore.QLocale.createSeparatedList') as mocked_createSeparatedList:
# GIVEN: A list of strings and the mocked Qt module.
mocked_qt.PYQT_VERSION_STR = u'4.9'
mocked_qt.qVersion.return_value = u'4.8'
mocked_createSeparatedList.return_value = u'Author 1, Author 2, and Author 3'
string_list = [u'Author 1', u'Author 2', u'Author 3']
# WHEN: We get a string build from the entries it the list and a seperator.
string_result = create_separated_list(string_list)
# THEN: We should have "Author 1, Author 2, and Author 3"
assert string_result == u'Author 1, Author 2, and Author 3', u'The string should be u\'Author 1, ' \
'Author 2, and Author 3\'.'
def create_separated_list_empty_list_test(self):
"""
Test the create_separated_list function with an empty list.
"""
with patch(u'openlp.core.lib.Qt') as mocked_qt:
# GIVEN: An empty list and the mocked Qt module.
mocked_qt.PYQT_VERSION_STR = u'4.8'
mocked_qt.qVersion.return_value = u'4.7'
string_list = []
# WHEN: We get a string build from the entries it the list and a seperator.
string_result = create_separated_list(string_list)
# THEN: We shoud have an emptry string.
assert string_result == u'', u'The string sould be empty.'
def create_separated_list_with_one_item_test(self):
"""
Test the create_separated_list function with a list consisting of only one entry.
"""
with patch(u'openlp.core.lib.Qt') as mocked_qt:
# GIVEN: A list with a string and the mocked Qt module.
mocked_qt.PYQT_VERSION_STR = u'4.8'
mocked_qt.qVersion.return_value = u'4.7'
string_list = [u'Author 1']
# WHEN: We get a string build from the entries it the list and a seperator.
string_result = create_separated_list(string_list)
# THEN: We should have "Author 1"
assert string_result == u'Author 1', u'The string should be u\'Author 1\'.'
def create_separated_list_with_two_items_test(self):
"""
Test the create_separated_list function with a list of two entries.
"""
with patch(u'openlp.core.lib.Qt') as mocked_qt, patch(u'openlp.core.lib.translate') as mocked_translate:
# GIVEN: A list of strings and the mocked Qt module.
mocked_qt.PYQT_VERSION_STR = u'4.8'
mocked_qt.qVersion.return_value = u'4.7'
mocked_translate.return_value = u'%s and %s'
string_list = [u'Author 1', u'Author 2']
# WHEN: We get a string build from the entries it the list and a seperator.
string_result = create_separated_list(string_list)
# THEN: We should have "Author 1 and Author 2"
assert string_result == u'Author 1 and Author 2', u'The string should be u\'Author 1 and Author 2\'.'
def create_separated_list_with_three_items_test(self):
"""
Test the create_separated_list function with a list of three items.
"""
with patch(u'openlp.core.lib.Qt') as mocked_qt, patch(u'openlp.core.lib.translate') as mocked_translate:
# GIVEN: A list with a string and the mocked Qt module.
mocked_qt.PYQT_VERSION_STR = u'4.8'
mocked_qt.qVersion.return_value = u'4.7'
# Always return the untranslated string.
mocked_translate.side_effect = lambda module, string_to_translate, comment: string_to_translate
string_list = [u'Author 1', u'Author 2', u'Author 3']
# WHEN: We get a string build from the entries it the list and a seperator.
string_result = create_separated_list(string_list)
# THEN: We should have "Author 1, Author 2, and Author 3"
assert string_result == u'Author 1, Author 2, and Author 3', u'The string should be u\'Author 1, ' \
'Author 2, and Author 3\'.'

View File

@ -2,13 +2,14 @@
Package to test the openlp.core.lib package. Package to test the openlp.core.lib package.
""" """
import os import os
from unittest import TestCase from unittest import TestCase
from mock import MagicMock from mock import MagicMock
from openlp.core.lib import Registry from openlp.core.lib import Registry
TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources'))
class TestRegistry(TestCase): class TestRegistry(TestCase):
def registry_service_test(self): def registry_service_test(self):

View File

@ -3,10 +3,9 @@
""" """
import os import os
import cPickle import cPickle
from unittest import TestCase from unittest import TestCase
from mock import MagicMock from mock import MagicMock
from openlp.core.lib import ServiceItem, Registry from openlp.core.lib import ServiceItem, Registry

View File

@ -0,0 +1,8 @@
import sip
sip.setapi(u'QDate', 2)
sip.setapi(u'QDateTime', 2)
sip.setapi(u'QString', 2)
sip.setapi(u'QTextStream', 2)
sip.setapi(u'QTime', 2)
sip.setapi(u'QUrl', 2)
sip.setapi(u'QVariant', 2)

View File

@ -0,0 +1,83 @@
"""
Package to test the openlp.core.ui package.
"""
from unittest import TestCase
from mock import MagicMock, patch
from openlp.core.lib import Registry
from openlp.core.ui import filerenameform
from PyQt4 import QtGui, QtTest
class TestStartFileRenameForm(TestCase):
def setUp(self):
"""
Create the UI
"""
registry = Registry.create()
self.app = QtGui.QApplication([])
self.main_window = QtGui.QMainWindow()
Registry().register(u'main_window', self.main_window)
self.form = filerenameform.FileRenameForm()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.form
del self.main_window
del self.app
def window_title_test(self):
"""
Test the windowTitle of the FileRenameDialog
"""
# GIVEN: A mocked QDialog.exec_() method
with patch(u'PyQt4.QtGui.QDialog.exec_') as mocked_exec:
# WHEN: The form is executed with no args
self.form.exec_()
# THEN: the window title is set correctly
self.assertEqual(self.form.windowTitle(), u'File Rename', u'The window title should be "File Rename"')
# WHEN: The form is executed with False arg
self.form.exec_(False)
# THEN: the window title is set correctly
self.assertEqual(self.form.windowTitle(), u'File Rename', u'The window title should be "File Rename"')
# WHEN: The form is executed with True arg
self.form.exec_(True)
# THEN: the window title is set correctly
self.assertEqual(self.form.windowTitle(), u'File Copy', u'The window title should be "File Copy"')
def line_edit_focus_test(self):
"""
Regression test for bug1067251
Test that the fileNameEdit setFocus has called with True when executed
"""
# GIVEN: A mocked QDialog.exec_() method and mocked fileNameEdit.setFocus() method.
with patch(u'PyQt4.QtGui.QDialog.exec_') as mocked_exec:
mocked_set_focus = MagicMock()
self.form.fileNameEdit.setFocus = mocked_set_focus
# WHEN: The form is executed
self.form.exec_()
# THEN: the setFocus method of the fileNameEdit has been called with True
mocked_set_focus.assert_called_with()
def file_name_validation_test(self):
"""
Test the fileNameEdit validation
"""
# GIVEN: QLineEdit with a validator set with illegal file name characters.
# WHEN: 'Typing' a string containing invalid file characters.
QtTest.QTest.keyClicks(self.form.fileNameEdit, u'I/n\\v?a*l|i<d> \F[i\l]e" :N+a%me')
# THEN: The text in the QLineEdit should be the same as the input string with the invalid chatacters filtered
# out.
self.assertEqual(self.form.fileNameEdit.text(), u'Invalid File Name')

View File

@ -0,0 +1,43 @@
"""
Package to test the openlp.core.lib package.
"""
from unittest import TestCase
from mock import MagicMock
from PyQt4 import QtGui
from openlp.core.lib import Registry, ScreenList
from openlp.core.ui.mainwindow import MainWindow
class TestStartNoteDialog(TestCase):
def setUp(self):
"""
Create the UI
"""
Registry.create()
self.app = QtGui.QApplication([])
ScreenList.create(self.app.desktop())
Registry().register(u'application', MagicMock())
self.main_window = MainWindow()
self.service_manager = Registry().get(u'service_manager')
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.main_window
del self.app
def basic_service_manager_test(self):
"""
Test the Service Manager display functionality
"""
# GIVEN: A New Service Manager instance
# WHEN I have an empty display
# THEN the count of items should be zero
self.assertEqual(self.service_manager.service_manager_list.topLevelItemCount(), 0,
u'The service manager list should be empty ')

View File

@ -2,11 +2,13 @@
Package to test the openlp.core.ui package. Package to test the openlp.core.ui package.
""" """
from unittest import TestCase from unittest import TestCase
from mock import patch from mock import patch
from PyQt4 import QtCore, QtGui, QtTest
from openlp.core.lib import Registry from openlp.core.lib import Registry
from openlp.core.ui import servicenoteform from openlp.core.ui import servicenoteform
from PyQt4 import QtCore, QtGui, QtTest
class TestStartNoteDialog(TestCase): class TestStartNoteDialog(TestCase):

View File

@ -2,11 +2,13 @@
Package to test the openlp.core.ui package. Package to test the openlp.core.ui package.
""" """
from unittest import TestCase from unittest import TestCase
from mock import MagicMock, patch from mock import MagicMock, patch
from PyQt4 import QtCore, QtGui, QtTest
from openlp.core.lib import Registry from openlp.core.lib import Registry
from openlp.core.ui import starttimeform from openlp.core.ui import starttimeform
from PyQt4 import QtCore, QtGui, QtTest
class TestStartTimeDialog(TestCase): class TestStartTimeDialog(TestCase):