From a6f8909d72e17268c53de5e1fa599c6e8b89b278 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Tue, 21 Aug 2018 21:05:22 -0700 Subject: [PATCH 1/7] Move to using a PEP 440 compliant version number --- setup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index fdbcdaea5..2d87d5f98 100755 --- a/setup.py +++ b/setup.py @@ -99,10 +99,11 @@ try: if tree_revision == tag_revision: version_string = tag_version.decode('utf-8') else: - version_string = '%s-bzr%s' % (tag_version.decode('utf-8'), tree_revision.decode('utf-8')) + version_string = '{version}-dev{revision}'.format(version=tag_version.decode('utf-8'), + revision=tree_revision.decode('utf-8')) ver_file = open(VERSION_FILE, 'w') ver_file.write(version_string) -except: +except Exception: ver_file = open(VERSION_FILE, 'r') version_string = ver_file.read().strip() finally: From be4795fba004114016e79b75c55adde761264fce Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Tue, 21 Aug 2018 22:04:11 -0700 Subject: [PATCH 2/7] Added merge proposal script; updated version style again --- scripts/mp_update.py | 49 ++++++++++++++++++++++++++++++++++++++++++++ setup.py | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 scripts/mp_update.py diff --git a/scripts/mp_update.py b/scripts/mp_update.py new file mode 100644 index 000000000..519231516 --- /dev/null +++ b/scripts/mp_update.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python2 +import sys +from argparse import ArgumentParser +from launchpadlib.launchpad import Launchpad + + +def parse_args(): + """ + Parse the command line arguments + """ + parser = ArgumentParser() + parser.add_argument('-p', '--merge-proposal', required=True, + help='The main part of the URL to the merge proposal, without the hostname.') + parser.add_argument('-m', '--message', required=True, + help='The comment to add to the merge proposal') + return parser.parse_args() + + +def get_merge_proposal(merge_proposal_url): + """ + Get the merge proposal for the ``merge_proposal_url`` + """ + lp = Launchpad.login_with('OpenLP CI', 'production', version='devel') + openlp_project = lp.projects['openlp'] + merge_proposals = openlp_project.getMergeProposals() + for merge_proposal in merge_proposals: + if str(merge_proposal).endwith(merge_proposal_url): + return merge_proposal + return None + + +def create_comment(merge_proposal, comment): + """ + Create a comment on the merge proposal + """ + merge_proposal.createComment(subject='comment', content=comment) + + +def main(): + """ + Run the thing + """ + args = parse_args() + merge_proposal = get_merge_proposal(args.merge_proposal) + if not merge_proposal: + print('No merge proposal with that URL found') + sys.exit(1) + else: + create_comment(merge_proposal, args.message) diff --git a/setup.py b/setup.py index 2d87d5f98..a28fa0300 100755 --- a/setup.py +++ b/setup.py @@ -99,7 +99,7 @@ try: if tree_revision == tag_revision: version_string = tag_version.decode('utf-8') else: - version_string = '{version}-dev{revision}'.format(version=tag_version.decode('utf-8'), + version_string = '{version}.dev{revision}'.format(version=tag_version.decode('utf-8'), revision=tree_revision.decode('utf-8')) ver_file = open(VERSION_FILE, 'w') ver_file.write(version_string) From 2e5ab6bfd46c972ed0713470e41cea7d3b39d7e8 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Tue, 21 Aug 2018 22:10:51 -0700 Subject: [PATCH 3/7] Oops, helps if the script actually works --- scripts/mp_update.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/mp_update.py b/scripts/mp_update.py index 519231516..619acc690 100644 --- a/scripts/mp_update.py +++ b/scripts/mp_update.py @@ -24,7 +24,7 @@ def get_merge_proposal(merge_proposal_url): openlp_project = lp.projects['openlp'] merge_proposals = openlp_project.getMergeProposals() for merge_proposal in merge_proposals: - if str(merge_proposal).endwith(merge_proposal_url): + if str(merge_proposal).endswith(merge_proposal_url): return merge_proposal return None @@ -47,3 +47,7 @@ def main(): sys.exit(1) else: create_comment(merge_proposal, args.message) + + +if __name__ == '__main__': + main() From e4cd6c2e633570c3ab2621c477bd49b50f134186 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Wed, 22 Aug 2018 07:24:30 -0700 Subject: [PATCH 4/7] Change the Launchpad credential storage to an unencrypted file --- scripts/mp_update.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/mp_update.py b/scripts/mp_update.py index 619acc690..047c62238 100644 --- a/scripts/mp_update.py +++ b/scripts/mp_update.py @@ -1,8 +1,12 @@ #!/usr/bin/env python2 import sys +import os from argparse import ArgumentParser +from launchpadlib.credentials import UnencryptedFileCredentialStore from launchpadlib.launchpad import Launchpad +HERE = os.path.dirname(os.path.abspath(__file__)) + def parse_args(): """ @@ -20,7 +24,8 @@ def get_merge_proposal(merge_proposal_url): """ Get the merge proposal for the ``merge_proposal_url`` """ - lp = Launchpad.login_with('OpenLP CI', 'production', version='devel') + lp = Launchpad.login_with('OpenLP CI', 'production', version='devel', + credential_store=UnencryptedFileCredentialStore(os.path.join(HERE, 'launchpadcreds.txt'))) openlp_project = lp.projects['openlp'] merge_proposals = openlp_project.getMergeProposals() for merge_proposal in merge_proposals: From f0eb2f15130e99d28a99a20feeb33c586439a990 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Wed, 22 Aug 2018 16:06:26 -0700 Subject: [PATCH 5/7] Add the ability to customise the subject --- scripts/mp_update.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/mp_update.py b/scripts/mp_update.py index 047c62238..662bfd147 100644 --- a/scripts/mp_update.py +++ b/scripts/mp_update.py @@ -17,6 +17,7 @@ def parse_args(): help='The main part of the URL to the merge proposal, without the hostname.') parser.add_argument('-m', '--message', required=True, help='The comment to add to the merge proposal') + parser.add_argument('-s', '--subject', default=None, help='The subject for the comment') return parser.parse_args() @@ -34,11 +35,13 @@ def get_merge_proposal(merge_proposal_url): return None -def create_comment(merge_proposal, comment): +def create_comment(merge_proposal, comment, subject): """ Create a comment on the merge proposal """ - merge_proposal.createComment(subject='comment', content=comment) + if not subject: + subject = 'Jenkins test update' + merge_proposal.createComment(subject, content=comment) def main(): @@ -51,7 +54,7 @@ def main(): print('No merge proposal with that URL found') sys.exit(1) else: - create_comment(merge_proposal, args.message) + create_comment(merge_proposal, args.message, args.subject) if __name__ == '__main__': From 42523cfa867e43094655860635625c61e9764fec Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Mon, 27 Aug 2018 10:48:47 -0700 Subject: [PATCH 6/7] Fix a problem with the subject in the LP comment; Include test resources and fonts. --- MANIFEST.in | 2 ++ scripts/mp_update.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index be81efb23..7bfefe740 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,9 +7,11 @@ recursive-include openlp *.css recursive-include openlp *.png recursive-include openlp *.ps recursive-include openlp *.json +recursive-include openlp *.ttf recursive-include documentation * recursive-include resources * recursive-include scripts * +recursive-include tests/resources * include copyright.txt include LICENSE include README.txt diff --git a/scripts/mp_update.py b/scripts/mp_update.py index 662bfd147..303913f9a 100644 --- a/scripts/mp_update.py +++ b/scripts/mp_update.py @@ -41,7 +41,7 @@ def create_comment(merge_proposal, comment, subject): """ if not subject: subject = 'Jenkins test update' - merge_proposal.createComment(subject, content=comment) + merge_proposal.createComment(subject=subject, content=comment) def main(): From 8d379e678505a02261bfc81ff617646693f57453 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 30 Aug 2018 22:49:26 -0700 Subject: [PATCH 7/7] Add some tests, we're up to 52% coverage now! --- openlp/core/ui/themeform.py | 2 +- .../openlp_core/ui/media/test_systemplayer.py | 24 +++++++++ .../openlp_core/ui/test_firsttimeform.py | 36 ++++++++++++++ tests/openlp_core/ui/test_themeform.py | 49 +++++++++++++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 tests/openlp_core/ui/test_themeform.py diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index 29b04477c..a154cd5a0 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -153,7 +153,7 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties): Calculate the number of lines on a page by rendering text """ # Do not trigger on start up - if self.currentPage != self.welcome_page: + if self.currentPage() != self.welcome_page: self.update_theme() self.theme_manager.generate_image(self.theme, True) diff --git a/tests/functional/openlp_core/ui/media/test_systemplayer.py b/tests/functional/openlp_core/ui/media/test_systemplayer.py index fc03e2541..1726f7e2e 100644 --- a/tests/functional/openlp_core/ui/media/test_systemplayer.py +++ b/tests/functional/openlp_core/ui/media/test_systemplayer.py @@ -508,6 +508,30 @@ class TestCheckMediaWorker(TestCase): # THEN: The correct values should be set up assert worker is not None + @patch('openlp.core.ui.media.systemplayer.functools.partial') + @patch('openlp.core.ui.media.systemplayer.QtMultimedia.QMediaContent') + def test_start(self, MockQMediaContent, mocked_partial): + """ + Test the start method + """ + # GIVEN: A CheckMediaWorker instance + worker = CheckMediaWorker('file.ogv') + MockQMediaContent.side_effect = lambda x: x + mocked_partial.side_effect = lambda x, y: y + + # WHEN: start() is called + with patch.object(worker, 'error') as mocked_error, \ + patch.object(worker, 'mediaStatusChanged') as mocked_status_change, \ + patch.object(worker, 'setMedia') as mocked_set_media, \ + patch.object(worker, 'play') as mocked_play: + worker.start() + + # THEN: The correct methods should be called + mocked_error.connect.assert_called_once_with('error') + mocked_status_change.connect.assert_called_once_with('media') + mocked_set_media.assert_called_once_with(QtCore.QUrl('file:file.ogv')) + mocked_play.assert_called_once_with() + def test_signals_media(self): """ Test the signals() signal of the CheckMediaWorker class with a "media" origin diff --git a/tests/functional/openlp_core/ui/test_firsttimeform.py b/tests/functional/openlp_core/ui/test_firsttimeform.py index cd507452e..76f1be051 100644 --- a/tests/functional/openlp_core/ui/test_firsttimeform.py +++ b/tests/functional/openlp_core/ui/test_firsttimeform.py @@ -233,3 +233,39 @@ class TestFirstTimeForm(TestCase, TestMixin): mocked_message_box.critical.assert_called_once_with( first_time_form, 'Network Error', 'There was a network error attempting to connect to retrieve ' 'initial configuration information', 'OK') + + @patch('openlp.core.ui.firsttimewizard.Settings') + def test_on_projectors_check_box_checked(self, MockSettings): + """ + Test that the projector panel is shown when the checkbox in the first time wizard is checked + """ + # GIVEN: A First Time Wizard and a mocked settings object + frw = FirstTimeForm(None) + mocked_settings = MagicMock() + mocked_settings.value.return_value = True + MockSettings.return_value = mocked_settings + + # WHEN: on_projectors_check_box_clicked() is called + frw.on_projectors_check_box_clicked() + + # THEN: The visibility of the projects panel should have been set + mocked_settings.value.assert_called_once_with('projector/show after wizard') + mocked_settings.setValue.assert_called_once_with('projector/show after wizard', False) + + @patch('openlp.core.ui.firsttimewizard.Settings') + def test_on_projectors_check_box_unchecked(self, MockSettings): + """ + Test that the projector panel is shown when the checkbox in the first time wizard is checked + """ + # GIVEN: A First Time Wizard and a mocked settings object + frw = FirstTimeForm(None) + mocked_settings = MagicMock() + mocked_settings.value.return_value = False + MockSettings.return_value = mocked_settings + + # WHEN: on_projectors_check_box_clicked() is called + frw.on_projectors_check_box_clicked() + + # THEN: The visibility of the projects panel should have been set + mocked_settings.value.assert_called_once_with('projector/show after wizard') + mocked_settings.setValue.assert_called_once_with('projector/show after wizard', True) diff --git a/tests/openlp_core/ui/test_themeform.py b/tests/openlp_core/ui/test_themeform.py new file mode 100644 index 000000000..a45654943 --- /dev/null +++ b/tests/openlp_core/ui/test_themeform.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2018 OpenLP Developers # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +Interface tests to test the ThemeWizard class and related methods. +""" +from unittest import TestCase + +from openlp.core.common.registry import Registry +from openlp.core.ui.themeform import ThemeForm +from tests.helpers.testmixin import TestMixin + + +class TestThemeManager(TestCase, TestMixin): + """ + Test the functions in the ThemeManager module + """ + def setUp(self): + """ + Create the UI + """ + Registry.create() + + def test_create_theme_wizard(self): + """ + Test creating a ThemeForm instance + """ + # GIVEN: A ThemeForm class + # WHEN: An object is created + # THEN: There should be no problems + ThemeForm(None)