diff --git a/tests/README.txt b/tests/README.txt new file mode 100644 index 000000000..493b5ccb5 --- /dev/null +++ b/tests/README.txt @@ -0,0 +1,34 @@ +Tests for OpenLP +================ + +This directory contains unit tests for OpenLP. The ``functional`` directory contains functional unit tests. + +Prerequisites +------------- + +In order to run the unit tests, you will need the following Python packages/libraries installed: + + - Mock + - Nose + +On Ubuntu you can simple install the python-mock and python-nose packages. Most other distributions will also have these +packages. On Windows and Mac OS X you will need to use ``pip`` or ``easy_install`` to install these packages. + +Running the Tests +----------------- + +To run the tests, navigate to the root directory of the OpenLP project, and then run the following command:: + + nosetests -v tests + +Or, to run only the functional tests, run the following command:: + + nosetests -v tests/functional + +Or, to run only a particular test suite within a file, run the following command:: + + nosetests -v tests/functional/test_applocation.py + +Finally, to only run a particular test, run the following command:: + + nosetests -v tests/functional/test_applocation.py:TestAppLocation.get_frozen_path_test diff --git a/testing/conftest.py b/tests/conftest.py similarity index 100% rename from testing/conftest.py rename to tests/conftest.py diff --git a/tests/functional/openlp_core_lib/__init__.py b/tests/functional/openlp_core_lib/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/functional/openlp_core_lib/test_lib.py b/tests/functional/openlp_core_lib/test_lib.py new file mode 100644 index 000000000..2edc9d462 --- /dev/null +++ b/tests/functional/openlp_core_lib/test_lib.py @@ -0,0 +1,158 @@ +""" +Package to test the openlp.core.lib package. +""" +from unittest import TestCase + +from mock import MagicMock, patch + +from openlp.core.lib import str_to_bool, translate, check_directory_exists + +class TestLib(TestCase): + + def str_to_bool_with_bool_test(self): + """ + Test the str_to_bool function with boolean input + """ + #GIVEN: A boolean value set to true + 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 + assert isinstance(true_result, bool), u'The result should be a boolean' + assert true_result is True, u'The result should be True' + + #GIVEN: A boolean value set to false + 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 + assert isinstance(false_result, bool), u'The result should be a boolean' + assert false_result is False, u'The result should be True' + + def str_to_bool_with_invalid_test(self): + """ + Test the str_to_bool function with a set of invalid inputs + """ + # 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 + assert int_result is False, u'The result should be False' + + # GIVEN: An string value with completely invalid input + invalid_string = u'my feet are wet' + + # WHEN: we convert it to a bool + str_result = str_to_bool(invalid_string) + + # THEN: we should get back a false + assert str_result is False, u'The result should be False' + + def str_to_bool_with_false_values_test(self): + """ + Test the str_to_bool function with a set of false inputs + """ + # GIVEN: A string set to "false" + false_string = u'false' + + # WHEN: we convert it to a bool + false_result = str_to_bool(false_string) + + # THEN: we should get back a false + assert false_result is False, u'The result should be False' + + # GIVEN: An string set to "NO" + no_string = u'NO' + + # WHEN: we convert it to a bool + str_result = str_to_bool(no_string) + + # THEN: we should get back a false + assert str_result is False, u'The result should be False' + + def str_to_bool_with_true_values_test(self): + """ + Test the str_to_bool function with a set of true inputs + """ + # GIVEN: A string set to "True" + true_string = u'True' + + # WHEN: we convert it to a bool + true_result = str_to_bool(true_string) + + # THEN: we should get back a true + assert true_result is True, u'The result should be True' + + # GIVEN: An string set to "yes" + yes_string = u'yes' + + # WHEN: we convert it to a bool + str_result = str_to_bool(yes_string) + + # THEN: we should get back a true + assert str_result is True, u'The result should be True' + + def translate_test(self): + """ + Test the translate() function + """ + # GIVEN: A string to translate and a mocked Qt translate function + context = u'OpenLP.Tests' + text = u'Untranslated string' + comment = u'A comment' + encoding = 1 + n = 1 + mocked_translate = MagicMock(return_value=u'Translated string') + + # WHEN: we call the translate function + result = translate(context, text, comment, encoding, n, mocked_translate) + + # THEN: the translated string should be returned, and the mocked function should have been called + mocked_translate.assert_called_with(context, text, comment, encoding, n) + assert result == u'Translated string', u'The translated string should have been returned' + + def check_directory_exists_test(self): + """ + Test the check_directory_exists() function + """ + with patch(u'openlp.core.lib.os.path.exists') as mocked_exists, \ + patch(u'openlp.core.lib.os.makedirs') as mocked_makedirs: + # GIVEN: A directory to check and a mocked out os.makedirs and os.path.exists + directory_to_check = u'existing/directory' + + # WHEN: os.path.exists returns True and we check to see if the directory exists + mocked_exists.return_value = True + check_directory_exists(directory_to_check) + + # THEN: Only os.path.exists should have been called + mocked_exists.assert_called_with(directory_to_check) + assert not mocked_makedirs.called, u'os.makedirs should not have been called' + + # WHEN: os.path.exists returns False and we check the directory exists + mocked_exists.return_value = False + check_directory_exists(directory_to_check) + + # THEN: Both the mocked functions should have been called + mocked_exists.assert_called_with(directory_to_check) + mocked_makedirs.assert_called_with(directory_to_check) + + # WHEN: os.path.exists raises an IOError + mocked_exists.side_effect = IOError() + check_directory_exists(directory_to_check) + + # THEN: We shouldn't get an exception though the mocked exists has been called + mocked_exists.assert_called_with(directory_to_check) + + # WHEN: Some other exception is raised + mocked_exists.side_effect = ValueError() + + # THEN: check_directory_exists raises an exception + mocked_exists.assert_called_with(directory_to_check) + self.assertRaises(ValueError, check_directory_exists, directory_to_check) diff --git a/tests/functional/openlp_core_utils/__init__.py b/tests/functional/openlp_core_utils/__init__.py new file mode 100644 index 000000000..33507f08b --- /dev/null +++ b/tests/functional/openlp_core_utils/__init__.py @@ -0,0 +1 @@ +__author__ = 'raoul' diff --git a/tests/functional/openlp_core_utils/test_applocation.py b/tests/functional/openlp_core_utils/test_applocation.py new file mode 100644 index 000000000..2d3c83e5a --- /dev/null +++ b/tests/functional/openlp_core_utils/test_applocation.py @@ -0,0 +1,98 @@ +""" +Functional tests to test the AppLocation class and related methods. +""" +from unittest import TestCase + +from mock import patch + +from openlp.core.utils import AppLocation + +class TestAppLocation(TestCase): + """ + A test suite to test out various methods around the AppLocation class. + """ + def get_data_path_test(self): + """ + Test the AppLocation.get_data_path() method + """ + with patch(u'openlp.core.utils.Settings') as mocked_class, \ + patch(u'openlp.core.utils.AppLocation.get_directory') as mocked_get_directory, \ + patch(u'openlp.core.utils.check_directory_exists') as mocked_check_directory_exists, \ + patch(u'openlp.core.utils.os') as mocked_os: + # GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory() + mocked_settings = mocked_class.return_value + mocked_settings.contains.return_value = False + mocked_get_directory.return_value = u'test/dir' + mocked_check_directory_exists.return_value = True + mocked_os.path.normpath.return_value = u'test/dir' + # WHEN: we call AppLocation.get_data_path() + data_path = AppLocation.get_data_path() + # THEN: check that all the correct methods were called, and the result is correct + mocked_settings.contains.assert_called_with(u'advanced/data path') + mocked_get_directory.assert_called_with(AppLocation.DataDir) + mocked_check_directory_exists.assert_called_with(u'test/dir') + assert data_path == u'test/dir', u'Result should be "test/dir"' + + def get_data_path_with_custom_location_test(self): + """ + Test the AppLocation.get_data_path() method when a custom location is set in the settings + """ + with patch(u'openlp.core.utils.Settings') as mocked_class,\ + patch(u'openlp.core.utils.os') as mocked_os: + # GIVEN: A mocked out Settings class which returns a custom data location + mocked_settings = mocked_class.return_value + mocked_settings.contains.return_value = True + mocked_settings.value.return_value.toString.return_value = u'custom/dir' + mocked_os.path.normpath.return_value = u'custom/dir' + # WHEN: we call AppLocation.get_data_path() + data_path = AppLocation.get_data_path() + # THEN: the mocked Settings methods were called and the value returned was our set up value + mocked_settings.contains.assert_called_with(u'advanced/data path') + mocked_settings.value.assert_called_with(u'advanced/data path') + mocked_settings.value.return_value.toString.assert_called_with() + assert data_path == u'custom/dir', u'Result should be "custom/dir"' + + def get_section_data_path_test(self): + """ + Test the AppLocation.get_section_data_path() method + """ + with patch(u'openlp.core.utils.AppLocation.get_data_path') as mocked_get_data_path, \ + patch(u'openlp.core.utils.check_directory_exists') as mocked_check_directory_exists: + # GIVEN: A mocked out AppLocation.get_data_path() + mocked_get_data_path.return_value = u'test/dir' + mocked_check_directory_exists.return_value = True + # WHEN: we call AppLocation.get_data_path() + data_path = AppLocation.get_section_data_path(u'section') + # THEN: check that all the correct methods were called, and the result is correct + mocked_check_directory_exists.assert_called_with(u'test/dir/section') + assert data_path == u'test/dir/section', u'Result should be "test/dir/section"' + + def get_directory_for_app_dir_test(self): + """ + Test the AppLocation.get_directory() method for AppLocation.AppDir + """ + with patch(u'openlp.core.utils._get_frozen_path') as mocked_get_frozen_path: + mocked_get_frozen_path.return_value = u'app/dir' + # WHEN: We call AppLocation.get_directory + directory = AppLocation.get_directory(AppLocation.AppDir) + # THEN: + assert directory == u'app/dir', u'Directory should be "app/dir"' + + def get_directory_for_plugins_dir_test(self): + """ + Test the AppLocation.get_directory() method for AppLocation.PluginsDir + """ + with patch(u'openlp.core.utils._get_frozen_path') as mocked_get_frozen_path, \ + patch(u'openlp.core.utils.os.path.abspath') as mocked_abspath, \ + patch(u'openlp.core.utils.os.path.split') as mocked_split, \ + patch(u'openlp.core.utils.sys') as mocked_sys: + mocked_abspath.return_value = u'plugins/dir' + mocked_split.return_value = [u'openlp'] + mocked_get_frozen_path.return_value = u'plugins/dir' + mocked_sys.frozen = 1 + mocked_sys.argv = ['openlp'] + # WHEN: We call AppLocation.get_directory + directory = AppLocation.get_directory(AppLocation.PluginsDir) + # THEN: + assert directory == u'plugins/dir', u'Directory should be "plugins/dir"' + diff --git a/tests/functional/openlp_core_utils/test_utils.py b/tests/functional/openlp_core_utils/test_utils.py new file mode 100644 index 000000000..2e826bc61 --- /dev/null +++ b/tests/functional/openlp_core_utils/test_utils.py @@ -0,0 +1,58 @@ +""" +Functional tests to test the AppLocation class and related methods. +""" +from unittest import TestCase + +from mock import patch + +from openlp.core.utils import get_filesystem_encoding, _get_frozen_path + +class TestUtils(TestCase): + """ + A test suite to test out various methods around the AppLocation class. + """ + def get_filesystem_encoding_test(self): + """ + Test the get_filesystem_encoding() function + """ + with patch(u'openlp.core.utils.sys.getfilesystemencoding') as mocked_getfilesystemencoding, \ + patch(u'openlp.core.utils.sys.getdefaultencoding') as mocked_getdefaultencoding: + # GIVEN: sys.getfilesystemencoding returns "cp1252" + mocked_getfilesystemencoding.return_value = u'cp1252' + + # WHEN: get_filesystem_encoding() is called + result = get_filesystem_encoding() + + # THEN: getdefaultencoding should have been called + mocked_getfilesystemencoding.assert_called_with() + assert not mocked_getdefaultencoding.called + assert result == u'cp1252', u'The result should be "cp1252"' + + # GIVEN: sys.getfilesystemencoding returns None and sys.getdefaultencoding returns "utf-8" + mocked_getfilesystemencoding.return_value = None + mocked_getdefaultencoding.return_value = u'utf-8' + + # WHEN: get_filesystem_encoding() is called + result = get_filesystem_encoding() + + # THEN: getdefaultencoding should have been called + mocked_getfilesystemencoding.assert_called_with() + mocked_getdefaultencoding.assert_called_with() + assert result == u'utf-8', u'The result should be "utf-8"' + + def get_frozen_path_test(self): + """ + Test the _get_frozen_path() function + """ + with patch(u'openlp.core.utils.sys') as mocked_sys: + # GIVEN: The sys module "without" a "frozen" attribute + mocked_sys.frozen = None + # WHEN: We call _get_frozen_path() with two parameters + # THEN: The non-frozen parameter is returned + assert _get_frozen_path(u'frozen', u'not frozen') == u'not frozen', u'Should return "not frozen"' + # GIVEN: The sys module *with* a "frozen" attribute + mocked_sys.frozen = 1 + # WHEN: We call _get_frozen_path() with two parameters + # THEN: The frozen parameter is returned + assert _get_frozen_path(u'frozen', u'not frozen') == u'frozen', u'Should return "frozen"' + diff --git a/testing/run.py b/tests/run.py similarity index 100% rename from testing/run.py rename to tests/run.py diff --git a/testing/test_app.py b/tests/test_app.py similarity index 100% rename from testing/test_app.py rename to tests/test_app.py