Phill has proposed merging lp:~phill-ridout/openlp/song_helper into lp:openlp.
Requested reviews: Tim Bentley (trb143) Phill (phill-ridout) For more details, see: https://code.launchpad.net/~phill-ridout/openlp/song_helper/+merge/185651 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 Now ready to go :) -- https://code.launchpad.net/~phill-ridout/openlp/song_helper/+merge/185651 Your team OpenLP Core is subscribed to branch lp:openlp.
=== added file 'tests/functional/openlp_plugins/songs/songfileimporthelper.py' --- tests/functional/openlp_plugins/songs/songfileimporthelper.py 1970-01-01 00:00:00 +0000 +++ tests/functional/openlp_plugins/songs/songfileimporthelper.py 2013-09-14 21:45:05 +0000 @@ -0,0 +1,113 @@ +""" +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 mock 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): + 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) + TestCase.__init__(self, *args, **kwargs) + + 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 '' + === modified file 'tests/functional/openlp_plugins/songs/test_songshowplusimport.py' --- tests/functional/openlp_plugins/songs/test_songshowplusimport.py 2013-08-31 18:17:38 +0000 +++ tests/functional/openlp_plugins/songs/test_songshowplusimport.py 2013-09-14 21:45:05 +0000 @@ -6,50 +6,24 @@ from unittest import TestCase from mock import patch, MagicMock +from tests.functional.openlp_plugins.songs.songfileimporthelper import SongImportTestHelper from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib.songshowplusimport import SongShowPlusImport -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' + SongImportTestHelper.__init__(self, *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): @@ -89,7 +63,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): """ @@ -166,70 +140,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 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-09-14 21:45:05 +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-09-14 21:45:05 +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
_______________________________________________ Mailing list: https://launchpad.net/~openlp-core Post to : openlp-core@lists.launchpad.net Unsubscribe : https://launchpad.net/~openlp-core More help : https://help.launchpad.net/ListHelp