Merge back to trunk

This commit is contained in:
Felipe Polo-Wood 2013-12-02 11:14:09 -05:00
commit b85b09c92c
11 changed files with 428 additions and 120 deletions

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 # vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
############################################################################### ###############################################################################
# OpenLP - Open Source Lyrics Projection # # OpenLP - Open Source Lyrics Projection #

View File

@ -184,7 +184,8 @@ class OpenLP(QtGui.QApplication):
``traceback`` ``traceback``
A traceback object with the details of where the exception occurred. A traceback object with the details of where the exception occurred.
""" """
log.exception(''.join(format_exception(exctype, value, traceback))) # We can't log.exception here because the last exception no longer exists, we're actually busy handling it.
log.critical(''.join(format_exception(exctype, value, traceback)))
if not hasattr(self, 'exception_form'): if not hasattr(self, 'exception_form'):
self.exception_form = ExceptionForm() self.exception_form = ExceptionForm()
self.exception_form.exception_text_edit.setPlainText(''.join(format_exception(exctype, value, traceback))) self.exception_form.exception_text_edit.setPlainText(''.join(format_exception(exctype, value, traceback)))

View File

@ -283,7 +283,7 @@ class AdvancedTab(SettingsTab):
self.service_name_day.setItemText(0, translate('OpenLP.AdvancedTab', 'Monday')) self.service_name_day.setItemText(0, translate('OpenLP.AdvancedTab', 'Monday'))
self.service_name_day.setItemText(1, translate('OpenLP.AdvancedTab', 'Tuesday')) self.service_name_day.setItemText(1, translate('OpenLP.AdvancedTab', 'Tuesday'))
self.service_name_day.setItemText(2, translate('OpenLP.AdvancedTab', 'Wednesday')) self.service_name_day.setItemText(2, translate('OpenLP.AdvancedTab', 'Wednesday'))
self.service_name_day.setItemText(3, translate('OpenLP.AdvancedTab', 'Thurdsday')) self.service_name_day.setItemText(3, translate('OpenLP.AdvancedTab', 'Thursday'))
self.service_name_day.setItemText(4, translate('OpenLP.AdvancedTab', 'Friday')) self.service_name_day.setItemText(4, translate('OpenLP.AdvancedTab', 'Friday'))
self.service_name_day.setItemText(5, translate('OpenLP.AdvancedTab', 'Saturday')) self.service_name_day.setItemText(5, translate('OpenLP.AdvancedTab', 'Saturday'))
self.service_name_day.setItemText(6, translate('OpenLP.AdvancedTab', 'Sunday')) self.service_name_day.setItemText(6, translate('OpenLP.AdvancedTab', 'Sunday'))

View File

@ -101,7 +101,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog):
""" """
Constructor. Constructor.
""" """
super(ExceptionForm, self).__init__(self.main_window) super(ExceptionForm, self).__init__()
self.setupUi(self) self.setupUi(self)
self.settings_section = 'crashreport' self.settings_section = 'crashreport'

View File

@ -102,10 +102,10 @@ class SongBeamerImport(SongImport):
""" """
Receive a single file or a list of files to import. Receive a single file or a list of files to import.
""" """
self.import_wizard.progress_bar.setMaximum(len(self.import_source))
if not isinstance(self.import_source, list): if not isinstance(self.import_source, list):
return return
for file in self.import_source: self.import_wizard.progress_bar.setMaximum(len(self.import_source))
for import_file in self.import_source:
# TODO: check that it is a valid SongBeamer file # TODO: check that it is a valid SongBeamer file
if self.stop_import_flag: if self.stop_import_flag:
return return
@ -113,12 +113,13 @@ class SongBeamerImport(SongImport):
self.currentVerse = '' self.currentVerse = ''
self.currentVerseType = VerseType.tags[VerseType.Verse] self.currentVerseType = VerseType.tags[VerseType.Verse]
read_verses = False read_verses = False
file_name = os.path.split(file)[1] file_name = os.path.split(import_file)[1]
if os.path.isfile(file): if os.path.isfile(import_file):
detect_file = open(file, 'r') # First open in binary mode to detect the encoding
detect_file = open(import_file, 'rb')
details = chardet.detect(detect_file.read()) details = chardet.detect(detect_file.read())
detect_file.close() detect_file.close()
infile = codecs.open(file, 'r', details['encoding']) infile = codecs.open(import_file, 'r', details['encoding'])
song_data = infile.readlines() song_data = infile.readlines()
infile.close() infile.close()
else: else:
@ -149,7 +150,7 @@ class SongBeamerImport(SongImport):
self.replaceHtmlTags() self.replaceHtmlTags()
self.addVerse(self.currentVerse, self.currentVerseType) self.addVerse(self.currentVerse, self.currentVerseType)
if not self.finish(): if not self.finish():
self.logError(file) self.logError(import_file)
def replaceHtmlTags(self): def replaceHtmlTags(self):
""" """

View File

@ -0,0 +1,155 @@
# -*- 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 #
###############################################################################
"""
This module contains tests for the Songbeamer song importer.
"""
import os
from unittest import TestCase
from tests.functional import MagicMock, patch
from openlp.plugins.songs.lib.songbeamerimport import SongBeamerImport
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__),
'..', '..', '..', 'resources', 'songbeamersongs'))
SONG_TEST_DATA = {'Lobsinget dem Herrn.sng':
{'title': 'GL 1 - Lobsinget dem Herrn',
'verses':
[('1. Lobsinget dem Herrn,\no preiset Ihn gern!\n'
'Anbetung und Lob Ihm gebühret.\n', 'v'),
('2. Lobsingt Seiner Lieb´,\ndie einzig ihn trieb,\n'
'zu sterben für unsere Sünden!\n', 'v'),
('3. Lobsingt Seiner Macht!\nSein Werk ist vollbracht:\n'
'Er sitzet zur Rechten des Vaters.\n', 'v'),
('4. Lobsingt seiner Treu´,\ndie immerdar neu,\n'
'bis Er uns zur Herrlichket führet!\n\n', 'v')],
'song_book_name': 'Glaubenslieder I',
'song_number': "1"}
}
class TestSongBeamerImport(TestCase):
"""
Test the functions in the :mod:`songbeamerimport` module.
"""
def create_importer_test(self):
"""
Test creating an instance of the SongBeamer file importer
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.songbeamerimport.SongImport'):
mocked_manager = MagicMock()
# WHEN: An importer object is created
importer = SongBeamerImport(mocked_manager)
# THEN: The importer object should not be None
self.assertIsNotNone(importer, 'Import should not be none')
def invalid_import_source_test(self):
"""
Test SongBeamerImport.doImport handles different invalid import_source values
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.songbeamerimport.SongImport'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = SongBeamerImport(mocked_manager)
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = True
# WHEN: Import source is not a list
for source in ['not a list', 0]:
importer.import_source = source
# 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')
def valid_import_source_test(self):
"""
Test SongBeamerImport.doImport handles different invalid import_source values
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.songbeamerimport.SongImport'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = SongBeamerImport(mocked_manager)
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = True
# WHEN: Import source is a list
importer.import_source = ['List', 'of', 'files']
# THEN: doImport should return none and the progress bar setMaximum should be called with the length of
# import_source.
self.assertIsNone(importer.doImport(),
'doImport should return None when import_source is a list and stop_import_flag is True')
mocked_import_wizard.progress_bar.setMaximum.assert_called_with(len(importer.import_source))
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.songbeamerimport.SongImport'):
for song_file in SONG_TEST_DATA:
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
mocked_add_verse = MagicMock()
mocked_finish = MagicMock()
mocked_finish.return_value = True
importer = SongBeamerImport(mocked_manager)
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = False
importer.addVerse = mocked_add_verse
importer.finish = mocked_finish
# WHEN: Importing each file
importer.import_source = [os.path.join(TEST_PATH, song_file)]
title = SONG_TEST_DATA[song_file]['title']
add_verse_calls = SONG_TEST_DATA[song_file]['verses']
song_book_name = SONG_TEST_DATA[song_file]['song_book_name']
song_number = SONG_TEST_DATA[song_file]['song_number']
# 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 verse_text, verse_tag in add_verse_calls:
mocked_add_verse.assert_any_call(verse_text, verse_tag)
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))
mocked_finish.assert_called_with()

View File

@ -33,51 +33,25 @@ This module contains tests for the SongShow Plus song importer.
import os import os
from unittest import TestCase from unittest import TestCase
from tests.helpers.songfileimport import SongImportTestHelper
from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.songshowplusimport import SongShowPlusImport from openlp.plugins.songs.lib.songshowplusimport import SongShowPlusImport
from tests.functional import patch, MagicMock from tests.functional import patch, MagicMock
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../resources/songshowplussongs')) TEST_PATH = os.path.abspath(
SONG_TEST_DATA = {'Amazing Grace.sbsong': os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'songshowplussongs'))
{'title': 'Amazing Grace (Demonstration)',
'authors': ['John Newton', 'Edwin Excell', 'John P. Rees'], class TestSongShowPlusFileImport(SongImportTestHelper):
'copyright': 'Public Domain ', def __init__(self, *args, **kwargs):
'ccli_number': 22025, self.importer_class_name = 'SongShowPlusImport'
'verses': self.importer_module_name = 'songshowplusimport'
[('Amazing grace! How sweet the sound!\r\nThat saved a wretch like me!\r\n' super(TestSongShowPlusFileImport, self).__init__(*args, **kwargs)
'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' def test_song_import(self):
'How precious did that grace appear,\r\nThe hour I first believed.', 'v2'), test_import = self.file_import(os.path.join(TEST_PATH, 'Amazing Grace.sbsong'),
('The Lord has promised good to me,\r\nHis Word my hope secures.\r\n' self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json')))
'He will my shield and portion be\r\nAs long as life endures.', 'v3'), test_import = self.file_import(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.sbsong'),
('Thro\' many dangers, toils and snares\r\nI have already come.\r\n' self.load_external_result_data(os.path.join(TEST_PATH, 'Beautiful Garden Of Prayer.json')))
'\'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': []}}
class TestSongShowPlusImport(TestCase): class TestSongShowPlusImport(TestCase):
@ -117,7 +91,7 @@ class TestSongShowPlusImport(TestCase):
# THEN: doImport should return none and the progress bar maximum should not be set. # 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.assertIsNone(importer.doImport(), 'doImport should return None when import_source is not a list')
self.assertEquals(mocked_import_wizard.progress_bar.setMaximum.called, False, 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): def valid_import_source_test(self):
""" """
@ -194,70 +168,3 @@ class TestSongShowPlusImport(TestCase):
self.assertEquals(importer.to_openlp_verse_tag(original_tag, ignore_unique=True), openlp_tag, 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"' 'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"'
% (openlp_tag, original_tag)) % (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()

View File

@ -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 ''

View File

@ -0,0 +1,25 @@
#LangCount=1
#Title=GL 1 - Lobsinget dem Herrn
#Editor=SongBeamer 4.20
#Version=3
#Format=F/K//
#TitleFormat=U
#ChurchSongID=0001
#Songbook=Glaubenslieder I / 1
---
1. Lobsinget dem Herrn,
o preiset Ihn gern!
Anbetung und Lob Ihm gebühret.
---
2. Lobsingt Seiner Lieb´,
die einzig ihn trieb,
zu sterben für unsere Sünden!
---
3. Lobsingt Seiner Macht!
Sein Werk ist vollbracht:
Er sitzet zur Rechten des Vaters.
---
4. Lobsingt seiner Treu´,
die immerdar neu,
bis Er uns zur Herrlichket führet!

View File

@ -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"
]
]
}

View File

@ -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"
]
]
}