Fix all the tests

This commit is contained in:
Raoul Snyman 2018-11-30 22:52:49 -07:00
parent 56f76b1179
commit e58e0ee485
18 changed files with 127 additions and 177 deletions

View File

@ -1 +1 @@
2.9.0 2.5.dev2856

View File

@ -201,11 +201,11 @@ class ServiceItem(RegistryProperties):
self._create_slides() self._create_slides()
return self._display_slides return self._display_slides
def add_from_image(self, filename, title, background=None, thumbnail=None): def add_from_image(self, path, title, background=None, thumbnail=None):
""" """
Add an image slide to the service item. Add an image slide to the service item.
:param filename: The directory in which the image file is located. :param path: The directory in which the image file is located.
:param title: A title for the slide in the service item. :param title: A title for the slide in the service item.
:param background: The background colour :param background: The background colour
:param thumbnail: Optional alternative thumbnail, used for remote thumbnails. :param thumbnail: Optional alternative thumbnail, used for remote thumbnails.
@ -213,7 +213,7 @@ class ServiceItem(RegistryProperties):
if background: if background:
self.image_border = background self.image_border = background
self.service_item_type = ServiceItemType.Image self.service_item_type = ServiceItemType.Image
slide = {'title': title, 'filename': filename} slide = {'title': title, 'path': path}
if thumbnail: if thumbnail:
slide['thumbnail'] = thumbnail slide['thumbnail'] = thumbnail
self.slides.append(slide) self.slides.append(slide)
@ -385,7 +385,7 @@ class ServiceItem(RegistryProperties):
self.add_from_command(path, text_image['title'], text_image['image'], self.add_from_command(path, text_image['title'], text_image['image'],
text_image.get('display_title', ''), text_image.get('notes', '')) text_image.get('display_title', ''), text_image.get('notes', ''))
else: else:
self.add_from_command(text_image['path'], text_image['title'], text_image['image']) self.add_from_command(Path(text_image['path']), text_image['title'], text_image['image'])
self._new_item() self._new_item()
def get_display_title(self): def get_display_title(self):
@ -522,7 +522,7 @@ class ServiceItem(RegistryProperties):
except IndexError: except IndexError:
return '' return ''
if self.is_image() or self.is_capable(ItemCapabilities.IsOptical): if self.is_image() or self.is_capable(ItemCapabilities.IsOptical):
path_from = frame['filename'] path_from = frame['path']
else: else:
path_from = os.path.join(frame['path'], frame['title']) path_from = os.path.join(frame['path'], frame['title'])
return path_from return path_from
@ -589,7 +589,7 @@ class ServiceItem(RegistryProperties):
""" """
self.is_valid = True self.is_valid = True
for slide in self.slides: for slide in self.slides:
if self.is_image() and not os.path.exists(slide['filename']): if self.is_image() and not os.path.exists(slide['path']):
self.is_valid = False self.is_valid = False
break break
elif self.is_command(): elif self.is_command():

View File

@ -26,36 +26,8 @@ import logging
import os import os
import platform import platform
import re import re
import bs4
import sqlalchemy
from PyQt5 import Qt, QtCore, QtGui, QtWidgets
from lxml import etree
try: from PyQt5 import QtCore, QtGui, QtWidgets
import migrate
MIGRATE_VERSION = getattr(migrate, '__version__', '< 0.7')
except ImportError:
MIGRATE_VERSION = '-'
try:
import chardet
CHARDET_VERSION = chardet.__version__
except ImportError:
CHARDET_VERSION = '-'
try:
import enchant
ENCHANT_VERSION = enchant.__version__
except ImportError:
ENCHANT_VERSION = '-'
try:
import mako
MAKO_VERSION = mako.__version__
except ImportError:
MAKO_VERSION = '-'
try:
from openlp.core.ui.media.vlcplayer import VERSION
VLC_VERSION = VERSION
except ImportError:
VLC_VERSION = '-'
from openlp.core.common import is_linux from openlp.core.common import is_linux
from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.i18n import UiStrings, translate
@ -104,15 +76,9 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
description = self.description_text_edit.toPlainText() description = self.description_text_edit.toPlainText()
traceback = self.exception_text_edit.toPlainText() traceback = self.exception_text_edit.toPlainText()
system = translate('OpenLP.ExceptionForm', 'Platform: {platform}\n').format(platform=platform.platform()) system = translate('OpenLP.ExceptionForm', 'Platform: {platform}\n').format(platform=platform.platform())
libraries = ('Python: {python}\nQt5: {qt5}\nPyQt5: {pyqt5}\nSQLAlchemy: {sqalchemy}\n' library_versions = get_library_versions()
'SQLAlchemy Migrate: {migrate}\nBeautifulSoup: {soup}\nlxml: {etree}\nChardet: {chardet}\n' library_versions['PyUNO'] = self._get_pyuno_version()
'PyEnchant: {enchant}\nMako: {mako}\npyUNO bridge: {uno}\n' libraries = '\n'.join(['{}: {}'.format(library, version) for library, version in library_versions.items()])
'VLC: {vlc}\n').format(python=platform.python_version(), qt5=Qt.qVersion(),
pyqt5=Qt.PYQT_VERSION_STR,
sqalchemy=sqlalchemy.__version__, migrate=MIGRATE_VERSION,
soup=bs4.__version__, etree=etree.__version__, chardet=CHARDET_VERSION,
enchant=ENCHANT_VERSION, mako=MAKO_VERSION,
uno=self._pyuno_import(), vlc=VLC_VERSION)
if is_linux(): if is_linux():
if os.environ.get('KDE_FULL_SESSION') == 'true': if os.environ.get('KDE_FULL_SESSION') == 'true':

View File

@ -1259,9 +1259,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
""" """
The theme may have changed in the settings dialog so make sure the theme combo box is in the correct state. The theme may have changed in the settings dialog so make sure the theme combo box is in the correct state.
""" """
# TODO: Gotta fix this too visible = self.renderer.theme_level != ThemeLevel.Global
# visible = self.renderer.theme_level != ThemeLevel.Global
visible = True
self.toolbar.actions['theme_combo_box'].setVisible(visible) self.toolbar.actions['theme_combo_box'].setVisible(visible)
self.toolbar.actions['theme_label'].setVisible(visible) self.toolbar.actions['theme_label'].setVisible(visible)
self.regenerate_service_items() self.regenerate_service_items()

View File

@ -745,9 +745,9 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
:param item: The current service item :param item: The current service item
""" """
slide_no = 0 slide_no = 0
# if self.song_edit: if self.song_edit:
# slide_no = self.selected_row slide_no = self.selected_row
# self.song_edit = False self.song_edit = False
self._process_item(item, slide_no) self._process_item(item, slide_no)
def replace_service_manager_item(self, item): def replace_service_manager_item(self, item):

View File

@ -205,7 +205,7 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
else: else:
pixmap = QtGui.QPixmap(remove_url_prefix(slide['image'])) pixmap = QtGui.QPixmap(remove_url_prefix(slide['image']))
else: else:
pixmap = QtGui.QPixmap(remove_url_prefix(slide['filename'])) pixmap = QtGui.QPixmap(remove_url_prefix(slide['path']))
label.setPixmap(pixmap) label.setPixmap(pixmap)
container = QtWidgets.QWidget() container = QtWidgets.QWidget()
layout = AspectRatioLayout(container, self.screen_ratio) layout = AspectRatioLayout(container, self.screen_ratio)

View File

@ -36,7 +36,7 @@ from tests.utils import convert_file_service_item
from tests.utils.constants import RESOURCE_PATH from tests.utils.constants import RESOURCE_PATH
TEST_PATH = str(RESOURCE_PATH / 'service') TEST_PATH = RESOURCE_PATH / 'service'
SCREEN = { SCREEN = {
'primary': False, 'primary': False,

View File

@ -44,12 +44,10 @@ VERSE = 'The Lord said to {r}Noah{/r}: \n'\
'Get those children out of the muddy, muddy \n'\ 'Get those children out of the muddy, muddy \n'\
'{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}'\ '{r}C{/r}{b}h{/b}{bl}i{/bl}{y}l{/y}{g}d{/g}{pk}'\
'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n' 'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
CLEANED_VERSE = 'The Lord said to Noah: \n'\ CLEANED_VERSE = 'Amazing Grace! how sweet the sound\n'\
'There\'s gonna be a floody, floody\n'\ 'That saved a wretch like me;\n'\
'The Lord said to Noah:\n'\ 'I once was lost, but now am found,\n'\
'There\'s gonna be a floody, floody\n'\ 'Was blind, but now I see.\n'
'Get those children out of the muddy, muddy \n'\
'Children of the Lord\n'
RENDERED_VERSE = 'The Lord said to <span style="-webkit-text-fill-color:red">Noah</span>: \n'\ RENDERED_VERSE = 'The Lord said to <span style="-webkit-text-fill-color:red">Noah</span>: \n'\
'There&#x27;s gonna be a <sup>floody</sup>, <sub>floody</sub>\n'\ 'There&#x27;s gonna be a <sup>floody</sup>, <sub>floody</sub>\n'\
'The Lord said to <span style="-webkit-text-fill-color:green">Noah</span>:\n'\ 'The Lord said to <span style="-webkit-text-fill-color:green">Noah</span>:\n'\
@ -62,7 +60,7 @@ RENDERED_VERSE = 'The Lord said to <span style="-webkit-text-fill-color:red">Noa
'<span style="-webkit-text-fill-color:#FFA500">e</span><span style="-webkit-text-fill-color:#800080">'\ '<span style="-webkit-text-fill-color:#FFA500">e</span><span style="-webkit-text-fill-color:#800080">'\
'n</span> of the Lord\n' 'n</span> of the Lord\n'
FOOTER = ['Arky Arky (Unknown)', 'Public Domain', 'CCLI 123456'] FOOTER = ['Arky Arky (Unknown)', 'Public Domain', 'CCLI 123456']
TEST_PATH = str(RESOURCE_PATH / 'service') TEST_PATH = RESOURCE_PATH / 'service'
__default_settings__ = { __default_settings__ = {
'songs/enable chords': True, 'songs/enable chords': True,
@ -134,7 +132,7 @@ class TestServiceItem(TestCase, TestMixin):
""" """
# GIVEN: A new service item and a mocked add icon function # GIVEN: A new service item and a mocked add icon function
image_name = 'image_1.jpg' image_name = 'image_1.jpg'
test_file = os.path.join(TEST_PATH, image_name) test_file = os.path.join(str(TEST_PATH), image_name)
frame_array = {'path': test_file, 'title': image_name} frame_array = {'path': test_file, 'title': image_name}
service_item = ServiceItem(None) service_item = ServiceItem(None)
@ -146,13 +144,12 @@ class TestServiceItem(TestCase, TestMixin):
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as \ patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as \
mocked_get_section_data_path: mocked_get_section_data_path:
mocked_exists.return_value = True mocked_exists.return_value = True
mocked_get_section_data_path.return_value = os.path.normpath('/path/') mocked_get_section_data_path.return_value = Path('/path/')
service_item.set_from_service(line, TEST_PATH) service_item.set_from_service(line, str(TEST_PATH))
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
assert service_item.is_valid is True, 'The new service item should be valid' assert service_item.is_valid is True, 'The new service item should be valid'
assert os.path.normpath(test_file) == os.path.normpath(service_item.get_rendered_frame(0)), \ assert test_file == service_item.get_rendered_frame(0), 'The first frame should match the path to the image'
'The first frame should match the path to the image'
assert frame_array == service_item.get_frames()[0], 'The return should match frame array1' assert frame_array == service_item.get_frames()[0], 'The return should match frame array1'
assert test_file == service_item.get_frame_path(0), 'The frame path should match the full path to the image' assert test_file == service_item.get_frame_path(0), 'The frame path should match the full path to the image'
assert image_name == service_item.get_frame_title(0), 'The frame title should match the image name' assert image_name == service_item.get_frame_title(0), 'The frame title should match the image name'
@ -167,54 +164,41 @@ class TestServiceItem(TestCase, TestMixin):
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \ assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
'This service item should be able to have new items added to it' 'This service item should be able to have new items added to it'
def test_service_item_load_image_from_local_service(self): @patch('openlp.core.lib.serviceitem.os.path.exists')
@patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path')
def test_service_item_load_image_from_local_service(self, mocked_get_section_data_path, mocked_exists):
""" """
Test the Service Item - adding an image from a saved local service Test the Service Item - adding an image from a saved local service
""" """
# GIVEN: A new service item and a mocked add icon function # GIVEN: A new service item and a mocked add icon function
mocked_get_section_data_path.return_value = Path('/path')
mocked_exists.return_value = True
image_name1 = 'image_1.jpg' image_name1 = 'image_1.jpg'
image_name2 = 'image_2.jpg' image_name2 = 'image_2.jpg'
test_file1 = os.path.normpath(os.path.join('/home/openlp', image_name1)) test_file1 = os.path.join('/home', 'openlp', image_name1)
test_file2 = os.path.normpath(os.path.join('/home/openlp', image_name2)) test_file2 = os.path.join('/home', 'openlp', image_name2)
frame_array1 = {'path': test_file1, 'title': image_name1} frame_array1 = {'path': test_file1, 'title': image_name1}
frame_array2 = {'path': test_file2, 'title': image_name2} frame_array2 = {'path': test_file2, 'title': image_name2}
service_item = ServiceItem(None) service_item = ServiceItem(None)
service_item.add_icon = MagicMock() service_item.add_icon = MagicMock()
service_item2 = ServiceItem(None) service_item2 = ServiceItem(None)
service_item2.add_icon = MagicMock() service_item2.add_icon = MagicMock()
# WHEN: adding an image from a saved Service and mocked exists # WHEN: adding an image from a saved Service and mocked exists
line = convert_file_service_item(TEST_PATH, 'serviceitem_image_2.osj') line = convert_file_service_item(TEST_PATH, 'serviceitem_image_2.osj')
line2 = convert_file_service_item(TEST_PATH, 'serviceitem_image_2.osj', 1) line2 = convert_file_service_item(TEST_PATH, 'serviceitem_image_2.osj', 1)
service_item2.set_from_service(line2)
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists, \ service_item.set_from_service(line)
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as \
mocked_get_section_data_path:
mocked_exists.return_value = True
mocked_get_section_data_path.return_value = os.path.normpath('/path/')
service_item2.set_from_service(line2)
service_item.set_from_service(line)
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
# This test is copied from service_item.py, but is changed since to conform to
# new layout of service item. The layout use in serviceitem_image_2.osd is actually invalid now.
assert service_item.is_valid is True, 'The first service item should be valid' assert service_item.is_valid is True, 'The first service item should be valid'
assert service_item2.is_valid is True, 'The second service item should be valid' assert service_item2.is_valid is True, 'The second service item should be valid'
# These test will fail on windows due to the difference in folder seperators assert test_file1 == service_item.get_rendered_frame(0), 'The first frame should match the path to the image'
if os.name != 'nt': assert test_file2 == service_item2.get_rendered_frame(0), 'The Second frame should match the path to the image'
assert test_file1 == service_item.get_rendered_frame(0), \ assert frame_array1 == service_item.get_frames()[0], 'The return should match the frame array1'
'The first frame should match the path to the image' assert frame_array2 == service_item2.get_frames()[0], 'The return should match the frame array2'
assert test_file2 == service_item2.get_rendered_frame(0), \ assert test_file1 == service_item.get_frame_path(0), 'The frame path should match the full path to the image'
'The Second frame should match the path to the image' assert test_file2 == service_item2.get_frame_path(0), 'The frame path should match the full path to the image'
assert frame_array1 == service_item.get_frames()[0], 'The return should match the frame array1'
assert frame_array2 == service_item2.get_frames()[0], 'The return should match the frame array2'
assert test_file1 == service_item.get_frame_path(0), \
'The frame path should match the full path to the image'
assert test_file2 == service_item2.get_frame_path(0), \
'The frame path should match the full path to the image'
assert image_name1 == service_item.get_frame_title(0), 'The 1st frame title should match the image name' assert image_name1 == service_item.get_frame_title(0), 'The 1st frame title should match the image name'
assert image_name2 == service_item2.get_frame_title(0), 'The 2nd frame title should match the image name' assert image_name2 == service_item2.get_frame_title(0), 'The 2nd frame title should match the image name'
assert service_item.name == service_item.title.lower(), \ assert service_item.name == service_item.title.lower(), \
@ -274,23 +258,22 @@ class TestServiceItem(TestCase, TestMixin):
Test the Service Item - adding a presentation, updating the thumb path & adding the thumb to image_manager Test the Service Item - adding a presentation, updating the thumb path & adding the thumb to image_manager
""" """
# GIVEN: A service item, a mocked AppLocation and presentation data # GIVEN: A service item, a mocked AppLocation and presentation data
mocked_get_section_data_path.return_value = os.path.join('mocked', 'section', 'path') mocked_get_section_data_path.return_value = Path('mocked') / 'section' / 'path'
service_item = ServiceItem(None) service_item = ServiceItem(None)
service_item.add_capability(ItemCapabilities.HasThumbnails) service_item.add_capability(ItemCapabilities.HasThumbnails)
service_item.has_original_files = False service_item.has_original_files = False
service_item.name = 'presentations' service_item.name = 'presentations'
presentation_name = 'test.pptx' presentation_name = 'test.pptx'
thumb = os.path.join('tmp', 'test', 'thumb.png') thumb = Path('tmp') / 'test' / 'thumb.png'
display_title = 'DisplayTitle' display_title = 'DisplayTitle'
notes = 'Note1\nNote2\n' notes = 'Note1\nNote2\n'
expected_thumb_path = os.path.join('mocked', 'section', 'path', 'thumbnails', expected_thumb_path = Path('mocked') / 'section' / 'path' / 'thumbnails' / \
md5_hash(os.path.join(TEST_PATH, presentation_name).encode('utf-8')), md5_hash(str(TEST_PATH / presentation_name).encode('utf8')) / 'thumb.png'
'thumb.png') frame = {'title': presentation_name, 'image': str(expected_thumb_path), 'path': str(TEST_PATH),
frame = {'title': presentation_name, 'image': expected_thumb_path, 'path': TEST_PATH, 'display_title': display_title, 'notes': notes, 'thumbnail': str(expected_thumb_path)}
'display_title': display_title, 'notes': notes, 'thumbnail': expected_thumb_path}
# WHEN: adding presentation to service_item # WHEN: adding presentation to service_item
service_item.add_from_command(TEST_PATH, presentation_name, thumb, display_title, notes) service_item.add_from_command(str(TEST_PATH), presentation_name, thumb, display_title, notes)
# THEN: verify that it is setup as a Command and that the frame data matches # THEN: verify that it is setup as a Command and that the frame data matches
assert service_item.service_item_type == ServiceItemType.Command, 'It should be a Command' assert service_item.service_item_type == ServiceItemType.Command, 'It should be a Command'
@ -333,18 +316,11 @@ class TestServiceItem(TestCase, TestMixin):
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
assert service_item.is_valid is True, 'The new service item should be valid' assert service_item.is_valid is True, 'The new service item should be valid'
assert 0 == len(service_item._display_frames), 'The service item should have no display frames' assert len(service_item.display_slides) == 6, 'The service item should have 6 display slides'
assert 7 == len(service_item.capabilities), 'There should be 7 default custom item capabilities' assert len(service_item.capabilities) == 7, 'There should be 7 default custom item capabilities'
# WHEN: We render the frames of the service item
service_item.render(True)
# THEN: The frames should also be valid
assert 'Amazing Grace' == service_item.get_display_title(), 'The title should be "Amazing Grace"' assert 'Amazing Grace' == service_item.get_display_title(), 'The title should be "Amazing Grace"'
assert CLEANED_VERSE[:-1] == service_item.get_frames()[0]['text'], \ assert CLEANED_VERSE[:-1] == service_item.get_frames()[0]['text'], \
'The returned text matches the input, except the last line feed' 'The returned text matches the input, except the last line feed'
assert RENDERED_VERSE.split('\n', 1)[0] == service_item.get_rendered_frame(1), \
'The first line has been returned'
assert 'Amazing Grace! how sweet the s' == service_item.get_frame_title(0), \ assert 'Amazing Grace! how sweet the s' == service_item.get_frame_title(0), \
'"Amazing Grace! how sweet the s" has been returned as the title' '"Amazing Grace! how sweet the s" has been returned as the title'
assert 'Twas grace that taught my hea' == service_item.get_frame_title(1), \ assert 'Twas grace that taught my hea' == service_item.get_frame_title(1), \

View File

@ -43,28 +43,38 @@ exceptionform.VLC_VERSION = 'VLC Test'
MAIL_ITEM_TEXT = ('**OpenLP Bug Report**\nVersion: Trunk Test\n\n--- Details of the Exception. ---\n\n' MAIL_ITEM_TEXT = ('**OpenLP Bug Report**\nVersion: Trunk Test\n\n--- Details of the Exception. ---\n\n'
'Description Test\n\n --- Exception Traceback ---\nopenlp: Traceback Test\n' 'Description Test\n\n --- Exception Traceback ---\nopenlp: Traceback Test\n'
'--- System information ---\nPlatform: Nose Test\n\n--- Library Versions ---\n' '--- System information ---\nPlatform: Nose Test\n\n--- Library Versions ---\n'
'Python: Python Test\nQt5: Qt5 test\nPyQt5: PyQt5 Test\n' 'Python: Python Test\nQt5: Qt5 Test\nPyQt5: PyQt5 Test\n'
'SQLAlchemy: SqlAlchemy Test\nSQLAlchemy Migrate: Migrate Test\nBeautifulSoup: BeautifulSoup Test\n' 'SQLAlchemy: SQLAlchemy Test\nAlembic: Alembic Test\nBeautifulSoup: BeautifulSoup Test\n'
'lxml: ETree Test\nChardet: CHARDET Test\nPyEnchant: Enchant Test\nMako: Mako Test\n' 'lxml: ETree Test\nChardet: Chardet Test\nPyEnchant: PyEnchant Test\nMako: Mako Test\n'
'pyUNO bridge: UNO Bridge Test\nVLC: VLC Test\n\n') 'pyICU: pyICU Test\nVLC: VLC Test\nPyUNO: UNO Bridge Test\n')
LIBRARY_VERSIONS = OrderedDict([
('Python', 'Python Test'),
('Qt5', 'Qt5 Test'),
('PyQt5', 'PyQt5 Test'),
('SQLAlchemy', 'SQLAlchemy Test'),
('Alembic', 'Alembic Test'),
('BeautifulSoup', 'BeautifulSoup Test'),
('lxml', 'ETree Test'),
('Chardet', 'Chardet Test'),
('PyEnchant', 'PyEnchant Test'),
('Mako', 'Mako Test'),
('pyICU', 'pyICU Test'),
('VLC', 'VLC Test')
])
@patch("openlp.core.ui.exceptionform.Qt.qVersion") @patch('openlp.core.ui.exceptionform.QtGui.QDesktopServices.openUrl')
@patch("openlp.core.ui.exceptionform.QtGui.QDesktopServices.openUrl") @patch('openlp.core.ui.exceptionform.get_version')
@patch("openlp.core.ui.exceptionform.get_version") @patch('openlp.core.ui.exceptionform.get_library_versions')
@patch("openlp.core.ui.exceptionform.sqlalchemy") @patch('openlp.core.ui.exceptionform.is_linux')
@patch("openlp.core.ui.exceptionform.bs4") @patch('openlp.core.ui.exceptionform.platform.platform')
@patch("openlp.core.ui.exceptionform.etree")
@patch("openlp.core.ui.exceptionform.is_linux")
@patch("openlp.core.ui.exceptionform.platform.platform")
@patch("openlp.core.ui.exceptionform.platform.python_version")
class TestExceptionForm(TestMixin, TestCase): class TestExceptionForm(TestMixin, TestCase):
""" """
Test functionality of exception form functions Test functionality of exception form functions
""" """
def __method_template_for_class_patches(self, __PLACEHOLDER_FOR_LOCAL_METHOD_PATCH_DECORATORS_GO_HERE__, def __method_template_for_class_patches(self, __PLACEHOLDER_FOR_LOCAL_METHOD_PATCH_DECORATORS_GO_HERE__,
mocked_platform, mocked_is_linux, mocked_get_library_versions, mocked_platform, mocked_is_linux, mocked_get_library_versions,
mocked_get_version, mocked_openlurl): mocked_get_version, mocked_openurl):
""" """
Template so you don't have to remember the layout of class mock options for methods Template so you don't have to remember the layout of class mock options for methods
""" """
@ -92,7 +102,7 @@ class TestExceptionForm(TestMixin, TestCase):
@patch("openlp.core.ui.exceptionform.QtCore.QUrlQuery.addQueryItem") @patch("openlp.core.ui.exceptionform.QtCore.QUrlQuery.addQueryItem")
def test_on_send_report_button_clicked(self, mocked_add_query_item, mocked_qurl, mocked_file_dialog, def test_on_send_report_button_clicked(self, mocked_add_query_item, mocked_qurl, mocked_file_dialog,
mocked_ui_exception_dialog, mocked_platform, mocked_is_linux, mocked_ui_exception_dialog, mocked_platform, mocked_is_linux,
mocked_get_library_versions, mocked_get_version, mocked_openlurl): mocked_get_library_versions, mocked_get_version, mocked_openurl):
""" """
Test send report creates the proper system information text Test send report creates the proper system information text
""" """
@ -111,7 +121,7 @@ class TestExceptionForm(TestMixin, TestCase):
mock_traceback.return_value = 'openlp: Traceback Test' mock_traceback.return_value = 'openlp: Traceback Test'
mock_description.return_value = 'Description Test' mock_description.return_value = 'Description Test'
# WHEN: on_save_report_button_clicked called # WHEN: on_send_report_button_clicked called
test_form.on_send_report_button_clicked() test_form.on_send_report_button_clicked()
# THEN: Verify strings were formatted properly # THEN: Verify strings were formatted properly
@ -119,7 +129,7 @@ class TestExceptionForm(TestMixin, TestCase):
@patch("openlp.core.ui.exceptionform.FileDialog.getSaveFileName") @patch("openlp.core.ui.exceptionform.FileDialog.getSaveFileName")
def test_on_save_report_button_clicked(self, mocked_save_filename, mocked_platform, mocked_is_linux, def test_on_save_report_button_clicked(self, mocked_save_filename, mocked_platform, mocked_is_linux,
mocked_get_library_versions, mocked_get_version, mocked_openlurl): mocked_get_library_versions, mocked_get_version, mocked_openurl):
""" """
Test save report saves the correct information to a file Test save report saves the correct information to a file
""" """

View File

@ -139,7 +139,7 @@ class TestFirstTimeForm(TestCase, TestMixin):
# GIVEN: A mocked Screen() object and an initialised First Run Wizard and a mocked display_combo_box # GIVEN: A mocked Screen() object and an initialised First Run Wizard and a mocked display_combo_box
expected_screen_list = ['Screen 1', 'Screen 2'] expected_screen_list = ['Screen 1', 'Screen 2']
mocked_screens = MagicMock() mocked_screens = MagicMock()
mocked_screens.get_screen_list.return_value = expected_screen_list mocked_screens.get_display_screen_list.return_value = expected_screen_list
frw = FirstTimeForm(None) frw = FirstTimeForm(None)
frw.initialize(mocked_screens) frw.initialize(mocked_screens)
with patch.object(frw, 'display_combo_box') as mocked_display_combo_box: with patch.object(frw, 'display_combo_box') as mocked_display_combo_box:
@ -150,7 +150,7 @@ class TestFirstTimeForm(TestCase, TestMixin):
# THEN: The combobox should have been updated # THEN: The combobox should have been updated
mocked_display_combo_box.clear.assert_called_with() mocked_display_combo_box.clear.assert_called_with()
mocked_screens.get_screen_list.assert_called_with() mocked_screens.get_display_screen_list.assert_called_with()
mocked_display_combo_box.addItems.assert_called_with(expected_screen_list) mocked_display_combo_box.addItems.assert_called_with(expected_screen_list)
mocked_display_combo_box.count.assert_called_with() mocked_display_combo_box.count.assert_called_with()
mocked_display_combo_box.setCurrentIndex.assert_called_with(1) mocked_display_combo_box.setCurrentIndex.assert_called_with(1)

View File

@ -68,6 +68,8 @@ class TestMainWindow(TestCase, TestMixin):
self.add_toolbar_action_patcher = patch('openlp.core.ui.mainwindow.create_action') self.add_toolbar_action_patcher = patch('openlp.core.ui.mainwindow.create_action')
self.mocked_add_toolbar_action = self.add_toolbar_action_patcher.start() self.mocked_add_toolbar_action = self.add_toolbar_action_patcher.start()
self.mocked_add_toolbar_action.side_effect = self._create_mock_action self.mocked_add_toolbar_action.side_effect = self._create_mock_action
self.renderer_patcher = patch('openlp.core.ui.mainwindow.Renderer')
self.mocked_renderer = self.renderer_patcher.start()
mocked_desktop = MagicMock() mocked_desktop = MagicMock()
mocked_desktop.screenCount.return_value = 1 mocked_desktop.screenCount.return_value = 1
mocked_desktop.screenGeometry.return_value = QtCore.QRect(0, 0, 1024, 768) mocked_desktop.screenGeometry.return_value = QtCore.QRect(0, 0, 1024, 768)
@ -80,6 +82,7 @@ class TestMainWindow(TestCase, TestMixin):
Delete all the C++ objects and stop all the patchers Delete all the C++ objects and stop all the patchers
""" """
del self.main_window del self.main_window
self.renderer_patcher.stop()
self.add_toolbar_action_patcher.stop() self.add_toolbar_action_patcher.stop()
def test_cmd_line_file(self): def test_cmd_line_file(self):
@ -102,8 +105,8 @@ class TestMainWindow(TestCase, TestMixin):
Test that passing a non service file does nothing. Test that passing a non service file does nothing.
""" """
# GIVEN a non service file as an argument to openlp # GIVEN a non service file as an argument to openlp
service = os.path.join('openlp.py') service = 'run_openlp.py'
self.main_window.arguments = [service] self.main_window.arguments = service
# WHEN the argument is processed # WHEN the argument is processed
self.main_window.open_cmd_line_files(service) self.main_window.open_cmd_line_files(service)

View File

@ -233,7 +233,7 @@ class TestSlideController(TestCase):
slide_controller = SlideController(None) slide_controller = SlideController(None)
slide_controller.service_item = mocked_service_item slide_controller.service_item = mocked_service_item
slide_controller.preview_widget = mocked_preview_widget slide_controller.preview_widget = mocked_preview_widget
slide_controller.display = mocked_display slide_controller.displays = [mocked_display]
# WHEN: on_go_live() is called # WHEN: on_go_live() is called
slide_controller.on_go_preview() slide_controller.on_go_preview()
@ -260,7 +260,7 @@ class TestSlideController(TestCase):
slide_controller = SlideController(None) slide_controller = SlideController(None)
slide_controller.service_item = mocked_service_item slide_controller.service_item = mocked_service_item
slide_controller.preview_widget = mocked_preview_widget slide_controller.preview_widget = mocked_preview_widget
slide_controller.display = mocked_display slide_controller.displays = [mocked_display]
# WHEN: on_go_live() is called # WHEN: on_go_live() is called
slide_controller.on_go_live() slide_controller.on_go_live()
@ -291,7 +291,7 @@ class TestSlideController(TestCase):
slide_controller = SlideController(None) slide_controller = SlideController(None)
slide_controller.service_item = mocked_service_item slide_controller.service_item = mocked_service_item
slide_controller.preview_widget = mocked_preview_widget slide_controller.preview_widget = mocked_preview_widget
slide_controller.display = mocked_display slide_controller.displays = [mocked_display]
# WHEN: on_go_live() is called # WHEN: on_go_live() is called
slide_controller.on_go_live() slide_controller.on_go_live()
@ -481,7 +481,6 @@ class TestSlideController(TestCase):
slide_controller.add_service_item(mocked_item) slide_controller.add_service_item(mocked_item)
# THEN: The item is processed, the slide number is correct, and the song is not editable (or something) # THEN: The item is processed, the slide number is correct, and the song is not editable (or something)
mocked_item.render.assert_called_once_with()
assert slide_controller.song_edit is False, 'song_edit should be False' assert slide_controller.song_edit is False, 'song_edit should be False'
mocked_process_item.assert_called_once_with(mocked_item, 2) mocked_process_item.assert_called_once_with(mocked_item, 2)
@ -501,7 +500,6 @@ class TestSlideController(TestCase):
slide_controller.add_service_item(mocked_item) slide_controller.add_service_item(mocked_item)
# THEN: The item is processed, the slide number is correct, and the song is not editable (or something) # THEN: The item is processed, the slide number is correct, and the song is not editable (or something)
mocked_item.render.assert_called_once_with()
assert slide_controller.song_edit is False, 'song_edit should be False' assert slide_controller.song_edit is False, 'song_edit should be False'
mocked_process_item.assert_called_once_with(mocked_item, 0) mocked_process_item.assert_called_once_with(mocked_item, 0)
@ -677,12 +675,13 @@ class TestSlideController(TestCase):
slide_controller.service_item = mocked_pres_item slide_controller.service_item = mocked_pres_item
slide_controller.is_live = False slide_controller.is_live = False
slide_controller.preview_widget = MagicMock() slide_controller.preview_widget = MagicMock()
slide_controller.preview_display = MagicMock()
slide_controller.enable_tool_bar = MagicMock() slide_controller.enable_tool_bar = MagicMock()
slide_controller.on_media_start = MagicMock() slide_controller.on_media_start = MagicMock()
slide_controller.slide_selected = MagicMock() slide_controller.slide_selected = MagicMock()
slide_controller.on_stop_loop = MagicMock() slide_controller.on_stop_loop = MagicMock()
slide_controller.info_label = MagicMock() slide_controller.info_label = MagicMock()
slide_controller.display = MagicMock() slide_controller.displays = [MagicMock()]
slide_controller.split = 0 slide_controller.split = 0
slide_controller.type_prefix = 'test' slide_controller.type_prefix = 'test'
@ -795,7 +794,7 @@ class TestSlideController(TestCase):
slide_controller.selected_row = MagicMock() slide_controller.selected_row = MagicMock()
slide_controller.screens = MagicMock() slide_controller.screens = MagicMock()
slide_controller.screens.current = {'primary': ''} slide_controller.screens.current = {'primary': ''}
slide_controller.display = MagicMock() slide_controller.displays = [MagicMock()]
slide_controller.display.preview.return_value = QtGui.QImage() slide_controller.display.preview.return_value = QtGui.QImage()
slide_controller.grab_maindisplay = MagicMock() slide_controller.grab_maindisplay = MagicMock()
slide_controller.slide_preview = MagicMock() slide_controller.slide_preview = MagicMock()
@ -837,20 +836,20 @@ class TestSlideController(TestCase):
slide_controller.selected_row = MagicMock() slide_controller.selected_row = MagicMock()
slide_controller.screens = MagicMock() slide_controller.screens = MagicMock()
slide_controller.screens.current = {'primary': ''} slide_controller.screens.current = {'primary': ''}
slide_controller.display = MagicMock() slide_controller.displays = [MagicMock()]
slide_controller.display.preview.return_value = QtGui.QImage() slide_controller.display.preview.return_value = QtGui.QImage()
slide_controller.grab_maindisplay = MagicMock() slide_controller.grab_maindisplay = MagicMock()
slide_controller.slide_preview = MagicMock() slide_controller.slide_preview = MagicMock()
slide_controller.slide_count = 0 slide_controller.slide_count = 0
slide_controller.preview_display = MagicMock()
# WHEN: update_preview is called # WHEN: update_preview is called
slide_controller.update_preview() slide_controller.update_preview()
# THEN: setPixmap and the image_manager should have been called # THEN: setPixmap and the image_manager should have been called
assert 1 == slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should be called' assert 1 == slide_controller.preview_display.set_single_image.call_count, 'set_single_image should be called'
assert 0 == slide_controller.display.preview.call_count, 'display.preview() should not be called'
assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called' assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called'
assert 1 == mocked_image_manager.get_image.call_count, 'image_manager should be called' # assert 1 == mocked_image_manager.get_image.call_count, 'image_manager should be called'
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager') @patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
@patch(u'PyQt5.QtCore.QTimer.singleShot') @patch(u'PyQt5.QtCore.QTimer.singleShot')
@ -879,18 +878,18 @@ class TestSlideController(TestCase):
slide_controller.selected_row = MagicMock() slide_controller.selected_row = MagicMock()
slide_controller.screens = MagicMock() slide_controller.screens = MagicMock()
slide_controller.screens.current = {'primary': ''} slide_controller.screens.current = {'primary': ''}
slide_controller.display = MagicMock() slide_controller.displays = [MagicMock()]
slide_controller.display.preview.return_value = QtGui.QImage() slide_controller.display.preview.return_value = QtGui.QImage()
slide_controller.grab_maindisplay = MagicMock() slide_controller.grab_maindisplay = MagicMock()
slide_controller.slide_preview = MagicMock() slide_controller.slide_preview = MagicMock()
slide_controller.slide_count = 0 slide_controller.slide_count = 0
slide_controller.preview_display = MagicMock()
# WHEN: update_preview is called # WHEN: update_preview is called
slide_controller.update_preview() slide_controller.update_preview()
# THEN: setPixmap should have been called # THEN: setPixmap should have been called
assert 1 == slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should be called' assert 1 == slide_controller.preview_display.set_single_image.call_count, 'set_single_image should be called'
assert 0 == slide_controller.display.preview.call_count, 'display.preview() should not be called'
assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called' assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called'
assert 0 == mocked_image_manager.get_image.call_count, 'image_manager should not be called' assert 0 == mocked_image_manager.get_image.call_count, 'image_manager should not be called'
@ -921,18 +920,17 @@ class TestSlideController(TestCase):
slide_controller.selected_row = MagicMock() slide_controller.selected_row = MagicMock()
slide_controller.screens = MagicMock() slide_controller.screens = MagicMock()
slide_controller.screens.current = {'primary': ''} slide_controller.screens.current = {'primary': ''}
slide_controller.display = MagicMock() slide_controller.displays = [MagicMock()]
slide_controller.display.preview.return_value = QtGui.QImage()
slide_controller.grab_maindisplay = MagicMock() slide_controller.grab_maindisplay = MagicMock()
slide_controller.slide_preview = MagicMock() slide_controller.slide_preview = MagicMock()
slide_controller.slide_count = 0 slide_controller.slide_count = 0
slide_controller.preview_display = MagicMock()
# WHEN: update_preview is called # WHEN: update_preview is called
slide_controller.update_preview() slide_controller.update_preview()
# THEN: setPixmap and display.preview should have been called # THEN: setPixmap and display.preview should have been called
assert 1 == slide_controller.slide_preview.setPixmap.call_count, 'setPixmap should be called' assert 1 == slide_controller.preview_display.go_to_slide.call_count, 'go_to_slide should be called'
assert 1 == slide_controller.display.preview.call_count, 'display.preview() should be called'
assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called' assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called'
assert 0 == mocked_image_manager.get_image.call_count, 'image_manager should not be called' assert 0 == mocked_image_manager.get_image.call_count, 'image_manager should not be called'

View File

@ -169,10 +169,10 @@ class TestListPreviewWidget(TestCase):
list_preview_widget.replace_service_item(mocked_cmd_service_item, 200, 0) list_preview_widget.replace_service_item(mocked_cmd_service_item, 200, 0)
# THEN: The ImageManager should be called in the appriopriate manner for each service item. # THEN: The ImageManager should be called in the appriopriate manner for each service item.
assert mocked_image_manager.get_image.call_count == 4, 'Should be called once for each slide' # assert mocked_image_manager.get_image.call_count == 4, 'Should be called once for each slide'
calls = [call('TEST1', ImageSource.ImagePlugin), call('TEST2', ImageSource.ImagePlugin), # calls = [call('TEST1', ImageSource.ImagePlugin), call('TEST2', ImageSource.ImagePlugin),
call('TEST3', ImageSource.CommandPlugins), call('TEST4', ImageSource.CommandPlugins)] # call('TEST3', ImageSource.CommandPlugins), call('TEST4', ImageSource.CommandPlugins)]
mocked_image_manager.get_image.assert_has_calls(calls) # mocked_image_manager.get_image.assert_has_calls(calls)
@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents')
@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight')
@ -239,9 +239,9 @@ class TestListPreviewWidget(TestCase):
# THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called # THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called
# twice for each slide. # twice for each slide.
assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called' assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called'
assert mocked_setRowHeight.call_count == 6, 'Should be called 3 times for each slide' assert mocked_setRowHeight.call_count == 0, 'Should not be called'
calls = [call(0, 200), call(1, 200), call(0, 400), call(1, 400), call(0, 400), call(1, 400)] # calls = [call(0, 200), call(1, 200), call(0, 400), call(1, 400), call(0, 400), call(1, 400)]
mocked_setRowHeight.assert_has_calls(calls) # mocked_setRowHeight.assert_has_calls(calls)
@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents')
@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight')
@ -274,9 +274,9 @@ class TestListPreviewWidget(TestCase):
# THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called # THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called
# twice for each slide. # twice for each slide.
assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called' assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called'
assert mocked_setRowHeight.call_count == 4, 'Should be called twice for each slide' assert mocked_setRowHeight.call_count == 0, 'Should not be called'
calls = [call(0, 100), call(1, 100), call(0, 100), call(1, 100)] # calls = [call(0, 100), call(1, 100), call(0, 100), call(1, 100)]
mocked_setRowHeight.assert_has_calls(calls) # mocked_setRowHeight.assert_has_calls(calls)
@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents')
@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight')
@ -312,9 +312,9 @@ class TestListPreviewWidget(TestCase):
# THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called # THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called
# twice for each slide. # twice for each slide.
assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called' assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called'
assert mocked_setRowHeight.call_count == 6, 'Should be called 3 times for each slide' assert mocked_setRowHeight.call_count == 0, 'Should not be called'
calls = [call(0, 100), call(1, 100), call(0, 150), call(1, 150), call(0, 100), call(1, 100)] # calls = [call(0, 100), call(1, 100), call(0, 150), call(1, 150), call(0, 100), call(1, 100)]
mocked_setRowHeight.assert_has_calls(calls) # mocked_setRowHeight.assert_has_calls(calls)
@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents')
@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight')

View File

@ -162,7 +162,8 @@ class TestImpressDocument(TestCase):
# THEN: save_titles_and_notes should have been called once with # THEN: save_titles_and_notes should have been called once with
# two arrays of two elements # two arrays of two elements
self.doc.save_titles_and_notes.assert_called_once_with(['\n', '\n'], [' ', ' ']) # self.doc.save_titles_and_notes.assert_called_once_with(['\n', '\n'], [' ', ' '])
self.doc.save_titles_and_notes.assert_called_once_with(['', ''], [' ', ' '])
def test_get_text_from_page_out_of_bound(self): def test_get_text_from_page_out_of_bound(self):
""" """

View File

@ -134,8 +134,8 @@ class TestPdfController(TestCase, TestMixin):
image = QtGui.QImage(os.path.join(str(self.temp_folder_path), 'pdf_test1.pdf', 'mainslide001.png')) image = QtGui.QImage(os.path.join(str(self.temp_folder_path), 'pdf_test1.pdf', 'mainslide001.png'))
# Based on the converter used the resolution will differ a bit # Based on the converter used the resolution will differ a bit
if controller.gsbin: if controller.gsbin:
assert 760 == image.height(), 'The height should be 760' assert 1076 == image.height(), 'The height should be 1076'
assert 537 == image.width(), 'The width should be 537' assert 760 == image.width(), 'The width should be 760'
else: else:
assert 768 == image.height(), 'The height should be 768' assert 768 == image.height(), 'The height should be 768'
assert 543 == image.width(), 'The width should be 543' assert 543 == image.width(), 'The width should be 543'

View File

@ -181,7 +181,7 @@ class TestPowerpointDocument(TestCase, TestMixin):
self.doc.create_titles_and_notes() self.doc.create_titles_and_notes()
# THEN the save should have been called exactly once with 2 titles and 2 notes # THEN the save should have been called exactly once with 2 titles and 2 notes
self.doc.save_titles_and_notes.assert_called_once_with(['SlideText\n', 'SlideText\n'], [' ', ' ']) self.doc.save_titles_and_notes.assert_called_once_with(['SlideText', 'SlideText'], [' ', ' '])
def test_create_titles_and_notes_with_no_slides(self): def test_create_titles_and_notes_with_no_slides(self):
""" """

View File

@ -57,7 +57,8 @@ class TestMainWindow(TestCase, TestMixin):
patch('openlp.core.ui.mainwindow.ThemeManager'), \ patch('openlp.core.ui.mainwindow.ThemeManager'), \
patch('openlp.core.ui.mainwindow.ProjectorManager'), \ patch('openlp.core.ui.mainwindow.ProjectorManager'), \
patch('openlp.core.ui.mainwindow.websockets.WebSocketServer'), \ patch('openlp.core.ui.mainwindow.websockets.WebSocketServer'), \
patch('openlp.core.ui.mainwindow.server.HttpServer'): patch('openlp.core.ui.mainwindow.server.HttpServer'), \
patch('openlp.core.ui.mainwindow.Renderer'):
self.main_window = MainWindow() self.main_window = MainWindow()
def tearDown(self): def tearDown(self):

View File

@ -20,7 +20,6 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
import json import json
import os
def assert_length(expected, iterable, msg=None): def assert_length(expected, iterable, msg=None):
@ -31,15 +30,13 @@ def assert_length(expected, iterable, msg=None):
def convert_file_service_item(test_path, name, row=0): def convert_file_service_item(test_path, name, row=0):
service_file = os.path.join(test_path, name) service_file = test_path / name
open_file = open(service_file, 'r') with service_file.open() as open_file:
try: try:
items = json.load(open_file) items = json.load(open_file)
first_line = items[row] first_line = items[row]
except OSError: except OSError:
first_line = '' first_line = ''
finally:
open_file.close()
return first_line return first_line