Merge lp:~phill-ridout/openlp/bug1125956 into lp:openlp

Proposed by Phill
Status: Superseded
Proposed branch: lp:~phill-ridout/openlp/bug1125956
Merge into: lp:openlp
Diff against target: 426 lines (+272/-36)
4 files modified
openlp/plugins/songs/lib/__init__.py (+1/-0)
openlp/plugins/songs/lib/songimport.py (+4/-1)
openlp/plugins/songs/lib/songshowplusimport.py (+33/-35)
tests/functional/openlp_plugins/songs/test_songshowplusimport.py (+234/-0)
To merge this branch: bzr merge lp:~phill-ridout/openlp/bug1125956
Reviewer Review Type Date Requested Status
Andreas Preikschat (community) Needs Fixing
Raoul Snyman Pending
Review via email: mp+156294@code.launchpad.net

This proposal supersedes a proposal from 2013-03-31.

This proposal has been superseded by a proposal from 2013-04-04.

Description of the change

Fixed importing of songs with verses numbered 1A, or 1.5 etc. in SongShowPlus importer
Added Tests for SongShow Plus importer
Moved the song files as requested

Changed regex string type to raw

To post a comment you must log in.
Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

427 === added file 'tests/resources/Amazing Grace.sbsong'
429 === added file 'tests/resources/Beautiful Garden Of Prayer.sbsong'

Please move them in a dir SongShowPlusSongs or something like that

review: Needs Fixing
Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote : Posted in a previous version of this proposal

152 + match = re.match(u'(\D*)(\d+)', verse_name)

For regular expression you use r'' instead of u''

20 - self.verseOrderListGenerated.append(verse_def)
21 + if verse_def not in self.verseOrderListGenerated:
22 + self.verseOrderListGenerated.append(verse_def)

Why are you changing this? Docs say:
        Add a verse. This is the whole verse, lines split by \\n. It will also
        attempt to detect duplicates. In this case it will just add to the verse
        order.
So we should append the verse_def in any case, shouldn't we?

review: Needs Fixing
Revision history for this message
Phill (phill-ridout) wrote : Posted in a previous version of this proposal

> 20 - self.verseOrderListGenerated.append(verse_def)
> 21 + if verse_def not in self.verseOrderListGenerated:
> 22 + self.verseOrderListGenerated.append(verse_def)
>
> Why are you changing this? Docs say:
> Add a verse. This is the whole verse, lines split by \\n. It will also
> attempt to detect duplicates. In this case it will just add to the
> verse
> order.
> So we should append the verse_def in any case, shouldn't we?

Because OpenLP does not support verse numbering such as V1A and V1B we are dropping the A and B so we have two verses called V1 being added to a song (instead of V1A and V1B)

Each time V1 appears in the verse order both verses called V1 (actually V1A and V1B) were being added to the verse order.

With out this change V1 was being added to the verse order twice (once for each verse called V1), however because of the above statement the actual verse order shown in the live or preview controller repeated both verses.

This is a bit hard to clearly explain. It is probably easier for you to see the result by checking out this branch and importing the song attached to http://support.openlp.org/issues/1897

Import it once with out the change on line 20 and once with the change and you will see the problem.

Revision history for this message
Phill (phill-ridout) wrote :

Ok, this is ready to merge providing you approve it!

Revision history for this message
Andreas Preikschat (googol-deactivatedaccount) wrote :

> Because OpenLP does not support verse numbering such as V1A and V1B we are dropping the A and B so
> we have two verses called V1 being added to a song (instead of V1A and V1B)

Then please add comment for this. Nobody will remember why this "if" was added.

review: Needs Fixing
lp:~phill-ridout/openlp/bug1125956 updated
2192. By Phill

Added comment

2193. By Phill

Removed the use of the mock's call helper object

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openlp/plugins/songs/lib/__init__.py'
--- openlp/plugins/songs/lib/__init__.py 2013-03-11 21:10:29 +0000
+++ openlp/plugins/songs/lib/__init__.py 2013-04-04 16:44:27 +0000
@@ -168,6 +168,7 @@
168 translate('SongsPlugin.VerseType', 'Intro'),168 translate('SongsPlugin.VerseType', 'Intro'),
169 translate('SongsPlugin.VerseType', 'Ending'),169 translate('SongsPlugin.VerseType', 'Ending'),
170 translate('SongsPlugin.VerseType', 'Other')]170 translate('SongsPlugin.VerseType', 'Other')]
171
171 translated_tags = [name[0].lower() for name in translated_names]172 translated_tags = [name[0].lower() for name in translated_names]
172173
173 @staticmethod174 @staticmethod
174175
=== modified file 'openlp/plugins/songs/lib/songimport.py'
--- openlp/plugins/songs/lib/songimport.py 2013-03-07 08:05:43 +0000
+++ openlp/plugins/songs/lib/songimport.py 2013-04-04 16:44:27 +0000
@@ -260,7 +260,10 @@
260 elif int(verse_def[1:]) > self.verseCounts[verse_def[0]]:260 elif int(verse_def[1:]) > self.verseCounts[verse_def[0]]:
261 self.verseCounts[verse_def[0]] = int(verse_def[1:])261 self.verseCounts[verse_def[0]] = int(verse_def[1:])
262 self.verses.append([verse_def, verse_text.rstrip(), lang])262 self.verses.append([verse_def, verse_text.rstrip(), lang])
263 self.verseOrderListGenerated.append(verse_def)263 # A verse_def refers to all verses with that name, adding it once adds every instance, so do not add if already
264 # used.
265 if verse_def not in self.verseOrderListGenerated:
266 self.verseOrderListGenerated.append(verse_def)
264267
265 def repeatVerse(self):268 def repeatVerse(self):
266 """269 """
267270
=== modified file 'openlp/plugins/songs/lib/songshowplusimport.py'
--- openlp/plugins/songs/lib/songshowplusimport.py 2013-03-07 08:05:43 +0000
+++ openlp/plugins/songs/lib/songshowplusimport.py 2013-04-04 16:44:27 +0000
@@ -32,6 +32,7 @@
32"""32"""
33import os33import os
34import logging34import logging
35import re
35import struct36import struct
3637
37from openlp.core.ui.wizard import WizardStrings38from openlp.core.ui.wizard import WizardStrings
@@ -44,43 +45,36 @@
44CCLI_NO = 545CCLI_NO = 5
45VERSE = 1246VERSE = 12
46CHORUS = 2047CHORUS = 20
48BRIDGE = 24
47TOPIC = 2949TOPIC = 29
48COMMENTS = 3050COMMENTS = 30
49VERSE_ORDER = 3151VERSE_ORDER = 31
50SONG_BOOK = 3552SONG_BOOK = 35
51SONG_NUMBER = 3653SONG_NUMBER = 36
52CUSTOM_VERSE = 3754CUSTOM_VERSE = 37
53BRIDGE = 24
5455
55log = logging.getLogger(__name__)56log = logging.getLogger(__name__)
5657
57class SongShowPlusImport(SongImport):58class SongShowPlusImport(SongImport):
58 """59 """
59 The :class:`SongShowPlusImport` class provides the ability to import song60 The :class:`SongShowPlusImport` class provides the ability to import song files from SongShow Plus.
60 files from SongShow Plus.
6161
62 **SongShow Plus Song File Format:**62 **SongShow Plus Song File Format:**
6363
64 The SongShow Plus song file format is as follows:64 The SongShow Plus song file format is as follows:
6565
66 * Each piece of data in the song file has some information that precedes66 * Each piece of data in the song file has some information that precedes it.
67 it.
68 * The general format of this data is as follows:67 * The general format of this data is as follows:
69 4 Bytes, forming a 32 bit number, a key if you will, this describes what68 4 Bytes, forming a 32 bit number, a key if you will, this describes what the data is (see blockKey below)
70 the data is (see blockKey below)69 4 Bytes, forming a 32 bit number, which is the number of bytes until the next block starts
71 4 Bytes, forming a 32 bit number, which is the number of bytes until the
72 next block starts
73 1 Byte, which tells how many bytes follows70 1 Byte, which tells how many bytes follows
74 1 or 4 Bytes, describes how long the string is, if its 1 byte, the string71 1 or 4 Bytes, describes how long the string is, if its 1 byte, the string is less than 255
75 is less than 255
76 The next bytes are the actual data.72 The next bytes are the actual data.
77 The next block of data follows on.73 The next block of data follows on.
7874
79 This description does differ for verses. Which includes extra bytes75 This description does differ for verses. Which includes extra bytes stating the verse type or number. In some cases
80 stating the verse type or number. In some cases a "custom" verse is used,76 a "custom" verse is used, in that case, this block will in include 2 strings, with the associated string length
81 in that case, this block will in include 2 strings, with the associated77 descriptors. The first string is the name of the verse, the second is the verse content.
82 string length descriptors. The first string is the name of the verse, the
83 second is the verse content.
8478
85 The file is ended with four null bytes.79 The file is ended with four null bytes.
8680
@@ -88,8 +82,9 @@
8882
89 * .sbsong83 * .sbsong
90 """84 """
91 otherList = {}85
92 otherCount = 086 other_count = 0
87 other_list = {}
9388
94 def __init__(self, manager, **kwargs):89 def __init__(self, manager, **kwargs):
95 """90 """
@@ -107,9 +102,9 @@
107 for file in self.import_source:102 for file in self.import_source:
108 if self.stop_import_flag:103 if self.stop_import_flag:
109 return104 return
110 self.sspVerseOrderList = []105 self.ssp_verse_order_list = []
111 other_count = 0106 self.other_count = 0
112 other_list = {}107 self.other_list = {}
113 file_name = os.path.split(file)[1]108 file_name = os.path.split(file)[1]
114 self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % file_name, 0)109 self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % file_name, 0)
115 song_data = open(file, 'rb')110 song_data = open(file, 'rb')
@@ -162,34 +157,37 @@
162 elif block_key == COMMENTS:157 elif block_key == COMMENTS:
163 self.comments = unicode(data, u'cp1252')158 self.comments = unicode(data, u'cp1252')
164 elif block_key == VERSE_ORDER:159 elif block_key == VERSE_ORDER:
165 verse_tag = self.toOpenLPVerseTag(data, True)160 verse_tag = self.to_openlp_verse_tag(data, True)
166 if verse_tag:161 if verse_tag:
167 if not isinstance(verse_tag, unicode):162 if not isinstance(verse_tag, unicode):
168 verse_tag = unicode(verse_tag, u'cp1252')163 verse_tag = unicode(verse_tag, u'cp1252')
169 self.sspVerseOrderList.append(verse_tag)164 self.ssp_verse_order_list.append(verse_tag)
170 elif block_key == SONG_BOOK:165 elif block_key == SONG_BOOK:
171 self.songBookName = unicode(data, u'cp1252')166 self.songBookName = unicode(data, u'cp1252')
172 elif block_key == SONG_NUMBER:167 elif block_key == SONG_NUMBER:
173 self.songNumber = ord(data)168 self.songNumber = ord(data)
174 elif block_key == CUSTOM_VERSE:169 elif block_key == CUSTOM_VERSE:
175 verse_tag = self.toOpenLPVerseTag(verse_name)170 verse_tag = self.to_openlp_verse_tag(verse_name)
176 self.addVerse(unicode(data, u'cp1252'), verse_tag)171 self.addVerse(unicode(data, u'cp1252'), verse_tag)
177 else:172 else:
178 log.debug("Unrecognised blockKey: %s, data: %s" % (block_key, data))173 log.debug("Unrecognised blockKey: %s, data: %s" % (block_key, data))
179 song_data.seek(next_block_starts)174 song_data.seek(next_block_starts)
180 self.verseOrderList = self.sspVerseOrderList175 self.verseOrderList = self.ssp_verse_order_list
181 song_data.close()176 song_data.close()
182 if not self.finish():177 if not self.finish():
183 self.logError(file)178 self.logError(file)
184179
185 def toOpenLPVerseTag(self, verse_name, ignore_unique=False):180 def to_openlp_verse_tag(self, verse_name, ignore_unique=False):
186 if verse_name.find(" ") != -1:181 # Have we got any digits? If so, verse number is everything from the digits to the end (OpenLP does not have
187 verse_parts = verse_name.split(" ")182 # concept of part verses, so just ignore any non integers on the end (including floats))
188 verse_type = verse_parts[0]183 match = re.match(r'(\D*)(\d+)', verse_name)
189 verse_number = verse_parts[1]184 if match:
185 verse_type = match.group(1).strip()
186 verse_number = match.group(2)
190 else:187 else:
188 # otherwise we assume number 1 and take the whole prefix as the verse tag
191 verse_type = verse_name189 verse_type = verse_name
192 verse_number = "1"190 verse_number = u'1'
193 verse_type = verse_type.lower()191 verse_type = verse_type.lower()
194 if verse_type == "verse":192 if verse_type == "verse":
195 verse_tag = VerseType.tags[VerseType.Verse]193 verse_tag = VerseType.tags[VerseType.Verse]
@@ -200,11 +198,11 @@
200 elif verse_type == "pre-chorus":198 elif verse_type == "pre-chorus":
201 verse_tag = VerseType.tags[VerseType.PreChorus]199 verse_tag = VerseType.tags[VerseType.PreChorus]
202 else:200 else:
203 if verse_name not in self.otherList:201 if verse_name not in self.other_list:
204 if ignore_unique:202 if ignore_unique:
205 return None203 return None
206 self.otherCount += 1204 self.other_count += 1
207 self.otherList[verse_name] = str(self.otherCount)205 self.other_list[verse_name] = str(self.other_count)
208 verse_tag = VerseType.tags[VerseType.Other]206 verse_tag = VerseType.tags[VerseType.Other]
209 verse_number = self.otherList[verse_name]207 verse_number = self.other_list[verse_name]
210 return verse_tag + verse_number208 return verse_tag + verse_number
211209
=== added file 'tests/functional/openlp_plugins/songs/test_songshowplusimport.py'
--- tests/functional/openlp_plugins/songs/test_songshowplusimport.py 1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_plugins/songs/test_songshowplusimport.py 2013-04-04 16:44:27 +0000
@@ -0,0 +1,234 @@
1"""
2This module contains tests for the SongShow Plus song importer.
3"""
4
5import os
6from unittest import TestCase
7from mock import call, patch, MagicMock
8
9from openlp.plugins.songs.lib import VerseType
10from openlp.plugins.songs.lib.songshowplusimport import SongShowPlusImport
11
12TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'../../../resources/songshowplussongs'))
13SONG_TEST_DATA = {u'Amazing Grace.sbsong':
14 {u'title': u'Amazing Grace (Demonstration)',
15 u'authors': [u'John Newton', u'Edwin Excell', u'John P. Rees'],
16 u'copyright': u'Public Domain ',
17 u'ccli_number': 22025,
18 u'verses':
19 [(u'Amazing grace! How sweet the sound!\r\nThat saved a wretch like me!\r\n'
20 u'I once was lost, but now am found;\r\nWas blind, but now I see.', u'v1'),
21 (u'\'Twas grace that taught my heart to fear,\r\nAnd grace my fears relieved.\r\n'
22 u'How precious did that grace appear,\r\nThe hour I first believed.', u'v2'),
23 (u'The Lord has promised good to me,\r\nHis Word my hope secures.\r\n'
24 u'He will my shield and portion be\r\nAs long as life endures.', u'v3'),
25 (u'Thro\' many dangers, toils and snares\r\nI have already come.\r\n'
26 u'\'Tis grace that brought me safe thus far,\r\nAnd grace will lead me home.', u'v4'),
27 (u'When we\'ve been there ten thousand years,\r\nBright shining as the sun,\r\n'
28 u'We\'ve no less days to sing God\'s praise,\r\nThan when we first begun.', u'v5')],
29 u'topics': [u'Assurance', u'Grace', u'Praise', u'Salvation'],
30 u'comments': u'\n\n\n',
31 u'song_book_name': u'Demonstration Songs',
32 u'song_number': 0,
33 u'verse_order_list': []},
34 u'Beautiful Garden Of Prayer.sbsong':
35 {u'title': u'Beautiful Garden Of Prayer (Demonstration)',
36 u'authors': [u'Eleanor Allen Schroll', u'James H. Fillmore'],
37 u'copyright': u'Public Domain ',
38 u'ccli_number': 60252,
39 u'verses':
40 [(u'There\'s a garden where Jesus is waiting,\r\nThere\'s a place that is wondrously fair.\r\n'
41 u'For it glows with the light of His presence,\r\n\'Tis the beautiful garden of prayer.', u'v1'),
42 (u'There\'s a garden where Jesus is waiting,\r\nAnd I go with my burden and care.\r\n'
43 u'Just to learn from His lips, words of comfort,\r\nIn the beautiful garden of prayer.', u'v2'),
44 (u'There\'s a garden where Jesus is waiting,\r\nAnd He bids you to come meet Him there,\r\n'
45 u'Just to bow and receive a new blessing,\r\nIn the beautiful garden of prayer.', u'v3'),
46 (u'O the beautiful garden, the garden of prayer,\r\nO the beautiful garden of prayer.\r\n'
47 u'There my Savior awaits, and He opens the gates\r\nTo the beautiful garden of prayer.', u'c1')],
48 u'topics': [u'Devotion', u'Prayer'],
49 u'comments': u'',
50 u'song_book_name': u'',
51 u'song_number': 0,
52 u'verse_order_list': []}}
53
54
55class TestSongShowPlusImport(TestCase):
56 """
57 Test the functions in the :mod:`songshowplusimport` module.
58 """
59 def create_importer_test(self):
60 """
61 Test creating an instance of the SongShow Plus file importer
62 """
63 # GIVEN: A mocked out SongImport class, and a mocked out "manager"
64 with patch(u'openlp.plugins.songs.lib.songshowplusimport.SongImport'):
65 mocked_manager = MagicMock()
66
67 # WHEN: An importer object is created
68 importer = SongShowPlusImport(mocked_manager)
69
70 # THEN: The importer object should not be None
71 self.assertIsNotNone(importer, u'Import should not be none')
72
73 def invalid_import_source_test(self):
74 """
75 Test SongShowPlusImport.doImport handles different invalid import_source values
76 """
77 # GIVEN: A mocked out SongImport class, and a mocked out "manager"
78 with patch(u'openlp.plugins.songs.lib.songshowplusimport.SongImport'):
79 mocked_manager = MagicMock()
80 mocked_import_wizard = MagicMock()
81 importer = SongShowPlusImport(mocked_manager)
82 importer.import_wizard = mocked_import_wizard
83 importer.stop_import_flag = True
84
85 # WHEN: Import source is not a list
86 for source in [u'not a list', 0]:
87 importer.import_source = source
88
89 # THEN: doImport should return none and the progress bar maximum should not be set.
90 self.assertIsNone(importer.doImport(), u'doImport should return None when import_source is not a list')
91 self.assertEquals(mocked_import_wizard.progress_bar.setMaximum.called, False,
92 u'setMaxium on import_wizard.progress_bar should not have been called')
93
94 def valid_import_source_test(self):
95 """
96 Test SongShowPlusImport.doImport handles different invalid import_source values
97 """
98 # GIVEN: A mocked out SongImport class, and a mocked out "manager"
99 with patch(u'openlp.plugins.songs.lib.songshowplusimport.SongImport'):
100 mocked_manager = MagicMock()
101 mocked_import_wizard = MagicMock()
102 importer = SongShowPlusImport(mocked_manager)
103 importer.import_wizard = mocked_import_wizard
104 importer.stop_import_flag = True
105
106 # WHEN: Import source is a list
107 importer.import_source = [u'List', u'of', u'files']
108
109 # THEN: doImport should return none and the progress bar setMaximum should be called with the length of
110 # import_source.
111 self.assertIsNone(importer.doImport(),
112 u'doImport should return None when import_source is a list and stop_import_flag is True')
113 mocked_import_wizard.progress_bar.setMaximum.assert_called_with(len(importer.import_source))
114
115 def to_openlp_verse_tag_test(self):
116 """
117 Test to_openlp_verse_tag method by simulating adding a verse
118 """
119 # GIVEN: A mocked out SongImport class, and a mocked out "manager"
120 with patch(u'openlp.plugins.songs.lib.songshowplusimport.SongImport'):
121 mocked_manager = MagicMock()
122 importer = SongShowPlusImport(mocked_manager)
123
124 # WHEN: Supplied with the following arguments replicating verses being added
125 test_values = [(u'Verse 1', VerseType.tags[VerseType.Verse] + u'1'),
126 (u'Verse 2', VerseType.tags[VerseType.Verse] + u'2'),
127 (u'verse1', VerseType.tags[VerseType.Verse] + u'1'),
128 (u'Verse', VerseType.tags[VerseType.Verse] + u'1'),
129 (u'Verse1', VerseType.tags[VerseType.Verse] + u'1'),
130 (u'chorus 1', VerseType.tags[VerseType.Chorus] + u'1'),
131 (u'bridge 1', VerseType.tags[VerseType.Bridge] + u'1'),
132 (u'pre-chorus 1', VerseType.tags[VerseType.PreChorus] + u'1'),
133 (u'different 1', VerseType.tags[VerseType.Other] + u'1'),
134 (u'random 1', VerseType.tags[VerseType.Other] + u'2')]
135
136 # THEN: The returned value should should correlate with the input arguments
137 for original_tag, openlp_tag in test_values:
138 self.assertEquals(importer.to_openlp_verse_tag(original_tag), openlp_tag,
139 u'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"'
140 % (openlp_tag, original_tag))
141
142 def to_openlp_verse_tag_verse_order_test(self):
143 """
144 Test to_openlp_verse_tag method by simulating adding a verse to the verse order
145 """
146 # GIVEN: A mocked out SongImport class, and a mocked out "manager"
147 with patch(u'openlp.plugins.songs.lib.songshowplusimport.SongImport'):
148 mocked_manager = MagicMock()
149 importer = SongShowPlusImport(mocked_manager)
150
151 # WHEN: Supplied with the following arguments replicating a verse order being added
152 test_values = [(u'Verse 1', VerseType.tags[VerseType.Verse] + u'1'),
153 (u'Verse 2', VerseType.tags[VerseType.Verse] + u'2'),
154 (u'verse1', VerseType.tags[VerseType.Verse] + u'1'),
155 (u'Verse', VerseType.tags[VerseType.Verse] + u'1'),
156 (u'Verse1', VerseType.tags[VerseType.Verse] + u'1'),
157 (u'chorus 1', VerseType.tags[VerseType.Chorus] + u'1'),
158 (u'bridge 1', VerseType.tags[VerseType.Bridge] + u'1'),
159 (u'pre-chorus 1', VerseType.tags[VerseType.PreChorus] + u'1'),
160 (u'different 1', VerseType.tags[VerseType.Other] + u'1'),
161 (u'random 1', VerseType.tags[VerseType.Other] + u'2'),
162 (u'unused 2', None)]
163
164 # THEN: The returned value should should correlate with the input arguments
165 for original_tag, openlp_tag in test_values:
166 self.assertEquals(importer.to_openlp_verse_tag(original_tag, ignore_unique=True), openlp_tag,
167 u'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"'
168 % (openlp_tag, original_tag))
169
170 def file_import_test(self):
171 """
172 Test the actual import of real song files and check that the imported data is correct.
173 """
174
175 # GIVEN: Test files with a mocked out SongImport class, a mocked out "manager", a mocked out "import_wizard",
176 # and mocked out "author", "add_copyright", "add_verse", "finish" methods.
177 with patch(u'openlp.plugins.songs.lib.songshowplusimport.SongImport'):
178 for song_file in SONG_TEST_DATA:
179 mocked_manager = MagicMock()
180 mocked_import_wizard = MagicMock()
181 mocked_parse_author = MagicMock()
182 mocked_add_copyright = MagicMock()
183 mocked_add_verse = MagicMock()
184 mocked_finish = MagicMock()
185 mocked_finish.return_value = True
186 importer = SongShowPlusImport(mocked_manager)
187 importer.import_wizard = mocked_import_wizard
188 importer.stop_import_flag = False
189 importer.parse_author = mocked_parse_author
190 importer.addCopyright = mocked_add_copyright
191 importer.addVerse = mocked_add_verse
192 importer.finish = mocked_finish
193 importer.topics = []
194
195 # WHEN: Importing each file
196 importer.import_source = [os.path.join(TEST_PATH, song_file)]
197 title = SONG_TEST_DATA[song_file][u'title']
198 parse_author_calls = [call(author) for author in SONG_TEST_DATA[song_file][u'authors']]
199 song_copyright = SONG_TEST_DATA[song_file][u'copyright']
200 ccli_number = SONG_TEST_DATA[song_file][u'ccli_number']
201 add_verse_calls = \
202 [call(verse_text, verse_tag) for verse_text, verse_tag in SONG_TEST_DATA[song_file][u'verses']]
203 topics = SONG_TEST_DATA[song_file][u'topics']
204 comments = SONG_TEST_DATA[song_file][u'comments']
205 song_book_name = SONG_TEST_DATA[song_file][u'song_book_name']
206 song_number = SONG_TEST_DATA[song_file][u'song_number']
207 verse_order_list = SONG_TEST_DATA[song_file][u'verse_order_list']
208
209 # THEN: doImport should return none, the song data should be as expected, and finish should have been
210 # called.
211 self.assertIsNone(importer.doImport(), u'doImport should return None when it has completed')
212 self.assertEquals(importer.title, title, u'title for %s should be "%s"' % (song_file, title))
213 mocked_parse_author.assert_has_calls(parse_author_calls)
214 if song_copyright:
215 mocked_add_copyright.assert_called_with(song_copyright)
216 if ccli_number:
217 self.assertEquals(importer.ccliNumber, ccli_number, u'ccliNumber for %s should be %s'
218 % (song_file, ccli_number))
219 mocked_add_verse.assert_has_calls(add_verse_calls)
220 if topics:
221 self.assertEquals(importer.topics, topics, u'topics for %s should be %s' % (song_file, topics))
222 if comments:
223 self.assertEquals(importer.comments, comments, u'comments for %s should be "%s"'
224 % (song_file, comments))
225 if song_book_name:
226 self.assertEquals(importer.songBookName, song_book_name, u'songBookName for %s should be "%s"'
227 % (song_file, song_book_name))
228 if song_number:
229 self.assertEquals(importer.songNumber, song_number, u'songNumber for %s should be %s'
230 % (song_file, song_number))
231 if verse_order_list:
232 self.assertEquals(importer.verseOrderList, [], u'verseOrderList for %s should be %s'
233 % (song_file, verse_order_list))
234 mocked_finish.assert_called_with()
0235
=== added directory 'tests/resources/songshowplussongs'
=== added file 'tests/resources/songshowplussongs/Amazing Grace.sbsong'
1Binary files tests/resources/songshowplussongs/Amazing Grace.sbsong 1970-01-01 00:00:00 +0000 and tests/resources/songshowplussongs/Amazing Grace.sbsong 2013-04-04 16:44:27 +0000 differ236Binary files tests/resources/songshowplussongs/Amazing Grace.sbsong 1970-01-01 00:00:00 +0000 and tests/resources/songshowplussongs/Amazing Grace.sbsong 2013-04-04 16:44:27 +0000 differ
=== added file 'tests/resources/songshowplussongs/Beautiful Garden Of Prayer.sbsong'
2Binary files tests/resources/songshowplussongs/Beautiful Garden Of Prayer.sbsong 1970-01-01 00:00:00 +0000 and tests/resources/songshowplussongs/Beautiful Garden Of Prayer.sbsong 2013-04-04 16:44:27 +0000 differ237Binary files tests/resources/songshowplussongs/Beautiful Garden Of Prayer.sbsong 1970-01-01 00:00:00 +0000 and tests/resources/songshowplussongs/Beautiful Garden Of Prayer.sbsong 2013-04-04 16:44:27 +0000 differ