Removed a duplicate test file, fixed up some tests, added some more tests

This commit is contained in:
Raoul Snyman 2018-01-12 21:57:16 -07:00
parent 6f9f68a99b
commit 83bc19520a
7 changed files with 217 additions and 151 deletions

View File

@ -26,9 +26,9 @@ from contextlib import suppress
from openlp.core.common import is_win
if is_win():
from pathlib import WindowsPath as PathVariant
from pathlib import WindowsPath as PathVariant # pragma: nocover
else:
from pathlib import PosixPath as PathVariant
from pathlib import PosixPath as PathVariant # pragma: nocover
log = logging.getLogger(__name__)

View File

@ -78,7 +78,10 @@ def get_thread_worker(thread_name):
:param str thread_name: The name of the thread
:returns: The worker for this thread name
"""
return Registry().get('application').worker_threads.get(thread_name)
thread_info = Registry().get('application').worker_threads.get(thread_name)
if not thread_info:
raise KeyError('No thread named "{}" exists'.format(thread_name))
return thread_info.get('worker')
def is_thread_finished(thread_name):
@ -88,8 +91,10 @@ def is_thread_finished(thread_name):
:param str thread_name: The name of the thread
:returns: True if the thread is finished, False if it is still running
"""
app = Registry().get('application')
return thread_name not in app.worker_threads or app.worker_threads[thread_name]['thread'].isFinished()
thread_info = Registry().get('application').worker_threads.get(thread_name)
if not thread_info:
raise KeyError('No thread named "{}" exists'.format(thread_name))
return thread_info['thread'].isFinished()
def make_remove_thread(thread_name):
@ -99,7 +104,8 @@ def make_remove_thread(thread_name):
:param str thread_name: The name of the thread which should be removed from the thread registry.
:returns: A function which will remove the thread from the thread registry.
"""
def remove_thread():
def remove_thread(): # pragma: nocover
"""
Stop and remove a registered thread

View File

@ -22,38 +22,40 @@
"""
Functional tests to test the API Error Class.
"""
from unittest import TestCase
from openlp.core.api.http.errors import NotFound, ServerError
from openlp.core.api.http.errors import HttpError, NotFound, ServerError
class TestApiError(TestCase):
def test_http_error():
"""
A test suite to test out the Error in the API code
Test the HTTPError class
"""
def test_not_found(self):
"""
Test the Not Found error displays the correct information
"""
# GIVEN:
# WHEN: I raise an exception
with self.assertRaises(Exception) as context:
raise NotFound()
# GIVEN: An HTTPError class
# WHEN: An instance is created
error = HttpError(400, 'Access Denied')
# THEN: we get an error and a status
assert 'Not Found' == context.exception.message, 'A Not Found exception should be thrown'
assert 404 == context.exception.status, 'A 404 status should be thrown'
# THEN: The to_response() method should return the correct information
assert error.to_response() == ('Access Denied', 400), 'to_response() should have returned the correct info'
def test_server_error(self):
"""
Test the server error displays the correct information
"""
# GIVEN:
# WHEN: I raise an exception
with self.assertRaises(Exception) as context:
raise ServerError()
# THEN: we get an error and a status
assert'Server Error' == context.exception.message, 'A Not Found exception should be thrown'
assert 500 == context.exception.status, 'A 500 status should be thrown'
def test_not_found():
"""
Test the Not Found error displays the correct information
"""
# GIVEN: A NotFound class
# WHEN: An instance is created
error = NotFound()
# THEN: The to_response() method should return the correct information
assert error.to_response() == ('Not Found', 404), 'to_response() should have returned the correct info'
def test_server_error():
"""
Test the server error displays the correct information
"""
# GIVEN: A ServerError class
# WHEN: An instance of the class is created
error = ServerError()
# THEN: The to_response() method should return the correct information
assert error.to_response() == ('Server Error', 500), 'to_response() should have returned the correct info'

View File

@ -27,7 +27,7 @@ from unittest import TestCase
from unittest.mock import ANY, MagicMock, patch
from openlp.core.common.path import Path, copy, copyfile, copytree, create_paths, path_to_str, replace_params, \
str_to_path, which
str_to_path, which, files_to_paths
class TestShutil(TestCase):
@ -401,3 +401,16 @@ class TestPath(TestCase):
except:
# THEN: `create_paths` raises an exception
pass
def test_files_to_paths(self):
"""
Test the files_to_paths() method
"""
# GIVEN: A list of string filenames
test_files = ['/tmp/openlp/file1.txt', '/tmp/openlp/file2.txt']
# WHEN: files_to_paths is called
result = files_to_paths(test_files)
# THEN: The result should be a list of Paths
assert result == [Path('/tmp/openlp/file1.txt'), Path('/tmp/openlp/file2.txt')]

View File

@ -1,87 +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 #
###############################################################################
"""
Package to test the openlp.core.lib.path package.
"""
import os
from unittest import TestCase
from openlp.core.common.path import Path, path_to_str, str_to_path
class TestPath(TestCase):
"""
Tests for the :mod:`openlp.core.lib.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
assert 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
assert 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
assert result is None

View File

@ -23,14 +23,14 @@
Package to test the openlp.core.lib.ui package.
"""
from unittest import TestCase
from unittest.mock import MagicMock, patch
from unittest.mock import MagicMock, patch, call
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.lib.ui import add_welcome_page, create_button_box, create_horizontal_adjusting_combo_box, \
create_button, create_action, create_valign_selection_widgets, find_and_set_in_combo_box, create_widget_action, \
set_case_insensitive_completer
set_case_insensitive_completer, critical_error_message_box
class TestUi(TestCase):
@ -80,6 +80,34 @@ class TestUi(TestCase):
assert 1 == len(btnbox.buttons())
assert QtWidgets.QDialogButtonBox.HelpRole, btnbox.buttonRole(btnbox.buttons()[0])
@patch('openlp.core.lib.ui.Registry')
def test_critical_error_message_box(self, MockRegistry):
"""
Test the critical_error_message_box() function
"""
# GIVEN: A mocked Registry
# WHEN: critical_error_message_box() is called
critical_error_message_box('Error', 'This is an error')
# THEN: The error_message() method on the main window should be called
MockRegistry.return_value.get.return_value.error_message.assert_called_once_with('Error', 'This is an error')
@patch('openlp.core.lib.ui.QtWidgets.QMessageBox.critical')
def test_critical_error_question(self, mocked_critical):
"""
Test the critical_error_message_box() function
"""
# GIVEN: A mocked critical() method and some other mocks
mocked_parent = MagicMock()
# WHEN: critical_error_message_box() is called
critical_error_message_box(None, 'This is a question', mocked_parent, True)
# THEN: The error_message() method on the main window should be called
mocked_critical.assert_called_once_with(mocked_parent, 'Error', 'This is a question',
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
QtWidgets.QMessageBox.No))
def test_create_horizontal_adjusting_combo_box(self):
"""
Test creating a horizontal adjusting combo box
@ -92,65 +120,64 @@ class TestUi(TestCase):
# THEN: We should get a ComboBox
assert isinstance(combo, QtWidgets.QComboBox)
assert 'combo1' == combo.objectName()
assert combo.objectName() == 'combo1'
assert QtWidgets.QComboBox.AdjustToMinimumContentsLength == combo.sizeAdjustPolicy()
def test_create_button(self):
@patch('openlp.core.lib.ui.log')
def test_create_button(self, mocked_log):
"""
Test creating a button
"""
# GIVEN: A dialog
dialog = QtWidgets.QDialog()
# WHEN: We create the button
btn = create_button(dialog, 'my_btn')
# THEN: We should get a button with a name
assert isinstance(btn, QtWidgets.QPushButton)
assert 'my_btn' == btn.objectName()
assert btn.isEnabled() is True
# WHEN: We create a button with some attributes
btn = create_button(dialog, 'my_btn', text='Hello', tooltip='How are you?', enabled=False)
btn = create_button(dialog, 'my_btn', text='Hello', tooltip='How are you?', enabled=False, role='test', test=1)
# THEN: We should get a button with those attributes
assert isinstance(btn, QtWidgets.QPushButton)
assert 'Hello' == btn.text()
assert 'How are you?' == btn.toolTip()
assert btn.objectName() == 'my_btn'
assert btn.text() == 'Hello'
assert btn.toolTip() == 'How are you?'
assert btn.isEnabled() is False
assert mocked_log.warning.call_args_list == [call('The role "test" is not defined in create_push_button().'),
call('Parameter test was not consumed in create_button().')]
def test_create_tool_button(self):
"""
Test creating a toolbutton
"""
# GIVEN: A dialog
dialog = QtWidgets.QDialog()
# WHEN: We create a toolbutton
btn = create_button(dialog, 'my_btn', btn_class='toolbutton')
# THEN: We should get a toolbutton
assert isinstance(btn, QtWidgets.QToolButton)
assert 'my_btn' == btn.objectName()
assert btn.objectName() == 'my_btn'
assert btn.isEnabled() is True
def test_create_action(self):
@patch('openlp.core.lib.ui.log')
def test_create_action(self, mocked_log):
"""
Test creating an action
"""
# GIVEN: A dialog
dialog = QtWidgets.QDialog()
# WHEN: We create an action
action = create_action(dialog, 'my_action')
# THEN: We should get a QAction
assert isinstance(action, QtWidgets.QAction)
assert 'my_action' == action.objectName()
# WHEN: We create an action with some properties
action = create_action(dialog, 'my_action', text='my text', icon=':/wizards/wizard_firsttime.bmp',
tooltip='my tooltip', statustip='my statustip')
tooltip='my tooltip', statustip='my statustip', test=1)
# THEN: These properties should be set
assert isinstance(action, QtWidgets.QAction)
assert 'my text' == action.text()
assert action.objectName() == 'my_action'
assert action.text() == 'my text'
assert isinstance(action.icon(), QtGui.QIcon)
assert 'my tooltip' == action.toolTip()
assert 'my statustip' == action.statusTip()
assert action.toolTip() == 'my tooltip'
assert action.statusTip() == 'my statustip'
mocked_log.warning.assert_called_once_with('Parameter test was not consumed in create_action().')
def test_create_action_on_mac_osx(self):
"""

View File

@ -22,9 +22,10 @@
"""
Package to test the openlp.core.threading package.
"""
from inspect import isfunction
from unittest.mock import MagicMock, call, patch
from openlp.core.version import run_thread
from openlp.core.threading import ThreadWorker, run_thread, get_thread_worker, is_thread_finished, make_remove_thread
def test_run_thread_no_name():
@ -88,3 +89,107 @@ def test_run_thread(MockRegistry, MockQThread):
'The threads finished signal should be connected to its deleteLater slot'
assert mocked_thread.finished.connect.call_count == 2, 'The signal should have been connected twice'
mocked_thread.start.assert_called_once_with()
def test_thread_worker():
"""
Test that creating a thread worker object and calling start throws and NotImplementedError
"""
# GIVEN: A ThreadWorker class
worker = ThreadWorker()
try:
# WHEN: calling start()
worker.start()
assert False, 'A NotImplementedError should have been thrown'
except NotImplementedError:
# A NotImplementedError should be thrown
pass
except Exception:
assert False, 'A NotImplementedError should have been thrown'
@patch('openlp.core.threading.Registry')
def test_get_thread_worker(MockRegistry):
"""
Test that calling the get_thread_worker() function returns the correct worker
"""
# GIVEN: A mocked thread worker
mocked_worker = MagicMock()
MockRegistry.return_value.get.return_value.worker_threads = {'test_thread': {'worker': mocked_worker}}
# WHEN: get_thread_worker() is called
worker = get_thread_worker('test_thread')
# THEN: The mocked worker is returned
assert worker is mocked_worker, 'The mocked worker should have been returned'
@patch('openlp.core.threading.Registry')
def test_get_thread_worker_mising(MockRegistry):
"""
Test that calling the get_thread_worker() function raises a KeyError if it does not exist
"""
# GIVEN: A mocked thread worker
MockRegistry.return_value.get.return_value.worker_threads = {}
try:
# WHEN: get_thread_worker() is called
get_thread_worker('test_thread')
assert False, 'A KeyError should have been raised'
except KeyError:
# THEN: The mocked worker is returned
pass
except Exception:
assert False, 'A KeyError should have been raised'
@patch('openlp.core.threading.Registry')
def test_is_thread_finished(MockRegistry):
"""
Test the is_thread_finished() function
"""
# GIVEN: A mock thread and worker
mocked_thread = MagicMock()
mocked_thread.isFinished.return_value = True
MockRegistry.return_value.get.return_value.worker_threads = {'test': {'thread': mocked_thread}}
# WHEN: is_thread_finished() is called
result = is_thread_finished('test')
# THEN: The result should be correct
assert result is True, 'is_thread_finished should have returned True'
@patch('openlp.core.threading.Registry')
def test_is_thread_finished_mising(MockRegistry):
"""
Test that calling the is_thread_finished() function raises a KeyError if it does not exist
"""
# GIVEN: A mocked thread worker
MockRegistry.return_value.get.return_value.worker_threads = {}
try:
# WHEN: get_thread_worker() is called
is_thread_finished('test_thread')
assert False, 'A KeyError should have been raised when calling is_thread_finished'
except KeyError:
# THEN: The mocked worker is returned
pass
except Exception:
assert False, 'A KeyError should have been raised when calling is_thread_finished'
def test_make_remove_thread():
"""
Test the make_remove_thread() function
"""
# GIVEN: A thread name
thread_name = 'test_thread'
# WHEN: make_remove_thread() is called
rm_func = make_remove_thread(thread_name)
# THEN: The result should be a function
assert isfunction(rm_func), 'make_remove_thread should return a function'
assert rm_func.__name__ == 'remove_thread'