Migrate core and common

This commit is contained in:
Tim 2020-02-13 20:50:39 +00:00
parent 3bda907d4d
commit 2eb385c774
No known key found for this signature in database
GPG Key ID: 3D454289AF831A6D
6 changed files with 716 additions and 738 deletions

View File

@ -19,35 +19,36 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # # along with this program. If not, see <https://www.gnu.org/licenses/>. #
########################################################################## ##########################################################################
""" """
Package to test the openlp.core.common package. Package to test the openlp.core.common.mixins package.
""" """
from unittest import TestCase import pytest
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from openlp.core.common.mixins import RegistryProperties from openlp.core.common.mixins import RegistryProperties
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
class TestRegistryProperties(TestCase, RegistryProperties): @pytest.fixture
""" def registry_env():
Test the functions in the ThemeManager module """An instance of the Registry"""
"""
def setUp(self):
"""
Create the Register
"""
Registry.create() Registry.create()
def test_no_application(self): class Test(RegistryProperties):
pass
return Test()
def test_no_application(registry_env):
""" """
Test property if no registry value assigned Test property if no registry value assigned
""" """
# GIVEN an Empty Registry # GIVEN an Empty Registry
# WHEN there is no Application # WHEN there is no Application
# THEN the application should be none # THEN the application should be none
assert self.application is None, 'The application value should be None' assert registry_env.application is None, 'The application value should be None'
def test_application(self):
def test_application(registry_env):
""" """
Test property if registry value assigned Test property if registry value assigned
""" """
@ -58,10 +59,11 @@ class TestRegistryProperties(TestCase, RegistryProperties):
Registry().register('application', application) Registry().register('application', application)
# THEN the application should be none # THEN the application should be none
assert self.application == application, 'The application value should match' assert registry_env.application == application, 'The application value should match'
@patch('openlp.core.common.mixins.is_win')
def test_application_on_windows(self, mocked_is_win): @patch('openlp.core.common.mixins.is_win')
def test_application_on_windows(mocked_is_win, registry_env):
""" """
Test property if registry value assigned on Windows Test property if registry value assigned on Windows
""" """
@ -73,10 +75,11 @@ class TestRegistryProperties(TestCase, RegistryProperties):
Registry().register('application', application) Registry().register('application', application)
# THEN the application should be none # THEN the application should be none
assert self.application == application, 'The application value should match' assert registry_env.application == application, 'The application value should match'
@patch('openlp.core.common.mixins.is_win')
def test_get_application_on_windows(self, mocked_is_win): @patch('openlp.core.common.mixins.is_win')
def test_get_application_on_windows(mocked_is_win):
""" """
Set that getting the application object on Windows happens dynamically Set that getting the application object on Windows happens dynamically
""" """

View File

@ -22,18 +22,15 @@
Package to test the openlp.core.common.path package. Package to test the openlp.core.common.path package.
""" """
import os import os
import pytest
from pathlib import Path from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from openlp.core.common.path import create_paths, files_to_paths, path_to_str, replace_params, str_to_path, which from openlp.core.common.path import create_paths, files_to_paths, path_to_str, replace_params, str_to_path, which
class TestShutil(TestCase): def test_replace_params_no_params():
"""
Tests for the :mod:`openlp.core.common.path` module
"""
def test_replace_params_no_params(self):
""" """
Test replace_params when called with and empty tuple instead of parameters to replace Test replace_params when called with and empty tuple instead of parameters to replace
""" """
@ -49,7 +46,8 @@ class TestShutil(TestCase):
assert test_args == result_args assert test_args == result_args
assert test_kwargs == result_kwargs assert test_kwargs == result_kwargs
def test_replace_params_params(self):
def test_replace_params_params():
""" """
Test replace_params when given a positional and a keyword argument to change Test replace_params when given a positional and a keyword argument to change
""" """
@ -65,7 +63,8 @@ class TestShutil(TestCase):
assert result_args == (1, '2') assert result_args == (1, '2')
assert result_kwargs == {'arg3': '3', 'arg4': 4} assert result_kwargs == {'arg3': '3', 'arg4': 4}
def test_which_no_command(self):
def test_which_no_command():
""" """
Test :func:`openlp.core.common.path.which` when the command is not found. Test :func:`openlp.core.common.path.which` when the command is not found.
""" """
@ -79,7 +78,8 @@ class TestShutil(TestCase):
mocked_shutil_which.assert_called_once_with('no_command') mocked_shutil_which.assert_called_once_with('no_command')
assert result is None assert result is None
def test_which_command(self):
def test_which_command():
""" """
Test :func:`openlp.core.common.path.which` when a command has been found. Test :func:`openlp.core.common.path.which` when a command has been found.
""" """
@ -96,22 +96,18 @@ class TestShutil(TestCase):
assert result == Path('path', 'to', 'command') assert result == Path('path', 'to', 'command')
class TestPath(TestCase): def test_path_to_str_type_error():
"""
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 Test that `path_to_str` raises a type error when called with an invalid type
""" """
# GIVEN: The `path_to_str` function # GIVEN: The `path_to_str` function
# WHEN: Calling `path_to_str` with an invalid Type # WHEN: Calling `path_to_str` with an invalid Type
# THEN: A TypeError should have been raised # THEN: A TypeError should have been raised
with self.assertRaises(TypeError): with pytest.raises(TypeError):
path_to_str(57) path_to_str(57)
def test_path_to_str_wth_str(self):
def test_path_to_str_wth_str():
""" """
Test that `path_to_str` just returns a str when given a str Test that `path_to_str` just returns a str when given a str
""" """
@ -122,7 +118,8 @@ class TestPath(TestCase):
# THEN: The string should be returned # THEN: The string should be returned
assert result == '/usr/bin' assert result == '/usr/bin'
def test_path_to_str_none(self):
def test_path_to_str_none():
""" """
Test that `path_to_str` correctly converts the path parameter when passed with None Test that `path_to_str` correctly converts the path parameter when passed with None
""" """
@ -133,7 +130,8 @@ class TestPath(TestCase):
# THEN: `path_to_str` should return an empty string # THEN: `path_to_str` should return an empty string
assert result == '' assert result == ''
def test_path_to_str_path_object(self):
def test_path_to_str_path_object():
""" """
Test that `path_to_str` correctly converts the path parameter when passed a Path object Test that `path_to_str` correctly converts the path parameter when passed a Path object
""" """
@ -144,7 +142,8 @@ class TestPath(TestCase):
# THEN: `path_to_str` should return a string representation of the Path object # THEN: `path_to_str` should return a string representation of the Path object
assert result == os.path.join('test', 'path') assert result == os.path.join('test', 'path')
def test_str_to_path_type_error(self):
def test_str_to_path_type_error():
""" """
Test that `str_to_path` returns None if called with invalid information Test that `str_to_path` returns None if called with invalid information
""" """
@ -153,7 +152,8 @@ class TestPath(TestCase):
# THEN: None is returned # THEN: None is returned
assert str_to_path(Path()) is None assert str_to_path(Path()) is None
def test_str_to_path_empty_str(self):
def test_str_to_path_empty_str():
""" """
Test that `str_to_path` correctly converts the string parameter when passed with and empty string Test that `str_to_path` correctly converts the string parameter when passed with and empty string
""" """
@ -164,7 +164,8 @@ class TestPath(TestCase):
# THEN: `path_to_str` should return None # THEN: `path_to_str` should return None
assert result is None assert result is None
def test_create_paths_dir_exists(self):
def test_create_paths_dir_exists():
""" """
Test the create_paths() function when the path already exists Test the create_paths() function when the path already exists
""" """
@ -179,7 +180,8 @@ class TestPath(TestCase):
mocked_path.exists.assert_called_once_with() mocked_path.exists.assert_called_once_with()
assert mocked_path.mkdir.call_count == 0, 'mkdir should not have been called' assert mocked_path.mkdir.call_count == 0, 'mkdir should not have been called'
def test_create_paths_dir_doesnt_exists(self):
def test_create_paths_dir_doesnt_exists():
""" """
Test the create_paths() function when the path does not already exist Test the create_paths() function when the path does not already exist
""" """
@ -194,8 +196,9 @@ class TestPath(TestCase):
mocked_path.exists.assert_called_once_with() mocked_path.exists.assert_called_once_with()
mocked_path.mkdir.assert_called_once_with(parents=True) mocked_path.mkdir.assert_called_once_with(parents=True)
@patch('openlp.core.common.path.log')
def test_create_paths_dir_io_error(self, mocked_logger): @patch('openlp.core.common.path.log')
def test_create_paths_dir_io_error(mocked_logger):
""" """
Test the create_paths() when an OSError is raised Test the create_paths() when an OSError is raised
""" """
@ -209,7 +212,8 @@ class TestPath(TestCase):
# THEN: The Error should have been logged # THEN: The Error should have been logged
mocked_logger.exception.assert_called_once_with('failed to check if directory exists or create directory') mocked_logger.exception.assert_called_once_with('failed to check if directory exists or create directory')
def test_create_paths_dir_value_error(self):
def test_create_paths_dir_value_error():
""" """
Test the create_paths() when an error other than OSError is raised Test the create_paths() when an error other than OSError is raised
""" """
@ -225,7 +229,8 @@ class TestPath(TestCase):
# THEN: `create_paths` raises an exception # THEN: `create_paths` raises an exception
pass pass
def test_files_to_paths(self):
def test_files_to_paths():
""" """
Test the files_to_paths() method Test the files_to_paths() method
""" """

View File

@ -21,21 +21,25 @@
""" """
Package to test the openlp.core.lib package. Package to test the openlp.core.lib package.
""" """
from unittest import TestCase import pytest
from unittest.mock import MagicMock from unittest.mock import MagicMock
from openlp.core.common.registry import Registry, RegistryBase from openlp.core.common.registry import Registry, RegistryBase
class TestRegistry(TestCase): def dummy_function_1():
return "function_1"
def test_registry_service(self):
def dummy_function_2():
return "function_2"
def test_registry_service(registry):
""" """
Test the registry creation and its usage Test the registry creation and its usage
""" """
# GIVEN: A new registry # GIVEN: A new registry
Registry.create()
# WHEN: I add a component it should save it # WHEN: I add a component it should save it
mock_1 = MagicMock() mock_1 = MagicMock()
Registry().register('test1', mock_1) Registry().register('test1', mock_1)
@ -45,9 +49,9 @@ class TestRegistry(TestCase):
# WHEN: I add a component for the second time I am mad. # WHEN: I add a component for the second time I am mad.
# THEN and I will get an exception # THEN and I will get an exception
with self.assertRaises(KeyError) as context: with pytest.raises(KeyError) as context:
Registry().register('test1', mock_1) Registry().register('test1', mock_1)
assert context.exception.args[0] == 'Duplicate service exception test1', \ assert context.value != KeyError('Duplicate service exception test1'), \
'KeyError exception should have been thrown for duplicate service' 'KeyError exception should have been thrown for duplicate service'
# WHEN I try to get back a non existent component # WHEN I try to get back a non existent component
@ -61,13 +65,13 @@ class TestRegistry(TestCase):
temp = Registry().get('test1') temp = Registry().get('test1')
assert temp is None, 'None should have been returned for deleted service' assert temp is None, 'None should have been returned for deleted service'
def test_registry_function(self):
def test_registry_function(registry):
""" """
Test the registry function creation and their usages Test the registry function creation and their usages
""" """
# GIVEN: An existing registry register a function # GIVEN: An existing registry register a function
Registry.create() Registry().register_function('test1', dummy_function_1)
Registry().register_function('test1', self.dummy_function_1)
# WHEN: I execute the function # WHEN: I execute the function
return_value = Registry().execute('test1') return_value = Registry().execute('test1')
@ -76,26 +80,25 @@ class TestRegistry(TestCase):
assert return_value[0] == 'function_1', 'A return value is provided and matches' assert return_value[0] == 'function_1', 'A return value is provided and matches'
# WHEN: I execute the a function with the same reference and execute the function # WHEN: I execute the a function with the same reference and execute the function
Registry().register_function('test1', self.dummy_function_1) Registry().register_function('test1', dummy_function_1)
return_value = Registry().execute('test1') return_value = Registry().execute('test1')
# THEN: I expect then function to have been called and a return given # THEN: I expect then function to have been called and a return given
assert return_value == ['function_1', 'function_1'], 'A return value list is provided and matches' assert return_value == ['function_1', 'function_1'], 'A return value list is provided and matches'
# WHEN: I execute the a 2nd function with the different reference and execute the function # WHEN: I execute the a 2nd function with the different reference and execute the function
Registry().register_function('test2', self.dummy_function_2) Registry().register_function('test2', dummy_function_2)
return_value = Registry().execute('test2') return_value = Registry().execute('test2')
# THEN: I expect then function to have been called and a return given # THEN: I expect then function to have been called and a return given
assert return_value[0] == 'function_2', 'A return value is provided and matches' assert return_value[0] == 'function_2', 'A return value is provided and matches'
def test_registry_working_flags(self):
def test_registry_working_flags(registry):
""" """
Test the registry working flags creation and its usage Test the registry working flags creation and its usage
""" """
# GIVEN: A new registry # GIVEN: A new registry
Registry.create()
# WHEN: I add a working flag it should save it # WHEN: I add a working flag it should save it
my_data = 'Lamas' my_data = 'Lamas'
my_data2 = 'More Lamas' my_data2 = 'More Lamas'
@ -113,39 +116,33 @@ class TestRegistry(TestCase):
# WHEN I try to get back a non existent Working Flag # WHEN I try to get back a non existent Working Flag
# THEN I will get an exception # THEN I will get an exception
with self.assertRaises(KeyError) as context1: with pytest.raises(KeyError) as context1:
temp = Registry().get_flag('test2') Registry().get_flag('test2')
assert context1.exception.args[0] == 'Working Flag test2 not found in list', \ assert context1.value != KeyError('Working Flag test2 not found in list'), \
'KeyError exception should have been thrown for missing working flag' 'KeyError exception should have been thrown for missing working flag'
# WHEN I try to replace a working flag I should be allowed # WHEN I try to replace a working flag I should be allowed
Registry().remove_flag('test1') Registry().remove_flag('test1')
# THEN I will get an exception # THEN I will get an exception
with self.assertRaises(KeyError) as context: with pytest.raises(KeyError) as context:
temp = Registry().get_flag('test1') Registry().get_flag('test1')
assert context.exception.args[0] == 'Working Flag test1 not found in list', \ assert context.value != 'Working Flag test1 not found in list', \
'KeyError exception should have been thrown for duplicate working flag' 'KeyError exception should have been thrown for duplicate working flag'
def test_remove_function(self):
def test_remove_function(registry):
""" """
Test the remove_function() method Test the remove_function() method
""" """
# GIVEN: An existing registry register a function # GIVEN: An existing registry register a function
Registry.create() Registry().register_function('test1', dummy_function_1)
Registry().register_function('test1', self.dummy_function_1)
# WHEN: Remove the function. # WHEN: Remove the function.
Registry().remove_function('test1', self.dummy_function_1) Registry().remove_function('test1', dummy_function_1)
# THEN: The method should not be available. # THEN: The method should not be available.
assert Registry().functions_list['test1'] == [], 'The function should not be in the dict anymore.' assert Registry().functions_list['test1'] == [], 'The function should not be in the dict anymore.'
def dummy_function_1(self):
return "function_1"
def dummy_function_2(self):
return "function_2"
class PlainStub(object): class PlainStub(object):
def __init__(self): def __init__(self):
@ -157,28 +154,23 @@ class RegistryStub(RegistryBase):
super().__init__() super().__init__()
class TestRegistryBase(TestCase): def test_registry_mixin_missing(registry):
def test_registry_mixin_missing(self):
""" """
Test the registry creation and its usage Test the registry creation and its usage
""" """
# GIVEN: A new registry # GIVEN: A new registry
Registry.create()
# WHEN: I create an instance of a class that doesn't inherit from RegistryMixin # WHEN: I create an instance of a class that doesn't inherit from RegistryMixin
PlainStub() PlainStub()
# THEN: Nothing is registered with the registry # THEN: Nothing is registered with the registry
assert len(Registry().functions_list) == 0, 'The function should not be in the dict anymore.' assert len(Registry().functions_list) == 0, 'The function should not be in the dict anymore.'
def test_registry_mixin_present(self):
def test_registry_mixin_present(registry):
""" """
Test the registry creation and its usage Test the registry creation and its usage
""" """
# GIVEN: A new registry # GIVEN: A new registry
Registry.create()
# WHEN: I create an instance of a class that inherits from RegistryMixin # WHEN: I create an instance of a class that inherits from RegistryMixin
RegistryStub() RegistryStub()

View File

@ -21,33 +21,15 @@
""" """
Package to test the openlp.core.lib.settings package. Package to test the openlp.core.lib.settings package.
""" """
import pytest
from pathlib import Path from pathlib import Path
from unittest import TestCase
from unittest.mock import call, patch from unittest.mock import call, patch
from openlp.core.common import settings from openlp.core.common import settings
from openlp.core.common.settings import Settings, media_players_conv from openlp.core.common.settings import Settings, media_players_conv
from tests.helpers.testmixin import TestMixin
class TestSettings(TestCase, TestMixin): def test_media_players_conv():
"""
Test the functions in the Settings module
"""
def setUp(self):
"""
Create the UI
"""
self.setup_application()
self.build_settings()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
self.destroy_settings()
def test_media_players_conv(self):
"""Test the media players conversion function""" """Test the media players conversion function"""
# GIVEN: A list of media players # GIVEN: A list of media players
media_players = 'phonon,webkit,vlc' media_players = 'phonon,webkit,vlc'
@ -58,7 +40,8 @@ class TestSettings(TestCase, TestMixin):
# THEN: The list should have been converted correctly # THEN: The list should have been converted correctly
assert result == 'system,webkit,vlc' assert result == 'system,webkit,vlc'
def test_default_value(self):
def test_default_value(settings):
"""Test reading a setting that doesn't exist yet""" """Test reading a setting that doesn't exist yet"""
# GIVEN: A setting that doesn't exist yet # GIVEN: A setting that doesn't exist yet
@ -68,7 +51,8 @@ class TestSettings(TestCase, TestMixin):
# THEN the default value is returned # THEN the default value is returned
assert default_value is False, 'The default value should be False' assert default_value is False, 'The default value should be False'
def test_save_new_value(self):
def test_save_new_value(settings):
"""Test saving a new setting""" """Test saving a new setting"""
# GIVEN: A setting that hasn't been saved yet # GIVEN: A setting that hasn't been saved yet
# WHEN a new value is saved into config # WHEN a new value is saved into config
@ -77,7 +61,8 @@ class TestSettings(TestCase, TestMixin):
# THEN the new value is returned when re-read # THEN the new value is returned when re-read
assert Settings().value('core/has run wizard') is True, 'The saved value should have been returned' assert Settings().value('core/has run wizard') is True, 'The saved value should have been returned'
def test_set_up_default_values(self):
def test_set_up_default_values():
"""Test that the default values are updated""" """Test that the default values are updated"""
# GIVEN: A Settings object with defaults # GIVEN: A Settings object with defaults
# WHEN: set_up_default_values() is called # WHEN: set_up_default_values() is called
@ -86,7 +71,8 @@ class TestSettings(TestCase, TestMixin):
# THEN: The default values should have been added to the dictionary # THEN: The default values should have been added to the dictionary
assert 'advanced/default service name' in Settings.__default_settings__ assert 'advanced/default service name' in Settings.__default_settings__
def test_get_default_value(self):
def test_get_default_value():
"""Test that the default value for a setting is returned""" """Test that the default value for a setting is returned"""
# GIVEN: A Settings class with a default value # GIVEN: A Settings class with a default value
Settings.__default_settings__['test/moo'] = 'baa' Settings.__default_settings__['test/moo'] = 'baa'
@ -97,7 +83,8 @@ class TestSettings(TestCase, TestMixin):
# THEN: The correct default value should be returned # THEN: The correct default value should be returned
assert result == 'baa' assert result == 'baa'
def test_settings_override(self):
def test_settings_override():
"""Test the Settings creation and its override usage""" """Test the Settings creation and its override usage"""
# GIVEN: an override for the settings # GIVEN: an override for the settings
screen_settings = { screen_settings = {
@ -111,7 +98,8 @@ class TestSettings(TestCase, TestMixin):
# THEN the default value is returned # THEN the default value is returned
assert extend == 'very wide', 'The default value of "very wide" should be returned' assert extend == 'very wide', 'The default value of "very wide" should be returned'
def test_save_existing_setting(self):
def test_save_existing_setting():
"""Test that saving an existing setting returns the new value""" """Test that saving an existing setting returns the new value"""
# GIVEN: An existing setting # GIVEN: An existing setting
Settings().extend_default_settings({'test/existing value': None}) Settings().extend_default_settings({'test/existing value': None})
@ -123,7 +111,8 @@ class TestSettings(TestCase, TestMixin):
# THEN the new value is returned when re-read # THEN the new value is returned when re-read
assert Settings().value('test/existing value') == 'new value', 'The saved value should be returned' assert Settings().value('test/existing value') == 'new value', 'The saved value should be returned'
def test_settings_override_with_group(self):
def test_settings_override_with_group():
"""Test the Settings creation and its override usage - with groups""" """Test the Settings creation and its override usage - with groups"""
# GIVEN: an override for the settings # GIVEN: an override for the settings
screen_settings = { screen_settings = {
@ -145,17 +134,19 @@ class TestSettings(TestCase, TestMixin):
# THEN the new value is returned when re-read # THEN the new value is returned when re-read
assert 'very short' == Settings().value('test/extend'), 'The saved value should be returned' assert 'very short' == Settings().value('test/extend'), 'The saved value should be returned'
def test_settings_nonexisting(self):
def test_settings_nonexisting():
"""Test the Settings on query for non-existing value""" """Test the Settings on query for non-existing value"""
# GIVEN: A new Settings setup # GIVEN: A new Settings setup
with self.assertRaises(KeyError) as cm: with pytest.raises(KeyError) as cm:
# WHEN reading a setting that doesn't exists # WHEN reading a setting that doesn't exists
Settings().value('core/does not exists') Settings().value('core/does not exists')
# THEN: An exception with the non-existing key should be thrown # THEN: An exception with the non-existing key should be thrown
assert str(cm.exception) == "'core/does not exists'", 'We should get an exception' assert str(cm.value) != KeyError("'core/does not exists'", 'We should get an exception')
def test_extend_default_settings(self):
def test_extend_default_settings():
"""Test that the extend_default_settings method extends the default settings""" """Test that the extend_default_settings method extends the default settings"""
# GIVEN: A patched __default_settings__ dictionary # GIVEN: A patched __default_settings__ dictionary
with patch.dict(Settings.__default_settings__, with patch.dict(Settings.__default_settings__,
@ -168,11 +159,12 @@ class TestSettings(TestCase, TestMixin):
assert Settings.__default_settings__ == {'test/setting 1': 1, 'test/setting 2': 2, 'test/setting 3': 4, assert Settings.__default_settings__ == {'test/setting 1': 1, 'test/setting 2': 2, 'test/setting 3': 4,
'test/extended 1': 1, 'test/extended 2': 2} 'test/extended 1': 1, 'test/extended 2': 2}
@patch('openlp.core.common.settings.QtCore.QSettings.contains')
@patch('openlp.core.common.settings.QtCore.QSettings.value') @patch('openlp.core.common.settings.QtCore.QSettings.contains')
@patch('openlp.core.common.settings.QtCore.QSettings.setValue') @patch('openlp.core.common.settings.QtCore.QSettings.value')
@patch('openlp.core.common.settings.QtCore.QSettings.remove') @patch('openlp.core.common.settings.QtCore.QSettings.setValue')
def test_upgrade_single_setting(self, mocked_remove, mocked_setValue, mocked_value, mocked_contains): @patch('openlp.core.common.settings.QtCore.QSettings.remove')
def test_upgrade_single_setting(mocked_remove, mocked_setValue, mocked_value, mocked_contains):
"""Test that the upgrade mechanism for settings works correctly for single value upgrades""" """Test that the upgrade mechanism for settings works correctly for single value upgrades"""
# GIVEN: A settings object with an upgrade step to take (99, so that we don't interfere with real ones) # GIVEN: A settings object with an upgrade step to take (99, so that we don't interfere with real ones)
local_settings = Settings() local_settings = Settings()
@ -194,11 +186,12 @@ class TestSettings(TestCase, TestMixin):
mocked_contains.assert_called_once_with('single/value') mocked_contains.assert_called_once_with('single/value')
mocked_remove.assert_called_once_with('single/value') mocked_remove.assert_called_once_with('single/value')
@patch('openlp.core.common.settings.QtCore.QSettings.contains')
@patch('openlp.core.common.settings.QtCore.QSettings.value') @patch('openlp.core.common.settings.QtCore.QSettings.contains')
@patch('openlp.core.common.settings.QtCore.QSettings.setValue') @patch('openlp.core.common.settings.QtCore.QSettings.value')
@patch('openlp.core.common.settings.QtCore.QSettings.remove') @patch('openlp.core.common.settings.QtCore.QSettings.setValue')
def test_upgrade_setting_value(self, mocked_remove, mocked_setValue, mocked_value, mocked_contains): @patch('openlp.core.common.settings.QtCore.QSettings.remove')
def test_upgrade_setting_value(mocked_remove, mocked_setValue, mocked_value, mocked_contains):
"""Test that the upgrade mechanism for settings correctly uses the new value when it's not a function""" """Test that the upgrade mechanism for settings correctly uses the new value when it's not a function"""
# GIVEN: A settings object with an upgrade step to take (99, so that we don't interfere with real ones) # GIVEN: A settings object with an upgrade step to take (99, so that we don't interfere with real ones)
local_settings = Settings() local_settings = Settings()
@ -220,11 +213,12 @@ class TestSettings(TestCase, TestMixin):
mocked_contains.assert_called_once_with('values/old value') mocked_contains.assert_called_once_with('values/old value')
mocked_remove.assert_called_once_with('values/old value') mocked_remove.assert_called_once_with('values/old value')
@patch('openlp.core.common.settings.QtCore.QSettings.contains')
@patch('openlp.core.common.settings.QtCore.QSettings.value') @patch('openlp.core.common.settings.QtCore.QSettings.contains')
@patch('openlp.core.common.settings.QtCore.QSettings.setValue') @patch('openlp.core.common.settings.QtCore.QSettings.value')
@patch('openlp.core.common.settings.QtCore.QSettings.remove') @patch('openlp.core.common.settings.QtCore.QSettings.setValue')
def test_upgrade_multiple_one_invalid(self, mocked_remove, mocked_setValue, mocked_value, mocked_contains): @patch('openlp.core.common.settings.QtCore.QSettings.remove')
def test_upgrade_multiple_one_invalid(mocked_remove, mocked_setValue, mocked_value, mocked_contains):
"""Test that the upgrade mechanism for settings works correctly for multiple values where one is invalid""" """Test that the upgrade mechanism for settings works correctly for multiple values where one is invalid"""
# GIVEN: A settings object with an upgrade step to take # GIVEN: A settings object with an upgrade step to take
local_settings = Settings() local_settings = Settings()
@ -243,7 +237,8 @@ class TestSettings(TestCase, TestMixin):
mocked_setValue.assert_called_once_with('settings/version', 99) mocked_setValue.assert_called_once_with('settings/version', 99)
assert mocked_contains.call_args_list == [call('multiple/value 1'), call('multiple/value 2')] assert mocked_contains.call_args_list == [call('multiple/value 1'), call('multiple/value 2')]
def test_can_upgrade(self):
def test_can_upgrade():
"""Test the Settings.can_upgrade() method""" """Test the Settings.can_upgrade() method"""
# GIVEN: A Settings object # GIVEN: A Settings object
local_settings = Settings() local_settings = Settings()
@ -254,7 +249,8 @@ class TestSettings(TestCase, TestMixin):
# THEN: The result should be True # THEN: The result should be True
assert result is True, 'The settings should be upgradeable' assert result is True, 'The settings should be upgradeable'
def test_convert_value_setting_none_str(self):
def test_convert_value_setting_none_str():
"""Test the Settings._convert_value() method when a setting is None and the default value is a string""" """Test the Settings._convert_value() method when a setting is None and the default value is a string"""
# GIVEN: A settings object # GIVEN: A settings object
# WHEN: _convert_value() is run # WHEN: _convert_value() is run
@ -263,7 +259,8 @@ class TestSettings(TestCase, TestMixin):
# THEN: The result should be an empty string # THEN: The result should be an empty string
assert result == '', 'The result should be an empty string' assert result == '', 'The result should be an empty string'
def test_convert_value_setting_none_list(self):
def test_convert_value_setting_none_list():
"""Test the Settings._convert_value() method when a setting is None and the default value is a list""" """Test the Settings._convert_value() method when a setting is None and the default value is a list"""
# GIVEN: A settings object # GIVEN: A settings object
# WHEN: _convert_value() is run # WHEN: _convert_value() is run
@ -272,7 +269,8 @@ class TestSettings(TestCase, TestMixin):
# THEN: The result should be an empty list # THEN: The result should be an empty list
assert result == [], 'The result should be an empty list' assert result == [], 'The result should be an empty list'
def test_convert_value_setting_json_Path(self):
def test_convert_value_setting_json_Path():
"""Test the Settings._convert_value() method when a setting is JSON and represents a Path object""" """Test the Settings._convert_value() method when a setting is JSON and represents a Path object"""
# GIVEN: A settings object # GIVEN: A settings object
# WHEN: _convert_value() is run # WHEN: _convert_value() is run
@ -282,7 +280,8 @@ class TestSettings(TestCase, TestMixin):
# THEN: The result should be a Path object # THEN: The result should be a Path object
assert isinstance(result, Path), 'The result should be a Path object' assert isinstance(result, Path), 'The result should be a Path object'
def test_convert_value_setting_bool_str(self):
def test_convert_value_setting_bool_str():
"""Test the Settings._convert_value() method when a setting is supposed to be a boolean""" """Test the Settings._convert_value() method when a setting is supposed to be a boolean"""
# GIVEN: A settings object # GIVEN: A settings object
# WHEN: _convert_value() is run # WHEN: _convert_value() is run

View File

@ -18,96 +18,95 @@
# You should have received a copy of the GNU General Public License # # You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. # # along with this program. If not, see <https://www.gnu.org/licenses/>. #
########################################################################## ##########################################################################
import pytest
from pathlib import Path from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.server import Server from openlp.core.server import Server
from tests.helpers.testmixin import TestMixin
class TestServer(TestCase, TestMixin): @pytest.fixture
""" def server(registry):
Test the Server Class used to check if OpenLP is running.
"""
def setUp(self):
Registry.create()
with patch('PyQt5.QtNetwork.QLocalSocket'): with patch('PyQt5.QtNetwork.QLocalSocket'):
self.server = Server() server = Server()
yield server
server.close_server()
def tearDown(self):
self.server.close_server()
def test_is_another_instance_running(self): def test_is_another_instance_running(server):
""" """
Run a test as if this was the first time and no instance is running Run a test as if this was the first time and no instance is running
""" """
# GIVEN: A running Server # GIVEN: A running Server
# WHEN: I ask for it to start # WHEN: I ask for it to start
value = self.server.is_another_instance_running() value = server.is_another_instance_running()
# THEN the following is called # THEN the following is called
self.server.out_socket.waitForConnected.assert_called_once_with() server.out_socket.waitForConnected.assert_called_once_with()
self.server.out_socket.connectToServer.assert_called_once_with(self.server.id) server.out_socket.connectToServer.assert_called_once_with(server.id)
assert isinstance(value, MagicMock) assert isinstance(value, MagicMock)
def test_is_another_instance_running_true(self):
def test_is_another_instance_running_true(server):
""" """
Run a test as if there is another instance running Run a test as if there is another instance running
""" """
# GIVEN: A running Server # GIVEN: A running Server
self.server.out_socket.waitForConnected.return_value = True server.out_socket.waitForConnected.return_value = True
# WHEN: I ask for it to start # WHEN: I ask for it to start
value = self.server.is_another_instance_running() value = server.is_another_instance_running()
# THEN the following is called # THEN the following is called
self.server.out_socket.waitForConnected.assert_called_once_with() server.out_socket.waitForConnected.assert_called_once_with()
self.server.out_socket.connectToServer.assert_called_once_with(self.server.id) server.out_socket.connectToServer.assert_called_once_with(server.id)
assert value is True assert value is True
def test_on_read_ready(self):
def test_on_read_ready(server):
""" """
Test the on_read_ready method calls the service_manager Test the on_read_ready method calls the service_manager
""" """
# GIVEN: A server with a service manager # GIVEN: A server with a service manager
self.server.in_stream = MagicMock() server.in_stream = MagicMock()
service_manager = MagicMock() service_manager = MagicMock()
Registry().register('service_manager', service_manager) Registry().register('service_manager', service_manager)
# WHEN: a file is added to the socket and the method called # WHEN: a file is added to the socket and the method called
file_name = '\\home\\superfly\\' file_name = '\\home\\superfly\\'
self.server.in_stream.readLine.return_value = file_name server.in_stream.readLine.return_value = file_name
self.server._on_ready_read() server._on_ready_read()
# THEN: the service will be loaded # THEN: the service will be loaded
assert service_manager.load_service.call_count == 1 assert service_manager.load_service.call_count == 1
service_manager.load_service.assert_called_once_with(Path(file_name)) service_manager.load_service.assert_called_once_with(Path(file_name))
@patch("PyQt5.QtCore.QTextStream")
def test_post_to_server(self, mocked_stream): @patch("PyQt5.QtCore.QTextStream")
def test_post_to_server(mocked_stream, server):
""" """
A Basic test with a post to the service A Basic test with a post to the service
:return: :return:
""" """
# GIVEN: A server # GIVEN: A server
# WHEN: I post to a server # WHEN: I post to a server
self.server.post_to_server(['l', 'a', 'm', 'a', 's']) server.post_to_server(['l', 'a', 'm', 'a', 's'])
# THEN: the file should be passed out to the socket # THEN: the file should be passed out to the socket
self.server.out_socket.write.assert_called_once_with(b'lamas') server.out_socket.write.assert_called_once_with(b'lamas')
@patch("PyQt5.QtCore.QTextStream")
def test_post_to_server_openlp(self, mocked_stream): @patch("PyQt5.QtCore.QTextStream")
def test_post_to_server_openlp(mocked_stream, server):
""" """
A Basic test with a post to the service with OpenLP A Basic test with a post to the service with OpenLP
:return: :return:
""" """
# GIVEN: A server # GIVEN: A server
# WHEN: I post to a server # WHEN: I post to a server
self.server.post_to_server(['l', 'a', 'm', 'a', 's', 'OpenLP']) server.post_to_server(['l', 'a', 'm', 'a', 's', 'OpenLP'])
# THEN: the file should be passed out to the socket # THEN: the file should be passed out to the socket
self.server.out_socket.write.assert_called_once_with(b'lamas') server.out_socket.write.assert_called_once_with(b'lamas')

View File

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
########################################################################## ##########################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- # # ---------------------------------------------------------------------- #
@ -18,44 +17,29 @@
# You should have received a copy of the GNU General Public License # # You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. # # along with this program. If not, see <https://www.gnu.org/licenses/>. #
########################################################################## ##########################################################################
from unittest import TestCase
from unittest.mock import MagicMock from unittest.mock import MagicMock
from openlp.core.state import State from openlp.core.state import State
from openlp.core.common.registry import Registry from openlp.core.common.registry import Registry
from openlp.core.lib.plugin import PluginStatus from openlp.core.lib.plugin import PluginStatus
from tests.helpers.testmixin import TestMixin
""" """
Test the Status class. Test the States class.
""" """
class TestState(TestCase, TestMixin): def test_add_service(state):
"""
Test the Server Class used to check if OpenLP is running.
"""
def setUp(self):
Registry.create()
def tearDown(self):
pass
def test_add_service(self):
# GIVEN a new state # GIVEN a new state
State().load_settings()
# WHEN I add a new service # WHEN I add a new service
State().add_service("test", 1, PluginStatus.Active) State().add_service("test", 1, PluginStatus.Active)
# THEN I have a saved service # THEN I have a saved service
assert len(State().modules) == 1 assert len(State().modules) == 1
def test_add_service_multiple(self):
# GIVEN a new state
State().load_settings()
def test_add_service_multiple(state):
# GIVEN a new state
# WHEN I add a new service twice # WHEN I add a new service twice
State().add_service("test", 1, PluginStatus.Active) State().add_service("test", 1, PluginStatus.Active)
State().add_service("test", 1, PluginStatus.Active) State().add_service("test", 1, PluginStatus.Active)
@ -63,10 +47,9 @@ class TestState(TestCase, TestMixin):
# THEN I have a single saved service # THEN I have a single saved service
assert len(State().modules) == 1 assert len(State().modules) == 1
def test_add_service_multiple_depend(self):
# GIVEN a new state
State().load_settings()
def test_add_service_multiple_depend(state):
# GIVEN a new state
# WHEN I add a new service twice # WHEN I add a new service twice
State().add_service("test", 1, 1, PluginStatus.Active) State().add_service("test", 1, 1, PluginStatus.Active)
State().add_service("test1", 1, 1, PluginStatus.Active, "test") State().add_service("test1", 1, 1, PluginStatus.Active, "test")
@ -76,10 +59,9 @@ class TestState(TestCase, TestMixin):
assert len(State().modules) == 2 assert len(State().modules) == 2
assert len(State().modules['test'].required_by) == 1 assert len(State().modules['test'].required_by) == 1
def test_add_service_multiple_depends(self):
# GIVEN a new state
State().load_settings()
def test_add_service_multiple_depends(state):
# GIVEN a new state
# WHEN I add a new service twice # WHEN I add a new service twice
State().add_service("test", 1, 1, PluginStatus.Active) State().add_service("test", 1, 1, PluginStatus.Active)
State().add_service("test1", 1, 1, PluginStatus.Active, "test") State().add_service("test1", 1, 1, PluginStatus.Active, "test")
@ -89,29 +71,27 @@ class TestState(TestCase, TestMixin):
assert len(State().modules) == 3 assert len(State().modules) == 3
assert len(State().modules['test'].required_by) == 2 assert len(State().modules['test'].required_by) == 2
def test_active_service(self):
# GIVEN a new state
State().load_settings()
def test_active_service(state):
# GIVEN a new state
# WHEN I add a new service which is Active # WHEN I add a new service which is Active
State().add_service("test", 1, 1, PluginStatus.Active) State().add_service("test", 1, 1, PluginStatus.Active)
# THEN I have a single saved service # THEN I have a single saved service
assert State().is_module_active('test') is True assert State().is_module_active('test') is True
def test_inactive_service(self):
# GIVEN a new state
State().load_settings()
def test_inactive_service(state):
# GIVEN a new state
# WHEN I add a new service which is Inactive # WHEN I add a new service which is Inactive
State().add_service("test", 1, 1, PluginStatus.Inactive) State().add_service("test", 1, 1, PluginStatus.Inactive)
# THEN I have a single saved service # THEN I have a single saved service
assert State().is_module_active('test') is False assert State().is_module_active('test') is False
def test_basic_preconditions_fail(self):
def test_basic_preconditions_fail(state, registry):
# GIVEN a new state # GIVEN a new state
State().load_settings()
Registry().register('test_plugin', MagicMock()) Registry().register('test_plugin', MagicMock())
# WHEN I add a new services with dependencies and a failed pre condition # WHEN I add a new services with dependencies and a failed pre condition
@ -129,9 +109,9 @@ class TestState(TestCase, TestMixin):
assert State().modules['test2'].pass_preconditions is False assert State().modules['test2'].pass_preconditions is False
assert State().modules['test1'].pass_preconditions is False assert State().modules['test1'].pass_preconditions is False
def test_basic_preconditions_pass(self):
def test_basic_preconditions_pass(state, registry):
# GIVEN a new state # GIVEN a new state
State().load_settings()
Registry().register('test_plugin', MagicMock()) Registry().register('test_plugin', MagicMock())
# WHEN I add a new services with dependencies and a failed pre condition # WHEN I add a new services with dependencies and a failed pre condition