openlp/tests/functional/openlp_core/lib/test_lib.py

860 lines
36 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
2019-04-13 13:00:22 +00:00
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2020 OpenLP Developers #
2019-04-13 13:00:22 +00:00
# ---------------------------------------------------------------------- #
# 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, either version 3 of the License, or #
# (at your option) any later version. #
# #
# 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, see <https://www.gnu.org/licenses/>. #
##########################################################################
2012-12-06 22:19:17 +00:00
"""
Package to test the openlp.core.lib package.
"""
import io
import os
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
2012-12-06 22:19:17 +00:00
2015-11-07 00:49:40 +00:00
from PyQt5 import QtCore, QtGui
2013-05-18 08:44:03 +00:00
from openlp.core.lib import DataType, build_icon, check_item_selected, create_separated_list, create_thumb, \
get_text_file_string, image_to_byte, read_or_fail, read_int, resize_image, seek_or_fail, str_to_bool, validate_thumb
2017-12-22 21:20:49 +00:00
from tests.utils.constants import RESOURCE_PATH
2012-12-06 22:19:17 +00:00
2012-12-07 21:15:10 +00:00
class TestLib(TestCase):
2012-12-06 22:19:17 +00:00
2016-05-31 21:40:13 +00:00
def test_str_to_bool_with_bool_true(self):
2012-12-06 22:19:17 +00:00
"""
Test the str_to_bool function with boolean input of True
2012-12-06 22:19:17 +00:00
"""
2013-03-30 08:46:34 +00:00
# GIVEN: A boolean value set to true
2012-12-06 22:19:17 +00:00
true_boolean = True
# WHEN: We "convert" it to a bool
true_result = str_to_bool(true_boolean)
# THEN: We should get back a True bool
2017-12-17 15:35:35 +00:00
assert isinstance(true_result, bool), 'The result should be a boolean'
assert true_result is True, 'The result should be True'
2012-12-06 22:19:17 +00:00
2016-05-31 21:40:13 +00:00
def test_str_to_bool_with_bool_false(self):
"""
Test the str_to_bool function with boolean input of False
"""
2013-03-30 08:46:34 +00:00
# GIVEN: A boolean value set to false
2012-12-06 22:19:17 +00:00
false_boolean = False
# WHEN: We "convert" it to a bool
false_result = str_to_bool(false_boolean)
# THEN: We should get back a True bool
2017-12-17 15:35:35 +00:00
assert isinstance(false_result, bool), 'The result should be a boolean'
assert false_result is False, 'The result should be True'
2012-12-06 22:19:17 +00:00
2016-05-31 21:40:13 +00:00
def test_str_to_bool_with_integer(self):
2012-12-06 22:19:17 +00:00
"""
Test the str_to_bool function with an integer input
2012-12-06 22:19:17 +00:00
"""
# GIVEN: An integer value
int_string = 1
# WHEN: we convert it to a bool
int_result = str_to_bool(int_string)
# THEN: we should get back a false
2017-12-17 15:35:35 +00:00
assert int_result is False, 'The result should be False'
2012-12-06 22:19:17 +00:00
2016-05-31 21:40:13 +00:00
def test_str_to_bool_with_invalid_string(self):
"""
Test the str_to_bool function with an invalid string
"""
2012-12-06 22:19:17 +00:00
# GIVEN: An string value with completely invalid input
2013-08-31 18:17:38 +00:00
invalid_string = 'my feet are wet'
2012-12-06 22:19:17 +00:00
# WHEN: we convert it to a bool
str_result = str_to_bool(invalid_string)
# THEN: we should get back a false
2017-12-17 15:35:35 +00:00
assert str_result is False, 'The result should be False'
2012-12-06 22:19:17 +00:00
2016-05-31 21:40:13 +00:00
def test_str_to_bool_with_string_false(self):
2012-12-06 22:19:17 +00:00
"""
Test the str_to_bool function with a string saying "false"
2012-12-06 22:19:17 +00:00
"""
# GIVEN: A string set to "false"
2013-08-31 18:17:38 +00:00
false_string = 'false'
2012-12-06 22:19:17 +00:00
# WHEN: we convert it to a bool
false_result = str_to_bool(false_string)
# THEN: we should get back a false
2017-12-17 15:35:35 +00:00
assert false_result is False, 'The result should be False'
2012-12-06 22:19:17 +00:00
2016-05-31 21:40:13 +00:00
def test_str_to_bool_with_string_no(self):
"""
Test the str_to_bool function with a string saying "NO"
"""
2012-12-06 22:19:17 +00:00
# GIVEN: An string set to "NO"
2013-08-31 18:17:38 +00:00
no_string = 'NO'
2012-12-06 22:19:17 +00:00
# WHEN: we convert it to a bool
str_result = str_to_bool(no_string)
# THEN: we should get back a false
2017-12-17 15:35:35 +00:00
assert str_result is False, 'The result should be False'
2012-12-06 22:19:17 +00:00
2016-05-31 21:40:13 +00:00
def test_str_to_bool_with_true_string_value(self):
2012-12-06 22:19:17 +00:00
"""
Test the str_to_bool function with a string set to "True"
2012-12-06 22:19:17 +00:00
"""
# GIVEN: A string set to "True"
2013-08-31 18:17:38 +00:00
true_string = 'True'
2012-12-06 22:19:17 +00:00
# WHEN: we convert it to a bool
true_result = str_to_bool(true_string)
# THEN: we should get back a true
2017-12-17 15:35:35 +00:00
assert true_result is True, 'The result should be True'
2012-12-06 22:19:17 +00:00
2016-05-31 21:40:13 +00:00
def test_str_to_bool_with_yes_string_value(self):
"""
Test the str_to_bool function with a string set to "yes"
"""
2012-12-06 22:19:17 +00:00
# GIVEN: An string set to "yes"
2013-08-31 18:17:38 +00:00
yes_string = 'yes'
2012-12-06 22:19:17 +00:00
# WHEN: we convert it to a bool
str_result = str_to_bool(yes_string)
# THEN: we should get back a true
2017-12-17 15:35:35 +00:00
assert str_result is True, 'The result should be True'
2012-12-06 22:19:17 +00:00
2016-05-31 21:40:13 +00:00
def test_get_text_file_string_no_file(self):
2012-12-10 20:48:37 +00:00
"""
Test the get_text_file_string() function when a file does not exist
"""
# GIVEN: A patched is_file which returns False, and a file path
with patch.object(Path, 'is_file', return_value=False):
file_path = Path('testfile.txt')
2012-12-10 20:48:37 +00:00
# WHEN: get_text_file_string is called
result = get_text_file_string(file_path)
2012-12-10 20:48:37 +00:00
# THEN: The result should be False
file_path.is_file.assert_called_with()
2017-12-17 15:35:35 +00:00
assert result is False, 'False should be returned if no file exists'
2012-12-10 20:48:37 +00:00
2016-05-31 21:40:13 +00:00
def test_get_text_file_string_read_error(self):
"""
Test the get_text_file_string() method when a read error happens
"""
# GIVEN: A patched open which raises an exception and is_file which returns True
with patch.object(Path, 'is_file'), \
patch.object(Path, 'open'):
file_path = Path('testfile.txt')
file_path.is_file.return_value = True
file_path.open.side_effect = OSError()
2012-12-10 20:48:37 +00:00
# WHEN: get_text_file_string is called
result = get_text_file_string(file_path)
2012-12-10 20:48:37 +00:00
# THEN: None should be returned
file_path.is_file.assert_called_once_with()
file_path.open.assert_called_once_with('r', encoding='utf-8')
2017-12-17 15:35:35 +00:00
assert result is None, 'None should be returned if the file cannot be opened'
2012-12-10 20:48:37 +00:00
2016-05-31 21:40:13 +00:00
def test_get_text_file_string_decode_error(self):
"""
Test the get_text_file_string() method when the contents cannot be decoded
"""
self.skipTest('Impossible to test due to conflicts when mocking out the "open" function')
2012-12-10 20:48:37 +00:00
2016-05-31 21:40:13 +00:00
def test_build_icon_with_qicon(self):
2013-01-07 20:21:14 +00:00
"""
Test the build_icon() function with a QIcon instance
"""
2016-10-30 08:29:22 +00:00
# GIVEN: An icon QIcon
icon = QtGui.QIcon()
2013-01-07 20:21:14 +00:00
2016-10-30 08:29:22 +00:00
# WHEN: We pass a QIcon instance in
result = build_icon(icon)
2013-01-07 20:21:14 +00:00
2016-10-30 08:29:22 +00:00
# THEN: The result should be the same icon as we passed in
2017-12-17 15:35:35 +00:00
assert icon is result, 'The result should be the same icon as we passed in'
2013-01-07 20:21:14 +00:00
2016-05-31 21:40:13 +00:00
def test_build_icon_with_resource(self):
2013-01-07 20:21:14 +00:00
"""
Test the build_icon() function with a resource URI
"""
2013-08-31 18:17:38 +00:00
with patch('openlp.core.lib.QtGui') as MockedQtGui, \
patch('openlp.core.lib.QtGui.QPixmap') as MockedQPixmap:
2013-01-07 20:21:14 +00:00
# GIVEN: A mocked QIcon and a mocked QPixmap
MockedQtGui.QIcon = MagicMock
MockedQtGui.QIcon.Normal = 1
MockedQtGui.QIcon.Off = 2
2013-08-31 18:17:38 +00:00
MockedQPixmap.return_value = 'mocked_pixmap'
resource_uri = ':/resource/uri'
2013-01-07 20:21:14 +00:00
# WHEN: We pass a QIcon instance in
result = build_icon(resource_uri)
# THEN: The result should be our mocked QIcon
MockedQPixmap.assert_called_with(resource_uri)
# There really should be more assert statements here but due to type checking and things they all break. The
# best we can do is to assert that we get back a MagicMock object.
2017-12-17 15:35:35 +00:00
assert isinstance(result, MagicMock), 'The result should be a MagicMock, because we mocked it out'
2013-01-07 20:21:14 +00:00
2016-05-31 21:40:13 +00:00
def test_image_to_byte(self):
2016-10-30 08:29:22 +00:00
"""
Test the image_to_byte() function
"""
with patch('openlp.core.lib.QtCore') as MockedQtCore:
# GIVEN: A set of mocked-out Qt classes
mocked_byte_array = MagicMock()
MockedQtCore.QByteArray.return_value = mocked_byte_array
mocked_buffer = MagicMock()
MockedQtCore.QBuffer.return_value = mocked_buffer
MockedQtCore.QIODevice.WriteOnly = 'writeonly'
mocked_image = MagicMock()
# WHEN: We convert an image to a byte array
result = image_to_byte(mocked_image, base_64=False)
# THEN: We should receive the mocked_buffer
MockedQtCore.QByteArray.assert_called_with()
MockedQtCore.QBuffer.assert_called_with(mocked_byte_array)
mocked_buffer.open.assert_called_with('writeonly')
mocked_image.save.assert_called_with(mocked_buffer, "PNG")
2017-12-17 15:35:35 +00:00
assert mocked_byte_array.toBase64.called is False
assert mocked_byte_array == result, 'The mocked out byte array should be returned'
2016-10-30 08:29:22 +00:00
def test_image_to_byte_base_64(self):
"""
Test the image_to_byte() function
"""
2013-08-31 18:17:38 +00:00
with patch('openlp.core.lib.QtCore') as MockedQtCore:
# GIVEN: A set of mocked-out Qt classes
mocked_byte_array = MagicMock()
MockedQtCore.QByteArray.return_value = mocked_byte_array
2015-11-20 19:30:46 +00:00
mocked_byte_array.toBase64.return_value = QtCore.QByteArray(b'base64mock')
mocked_buffer = MagicMock()
MockedQtCore.QBuffer.return_value = mocked_buffer
2013-08-31 18:17:38 +00:00
MockedQtCore.QIODevice.WriteOnly = 'writeonly'
mocked_image = MagicMock()
# WHEN: We convert an image to a byte array
result = image_to_byte(mocked_image)
2014-05-02 06:42:17 +00:00
# THEN: We should receive a value of 'base64mock'
MockedQtCore.QByteArray.assert_called_with()
MockedQtCore.QBuffer.assert_called_with(mocked_byte_array)
2013-08-31 18:17:38 +00:00
mocked_buffer.open.assert_called_with('writeonly')
mocked_image.save.assert_called_with(mocked_buffer, "PNG")
mocked_byte_array.toBase64.assert_called_with()
2017-12-17 15:35:35 +00:00
assert 'base64mock' == result, 'The result should be the return value of the mocked out base64 method'
2016-05-31 21:40:13 +00:00
def test_create_thumb_with_size(self):
2013-05-18 08:44:03 +00:00
"""
Test the create_thumb() function with a given size.
2013-05-18 08:44:03 +00:00
"""
# GIVEN: An image to create a thumb of.
2017-12-22 21:20:49 +00:00
image_path = RESOURCE_PATH / 'church.jpg'
thumb_path = RESOURCE_PATH / 'church_thumb.jpg'
2013-05-18 08:44:03 +00:00
thumb_size = QtCore.QSize(10, 20)
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
# last test.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
2013-05-18 08:44:03 +00:00
pass
# Only continue when the thumb does not exist.
2017-12-17 15:35:35 +00:00
assert thumb_path.exists() is False, 'Test was not run, because the thumb already exists.'
2013-05-18 08:44:03 +00:00
# WHEN: Create the thumb.
icon = create_thumb(image_path, thumb_path, size=thumb_size)
# THEN: Check if the thumb was created and scaled to the given size.
2017-12-23 09:09:45 +00:00
assert thumb_path.exists() is True, 'Test was not ran, because the thumb already exists'
2017-12-17 15:35:35 +00:00
assert isinstance(icon, QtGui.QIcon), 'The icon should be a QIcon'
2017-12-18 17:10:04 +00:00
assert icon.isNull() is False, 'The icon should not be null'
2017-12-17 15:35:35 +00:00
assert thumb_size == QtGui.QImageReader(str(thumb_path)).size(), 'The thumb should have the given size'
2013-05-18 08:44:03 +00:00
# Remove the thumb so that the test actually tests if the thumb will be created.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
2013-05-18 08:44:03 +00:00
pass
2016-05-31 21:40:13 +00:00
def test_create_thumb_no_size(self):
"""
Test the create_thumb() function with no size specified.
"""
# GIVEN: An image to create a thumb of.
2017-12-22 21:20:49 +00:00
image_path = RESOURCE_PATH / 'church.jpg'
thumb_path = RESOURCE_PATH / 'church_thumb.jpg'
expected_size = QtCore.QSize(63, 88)
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
# last test.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
# Only continue when the thumb does not exist.
2017-12-17 15:35:35 +00:00
assert thumb_path.exists() is False, 'Test was not run, because the thumb already exists.'
# WHEN: Create the thumb.
icon = create_thumb(image_path, thumb_path)
# THEN: Check if the thumb was created, retaining its aspect ratio.
2017-12-23 09:09:45 +00:00
assert thumb_path.exists() is True, 'Test was not ran, because the thumb already exists'
2017-12-17 15:35:35 +00:00
assert isinstance(icon, QtGui.QIcon), 'The icon should be a QIcon'
assert icon.isNull() is False, 'The icon should not be null'
assert expected_size == QtGui.QImageReader(str(thumb_path)).size(), 'The thumb should have the given size'
# Remove the thumb so that the test actually tests if the thumb will be created.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
2016-05-31 21:40:13 +00:00
def test_create_thumb_invalid_size(self):
"""
Test the create_thumb() function with invalid size specified.
"""
# GIVEN: An image to create a thumb of.
2017-12-22 21:20:49 +00:00
image_path = RESOURCE_PATH / 'church.jpg'
thumb_path = RESOURCE_PATH / 'church_thumb.jpg'
thumb_size = QtCore.QSize(-1, -1)
expected_size = QtCore.QSize(63, 88)
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
# last test.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
# Only continue when the thumb does not exist.
2017-12-17 15:35:35 +00:00
assert thumb_path.exists() is False, 'Test was not run, because the thumb already exists.'
# WHEN: Create the thumb.
2016-05-05 19:03:12 +00:00
icon = create_thumb(image_path, thumb_path, size=thumb_size)
# THEN: Check if the thumb was created, retaining its aspect ratio.
2017-12-17 15:35:35 +00:00
assert thumb_path.exists() is True, 'Test was not ran, because the thumb already exists'
assert isinstance(icon, QtGui.QIcon), 'The icon should be a QIcon'
assert icon.isNull() is False, 'The icon should not be null'
assert expected_size == QtGui.QImageReader(str(thumb_path)).size(), 'The thumb should have the given size'
# Remove the thumb so that the test actually tests if the thumb will be created.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
2016-05-31 21:40:13 +00:00
def test_create_thumb_width_only(self):
"""
Test the create_thumb() function with a size of only width specified.
"""
# GIVEN: An image to create a thumb of.
2017-12-22 21:20:49 +00:00
image_path = RESOURCE_PATH / 'church.jpg'
thumb_path = RESOURCE_PATH / 'church_thumb.jpg'
thumb_size = QtCore.QSize(100, -1)
expected_size = QtCore.QSize(100, 137)
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
# last test.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
# Only continue when the thumb does not exist.
2017-12-17 15:35:35 +00:00
assert thumb_path.exists() is False, 'Test was not run, because the thumb already exists.'
# WHEN: Create the thumb.
icon = create_thumb(image_path, thumb_path, size=thumb_size)
# THEN: Check if the thumb was created, retaining its aspect ratio.
2017-12-17 15:35:35 +00:00
assert thumb_path.exists() is True, 'Test was not ran, because the thumb already exists'
assert isinstance(icon, QtGui.QIcon), 'The icon should be a QIcon'
assert icon.isNull() is False, 'The icon should not be null'
assert expected_size == QtGui.QImageReader(str(thumb_path)).size(), 'The thumb should have the given size'
# Remove the thumb so that the test actually tests if the thumb will be created.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
2016-05-31 21:40:13 +00:00
def test_create_thumb_height_only(self):
"""
Test the create_thumb() function with a size of only height specified.
"""
# GIVEN: An image to create a thumb of.
2017-12-22 21:20:49 +00:00
image_path = RESOURCE_PATH / 'church.jpg'
thumb_path = RESOURCE_PATH / 'church_thumb.jpg'
thumb_size = QtCore.QSize(-1, 100)
expected_size = QtCore.QSize(72, 100)
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
# last test.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
# Only continue when the thumb does not exist.
2017-12-17 15:35:35 +00:00
assert thumb_path.exists() is False, 'Test was not run, because the thumb already exists.'
# WHEN: Create the thumb.
icon = create_thumb(image_path, thumb_path, size=thumb_size)
# THEN: Check if the thumb was created, retaining its aspect ratio.
2017-12-23 09:09:45 +00:00
assert thumb_path.exists() is True, 'Test was not ran, because the thumb already exists'
2017-12-17 15:35:35 +00:00
assert isinstance(icon, QtGui.QIcon), 'The icon should be a QIcon'
assert icon.isNull() is False, 'The icon should not be null'
assert expected_size == QtGui.QImageReader(str(thumb_path)).size(), 'The thumb should have the given size'
# Remove the thumb so that the test actually tests if the thumb will be created.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
2016-05-31 21:40:13 +00:00
def test_create_thumb_empty_img(self):
"""
Test the create_thumb() function with a size of only height specified.
"""
# GIVEN: An image to create a thumb of.
2017-12-22 21:20:49 +00:00
image_path = RESOURCE_PATH / 'church.jpg'
thumb_path = RESOURCE_PATH / 'church_thumb.jpg'
thumb_size = QtCore.QSize(-1, 100)
expected_size_1 = QtCore.QSize(88, 88)
expected_size_2 = QtCore.QSize(100, 100)
# Remove the thumb so that the test actually tests if the thumb will be created. Maybe it was not deleted in the
# last test.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
# Only continue when the thumb does not exist.
2017-12-17 15:35:35 +00:00
assert thumb_path.exists() is False, 'Test was not run, because the thumb already exists.'
# WHEN: Create the thumb.
with patch('openlp.core.lib.QtGui.QImageReader.size') as mocked_size:
mocked_size.return_value = QtCore.QSize(0, 0)
icon = create_thumb(image_path, thumb_path, size=None)
# THEN: Check if the thumb was created with aspect ratio of 1.
2017-12-23 09:09:45 +00:00
assert thumb_path.exists() is True, 'Test was not ran, because the thumb already exists'
2017-12-17 15:35:35 +00:00
assert isinstance(icon, QtGui.QIcon), 'The icon should be a QIcon'
assert icon.isNull() is False, 'The icon should not be null'
assert expected_size_1 == QtGui.QImageReader(str(thumb_path)).size(), 'The thumb should have the given size'
# WHEN: Create the thumb.
with patch('openlp.core.lib.QtGui.QImageReader.size') as mocked_size:
mocked_size.return_value = QtCore.QSize(0, 0)
icon = create_thumb(image_path, thumb_path, size=thumb_size)
2016-05-18 17:06:25 +00:00
# THEN: Check if the thumb was created with aspect ratio of 1.
2017-12-17 15:35:35 +00:00
assert isinstance(icon, QtGui.QIcon), 'The icon should be a QIcon'
assert icon.isNull() is False, 'The icon should not be null'
assert expected_size_2 == QtGui.QImageReader(str(thumb_path)).size(), 'The thumb should have the given size'
# Remove the thumb so that the test actually tests if the thumb will be created.
try:
2017-11-18 11:23:15 +00:00
thumb_path.unlink()
2018-10-27 01:40:20 +00:00
except Exception:
pass
@patch('openlp.core.lib.QtWidgets', MagicMock())
2016-05-31 21:40:13 +00:00
def test_check_item_selected_true(self):
"""
2013-05-18 08:44:03 +00:00
Test that the check_item_selected() function returns True when there are selected indexes
"""
2015-11-07 00:49:40 +00:00
# GIVEN: A mocked out QtWidgets module and a list widget with selected indexes
mocked_list_widget = MagicMock()
mocked_list_widget.selectedIndexes.return_value = True
2013-08-31 18:17:38 +00:00
message = 'message'
# WHEN: We check if there are selected items
result = check_item_selected(mocked_list_widget, message)
# THEN: The selectedIndexes function should have been called and the result should be true
mocked_list_widget.selectedIndexes.assert_called_with()
2017-12-17 15:35:35 +00:00
assert result is True, 'The result should be True'
2016-05-31 21:40:13 +00:00
def test_check_item_selected_false(self):
"""
Test that the check_item_selected() function returns False when there are no selected indexes.
"""
2015-11-07 00:49:40 +00:00
# GIVEN: A mocked out QtWidgets module and a list widget with selected indexes
with patch('openlp.core.lib.QtWidgets') as MockedQtWidgets, \
patch('openlp.core.lib.translate') as mocked_translate:
2013-08-31 18:17:38 +00:00
mocked_translate.return_value = 'mocked translate'
mocked_list_widget = MagicMock()
mocked_list_widget.selectedIndexes.return_value = False
2013-08-31 18:17:38 +00:00
mocked_list_widget.parent.return_value = 'parent'
message = 'message'
# WHEN: We check if there are selected items
result = check_item_selected(mocked_list_widget, message)
# THEN: The selectedIndexes function should have been called and the result should be true
mocked_list_widget.selectedIndexes.assert_called_with()
2015-11-07 00:49:40 +00:00
MockedQtWidgets.QMessageBox.information.assert_called_with('parent', 'mocked translate', 'message')
2017-12-17 15:35:35 +00:00
assert result is False, 'The result should be False'
2016-05-31 21:40:13 +00:00
def test_validate_thumb_file_does_not_exist(self):
2013-01-21 13:04:18 +00:00
"""
Test the validate_thumb() function when the thumbnail does not exist
"""
# GIVEN: A mocked out os module, with path.exists returning False, and fake paths to a file and a thumb
with patch.object(Path, 'exists', return_value=False):
2017-09-17 19:43:15 +00:00
file_path = Path('path', 'to', 'file')
thumb_path = Path('path', 'to', 'thumb')
2013-02-06 17:36:36 +00:00
# WHEN: we run the validate_thumb() function
result = validate_thumb(file_path, thumb_path)
2013-02-06 17:36:36 +00:00
# THEN: we should have called a few functions, and the result should be False
2017-09-17 19:43:15 +00:00
thumb_path.exists.assert_called_once_with()
2017-12-17 15:35:35 +00:00
assert result is False, 'The result should be False'
2013-02-06 17:36:36 +00:00
2016-05-31 21:40:13 +00:00
def test_validate_thumb_file_exists_and_newer(self):
"""
Test the validate_thumb() function when the thumbnail exists and has a newer timestamp than the file
2013-01-21 13:04:18 +00:00
"""
2017-09-17 19:43:15 +00:00
with patch.object(Path, 'exists'), patch.object(Path, 'stat'):
# GIVEN: Mocked file_path and thumb_path which return different values fo the modified times
file_path = MagicMock(**{'stat.return_value': MagicMock(st_mtime=10)})
thumb_path = MagicMock(**{'exists.return_value': True, 'stat.return_value': MagicMock(st_mtime=11)})
2013-01-21 13:04:18 +00:00
# WHEN: we run the validate_thumb() function
2017-09-17 19:43:15 +00:00
result = validate_thumb(file_path, thumb_path)
2013-01-21 13:04:18 +00:00
2017-09-17 19:43:15 +00:00
# THEN: `validate_thumb` should return True
2017-12-17 15:35:35 +00:00
assert result is True
2016-05-31 21:40:13 +00:00
def test_validate_thumb_file_exists_and_older(self):
"""
Test the validate_thumb() function when the thumbnail exists but is older than the file
"""
2017-09-17 19:43:15 +00:00
# GIVEN: Mocked file_path and thumb_path which return different values fo the modified times
file_path = MagicMock(**{'stat.return_value': MagicMock(st_mtime=10)})
thumb_path = MagicMock(**{'exists.return_value': True, 'stat.return_value': MagicMock(st_mtime=9)})
2013-02-06 17:36:36 +00:00
2017-09-17 19:43:15 +00:00
# WHEN: we run the validate_thumb() function
result = validate_thumb(file_path, thumb_path)
2017-09-17 19:43:15 +00:00
# THEN: `validate_thumb` should return False
thumb_path.stat.assert_called_once_with()
2017-12-17 15:35:35 +00:00
assert result is False, 'The result should be False'
2013-02-06 17:36:36 +00:00
2016-05-31 21:40:13 +00:00
def test_resize_thumb(self):
2014-06-10 09:39:24 +00:00
"""
Test the resize_thumb() function
"""
# GIVEN: A path to an image.
2017-12-22 21:20:49 +00:00
image_path = str(RESOURCE_PATH / 'church.jpg')
2014-06-10 09:39:24 +00:00
wanted_width = 777
wanted_height = 72
# We want the background to be white.
wanted_background_hex = '#FFFFFF'
wanted_background_rgb = QtGui.QColor(wanted_background_hex).rgb()
# WHEN: Resize the image and add a background.
image = resize_image(image_path, wanted_width, wanted_height, wanted_background_hex)
# THEN: Check if the size is correct and the background was set.
result_size = image.size()
2017-12-17 15:35:35 +00:00
assert wanted_height == result_size.height(), 'The image should have the requested height.'
assert wanted_width == result_size.width(), 'The image should have the requested width.'
assert image.pixel(0, 0) == wanted_background_rgb, 'The background should be white.'
2014-06-10 09:39:24 +00:00
2017-04-30 17:32:27 +00:00
def test_resize_thumb_ignoring_aspect_ratio(self):
"""
Test the resize_thumb() function ignoring aspect ratio
"""
# GIVEN: A path to an image.
2017-12-22 21:20:49 +00:00
image_path = str(RESOURCE_PATH / 'church.jpg')
2017-04-30 17:32:27 +00:00
wanted_width = 1000
wanted_height = 1000
# We want the background to be white.
wanted_background_hex = '#FFFFFF'
wanted_background_rgb = QtGui.QColor(wanted_background_hex).rgb()
# WHEN: Resize the image and add a background.
image = resize_image(image_path, wanted_width, wanted_height, wanted_background_hex, True)
# THEN: Check if the size is correct and the background was set.
result_size = image.size()
2017-12-17 15:35:35 +00:00
assert wanted_height == result_size.height(), 'The image should have the requested height.'
assert wanted_width == result_size.width(), 'The image should have the requested width.'
assert image.pixel(0, 0) == wanted_background_rgb, 'The background should be white.'
2014-06-10 09:39:24 +00:00
2017-10-07 07:05:07 +00:00
@patch('openlp.core.lib.QtCore.QLocale.createSeparatedList')
def test_create_separated_list_qlocate(self, mocked_createSeparatedList):
2013-02-06 17:36:36 +00:00
"""
2013-05-18 08:44:03 +00:00
Test the create_separated_list function using the Qt provided method
2013-02-06 17:36:36 +00:00
"""
2017-10-07 07:05:07 +00:00
# GIVEN: A list of strings and the mocked Qt module.
mocked_createSeparatedList.return_value = 'Author 1, Author 2, and Author 3'
string_list = ['Author 1', 'Author 2', 'Author 3']
2013-02-06 17:36:36 +00:00
2017-10-07 07:05:07 +00:00
# WHEN: We get a string build from the entries it the list and a separator.
string_result = create_separated_list(string_list)
2013-02-06 17:36:36 +00:00
2017-10-07 07:05:07 +00:00
# THEN: We should have "Author 1, Author 2, and Author 3"
2017-12-17 15:35:35 +00:00
assert string_result == 'Author 1, Author 2 and Author 3', \
'The string should be "Author 1, Author 2, and Author 3".'
2013-02-06 17:36:36 +00:00
2016-05-31 21:40:13 +00:00
def test_create_separated_list_empty_list(self):
2013-02-06 17:36:36 +00:00
"""
2013-05-18 08:44:03 +00:00
Test the create_separated_list function with an empty list
2013-02-06 17:36:36 +00:00
"""
# GIVEN: An empty list
string_list = []
2013-02-06 17:36:36 +00:00
# WHEN: We get a string build from the entries it the list and a separator.
string_result = create_separated_list(string_list)
2013-02-06 17:36:36 +00:00
# THEN: We shoud have an emptry string.
2017-12-17 15:35:35 +00:00
assert string_result == '', 'The string sould be empty.'
2013-02-06 17:36:36 +00:00
2016-05-31 21:40:13 +00:00
def test_create_separated_list_with_one_item(self):
2013-02-06 17:36:36 +00:00
"""
2013-05-18 08:44:03 +00:00
Test the create_separated_list function with a list consisting of only one entry
2013-02-06 17:36:36 +00:00
"""
# GIVEN: A list with a string.
string_list = ['Author 1']
2013-02-06 17:36:36 +00:00
# WHEN: We get a string build from the entries it the list and a separator.
string_result = create_separated_list(string_list)
2013-02-06 17:36:36 +00:00
# THEN: We should have "Author 1"
2017-12-17 15:35:35 +00:00
assert string_result == 'Author 1', 'The string should be "Author 1".'
2013-02-06 17:36:36 +00:00
2016-05-31 21:40:13 +00:00
def test_create_separated_list_with_two_items(self):
2013-02-06 17:36:36 +00:00
"""
2013-05-18 08:44:03 +00:00
Test the create_separated_list function with a list of two entries
2013-02-06 17:36:36 +00:00
"""
# GIVEN: A list with two strings.
string_list = ['Author 1', 'Author 2']
2013-02-06 17:36:36 +00:00
# WHEN: We get a string build from the entries it the list and a seperator.
string_result = create_separated_list(string_list)
2013-02-06 17:36:36 +00:00
# THEN: We should have "Author 1 and Author 2"
2017-12-17 15:35:35 +00:00
assert string_result == 'Author 1 and Author 2', 'The string should be "Author 1 and Author 2".'
2013-02-06 17:36:36 +00:00
2016-05-31 21:40:13 +00:00
def test_create_separated_list_with_three_items(self):
2013-02-06 17:36:36 +00:00
"""
2013-05-18 08:44:03 +00:00
Test the create_separated_list function with a list of three items
2013-02-06 17:36:36 +00:00
"""
# GIVEN: A list with three strings.
string_list = ['Author 1', 'Author 2', 'Author 3']
2013-02-06 17:36:36 +00:00
# WHEN: We get a string build from the entries it the list and a seperator.
string_result = create_separated_list(string_list)
2013-02-06 17:36:36 +00:00
2016-11-21 21:07:01 +00:00
# THEN: We should have "Author 1, Author 2 and Author 3"
2017-12-17 15:35:35 +00:00
assert string_result == 'Author 1, Author 2 and Author 3', \
'The string should be "Author 1, Author 2, and Author 3".'
def test_read_or_fail_fail(self):
"""
Test the :func:`read_or_fail` function when attempting to read more data than the buffer contains.
"""
# GIVEN: Some test data
test_data = io.BytesIO(b'test data')
# WHEN: Attempting to read past the end of the buffer
# THEN: An OSError should be raised.
with self.assertRaises(OSError):
read_or_fail(test_data, 15)
def test_read_or_fail_success(self):
"""
Test the :func:`read_or_fail` function when reading data that is in the buffer.
"""
# GIVEN: Some test data
test_data = io.BytesIO(b'test data')
# WHEN: Attempting to read data that should exist.
result = read_or_fail(test_data, 4)
# THEN: The data of the requested length should be returned
assert result == b'test'
def test_read_int_u8_big(self):
"""
Test the :func:`read_int` function when reading an unsigned 8-bit int using 'big' endianness.
"""
# GIVEN: Some test data
test_data = io.BytesIO(b'\x0f\xf0\x0f\xf0')
# WHEN: Reading a an unsigned 8-bit int
result = read_int(test_data, DataType.U8, 'big')
# THEN: The an int should have been returned of the expected value
assert result == 15
def test_read_int_u8_little(self):
"""
Test the :func:`read_int` function when reading an unsigned 8-bit int using 'little' endianness.
"""
# GIVEN: Some test data
test_data = io.BytesIO(b'\x0f\xf0\x0f\xf0')
# WHEN: Reading a an unsigned 8-bit int
result = read_int(test_data, DataType.U8, 'little')
# THEN: The an int should have been returned of the expected value
assert result == 15
def test_read_int_u16_big(self):
"""
Test the :func:`read_int` function when reading an unsigned 16-bit int using 'big' endianness.
"""
# GIVEN: Some test data
test_data = io.BytesIO(b'\x0f\xf0\x0f\xf0')
# WHEN: Reading a an unsigned 16-bit int
result = read_int(test_data, DataType.U16, 'big')
# THEN: The an int should have been returned of the expected value
assert result == 4080
def test_read_int_u16_little(self):
"""
Test the :func:`read_int` function when reading an unsigned 16-bit int using 'little' endianness.
"""
# GIVEN: Some test data
test_data = io.BytesIO(b'\x0f\xf0\x0f\xf0')
# WHEN: Reading a an unsigned 16-bit int
result = read_int(test_data, DataType.U16, 'little')
# THEN: The an int should have been returned of the expected value
assert result == 61455
def test_read_int_u32_big(self):
"""
Test the :func:`read_int` function when reading an unsigned 32-bit int using 'big' endianness.
"""
# GIVEN: Some test data
test_data = io.BytesIO(b'\x0f\xf0\x0f\xf0')
# WHEN: Reading a an unsigned 32-bit int
result = read_int(test_data, DataType.U32, 'big')
# THEN: The an int should have been returned of the expected value
assert result == 267390960
def test_read_int_u32_little(self):
"""
Test the :func:`read_int` function when reading an unsigned 32-bit int using 'little' endianness.
"""
# GIVEN: Some test data
test_data = io.BytesIO(b'\x0f\xf0\x0f\xf0')
# WHEN: Reading a an unsigned 32-bit int
result = read_int(test_data, DataType.U32, 'little')
# THEN: The an int should have been returned of the expected value
assert result == 4027576335
def test_seek_or_fail_default_method(self):
"""
Test the :func:`seek_or_fail` function when using the default value for the :arg:`how`
"""
# GIVEN: A mocked_file_like_object
mocked_file_like_object = MagicMock(**{'seek.return_value': 5, 'tell.return_value': 0})
# WHEN: Calling seek_or_fail with out the how arg set
seek_or_fail(mocked_file_like_object, 5)
# THEN: seek should be called using the os.SEEK_SET constant
mocked_file_like_object.seek.assert_called_once_with(5, os.SEEK_SET)
def test_seek_or_fail_os_end(self):
"""
Test the :func:`seek_or_fail` function when called with an unsupported seek operation.
"""
# GIVEN: A Mocked object
# WHEN: Attempting to seek relative to the end
# THEN: An NotImplementedError should have been raised
with self.assertRaises(NotImplementedError):
seek_or_fail(MagicMock(), 1, os.SEEK_END)
def test_seek_or_fail_valid_seek_set(self):
"""
Test that :func:`seek_or_fail` successfully seeks to the correct position.
"""
# GIVEN: A mocked file-like object
mocked_file_like_object = MagicMock(**{'tell.return_value': 3, 'seek.return_value': 5})
# WHEN: Attempting to seek from the beginning
result = seek_or_fail(mocked_file_like_object, 5, os.SEEK_SET)
# THEN: The new position should be 5 from the beginning
assert result == 5
def test_seek_or_fail_invalid_seek_set(self):
"""
Test that :func:`seek_or_fail` raises an exception when seeking past the end.
"""
# GIVEN: A Mocked file-like object
mocked_file_like_object = MagicMock(**{'tell.return_value': 3, 'seek.return_value': 10})
# WHEN: Attempting to seek from the beginning past the end
# THEN: An OSError should have been raised
with self.assertRaises(OSError):
seek_or_fail(mocked_file_like_object, 15, os.SEEK_SET)
def test_seek_or_fail_valid_seek_cur(self):
"""
Test that :func:`seek_or_fail` successfully seeks to the correct position.
"""
# GIVEN: A mocked file_like object
mocked_file_like_object = MagicMock(**{'tell.return_value': 3, 'seek.return_value': 8})
# WHEN: Attempting to seek from the current position
result = seek_or_fail(mocked_file_like_object, 5, os.SEEK_CUR)
# THEN: The new position should be 8 (5 from its starting position)
assert result == 8
def test_seek_or_fail_invalid_seek_cur(self):
"""
Test that :func:`seek_or_fail` raises an exception when seeking past the end.
"""
# GIVEN: A mocked file_like object
mocked_file_like_object = MagicMock(**{'tell.return_value': 3, 'seek.return_value': 10})
# WHEN: Attempting to seek from the current position pas the end.
# THEN: An OSError should have been raised
with self.assertRaises(OSError):
seek_or_fail(mocked_file_like_object, 15, os.SEEK_CUR)