2013-10-13 17:02:12 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2019-04-13 13:00:22 +00:00
|
|
|
##########################################################################
|
|
|
|
# OpenLP - Open Source Lyrics Projection #
|
|
|
|
# ---------------------------------------------------------------------- #
|
2020-12-30 21:42:49 +00:00
|
|
|
# Copyright (c) 2008-2021 OpenLP Developers #
|
2019-04-13 13:00:22 +00:00
|
|
|
# ---------------------------------------------------------------------- #
|
|
|
|
# This program is free software: you can redistribute it and/or modify #
|
|
|
|
# it under the terms of the GNU General Public License as published by #
|
|
|
|
# the Free Software Foundation, either version 3 of the License, or #
|
|
|
|
# (at your option) any later version. #
|
|
|
|
# #
|
|
|
|
# This program is distributed in the hope that it will be useful, #
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
|
|
|
# GNU General Public License for more details. #
|
|
|
|
# #
|
|
|
|
# You should have received a copy of the GNU General Public License #
|
|
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
|
|
|
|
##########################################################################
|
2013-10-13 17:02:12 +00:00
|
|
|
"""
|
|
|
|
Package to test the openlp.core.lib.theme package.
|
|
|
|
"""
|
2020-07-01 16:12:00 +00:00
|
|
|
import pytest
|
|
|
|
from PyQt5 import QtCore
|
2017-09-26 16:39:13 +00:00
|
|
|
from pathlib import Path
|
2019-10-26 10:00:07 +00:00
|
|
|
from unittest.mock import MagicMock, patch
|
2013-10-13 17:02:12 +00:00
|
|
|
|
2019-12-12 01:03:35 +00:00
|
|
|
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, TransitionType, TransitionSpeed, Theme
|
2019-07-03 13:23:23 +00:00
|
|
|
|
|
|
|
|
2020-07-01 16:12:00 +00:00
|
|
|
@pytest.fixture
|
|
|
|
def mock_geometry():
|
|
|
|
mocked_screen = MagicMock()
|
|
|
|
mocked_screen.display_geometry = QtCore.QRect(10, 20, 400, 600)
|
|
|
|
mocked_screenlist = MagicMock()
|
|
|
|
mocked_screenlist.current = mocked_screen
|
|
|
|
screenlist_patcher = patch('openlp.core.lib.theme.ScreenList', return_value=mocked_screenlist)
|
|
|
|
screenlist_patcher.start()
|
|
|
|
yield
|
|
|
|
screenlist_patcher.stop()
|
|
|
|
|
|
|
|
|
2020-02-15 21:04:17 +00:00
|
|
|
def test_background_type_to_string():
|
2019-07-03 13:23:23 +00:00
|
|
|
"""
|
2020-02-15 21:04:17 +00:00
|
|
|
Test the to_string method of :class:`BackgroundType`
|
2019-07-03 13:23:23 +00:00
|
|
|
"""
|
2020-02-15 21:04:17 +00:00
|
|
|
# GIVEN: The BackgroundType members
|
|
|
|
background_type_solid = BackgroundType.Solid
|
|
|
|
background_type_gradient = BackgroundType.Gradient
|
|
|
|
background_type_image = BackgroundType.Image
|
|
|
|
background_type_transparent = BackgroundType.Transparent
|
|
|
|
background_type_video = BackgroundType.Video
|
|
|
|
background_type_stream = BackgroundType.Stream
|
|
|
|
|
|
|
|
# WHEN: Calling BackgroundType.to_string
|
|
|
|
# THEN: The string equivalents should be returned
|
|
|
|
assert BackgroundType.to_string(background_type_solid) == 'solid'
|
|
|
|
assert BackgroundType.to_string(background_type_gradient) == 'gradient'
|
|
|
|
assert BackgroundType.to_string(background_type_image) == 'image'
|
|
|
|
assert BackgroundType.to_string(background_type_transparent) == 'transparent'
|
|
|
|
assert BackgroundType.to_string(background_type_video) == 'video'
|
|
|
|
assert BackgroundType.to_string(background_type_stream) == 'stream'
|
|
|
|
|
|
|
|
|
|
|
|
def test_background_type_from_string():
|
2013-10-13 17:02:12 +00:00
|
|
|
"""
|
2020-02-15 21:04:17 +00:00
|
|
|
Test the from_string method of :class:`BackgroundType`
|
2013-10-13 17:02:12 +00:00
|
|
|
"""
|
2020-02-15 21:04:17 +00:00
|
|
|
# GIVEN: The BackgroundType strings
|
|
|
|
background_type_solid = 'solid'
|
|
|
|
background_type_gradient = 'gradient'
|
|
|
|
background_type_image = 'image'
|
|
|
|
background_type_transparent = 'transparent'
|
|
|
|
background_type_video = 'video'
|
|
|
|
background_type_stream = 'stream'
|
|
|
|
|
|
|
|
# WHEN: Calling BackgroundType.from_string
|
|
|
|
# THEN: The enum equivalents should be returned
|
|
|
|
assert BackgroundType.from_string(background_type_solid) == BackgroundType.Solid
|
|
|
|
assert BackgroundType.from_string(background_type_gradient) == BackgroundType.Gradient
|
|
|
|
assert BackgroundType.from_string(background_type_image) == BackgroundType.Image
|
|
|
|
assert BackgroundType.from_string(background_type_transparent) == BackgroundType.Transparent
|
|
|
|
assert BackgroundType.from_string(background_type_video) == BackgroundType.Video
|
|
|
|
assert BackgroundType.from_string(background_type_stream) == BackgroundType.Stream
|
|
|
|
|
|
|
|
|
|
|
|
def test_background_gradient_type_to_string():
|
|
|
|
"""
|
|
|
|
Test the to_string method of :class:`BackgroundGradientType`
|
|
|
|
"""
|
|
|
|
# GIVEN: The BackgroundGradientType member
|
|
|
|
background_gradient_horizontal = BackgroundGradientType.Horizontal
|
|
|
|
background_gradient_vertical = BackgroundGradientType.Vertical
|
|
|
|
background_gradient_circular = BackgroundGradientType.Circular
|
|
|
|
background_gradient_left_top = BackgroundGradientType.LeftTop
|
|
|
|
background_gradient_left_bottom = BackgroundGradientType.LeftBottom
|
|
|
|
|
|
|
|
# WHEN: Calling BackgroundGradientType.to_string
|
|
|
|
# THEN: The string equivalents should be returned
|
|
|
|
assert BackgroundGradientType.to_string(background_gradient_horizontal) == 'horizontal'
|
|
|
|
assert BackgroundGradientType.to_string(background_gradient_vertical) == 'vertical'
|
|
|
|
assert BackgroundGradientType.to_string(background_gradient_circular) == 'circular'
|
|
|
|
assert BackgroundGradientType.to_string(background_gradient_left_top) == 'leftTop'
|
|
|
|
assert BackgroundGradientType.to_string(background_gradient_left_bottom) == 'leftBottom'
|
|
|
|
|
|
|
|
|
|
|
|
def test_background_gradient_type_from_string():
|
|
|
|
"""
|
|
|
|
Test the from_string method of :class:`BackgroundGradientType`
|
|
|
|
"""
|
|
|
|
# GIVEN: The BackgroundGradientType strings
|
|
|
|
background_gradient_horizontal = 'horizontal'
|
|
|
|
background_gradient_vertical = 'vertical'
|
|
|
|
background_gradient_circular = 'circular'
|
|
|
|
background_gradient_left_top = 'leftTop'
|
|
|
|
background_gradient_left_bottom = 'leftBottom'
|
|
|
|
|
|
|
|
# WHEN: Calling BackgroundGradientType.from_string
|
|
|
|
# THEN: The enum equivalents should be returned
|
|
|
|
assert BackgroundGradientType.from_string(background_gradient_horizontal) == BackgroundGradientType.Horizontal
|
|
|
|
assert BackgroundGradientType.from_string(background_gradient_vertical) == BackgroundGradientType.Vertical
|
|
|
|
assert BackgroundGradientType.from_string(background_gradient_circular) == BackgroundGradientType.Circular
|
|
|
|
assert BackgroundGradientType.from_string(background_gradient_left_top) == BackgroundGradientType.LeftTop
|
|
|
|
assert BackgroundGradientType.from_string(background_gradient_left_bottom) == BackgroundGradientType.LeftBottom
|
|
|
|
|
|
|
|
|
|
|
|
def test_transition_type_to_string():
|
|
|
|
"""
|
|
|
|
Test the to_string method of :class:`TransitionType`
|
|
|
|
"""
|
|
|
|
# GIVEN: The TransitionType member
|
|
|
|
transition_type_fade = TransitionType.Fade
|
|
|
|
transition_type_slide = TransitionType.Slide
|
|
|
|
transition_type_convex = TransitionType.Convex
|
|
|
|
transition_type_concave = TransitionType.Concave
|
|
|
|
transition_type_zoom = TransitionType.Zoom
|
|
|
|
|
|
|
|
# WHEN: Calling TransitionType.to_string
|
|
|
|
# THEN: The string equivalents should be returned
|
|
|
|
assert TransitionType.to_string(transition_type_fade) == 'fade'
|
|
|
|
assert TransitionType.to_string(transition_type_slide) == 'slide'
|
|
|
|
assert TransitionType.to_string(transition_type_convex) == 'convex'
|
|
|
|
assert TransitionType.to_string(transition_type_concave) == 'concave'
|
|
|
|
assert TransitionType.to_string(transition_type_zoom) == 'zoom'
|
|
|
|
|
|
|
|
|
|
|
|
def test_transition_type_from_string():
|
|
|
|
"""
|
|
|
|
Test the from_string method of :class:`TransitionType`
|
|
|
|
"""
|
|
|
|
# GIVEN: The TransitionType strings
|
|
|
|
transition_type_fade = 'fade'
|
|
|
|
transition_type_slide = 'slide'
|
|
|
|
transition_type_convex = 'convex'
|
|
|
|
transition_type_concave = 'concave'
|
|
|
|
transition_type_zoom = 'zoom'
|
|
|
|
|
|
|
|
# WHEN: Calling TransitionType.from_string
|
|
|
|
# THEN: The enum equivalents should be returned
|
|
|
|
assert TransitionType.from_string(transition_type_fade) == TransitionType.Fade
|
|
|
|
assert TransitionType.from_string(transition_type_slide) == TransitionType.Slide
|
|
|
|
assert TransitionType.from_string(transition_type_convex) == TransitionType.Convex
|
|
|
|
assert TransitionType.from_string(transition_type_concave) == TransitionType.Concave
|
|
|
|
assert TransitionType.from_string(transition_type_zoom) == TransitionType.Zoom
|
|
|
|
|
|
|
|
|
|
|
|
def test_transition_speed_to_string():
|
|
|
|
"""
|
|
|
|
Test the to_string method of :class:`TransitionSpeed`
|
|
|
|
"""
|
|
|
|
# GIVEN: The TransitionSpeed member
|
|
|
|
transition_speed_normal = TransitionSpeed.Normal
|
|
|
|
transition_speed_fast = TransitionSpeed.Fast
|
|
|
|
transition_speed_slow = TransitionSpeed.Slow
|
|
|
|
|
|
|
|
# WHEN: Calling TransitionSpeed.to_string
|
|
|
|
# THEN: The string equivalents should be returned
|
|
|
|
assert TransitionSpeed.to_string(transition_speed_normal) == 'normal'
|
|
|
|
assert TransitionSpeed.to_string(transition_speed_fast) == 'fast'
|
|
|
|
assert TransitionSpeed.to_string(transition_speed_slow) == 'slow'
|
|
|
|
|
|
|
|
|
|
|
|
def test_transition_speed_from_string():
|
|
|
|
"""
|
|
|
|
Test the from_string method of :class:`TransitionSpeed`
|
|
|
|
"""
|
|
|
|
# GIVEN: The TransitionSpeed strings
|
|
|
|
transition_speed_normal = 'normal'
|
|
|
|
transition_speed_fast = 'fast'
|
|
|
|
transition_speed_slow = 'slow'
|
|
|
|
|
|
|
|
# WHEN: Calling TransitionSpeed.from_string
|
|
|
|
# THEN: The enum equivalents should be returned
|
|
|
|
assert TransitionSpeed.from_string(transition_speed_normal) == TransitionSpeed.Normal
|
|
|
|
assert TransitionSpeed.from_string(transition_speed_fast) == TransitionSpeed.Fast
|
|
|
|
assert TransitionSpeed.from_string(transition_speed_slow) == TransitionSpeed.Slow
|
|
|
|
|
|
|
|
|
2020-07-01 16:12:00 +00:00
|
|
|
def test_new_theme(mock_geometry):
|
2020-02-15 21:04:17 +00:00
|
|
|
"""
|
|
|
|
Test the Theme constructor
|
|
|
|
"""
|
|
|
|
# GIVEN: The Theme class
|
|
|
|
# WHEN: A theme object is created
|
|
|
|
default_theme = Theme()
|
|
|
|
|
|
|
|
# THEN: The default values should be correct
|
|
|
|
check_theme(default_theme)
|
|
|
|
|
|
|
|
|
2020-07-01 16:12:00 +00:00
|
|
|
def test_expand_json(mock_geometry):
|
2020-02-15 21:04:17 +00:00
|
|
|
"""
|
|
|
|
Test the expand_json method
|
|
|
|
"""
|
|
|
|
# GIVEN: A Theme object and some JSON to "expand"
|
|
|
|
theme = Theme()
|
|
|
|
theme_json = {
|
|
|
|
'background': {
|
|
|
|
'border_color': '#000000',
|
|
|
|
'type': 'solid'
|
|
|
|
},
|
|
|
|
'display': {
|
|
|
|
'vertical_align': 0
|
|
|
|
},
|
|
|
|
'font': {
|
|
|
|
'footer': {
|
|
|
|
'bold': False
|
2016-07-24 20:41:27 +00:00
|
|
|
},
|
2020-02-15 21:04:17 +00:00
|
|
|
'main': {
|
|
|
|
'name': 'Arial'
|
2016-07-24 20:41:27 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-15 21:04:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# WHEN: Theme.expand_json() is run
|
|
|
|
theme.expand_json(theme_json)
|
|
|
|
|
|
|
|
# THEN: The attributes should be set on the object
|
|
|
|
check_theme(theme)
|
|
|
|
|
|
|
|
|
2020-07-01 16:12:00 +00:00
|
|
|
def test_extend_image_filename(mock_geometry):
|
2020-02-15 21:04:17 +00:00
|
|
|
"""
|
|
|
|
Test the extend_image_filename method
|
|
|
|
"""
|
|
|
|
# GIVEN: A theme object
|
|
|
|
theme = Theme()
|
|
|
|
theme.theme_name = 'MyBeautifulTheme'
|
|
|
|
theme.background_filename = Path('video.mp4')
|
|
|
|
theme.background_type = 'video'
|
|
|
|
path = Path.home()
|
|
|
|
|
|
|
|
# WHEN: Theme.extend_image_filename is run
|
|
|
|
theme.extend_image_filename(path)
|
2013-10-13 17:02:12 +00:00
|
|
|
|
2020-02-15 21:04:17 +00:00
|
|
|
# THEN: The filename of the background should be correct
|
|
|
|
expected_filename = path / 'MyBeautifulTheme' / 'video.mp4'
|
|
|
|
assert expected_filename == theme.background_filename
|
|
|
|
assert 'MyBeautifulTheme' == theme.theme_name
|
|
|
|
|
|
|
|
|
2020-07-01 16:12:00 +00:00
|
|
|
def test_save_retrieve(mock_geometry):
|
2020-02-15 21:04:17 +00:00
|
|
|
"""
|
|
|
|
Load a dummy theme, save it and reload it
|
|
|
|
"""
|
|
|
|
# GIVEN: The default Theme class
|
|
|
|
# WHEN: A theme object is created
|
|
|
|
default_theme = Theme()
|
|
|
|
# THEN: The default values should be correct
|
|
|
|
save_theme_json = default_theme.export_theme()
|
|
|
|
lt = Theme()
|
|
|
|
lt.load_theme(save_theme_json)
|
|
|
|
check_theme(lt)
|
|
|
|
|
|
|
|
|
2020-07-01 16:12:00 +00:00
|
|
|
def test_set_default_header_footer_overridden(mock_geometry):
|
|
|
|
"""
|
|
|
|
Check that when the theme header and footer locations are overridden, the defaults are not set
|
|
|
|
"""
|
|
|
|
# GIVEN: A theme with the overrides on
|
|
|
|
theme = Theme()
|
|
|
|
theme.set_default_header = MagicMock()
|
|
|
|
theme.set_default_footer = MagicMock()
|
|
|
|
theme.font_main_override = True
|
|
|
|
theme.font_footer_override = True
|
|
|
|
|
|
|
|
# WHEN: set_default_header_footer is called
|
|
|
|
theme.set_default_header_footer()
|
|
|
|
|
|
|
|
# THEN: Neither header or footer default fns should have been called
|
|
|
|
assert theme.set_default_header.call_count == 0
|
|
|
|
assert theme.set_default_footer.call_count == 0
|
|
|
|
|
|
|
|
|
2020-02-15 21:04:17 +00:00
|
|
|
def test_set_default_footer(mock_geometry):
|
|
|
|
"""
|
|
|
|
Test the set_default_footer function sets the footer back to default
|
|
|
|
(reletive to the screen)
|
|
|
|
"""
|
|
|
|
# GIVEN: A screen geometry object and a Theme footer with a strange area
|
|
|
|
theme = Theme()
|
|
|
|
theme.font_main_x = 20
|
|
|
|
theme.font_footer_x = 207
|
|
|
|
theme.font_footer_y = 25
|
|
|
|
theme.font_footer_width = 4253
|
|
|
|
theme.font_footer_height = 5423
|
|
|
|
|
|
|
|
# WHEN: set_default_footer is called
|
|
|
|
theme.set_default_footer()
|
|
|
|
|
|
|
|
# THEN: footer should be set, header should not have changed
|
|
|
|
assert theme.font_main_x == 20, 'header should not have been changed'
|
|
|
|
assert theme.font_footer_x == 10, 'x pos should be reset to default of 10'
|
|
|
|
assert theme.font_footer_y == 540, 'y pos should be reset to (screen_size_height * 9 / 10)'
|
|
|
|
assert theme.font_footer_width == 380, 'width should have been reset to (screen_size_width - 20)'
|
|
|
|
assert theme.font_footer_height == 60, 'height should have been reset to (screen_size_height / 10)'
|
|
|
|
|
|
|
|
|
|
|
|
def test_set_default_header(mock_geometry):
|
|
|
|
"""
|
|
|
|
Test the set_default_header function sets the header back to default
|
|
|
|
(reletive to the screen)
|
|
|
|
"""
|
|
|
|
# GIVEN: A screen geometry object and a Theme header with a strange area
|
|
|
|
theme = Theme()
|
|
|
|
theme.font_footer_x = 200
|
|
|
|
theme.font_main_x = 687
|
|
|
|
theme.font_main_y = 546
|
|
|
|
theme.font_main_width = 345
|
|
|
|
theme.font_main_height = 653
|
|
|
|
|
|
|
|
# WHEN: set_default_header is called
|
|
|
|
theme.set_default_header()
|
|
|
|
|
|
|
|
# THEN: footer should be set, header should not have changed
|
|
|
|
assert theme.font_footer_x == 200, 'footer should not have been changed'
|
|
|
|
assert theme.font_main_x == 10, 'x pos should be reset to default of 10'
|
|
|
|
assert theme.font_main_y == 0, 'y pos should be reset to 0'
|
|
|
|
assert theme.font_main_width == 380, 'width should have been reset to (screen_size_width - 20)'
|
|
|
|
assert theme.font_main_height == 540, 'height should have been reset to (screen_size_height * 9 / 10)'
|
|
|
|
|
|
|
|
|
|
|
|
def test_set_default_header_footer(mock_geometry):
|
|
|
|
"""
|
|
|
|
Test the set_default_header_footer function sets the header and footer back to default
|
|
|
|
(reletive to the screen)
|
|
|
|
"""
|
|
|
|
# GIVEN: A screen geometry object and a Theme header with a strange area
|
|
|
|
theme = Theme()
|
|
|
|
theme.font_footer_x = 200
|
|
|
|
theme.font_main_x = 687
|
|
|
|
|
|
|
|
# WHEN: set_default_header is called
|
|
|
|
theme.set_default_header_footer()
|
|
|
|
|
|
|
|
# THEN: footer should be set, header should not have changed
|
|
|
|
assert theme.font_footer_x == 10, 'footer x pos should be reset to default of 10'
|
|
|
|
assert theme.font_main_x == 10, 'header x pos should be reset to default of 10'
|
|
|
|
|
|
|
|
|
|
|
|
def check_theme(theme):
|
|
|
|
assert '#000000' == theme.background_border_color, 'background_border_color should be "#000000"'
|
|
|
|
assert 'solid' == theme.background_type, 'background_type should be "solid"'
|
|
|
|
assert 0 == theme.display_vertical_align, 'display_vertical_align should be 0'
|
|
|
|
assert theme.font_footer_bold is False, 'font_footer_bold should be False'
|
|
|
|
assert 'Arial' == theme.font_main_name, 'font_main_name should be "Arial"'
|
|
|
|
assert 53 == len(theme.__dict__), 'The theme should have 53 attributes'
|