openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #22043
[Merge] lp:~phill-ridout/openlp/song_helper into lp:openlp
Phill has proposed merging lp:~phill-ridout/openlp/song_helper into lp:openlp.
Requested reviews:
Tim Bentley (trb143)
Raoul Snyman (raoul-snyman)
Andreas Preikschat (googol)
Phill (phill-ridout)
For more details, see:
https://code.launchpad.net/~phill-ridout/openlp/song_helper/+merge/191067
Changed to py3
Adds a helper class to reduce the work in testing the actual import of song files.
Changed SongShowPlus importer so that it uses this new class
Fixed up imports and added copyright/license info
--
https://code.launchpad.net/~phill-ridout/openlp/song_helper/+merge/191067
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'tests/functional/openlp_plugins/songs/test_songshowplusimport.py'
--- tests/functional/openlp_plugins/songs/test_songshowplusimport.py 2013-09-19 21:02:28 +0000
+++ tests/functional/openlp_plugins/songs/test_songshowplusimport.py 2013-10-14 22:06:52 +0000
@@ -33,51 +33,25 @@
import os
from unittest import TestCase
+from tests.helpers.songfileimport import SongImportTestHelper
from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.songshowplusimport import SongShowPlusImport
from tests.functional import patch, MagicMock
-TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../resources/songshowplussongs'))
-SONG_TEST_DATA = {'Amazing Grace.sbsong':
- {'title': 'Amazing Grace (Demonstration)',
- 'authors': ['John Newton', 'Edwin Excell', 'John P. Rees'],
- 'copyright': 'Public Domain ',
- 'ccli_number': 22025,
- 'verses':
- [('Amazing grace! How sweet the sound!\r\nThat saved a wretch like me!\r\n'
- 'I once was lost, but now am found;\r\nWas blind, but now I see.', 'v1'),
- ('\'Twas grace that taught my heart to fear,\r\nAnd grace my fears relieved.\r\n'
- 'How precious did that grace appear,\r\nThe hour I first believed.', 'v2'),
- ('The Lord has promised good to me,\r\nHis Word my hope secures.\r\n'
- 'He will my shield and portion be\r\nAs long as life endures.', 'v3'),
- ('Thro\' many dangers, toils and snares\r\nI have already come.\r\n'
- '\'Tis grace that brought me safe thus far,\r\nAnd grace will lead me home.', 'v4'),
- ('When we\'ve been there ten thousand years,\r\nBright shining as the sun,\r\n'
- 'We\'ve no less days to sing God\'s praise,\r\nThan when we first begun.', 'v5')],
- 'topics': ['Assurance', 'Grace', 'Praise', 'Salvation'],
- 'comments': '\n\n\n',
- 'song_book_name': 'Demonstration Songs',
- 'song_number': 0,
- 'verse_order_list': []},
- 'Beautiful Garden Of Prayer.sbsong':
- {'title': 'Beautiful Garden Of Prayer (Demonstration)',
- 'authors': ['Eleanor Allen Schroll', 'James H. Fillmore'],
- 'copyright': 'Public Domain ',
- 'ccli_number': 60252,
- 'verses':
- [('There\'s a garden where Jesus is waiting,\r\nThere\'s a place that is wondrously fair.\r\n'
- 'For it glows with the light of His presence,\r\n\'Tis the beautiful garden of prayer.', 'v1'),
- ('There\'s a garden where Jesus is waiting,\r\nAnd I go with my burden and care.\r\n'
- 'Just to learn from His lips, words of comfort,\r\nIn the beautiful garden of prayer.', 'v2'),
- ('There\'s a garden where Jesus is waiting,\r\nAnd He bids you to come meet Him there,\r\n'
- 'Just to bow and receive a new blessing,\r\nIn the beautiful garden of prayer.', 'v3'),
- ('O the beautiful garden, the garden of prayer,\r\nO the beautiful garden of prayer.\r\n'
- 'There my Savior awaits, and He opens the gates\r\nTo the beautiful garden of prayer.', 'c1')],
- 'topics': ['Devotion', 'Prayer'],
- 'comments': '',
- 'song_book_name': '',
- 'song_number': 0,
- 'verse_order_list': []}}
+TEST_PATH = os.path.abspath(
+ os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'songshowplussongs'))
+
+class TestSongShowPlusFileImport(SongImportTestHelper):
+ def __init__(self, *args, **kwargs):
+ self.importer_class_name = 'SongShowPlusImport'
+ self.importer_module_name = 'songshowplusimport'
+ super(TestSongShowPlusFileImport, self).__init__(*args, **kwargs)
+
+ def test_song_import(self):
+ test_import = self.file_import(os.path.join(TEST_PATH, 'Amazing Grace.sbsong'),
+ self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json')))
+ test_import = self.file_import(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.sbsong'),
+ self.load_external_result_data(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.json')))
class TestSongShowPlusImport(TestCase):
@@ -117,7 +91,7 @@
# THEN: doImport should return none and the progress bar maximum should not be set.
self.assertIsNone(importer.doImport(), 'doImport should return None when import_source is not a list')
self.assertEquals(mocked_import_wizard.progress_bar.setMaximum.called, False,
- 'setMaxium on import_wizard.progress_bar should not have been called')
+ 'setMaximum on import_wizard.progress_bar should not have been called')
def valid_import_source_test(self):
"""
@@ -194,70 +168,3 @@
self.assertEquals(importer.to_openlp_verse_tag(original_tag, ignore_unique=True), openlp_tag,
'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"'
% (openlp_tag, original_tag))
-
- def file_import_test(self):
- """
- Test the actual import of real song files and check that the imported data is correct.
- """
-
- # GIVEN: Test files with a mocked out SongImport class, a mocked out "manager", a mocked out "import_wizard",
- # and mocked out "author", "add_copyright", "add_verse", "finish" methods.
- with patch('openlp.plugins.songs.lib.songshowplusimport.SongImport'):
- for song_file in SONG_TEST_DATA:
- mocked_manager = MagicMock()
- mocked_import_wizard = MagicMock()
- mocked_parse_author = MagicMock()
- mocked_add_copyright = MagicMock()
- mocked_add_verse = MagicMock()
- mocked_finish = MagicMock()
- mocked_finish.return_value = True
- importer = SongShowPlusImport(mocked_manager)
- importer.import_wizard = mocked_import_wizard
- importer.stop_import_flag = False
- importer.parse_author = mocked_parse_author
- importer.addCopyright = mocked_add_copyright
- importer.addVerse = mocked_add_verse
- importer.finish = mocked_finish
- importer.topics = []
-
- # WHEN: Importing each file
- importer.import_source = [os.path.join(TEST_PATH, song_file)]
- title = SONG_TEST_DATA[song_file]['title']
- author_calls = SONG_TEST_DATA[song_file]['authors']
- song_copyright = SONG_TEST_DATA[song_file]['copyright']
- ccli_number = SONG_TEST_DATA[song_file]['ccli_number']
- add_verse_calls = SONG_TEST_DATA[song_file]['verses']
- topics = SONG_TEST_DATA[song_file]['topics']
- comments = SONG_TEST_DATA[song_file]['comments']
- song_book_name = SONG_TEST_DATA[song_file]['song_book_name']
- song_number = SONG_TEST_DATA[song_file]['song_number']
- verse_order_list = SONG_TEST_DATA[song_file]['verse_order_list']
-
- # THEN: doImport should return none, the song data should be as expected, and finish should have been
- # called.
- self.assertIsNone(importer.doImport(), 'doImport should return None when it has completed')
- self.assertEquals(importer.title, title, 'title for %s should be "%s"' % (song_file, title))
- for author in author_calls:
- mocked_parse_author.assert_any_call(author)
- if song_copyright:
- mocked_add_copyright.assert_called_with(song_copyright)
- if ccli_number:
- self.assertEquals(importer.ccliNumber, ccli_number, 'ccliNumber for %s should be %s'
- % (song_file, ccli_number))
- for verse_text, verse_tag in add_verse_calls:
- mocked_add_verse.assert_any_call(verse_text, verse_tag)
- if topics:
- self.assertEquals(importer.topics, topics, 'topics for %s should be %s' % (song_file, topics))
- if comments:
- self.assertEquals(importer.comments, comments, 'comments for %s should be "%s"'
- % (song_file, comments))
- if song_book_name:
- self.assertEquals(importer.songBookName, song_book_name, 'songBookName for %s should be "%s"'
- % (song_file, song_book_name))
- if song_number:
- self.assertEquals(importer.songNumber, song_number, 'songNumber for %s should be %s'
- % (song_file, song_number))
- if verse_order_list:
- self.assertEquals(importer.verseOrderList, [], 'verseOrderList for %s should be %s'
- % (song_file, verse_order_list))
- mocked_finish.assert_called_with()
=== added directory 'tests/helpers'
=== added file 'tests/helpers/songfileimport.py'
--- tests/helpers/songfileimport.py 1970-01-01 00:00:00 +0000
+++ tests/helpers/songfileimport.py 2013-10-14 22:06:52 +0000
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2013 Raoul Snyman #
+# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
+# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
+# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
+# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
+# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
+# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
+# --------------------------------------------------------------------------- #
+# 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 #
+###############################################################################
+"""
+The :mod:`songfileimporthelper` modules provides a helper class and methods to easily enable testing the import of
+song files from third party applications.
+"""
+import json
+from unittest import TestCase
+
+from tests.functional import patch, MagicMock
+
+class SongImportTestHelper(TestCase):
+ """
+ This class is designed to be a helper class to reduce repition when testing the import of song files.
+ """
+ def __init__(self, *args, **kwargs):
+ super(SongImportTestHelper, self).__init__(*args, **kwargs)
+ self.importer_module = __import__(
+ 'openlp.plugins.songs.lib.%s' % self.importer_module_name, fromlist=[self.importer_class_name])
+ self.importer_class = getattr(self.importer_module, self.importer_class_name)
+
+ def setUp(self):
+ """
+ Patch and set up the mocks required.
+ """
+ self.add_copyright_patcher = patch(
+ 'openlp.plugins.songs.lib.%s.%s.addCopyright' % (self.importer_module_name, self.importer_class_name))
+ self.add_verse_patcher = patch(
+ 'openlp.plugins.songs.lib.%s.%s.addVerse' % (self.importer_module_name, self.importer_class_name))
+ self.finish_patcher = patch(
+ 'openlp.plugins.songs.lib.%s.%s.finish' % (self.importer_module_name, self.importer_class_name))
+ self.parse_author_patcher = patch(
+ 'openlp.plugins.songs.lib.%s.%s.parse_author' % (self.importer_module_name, self.importer_class_name))
+ self.song_import_patcher = patch('openlp.plugins.songs.lib.%s.SongImport' % self.importer_module_name)
+ self.mocked_add_copyright = self.add_copyright_patcher.start()
+ self.mocked_add_verse = self.add_verse_patcher.start()
+ self.mocked_finish = self.finish_patcher.start()
+ self.mocked_parse_author = self.parse_author_patcher.start()
+ self.mocked_song_importer = self.song_import_patcher.start()
+ self.mocked_manager = MagicMock()
+ self.mocked_import_wizard = MagicMock()
+ self.mocked_finish.return_value = True
+
+ def tearDown(self):
+ """
+ Clean up
+ """
+ self.add_copyright_patcher.stop()
+ self.add_verse_patcher.stop()
+ self.finish_patcher.stop()
+ self.parse_author_patcher.stop()
+ self.song_import_patcher.stop()
+
+ def load_external_result_data(self, file_name):
+ """
+ A method to load and return an object containing the song data from an external file.
+ """
+ result_file = open(file_name, 'rb')
+ return json.loads(result_file.read().decode())
+
+ def file_import(self, source_file_name, result_data):
+ """
+ Import the given file and check that it has imported correctly
+ """
+ importer = self.importer_class(self.mocked_manager)
+ importer.import_wizard = self.mocked_import_wizard
+ importer.stop_import_flag = False
+ importer.topics = []
+
+ # WHEN: Importing the source file
+ importer.import_source = [source_file_name]
+ add_verse_calls = self._get_data(result_data, 'verses')
+ author_calls = self._get_data(result_data, 'authors')
+ ccli_number = self._get_data(result_data, 'ccli_number')
+ comments = self._get_data(result_data, 'comments')
+ song_book_name = self._get_data(result_data, 'song_book_name')
+ song_copyright = self._get_data(result_data, 'copyright')
+ song_number = self._get_data(result_data, 'song_number')
+ title = self._get_data(result_data, 'title')
+ topics = self._get_data(result_data, 'topics')
+ verse_order_list = self._get_data(result_data, 'verse_order_list')
+
+ # THEN: doImport should return none, the song data should be as expected, and finish should have been
+ # called.
+ self.assertIsNone(importer.doImport(), 'doImport should return None when it has completed')
+ self.assertEquals(importer.title, title, 'title for %s should be "%s"' % (source_file_name, title))
+ for author in author_calls:
+ self.mocked_parse_author.assert_any_call(author)
+ if song_copyright:
+ self.mocked_add_copyright.assert_called_with(song_copyright)
+ if ccli_number:
+ self.assertEquals(importer.ccliNumber, ccli_number, 'ccliNumber for %s should be %s'
+ % (source_file_name, ccli_number))
+ for verse_text, verse_tag in add_verse_calls:
+ self.mocked_add_verse.assert_any_call(verse_text, verse_tag)
+ if topics:
+ self.assertEquals(importer.topics, topics, 'topics for %s should be %s' % (source_file_name, topics))
+ if comments:
+ self.assertEquals(importer.comments, comments, 'comments for %s should be "%s"'
+ % (source_file_name, comments))
+ if song_book_name:
+ self.assertEquals(importer.songBookName, song_book_name, 'songBookName for %s should be "%s"'
+ % (source_file_name, song_book_name))
+ if song_number:
+ self.assertEquals(importer.songNumber, song_number, 'songNumber for %s should be %s'
+ % (source_file_name, song_number))
+ if verse_order_list:
+ self.assertEquals(importer.verseOrderList, [], 'verseOrderList for %s should be %s'
+ % (source_file_name, verse_order_list))
+ self.mocked_finish.assert_called_with()
+
+ def _get_data(self, data, key):
+ if key in data:
+ return data[key]
+ return ''
+
=== added file 'tests/resources/songshowplussongs/Amazing Grace.json'
--- tests/resources/songshowplussongs/Amazing Grace.json 1970-01-01 00:00:00 +0000
+++ tests/resources/songshowplussongs/Amazing Grace.json 2013-10-14 22:06:52 +0000
@@ -0,0 +1,42 @@
+{
+ "authors": [
+ "John Newton",
+ "Edwin Excell",
+ "John P. Rees"
+ ],
+ "ccli_number": 22025,
+ "comments": "\n\n\n",
+ "copyright": "Public Domain ",
+ "song_book_name": "Demonstration Songs",
+ "song_number": 0,
+ "title": "Amazing Grace (Demonstration)",
+ "topics": [
+ "Assurance",
+ "Grace",
+ "Praise",
+ "Salvation"
+ ],
+ "verse_order_list": [],
+ "verses": [
+ [
+ "Amazing grace! How sweet the sound!\r\nThat saved a wretch like me!\r\nI once was lost, but now am found;\r\nWas blind, but now I see.",
+ "v1"
+ ],
+ [
+ "'Twas grace that taught my heart to fear,\r\nAnd grace my fears relieved.\r\nHow precious did that grace appear,\r\nThe hour I first believed.",
+ "v2"
+ ],
+ [
+ "The Lord has promised good to me,\r\nHis Word my hope secures.\r\nHe will my shield and portion be\r\nAs long as life endures.",
+ "v3"
+ ],
+ [
+ "Thro' many dangers, toils and snares\r\nI have already come.\r\n'Tis grace that brought me safe thus far,\r\nAnd grace will lead me home.",
+ "v4"
+ ],
+ [
+ "When we've been there ten thousand years,\r\nBright shining as the sun,\r\nWe've no less days to sing God's praise,\r\nThan when we first begun.",
+ "v5"
+ ]
+ ]
+}
\ No newline at end of file
=== added file 'tests/resources/songshowplussongs/Beautiful Garden Of Prayer.json'
--- tests/resources/songshowplussongs/Beautiful Garden Of Prayer.json 1970-01-01 00:00:00 +0000
+++ tests/resources/songshowplussongs/Beautiful Garden Of Prayer.json 2013-10-14 22:06:52 +0000
@@ -0,0 +1,35 @@
+{
+ "authors": [
+ "Eleanor Allen Schroll",
+ "James H. Fillmore"
+ ],
+ "ccli_number": 60252,
+ "comments": "",
+ "copyright": "Public Domain ",
+ "song_book_name": "",
+ "song_number": 0,
+ "title": "Beautiful Garden Of Prayer (Demonstration)",
+ "topics": [
+ "Devotion",
+ "Prayer"
+ ],
+ "verse_order_list": [],
+ "verses": [
+ [
+ "There's a garden where Jesus is waiting,\r\nThere's a place that is wondrously fair.\r\nFor it glows with the light of His presence,\r\n'Tis the beautiful garden of prayer.",
+ "v1"
+ ],
+ [
+ "There's a garden where Jesus is waiting,\r\nAnd I go with my burden and care.\r\nJust to learn from His lips, words of comfort,\r\nIn the beautiful garden of prayer.",
+ "v2"
+ ],
+ [
+ "There's a garden where Jesus is waiting,\r\nAnd He bids you to come meet Him there,\r\nJust to bow and receive a new blessing,\r\nIn the beautiful garden of prayer.",
+ "v3"
+ ],
+ [
+ "O the beautiful garden, the garden of prayer,\r\nO the beautiful garden of prayer.\r\nThere my Savior awaits, and He opens the gates\r\nTo the beautiful garden of prayer.",
+ "c1"
+ ]
+ ]
+}
\ No newline at end of file
Follow ups