Try to fix paths in coverage report generation

- Add the local path to coverage config
- Fix the paths before generating an HTML report
This commit is contained in:
Tim Bentley 2019-12-04 20:01:02 +00:00 committed by Raoul Snyman
parent 205442fed7
commit 9fd6752a83
4 changed files with 1045 additions and 1020 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@
.vscode .vscode
.eggs .eggs
.venv .venv
.mypy_cache
OpenLP.egg-info OpenLP.egg-info
\#*\# \#*\#
__pycache__ __pycache__

View File

@ -34,7 +34,6 @@ from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.mixins import LogMixin, RegistryProperties from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.registry import Registry, RegistryBase from openlp.core.common.registry import Registry, RegistryBase
from openlp.core.common.settings import Settings
from openlp.core.display.screens import ScreenList from openlp.core.display.screens import ScreenList
from openlp.core.display.window import DisplayWindow from openlp.core.display.window import DisplayWindow
from openlp.core.lib import ServiceItemAction, image_to_byte from openlp.core.lib import ServiceItemAction, image_to_byte
@ -324,7 +323,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.play_slides_once = create_action(self, 'playSlidesOnce', text=UiStrings().PlaySlidesToEnd, self.play_slides_once = create_action(self, 'playSlidesOnce', text=UiStrings().PlaySlidesToEnd,
icon=UiIcons().clock, checked=False, can_shortcuts=True, icon=UiIcons().clock, checked=False, can_shortcuts=True,
category=self.category, triggers=self.on_play_slides_once) category=self.category, triggers=self.on_play_slides_once)
if Settings().value(self.main_window.advanced_settings_section + '/slide limits') == SlideLimits.Wrap: if self.settings.value(self.main_window.advanced_settings_section + '/slide limits') == SlideLimits.Wrap:
self.play_slides_menu.setDefaultAction(self.play_slides_loop) self.play_slides_menu.setDefaultAction(self.play_slides_loop)
else: else:
self.play_slides_menu.setDefaultAction(self.play_slides_once) self.play_slides_menu.setDefaultAction(self.play_slides_once)
@ -697,13 +696,13 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
""" """
Adjusts the value of the ``delay_spin_box`` to the given one. Adjusts the value of the ``delay_spin_box`` to the given one.
""" """
self.delay_spin_box.setValue(Settings().value('core/loop delay')) self.delay_spin_box.setValue(self.settings.value('core/loop delay'))
def update_slide_limits(self): def update_slide_limits(self):
""" """
Updates the Slide Limits variable from the settings. Updates the Slide Limits variable from the settings.
""" """
self.slide_limits = Settings().value(self.main_window.advanced_settings_section + '/slide limits') self.slide_limits = self.settings.value(self.main_window.advanced_settings_section + '/slide limits')
def enable_tool_bar(self, item): def enable_tool_bar(self, item):
""" """
@ -737,7 +736,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.play_slides_loop.setIcon(UiIcons().clock) self.play_slides_loop.setIcon(UiIcons().clock)
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop) self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
if item.is_text(): if item.is_text():
if (Settings().value(self.main_window.songs_settings_section + '/display songbar') and if (self.settings.value(self.main_window.songs_settings_section + '/display songbar') and
not self.song_menu.menu().isEmpty()): not self.song_menu.menu().isEmpty()):
self.toolbar.set_widget_visible('song_menu', True) self.toolbar.set_widget_visible('song_menu', True)
if item.is_capable(ItemCapabilities.CanLoop) and len(item.slides) > 1: if item.is_capable(ItemCapabilities.CanLoop) and len(item.slides) > 1:
@ -1013,9 +1012,9 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.theme_screen.setChecked(False) self.theme_screen.setChecked(False)
self.desktop_screen.setChecked(False) self.desktop_screen.setChecked(False)
if checked: if checked:
Settings().setValue(self.main_window.general_settings_section + '/screen blank', 'blanked') self.settings.setValue(self.main_window.general_settings_section + '/screen blank', 'blanked')
else: else:
Settings().remove(self.main_window.general_settings_section + '/screen blank') self.settings.remove(self.main_window.general_settings_section + '/screen blank')
self.blank_plugin() self.blank_plugin()
self.update_preview() self.update_preview()
self.on_toggle_loop() self.on_toggle_loop()
@ -1034,9 +1033,9 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.theme_screen.setChecked(checked) self.theme_screen.setChecked(checked)
self.desktop_screen.setChecked(False) self.desktop_screen.setChecked(False)
if checked: if checked:
Settings().setValue(self.main_window.general_settings_section + '/screen blank', 'themed') self.settings.setValue(self.main_window.general_settings_section + '/screen blank', 'themed')
else: else:
Settings().remove(self.main_window.general_settings_section + '/screen blank') self.settings.remove(self.main_window.general_settings_section + '/screen blank')
self.blank_plugin() self.blank_plugin()
self.update_preview() self.update_preview()
self.on_toggle_loop() self.on_toggle_loop()
@ -1056,9 +1055,9 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.theme_screen.setChecked(False) self.theme_screen.setChecked(False)
self.desktop_screen.setChecked(checked) self.desktop_screen.setChecked(checked)
if checked: if checked:
Settings().setValue(self.main_window.general_settings_section + '/screen blank', 'hidden') self.settings.setValue(self.main_window.general_settings_section + '/screen blank', 'hidden')
else: else:
Settings().remove(self.main_window.general_settings_section + '/screen blank') self.settings.remove(self.main_window.general_settings_section + '/screen blank')
self.hide_plugin(checked) self.hide_plugin(checked)
self.update_preview() self.update_preview()
self.on_toggle_loop() self.on_toggle_loop()
@ -1145,7 +1144,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
return return
# If "click live slide to unblank" is enabled, unblank the display. And start = Item is sent to Live. # If "click live slide to unblank" is enabled, unblank the display. And start = Item is sent to Live.
# Note: If this if statement is placed at the bottom of this function instead of top slide transitions are lost. # Note: If this if statement is placed at the bottom of this function instead of top slide transitions are lost.
if self.is_live and Settings().value('core/click live slide to unblank'): if self.is_live and self.settings.value('core/click live slide to unblank'):
if not start: if not start:
Registry().execute('slidecontroller_live_unblank') Registry().execute('slidecontroller_live_unblank')
row = self.preview_widget.current_slide_number() row = self.preview_widget.current_slide_number()
@ -1353,7 +1352,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd) self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
self.play_slides_menu.setDefaultAction(self.play_slides_loop) self.play_slides_menu.setDefaultAction(self.play_slides_loop)
self.play_slides_once.setChecked(False) self.play_slides_once.setChecked(False)
if Settings().value('core/click live slide to unblank'): if self.settings.value('core/click live slide to unblank'):
Registry().execute('slidecontroller_live_unblank') Registry().execute('slidecontroller_live_unblank')
else: else:
self.play_slides_loop.setIcon(UiIcons().clock) self.play_slides_loop.setIcon(UiIcons().clock)
@ -1378,7 +1377,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop) self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
self.play_slides_menu.setDefaultAction(self.play_slides_once) self.play_slides_menu.setDefaultAction(self.play_slides_once)
self.play_slides_loop.setChecked(False) self.play_slides_loop.setChecked(False)
if Settings().value('core/click live slide to unblank'): if self.settings.value('core/click live slide to unblank'):
Registry().execute('slidecontroller_live_unblank') Registry().execute('slidecontroller_live_unblank')
else: else:
self.play_slides_once.setIcon(UiIcons().clock) self.play_slides_once.setIcon(UiIcons().clock)
@ -1423,7 +1422,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
Triggered when a preview slide item is double clicked Triggered when a preview slide item is double clicked
""" """
if self.service_item: if self.service_item:
if Settings().value('advanced/double click live') and Settings().value('core/auto unblank'): if self.settings.value('advanced/double click live') and self.settings.value('core/auto unblank'):
# Live and Preview have issues if we have video or presentations # Live and Preview have issues if we have video or presentations
# playing in both at the same time. # playing in both at the same time.
if self.service_item.is_command(): if self.service_item.is_command():

View File

@ -23,6 +23,7 @@ All the tests
""" """
import os import os
from tempfile import mkstemp from tempfile import mkstemp
from unittest.mock import MagicMock
import pytest import pytest
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtWidgets
@ -39,24 +40,34 @@ def qapp():
del app del app
@pytest.fixture
def registry():
"""An instance of the Registry"""
Registry.create()
@pytest.yield_fixture @pytest.yield_fixture
def settings(qapp): def settings(qapp, registry):
"""A Settings() instance""" """A Settings() instance"""
fd, ini_file = mkstemp('.ini') fd, ini_file = mkstemp('.ini')
Settings.set_filename(ini_file) Settings.set_filename(ini_file)
Registry.create()
Settings().setDefaultFormat(QtCore.QSettings.IniFormat) Settings().setDefaultFormat(QtCore.QSettings.IniFormat)
# Needed on windows to make sure a Settings object is available during the tests # Needed on windows to make sure a Settings object is available during the tests
sets = Settings() sets = Settings()
sets.setValue('themes/global theme', 'my_theme') sets.setValue('themes/global theme', 'my_theme')
Registry().register('settings', set) Registry().register('settings', sets)
yield sets yield sets
del sets del sets
os.close(fd) os.close(fd)
os.unlink(Settings().fileName()) os.unlink(Settings().fileName())
@pytest.fixture @pytest.yield_fixture
def registry(): def mock_settings(registry):
"""An instance of the Registry""" """A Mock Settings() instance"""
Registry.create() # Create and register a mock settings object to work with
mock_settings = MagicMock()
Registry().register('settings', mock_settings)
yield mock_settings
Registry().remove('settings')
del mock_settings

View File

@ -21,7 +21,6 @@
""" """
Package to test the openlp.core.ui.slidecontroller package. Package to test the openlp.core.ui.slidecontroller package.
""" """
from unittest import TestCase
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtGui from PyQt5 import QtCore, QtGui
@ -32,15 +31,7 @@ from openlp.core.ui.slidecontroller import NON_TEXT_MENU, WIDE_MENU, InfoLabel,
SlideController SlideController
class TestSlideController(TestCase): def test_initial_slide_controller(registry):
def setUp(self):
"""
Set up the components need for all tests.
"""
Registry.create()
def test_initial_slide_controller(self):
""" """
Test the initial slide controller state . Test the initial slide controller state .
""" """
@ -51,7 +42,8 @@ class TestSlideController(TestCase):
# THEN: The controller should not be a live controller. # THEN: The controller should not be a live controller.
assert slide_controller.is_live is False, 'The base slide controller should not be a live controller' assert slide_controller.is_live is False, 'The base slide controller should not be a live controller'
def test_text_service_item_blank(self):
def test_text_service_item_blank():
""" """
Test that loading a text-based service item into the slide controller sets the correct blank menu Test that loading a text-based service item into the slide controller sets the correct blank menu
""" """
@ -70,7 +62,8 @@ class TestSlideController(TestCase):
# THEN: the call to set the visible items on the toolbar should be correct # THEN: the call to set the visible items on the toolbar should be correct
toolbar.set_widget_visible.assert_called_with(WIDE_MENU, True) toolbar.set_widget_visible.assert_called_with(WIDE_MENU, True)
def test_non_text_service_item_blank(self):
def test_non_text_service_item_blank():
""" """
Test that loading a non-text service item into the slide controller sets the correct blank menu Test that loading a non-text service item into the slide controller sets the correct blank menu
""" """
@ -89,14 +82,13 @@ class TestSlideController(TestCase):
# THEN: then call set up the toolbar to blank the display screen. # THEN: then call set up the toolbar to blank the display screen.
toolbar.set_widget_visible.assert_called_with(NON_TEXT_MENU, True) toolbar.set_widget_visible.assert_called_with(NON_TEXT_MENU, True)
@patch('openlp.core.ui.slidecontroller.Settings')
def test_receive_spin_delay(self, MockedSettings): def test_receive_spin_delay(mock_settings):
""" """
Test that the spin box is updated accordingly after a call to receive_spin_delay() Test that the spin box is updated accordingly after a call to receive_spin_delay()
""" """
# GIVEN: A new SlideController instance. # GIVEN: A new SlideController instance.
mocked_value = MagicMock(return_value=1) mock_settings.value.return_value = 1
MockedSettings.return_value = MagicMock(value=mocked_value)
mocked_delay_spin_box = MagicMock() mocked_delay_spin_box = MagicMock()
slide_controller = SlideController(None) slide_controller = SlideController(None)
slide_controller.delay_spin_box = mocked_delay_spin_box slide_controller.delay_spin_box = mocked_delay_spin_box
@ -104,11 +96,13 @@ class TestSlideController(TestCase):
# WHEN: The receive_spin_delay() method is called # WHEN: The receive_spin_delay() method is called
slide_controller.receive_spin_delay() slide_controller.receive_spin_delay()
# THEN: The Settings()value() and delay_spin_box.setValue() methods should have been called correctly # THEN: The settings value() and delay_spin_box.setValue() methods should have been called correctly
mocked_value.assert_called_with('core/loop delay') msv = mock_settings.value
msv.assert_called_with('core/loop delay')
mocked_delay_spin_box.setValue.assert_called_with(1) mocked_delay_spin_box.setValue.assert_called_with(1)
def test_toggle_display_blank(self):
def test_toggle_display_blank():
""" """
Check that the toggle_display('blank') method calls the on_blank_display() method Check that the toggle_display('blank') method calls the on_blank_display() method
""" """
@ -129,7 +123,8 @@ class TestSlideController(TestCase):
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called' assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called' assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
def test_toggle_display_hide(self):
def test_toggle_display_hide():
""" """
Check that the toggle_display('hide') method calls the on_blank_display() method Check that the toggle_display('hide') method calls the on_blank_display() method
""" """
@ -150,7 +145,8 @@ class TestSlideController(TestCase):
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called' assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called' assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
def test_toggle_display_theme(self):
def test_toggle_display_theme():
""" """
Check that the toggle_display('theme') method calls the on_theme_display() method Check that the toggle_display('theme') method calls the on_theme_display() method
""" """
@ -171,7 +167,8 @@ class TestSlideController(TestCase):
assert 0 == mocked_on_blank_display.call_count, 'on_blank_display should not have been called' assert 0 == mocked_on_blank_display.call_count, 'on_blank_display should not have been called'
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called' assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
def test_toggle_display_desktop(self):
def test_toggle_display_desktop():
""" """
Check that the toggle_display('desktop') method calls the on_hide_display() method Check that the toggle_display('desktop') method calls the on_hide_display() method
""" """
@ -192,7 +189,8 @@ class TestSlideController(TestCase):
assert 0 == mocked_on_blank_display.call_count, 'on_blank_display should not have been called' assert 0 == mocked_on_blank_display.call_count, 'on_blank_display should not have been called'
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called' assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
def test_toggle_display_show(self):
def test_toggle_display_show():
""" """
Check that the toggle_display('show') method calls all the on_X_display() methods Check that the toggle_display('show') method calls all the on_X_display() methods
""" """
@ -213,7 +211,8 @@ class TestSlideController(TestCase):
mocked_on_theme_display.assert_called_once_with(False) mocked_on_theme_display.assert_called_once_with(False)
mocked_on_hide_display.assert_called_once_with(False) mocked_on_hide_display.assert_called_once_with(False)
def test_on_go_live_preview_controller(self):
def test_on_go_live_preview_controller():
""" """
Test that when the on_go_preview() method is called the message is sent to the preview controller and focus is Test that when the on_go_preview() method is called the message is sent to the preview controller and focus is
set correctly. set correctly.
@ -240,7 +239,8 @@ class TestSlideController(TestCase):
# THEN: the preview controller should have the service item and the focus set to live # THEN: the preview controller should have the service item and the focus set to live
mocked_preview_controller.preview_widget.setFocus.assert_called_once_with() mocked_preview_controller.preview_widget.setFocus.assert_called_once_with()
def test_on_go_live_live_controller(self):
def test_on_go_live_live_controller():
""" """
Test that when the on_go_live() method is called the message is sent to the live controller and focus is Test that when the on_go_live() method is called the message is sent to the live controller and focus is
set correctly. set correctly.
@ -268,7 +268,8 @@ class TestSlideController(TestCase):
mocked_live_controller.add_service_manager_item.assert_called_once_with(mocked_service_item, 1) mocked_live_controller.add_service_manager_item.assert_called_once_with(mocked_service_item, 1)
mocked_live_controller.preview_widget.setFocus.assert_called_once_with() mocked_live_controller.preview_widget.setFocus.assert_called_once_with()
def test_on_go_live_service_manager(self):
def test_on_go_live_service_manager():
""" """
Test that when the on_go_live() method is called the message is sent to the live controller and focus is Test that when the on_go_live() method is called the message is sent to the live controller and focus is
set correctly. set correctly.
@ -299,7 +300,8 @@ class TestSlideController(TestCase):
mocked_service_manager.preview_live.assert_called_once_with(42, 1) mocked_service_manager.preview_live.assert_called_once_with(42, 1)
mocked_live_controller.preview_widget.setFocus.assert_called_once_with() mocked_live_controller.preview_widget.setFocus.assert_called_once_with()
def test_service_previous(self):
def test_service_previous():
""" """
Check that calling the service_previous() method adds the previous key to the queue and processes the queue Check that calling the service_previous() method adds the previous key to the queue and processes the queue
""" """
@ -317,7 +319,8 @@ class TestSlideController(TestCase):
mocked_keypress_queue.append.assert_called_once_with(ServiceItemAction.Previous) mocked_keypress_queue.append.assert_called_once_with(ServiceItemAction.Previous)
mocked_process_queue.assert_called_once_with() mocked_process_queue.assert_called_once_with()
def test_service_next(self):
def test_service_next():
""" """
Check that calling the service_next() method adds the next key to the queue and processes the queue Check that calling the service_next() method adds the next key to the queue and processes the queue
""" """
@ -335,16 +338,14 @@ class TestSlideController(TestCase):
mocked_keypress_queue.append.assert_called_once_with(ServiceItemAction.Next) mocked_keypress_queue.append.assert_called_once_with(ServiceItemAction.Next)
mocked_process_queue.assert_called_once_with() mocked_process_queue.assert_called_once_with()
@patch('openlp.core.ui.slidecontroller.Settings')
def test_update_slide_limits(self, MockedSettings): def test_update_slide_limits(mock_settings):
""" """
Test that calling the update_slide_limits() method updates the slide limits Test that calling the update_slide_limits() method updates the slide limits
""" """
# GIVEN: A mocked out Settings object, a new SlideController and a mocked out main_window # GIVEN: A mocked out Settings object, a new SlideController and a mocked out main_window
mocked_value = MagicMock(return_value=10) mock_settings.value.return_value = 10
MockedSettings.return_value = MagicMock(value=mocked_value)
mocked_main_window = MagicMock(advanced_settings_section='advanced') mocked_main_window = MagicMock(advanced_settings_section='advanced')
Registry.create()
Registry().register('main_window', mocked_main_window) Registry().register('main_window', mocked_main_window)
slide_controller = SlideController(None) slide_controller = SlideController(None)
@ -352,10 +353,12 @@ class TestSlideController(TestCase):
slide_controller.update_slide_limits() slide_controller.update_slide_limits()
# THEN: The value of slide_limits should be 10 # THEN: The value of slide_limits should be 10
mocked_value.assert_called_once_with('advanced/slide limits') msv = mock_settings.value
msv.assert_called_once_with('advanced/slide limits')
assert 10 == slide_controller.slide_limits, 'Slide limits should have been updated to 10' assert 10 == slide_controller.slide_limits, 'Slide limits should have been updated to 10'
def test_enable_tool_bar_live(self):
def test_enable_tool_bar_live():
""" """
Check that when enable_tool_bar on a live slide controller is called, enable_live_tool_bar is called Check that when enable_tool_bar on a live slide controller is called, enable_live_tool_bar is called
""" """
@ -375,7 +378,8 @@ class TestSlideController(TestCase):
mocked_enable_live_tool_bar.assert_called_once_with(mocked_service_item) mocked_enable_live_tool_bar.assert_called_once_with(mocked_service_item)
assert 0 == mocked_enable_preview_tool_bar.call_count, 'The preview method should not have been called' assert 0 == mocked_enable_preview_tool_bar.call_count, 'The preview method should not have been called'
def test_enable_tool_bar_preview(self):
def test_enable_tool_bar_preview():
""" """
Check that when enable_tool_bar on a preview slide controller is called, enable_preview_tool_bar is called Check that when enable_tool_bar on a preview slide controller is called, enable_preview_tool_bar is called
""" """
@ -395,7 +399,8 @@ class TestSlideController(TestCase):
mocked_enable_preview_tool_bar.assert_called_once_with(mocked_service_item) mocked_enable_preview_tool_bar.assert_called_once_with(mocked_service_item)
assert 0 == mocked_enable_live_tool_bar.call_count, 'The live method should not have been called' assert 0 == mocked_enable_live_tool_bar.call_count, 'The live method should not have been called'
def test_refresh_service_item_text(self):
def test_refresh_service_item_text():
""" """
Test that the refresh_service_item() method refreshes a text service item Test that the refresh_service_item() method refreshes a text service item
""" """
@ -418,7 +423,8 @@ class TestSlideController(TestCase):
mocked_service_item.render.assert_called_once_with() mocked_service_item.render.assert_called_once_with()
mocked_process_item.assert_called_once_with(mocked_service_item, 5) mocked_process_item.assert_called_once_with(mocked_service_item, 5)
def test_refresh_service_item_image(self):
def test_refresh_service_item_image():
""" """
Test that the refresh_service_item() method refreshes a image service item Test that the refresh_service_item() method refreshes a image service item
""" """
@ -441,7 +447,8 @@ class TestSlideController(TestCase):
mocked_service_item.render.assert_called_once_with() mocked_service_item.render.assert_called_once_with()
mocked_process_item.assert_called_once_with(mocked_service_item, 5) mocked_process_item.assert_called_once_with(mocked_service_item, 5)
def test_refresh_service_item_not_image_or_text(self):
def test_refresh_service_item_not_image_or_text():
""" """
Test that the refresh_service_item() method does not refresh a service item if it's neither text or an image Test that the refresh_service_item() method does not refresh a service item if it's neither text or an image
""" """
@ -464,7 +471,8 @@ class TestSlideController(TestCase):
assert 0 == mocked_service_item.render.call_count, 'The render() method should not have been called' assert 0 == mocked_service_item.render.call_count, 'The render() method should not have been called'
assert 0 == mocked_process_item.call_count, 'The mocked_process_item() method should not have been called' assert 0 == mocked_process_item.call_count, 'The mocked_process_item() method should not have been called'
def test_add_service_item_with_song_edit(self):
def test_add_service_item_with_song_edit():
""" """
Test the add_service_item() method when song_edit is True Test the add_service_item() method when song_edit is True
""" """
@ -483,7 +491,8 @@ class TestSlideController(TestCase):
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)
def test_add_service_item_without_song_edit(self):
def test_add_service_item_without_song_edit():
""" """
Test the add_service_item() method when song_edit is False Test the add_service_item() method when song_edit is False
""" """
@ -502,7 +511,8 @@ class TestSlideController(TestCase):
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)
def test_replace_service_manager_item_different_items(self):
def test_replace_service_manager_item_different_items():
""" """
Test that when the service items are not the same, nothing happens Test that when the service items are not the same, nothing happens
""" """
@ -523,7 +533,8 @@ class TestSlideController(TestCase):
assert 0 == mocked_preview_widget.current_slide_number.call_count, \ assert 0 == mocked_preview_widget.current_slide_number.call_count, \
'The preview_widget current_slide_number.() method should not have been called' 'The preview_widget current_slide_number.() method should not have been called'
def test_replace_service_manager_item_same_item(self):
def test_replace_service_manager_item_same_item():
""" """
Test that when the service item is the same, the service item is reprocessed Test that when the service item is the same, the service item is reprocessed
""" """
@ -544,7 +555,8 @@ class TestSlideController(TestCase):
mocked_preview_widget.current_slide_number.assert_called_with() mocked_preview_widget.current_slide_number.assert_called_with()
mocked_process_item.assert_called_once_with(mocked_item, 7) mocked_process_item.assert_called_once_with(mocked_item, 7)
def test_on_slide_blank(self):
def test_on_slide_blank():
""" """
Test on_slide_blank Test on_slide_blank
""" """
@ -558,7 +570,8 @@ class TestSlideController(TestCase):
# THEN: on_blank_display should have been called with True # THEN: on_blank_display should have been called with True
slide_controller.on_blank_display.assert_called_once_with(True) slide_controller.on_blank_display.assert_called_once_with(True)
def test_on_slide_unblank(self):
def test_on_slide_unblank():
""" """
Test on_slide_unblank Test on_slide_unblank
""" """
@ -572,7 +585,8 @@ class TestSlideController(TestCase):
# THEN: on_blank_display should have been called with False # THEN: on_blank_display should have been called with False
slide_controller.on_blank_display.assert_called_once_with(False) slide_controller.on_blank_display.assert_called_once_with(False)
def test_on_slide_selected_index_no_service_item(self):
def test_on_slide_selected_index_no_service_item():
""" """
Test that when there is no service item, the on_slide_selected_index() method returns immediately Test that when there is no service item, the on_slide_selected_index() method returns immediately
""" """
@ -587,8 +601,9 @@ class TestSlideController(TestCase):
# THEN: It should have exited early # THEN: It should have exited early
assert 0 == mocked_item.is_command.call_count, 'The service item should have not been called' assert 0 == mocked_item.is_command.call_count, 'The service item should have not been called'
@patch.object(Registry, 'execute') @patch.object(Registry, 'execute')
def test_on_slide_selected_index_service_item_command(self, mocked_execute): def test_on_slide_selected_index_service_item_command(mocked_execute):
""" """
Test that when there is a command service item, the command is executed Test that when there is a command service item, the command is executed
""" """
@ -617,8 +632,9 @@ class TestSlideController(TestCase):
assert 0 == mocked_preview_widget.change_slide.call_count, 'Change slide should not have been called' assert 0 == mocked_preview_widget.change_slide.call_count, 'Change slide should not have been called'
assert 0 == mocked_slide_selected.call_count, 'slide_selected should not have been called' assert 0 == mocked_slide_selected.call_count, 'slide_selected should not have been called'
@patch.object(Registry, 'execute') @patch.object(Registry, 'execute')
def test_on_slide_selected_index_service_item_not_command(self, mocked_execute): def test_on_slide_selected_index_service_item_not_command(mocked_execute):
""" """
Test that when there is a service item but it's not a command, the preview widget is updated Test that when there is a service item but it's not a command, the preview widget is updated
""" """
@ -646,8 +662,9 @@ class TestSlideController(TestCase):
mocked_preview_widget.change_slide.assert_called_once_with(7) mocked_preview_widget.change_slide.assert_called_once_with(7)
mocked_slide_selected.assert_called_once_with() mocked_slide_selected.assert_called_once_with()
@patch.object(Registry, 'execute') @patch.object(Registry, 'execute')
def test_process_item(self, mocked_execute): def test_process_item(mocked_execute):
""" """
Test that presentation service-items is closed when followed by a media service-item Test that presentation service-items is closed when followed by a media service-item
""" """
@ -667,8 +684,8 @@ class TestSlideController(TestCase):
mocked_media_item.is_image.return_value = False mocked_media_item.is_image.return_value = False
mocked_media_item.from_service = False mocked_media_item.from_service = False
mocked_media_item.get_frames.return_value = [] mocked_media_item.get_frames.return_value = []
Registry.create()
mocked_main_window = MagicMock() mocked_main_window = MagicMock()
Registry.create()
Registry().register('main_window', mocked_main_window) Registry().register('main_window', mocked_main_window)
Registry().register('media_controller', MagicMock()) Registry().register('media_controller', MagicMock())
slide_controller = SlideController(None) slide_controller = SlideController(None)
@ -693,7 +710,8 @@ class TestSlideController(TestCase):
assert 'mocked_presentation_item_stop' == mocked_execute.call_args_list[1][0][0], \ assert 'mocked_presentation_item_stop' == mocked_execute.call_args_list[1][0][0], \
'The presentation should have been stopped.' 'The presentation should have been stopped.'
def test_live_stolen_focus_shortcuts(self):
def test_live_stolen_focus_shortcuts():
""" """
Test that all the needed shortcuts are available in scenarios where Live has stolen focus. Test that all the needed shortcuts are available in scenarios where Live has stolen focus.
These are found under def __add_actions_to_widget(self, widget): in slidecontroller.py These are found under def __add_actions_to_widget(self, widget): in slidecontroller.py
@ -721,20 +739,19 @@ class TestSlideController(TestCase):
slide_controller.theme_screen, slide_controller.blank_screen slide_controller.theme_screen, slide_controller.blank_screen
]) ])
@patch('openlp.core.ui.slidecontroller.Settings')
def test_on_preview_double_click_unblank_display(self, MockedSettings): def test_on_preview_double_click_unblank_display(mock_settings):
# GIVEN: A slide controller, actions needed, settins set to True. # GIVEN: A slide controller, actions needed, settings set to True.
slide_controller = SlideController(None) slide_controller = SlideController(None)
mocked_settings = MagicMock() mocked_settings = MagicMock()
mocked_settings.return_value = True mocked_settings.return_value = True
MockedSettings.return_value = mocked_settings mock_settings.return_value = mocked_settings
slide_controller.service_item = MagicMock() slide_controller.service_item = MagicMock()
slide_controller.service_item.is_media = MagicMock() slide_controller.service_item.is_media = MagicMock()
slide_controller.on_media_close = MagicMock() slide_controller.on_media_close = MagicMock()
slide_controller.on_go_live = MagicMock() slide_controller.on_go_live = MagicMock()
slide_controller.on_preview_add_to_service = MagicMock() slide_controller.on_preview_add_to_service = MagicMock()
slide_controller.media_reset = MagicMock() slide_controller.media_reset = MagicMock()
Registry.create()
Registry().set_flag('has doubleclick added item to service', True) Registry().set_flag('has doubleclick added item to service', True)
# WHEN: on_preview_double_click is called # WHEN: on_preview_double_click is called
@ -744,20 +761,17 @@ class TestSlideController(TestCase):
assert 1 == slide_controller.on_go_live.call_count, 'on_go_live should have been called once.' assert 1 == slide_controller.on_go_live.call_count, 'on_go_live should have been called once.'
assert 0 == slide_controller.on_preview_add_to_service.call_count, 'Should have not been called.' assert 0 == slide_controller.on_preview_add_to_service.call_count, 'Should have not been called.'
@patch('openlp.core.ui.slidecontroller.Settings')
def test_on_preview_double_click_add_to_service(self, MockedSettings): def test_on_preview_double_click_add_to_service(mock_settings):
# GIVEN: A slide controller, actions needed, settins set to False. # GIVEN: A slide controller, actions needed, settings set to False.
slide_controller = SlideController(None) slide_controller = SlideController(None)
mocked_settings = MagicMock() mock_settings.value.return_value = False
mocked_settings.value.return_value = False
MockedSettings.return_value = mocked_settings
slide_controller.service_item = MagicMock() slide_controller.service_item = MagicMock()
slide_controller.service_item.is_media = MagicMock() slide_controller.service_item.is_media = MagicMock()
slide_controller.on_media_close = MagicMock() slide_controller.on_media_close = MagicMock()
slide_controller.on_go_live = MagicMock() slide_controller.on_go_live = MagicMock()
slide_controller.on_preview_add_to_service = MagicMock() slide_controller.on_preview_add_to_service = MagicMock()
slide_controller.media_reset = MagicMock() slide_controller.media_reset = MagicMock()
Registry.create()
Registry().set_flag('has doubleclick added item to service', False) Registry().set_flag('has doubleclick added item to service', False)
# WHEN: on_preview_double_click is called # WHEN: on_preview_double_click is called
@ -767,9 +781,10 @@ class TestSlideController(TestCase):
assert 0 == slide_controller.on_go_live.call_count, 'on_go_live Should have not been called.' assert 0 == slide_controller.on_go_live.call_count, 'on_go_live Should have not been called.'
assert 1 == slide_controller.on_preview_add_to_service.call_count, 'Should have been called once.' assert 1 == slide_controller.on_preview_add_to_service.call_count, 'Should have been called once.'
@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')
def test_update_preview_live(self, mocked_singleShot, mocked_image_manager): def test_update_preview_live(mocked_singleShot, mocked_image_manager):
""" """
Test that the preview screen is updated with a screen grab for live service items Test that the preview screen is updated with a screen grab for live service items
""" """
@ -809,9 +824,10 @@ class TestSlideController(TestCase):
assert 2 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should have been called 2 times' assert 2 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should have been called 2 times'
assert 0 == mocked_image_manager.get_image.call_count, 'image_manager not be called' assert 0 == mocked_image_manager.get_image.call_count, 'image_manager not 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')
def test_update_preview_pres(self, mocked_singleShot, mocked_image_manager): def test_update_preview_pres(mocked_singleShot, mocked_image_manager):
""" """
Test that the preview screen is updated with the correct preview for presentation service items Test that the preview screen is updated with the correct preview for presentation service items
""" """
@ -849,11 +865,11 @@ class TestSlideController(TestCase):
# THEN: setPixmap and the image_manager should have been called # THEN: setPixmap and the image_manager should have been called
assert 1 == slide_controller.preview_display.set_single_image.call_count, 'set_single_image should be called' assert 1 == slide_controller.preview_display.set_single_image.call_count, 'set_single_image 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 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')
def test_update_preview_media(self, mocked_singleShot, mocked_image_manager): def test_update_preview_media(mocked_singleShot, mocked_image_manager):
""" """
Test that the preview screen is updated with the correct preview for media service items Test that the preview screen is updated with the correct preview for media service items
""" """
@ -893,9 +909,10 @@ class TestSlideController(TestCase):
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'
@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')
def test_update_preview_image(self, mocked_singleShot, mocked_image_manager): def test_update_preview_image(mocked_singleShot, mocked_image_manager):
""" """
Test that the preview screen is updated with the correct preview for image service items Test that the preview screen is updated with the correct preview for image service items
""" """
@ -935,14 +952,14 @@ class TestSlideController(TestCase):
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'
class TestInfoLabel(TestCase): def test_paint_event_text_fits():
def test_paint_event_text_fits(self):
""" """
Test the paintEvent method when text fits the label Test the paintEvent method when text fits the label
""" """
font = QtGui.QFont()
metrics = QtGui.QFontMetrics(font)
with patch('openlp.core.ui.slidecontroller.QtWidgets.QLabel'), \ with patch('openlp.core.ui.slidecontroller.QtWidgets.QLabel'), \
patch('openlp.core.ui.slidecontroller.QtGui.QFontMetrics') as MockFontMetrics, \
patch('openlp.core.ui.slidecontroller.QtGui.QPainter') as mocked_qpainter: patch('openlp.core.ui.slidecontroller.QtGui.QPainter') as mocked_qpainter:
# GIVEN: An instance of InfoLabel, with mocked text return, width and rect methods # GIVEN: An instance of InfoLabel, with mocked text return, width and rect methods
@ -955,28 +972,28 @@ class TestInfoLabel(TestCase):
info_label.rect = mocked_rect info_label.rect = mocked_rect
info_label.text = mocked_text info_label.text = mocked_text
info_label.width = mocked_width info_label.width = mocked_width
mocked_font_metrics = MagicMock()
mocked_font_metrics.elidedText.return_value = test_string
MockFontMetrics.return_value = mocked_font_metrics
# WHEN: The instance is wider than its text, and the paintEvent method is called # WHEN: The instance is wider than its text, and the paintEvent method is called
info_label.width.return_value = metrics.boundingRect(test_string).width() + 20
info_label.paintEvent(MagicMock()) info_label.paintEvent(MagicMock())
# THEN: The text should be drawn centered with the complete test_string # THEN: The text should be drawn centered with the complete test_string
mocked_qpainter().drawText.assert_called_once_with(mocked_rect(), QtCore.Qt.AlignCenter, test_string) mocked_qpainter().drawText.assert_called_once_with(mocked_rect(), QtCore.Qt.AlignCenter, test_string)
def test_paint_event_text_doesnt_fit(self):
def test_paint_event_text_doesnt_fit():
""" """
Test the paintEvent method when text fits the label Test the paintEvent method when text fits the label
""" """
font = QtGui.QFont()
metrics = QtGui.QFontMetrics(font)
with patch('openlp.core.ui.slidecontroller.QtWidgets.QLabel'), \ with patch('openlp.core.ui.slidecontroller.QtWidgets.QLabel'), \
patch('openlp.core.ui.slidecontroller.QtGui.QFontMetrics') as MockFontMetrics, \
patch('openlp.core.ui.slidecontroller.QtGui.QPainter') as mocked_qpainter: patch('openlp.core.ui.slidecontroller.QtGui.QPainter') as mocked_qpainter:
# GIVEN: An instance of InfoLabel, with mocked text return, width and rect methods # GIVEN: An instance of InfoLabel, with mocked text return, width and rect methods
info_label = InfoLabel() info_label = InfoLabel()
test_string = 'Label Text' test_string = 'Label Text'
elided_test_string = test_string[0:5] + '...'
mocked_rect = MagicMock() mocked_rect = MagicMock()
mocked_text = MagicMock() mocked_text = MagicMock()
mocked_width = MagicMock() mocked_width = MagicMock()
@ -984,18 +1001,19 @@ class TestInfoLabel(TestCase):
info_label.rect = mocked_rect info_label.rect = mocked_rect
info_label.text = mocked_text info_label.text = mocked_text
info_label.width = mocked_width info_label.width = mocked_width
mocked_font_metrics = MagicMock()
mocked_font_metrics.elidedText.return_value = elided_test_string
MockFontMetrics.return_value = mocked_font_metrics
# WHEN: The instance is narrower than its text, and the paintEvent method is called # WHEN: The instance is narrower than its text, and the paintEvent method is called
label_width = metrics.boundingRect(test_string).width() - 20
info_label.width.return_value = label_width
info_label.paintEvent(MagicMock()) info_label.paintEvent(MagicMock())
# THEN: The text should be drawn aligned left with an elided test_string # THEN: The text should be drawn aligned left with an elided test_string
elided_test_string = metrics.elidedText(test_string, QtCore.Qt.ElideRight, label_width)
mocked_qpainter().drawText.assert_called_once_with(mocked_rect(), QtCore.Qt.AlignLeft, elided_test_string) mocked_qpainter().drawText.assert_called_once_with(mocked_rect(), QtCore.Qt.AlignLeft, elided_test_string)
@patch('builtins.super') @patch('builtins.super')
def test_set_text(self, mocked_super): def test_set_text(mocked_super):
""" """
Test the reimplemented setText method Test the reimplemented setText method
""" """
@ -1012,9 +1030,7 @@ class TestInfoLabel(TestCase):
mocked_super().setText.assert_called_once_with('Label Text') mocked_super().setText.assert_called_once_with('Label Text')
class TestLiveController(TestCase): def test_initial_live_controller():
def test_initial_live_controller(self):
""" """
Test the initial live slide controller state . Test the initial live slide controller state .
""" """
@ -1027,9 +1043,7 @@ class TestLiveController(TestCase):
assert live_controller.is_live is True, 'The slide controller should be a live controller' assert live_controller.is_live is True, 'The slide controller should be a live controller'
class TestPreviewLiveController(TestCase): def test_initial_preview_controller():
def test_initial_preview_controller(self):
""" """
Test the initial preview slide controller state. Test the initial preview slide controller state.
""" """