# -*- coding: utf-8 -*- ########################################################################## # OpenLP - Open Source Lyrics Projection # # ---------------------------------------------------------------------- # # Copyright (c) 2008-2022 OpenLP Developers # # ---------------------------------------------------------------------- # # 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 . # ########################################################################## """ Test the :mod:`~openlp.core.display.render` package. """ from unittest.mock import MagicMock, patch from openlp.core.display.render import compare_chord_lyric_width, find_formatting_tags, remove_tags, render_chords, \ render_chords_for_printing, render_tags, ThemePreviewRenderer from openlp.core.lib.formattingtags import FormattingTags @patch('openlp.core.display.render.FormattingTags.get_html_tags') def test_remove_tags(mocked_get_tags): """ Test remove_tags() method. """ # GIVEN: Mocked get_html_tags() method. mocked_get_tags.return_value = [{ 'desc': 'Black', 'start tag': '{b}', 'start html': '', 'end tag': '{/b}', 'end html': '', 'protected': True, 'temporary': False, 'hidden': False }, { 'desc': 'Italics', 'start tag': '{it}', 'start html': '', 'end tag': '{/it}', 'end html': '', 'protected': True, 'temporary': False, 'hidden': False }, { 'desc': 'Superscript', 'start tag': '{su}', 'start html': '', 'end tag': '{/su}', 'end html': '', 'protected': True, 'temporary': False, 'hidden': False }] string_to_pass = 'ASDF
foo{br}bar {b}black{/b} {su}1,1 {/su}In the {it}beggining{/it}...' expected_string = 'ASDF\nfoo\nbar black 1,1 In the beggining...' # WHEN: Clean the string. result_string = remove_tags(string_to_pass) # THEN: The strings should be identical. assert result_string == expected_string, 'The strings should be identical' @patch('openlp.core.display.render.FormattingTags.get_html_tags') def test_render_tags(mocked_get_tags, settings): """ Test the render_tags() method. """ # GIVEN: Mocked get_html_tags() method. settings.setValue('songs/chord notation', 'english') mocked_get_tags.return_value = [ { 'desc': 'Black', 'start tag': '{b}', 'start html': '', 'end tag': '{/b}', 'end html': '', 'protected': True, 'temporary': False, 'hidden': False }, { 'desc': 'Yellow', 'start tag': '{y}', 'start html': '', 'end tag': '{/y}', 'end html': '', 'protected': True, 'temporary': False, 'hidden': False }, { 'desc': 'Green', 'start tag': '{g}', 'start html': '', 'end tag': '{/g}', 'end html': '', 'protected': True, 'temporary': False, 'hidden': False } ] string_to_pass = '{b}black{/b}{y}yellow{/y}' expected_string = 'black' + \ 'yellow' # WHEN: Replace the tags. result_string = render_tags(string_to_pass) # THEN: The strings should be identical. assert result_string == expected_string, 'The strings should be identical.' def test_render_chords(settings): """ Test that the rendering of chords works as expected. """ # GIVEN: A lyrics-line with chords settings.setValue('songs/chord notation', 'english') text_with_chords = 'H[C]alleluya.[F] [G/B]' # WHEN: Expanding the chords text_with_rendered_chords = render_chords(text_with_chords) # THEN: We should get html that looks like below expected_html = 'HC' \ 'alleluya.F' \ '   G/B' assert text_with_rendered_chords == expected_html, 'The rendered chords should look as expected' def test_render_chords_with_special_chars(settings): """ Test that the rendering of chords works as expected when special chars are involved. """ # GIVEN: A lyrics-line with chords settings.setValue('songs/chord notation', 'english') text_with_chords = "I[D]'M NOT MOVED BY WHAT I SEE HALLE[F]LUJA[C]H" # WHEN: Expanding the chords text_with_rendered_chords = render_tags(text_with_chords, can_render_chords=True) # THEN: We should get html that looks like below expected_html = 'ID' \ ''M NOT MOVED BY WHAT I SEE HALLEF' \ 'LUJACH' assert text_with_rendered_chords == expected_html, 'The rendered chords should look as expected' def test_compare_chord_lyric_short_chord(): """ Test that the chord/lyric comparing works. """ # GIVEN: A chord and some lyric chord = 'C' lyrics = 'alleluya' # WHEN: Comparing the chord and lyrics ret = compare_chord_lyric_width(chord, lyrics) # THEN: The returned value should 0 because the lyric is longer than the chord assert ret == 0, 'The returned value should 0 because the lyric is longer than the chord' def test_compare_chord_lyric_long_chord(): """ Test that the chord/lyric comparing works. """ # GIVEN: A chord and some lyric chord = 'Gsus' lyrics = 'me' # WHEN: Comparing the chord and lyrics ret = compare_chord_lyric_width(chord, lyrics) # THEN: The returned value should 4 because the chord is longer than the lyric assert ret == 4, 'The returned value should 4 because the chord is longer than the lyric' def test_render_chords_for_printing(settings): """ Test that the rendering of chords for printing works as expected. """ # GIVEN: A lyrics-line with chords settings.setValue('songs/chord notation', 'english') text_with_chords = '{st}[D]Amazing {r}gr[D7]ace{/r} how [G]sweet the [D]sound [F]{/st}' FormattingTags.load_tags() # WHEN: Expanding the chords text_with_rendered_chords = render_chords_for_printing(text_with_chords, '{br}') # THEN: We should get html that looks like below expected_html = '
'\ '
 D
{st}{/st}' \ '{st}Amazing {/st}
' \ '
 D7
{st}{r}gr' \ '{/r}{/st}{r}{st}ace{/r} {/st}
'\ '
 
{st} {/st}
' \ '
 
{st}how {/st}' \ '
G
{st}' \ 'sweet {/st}
 
{st}the {/st}
' \ '
D
{st}sound {/st}
 
{st} {/st}
' \ '' \ '
F
{st}{/st} 
' assert text_with_rendered_chords == expected_html, 'The rendered chords should look as expected!' def test_find_formatting_tags(settings): """ Test that find_formatting_tags works as expected """ # GIVEN: Lyrics with formatting tags and a empty list of formatting tags lyrics = '{st}Amazing {r}grace{/r} how sweet the sound' tags = [] FormattingTags.load_tags() # WHEN: Detecting active formatting tags active_tags = find_formatting_tags(lyrics, tags) # THEN: The list of active tags should contain only 'st' assert active_tags == ['st'], 'The list of active tags should contain only "st"' def test_format_slide(settings): """ Test that the format_slide function works as expected """ # GIVEN: Renderer where no text fits on screen (force one line per slide) with patch('openlp.core.display.render.ThemePreviewRenderer.__init__') as init_fn: init_fn.return_value = None preview_renderer = ThemePreviewRenderer() lyrics = 'hello {st}test{/st}\nline two\n[---]\nline after optional split' preview_renderer._is_initialised = True preview_renderer.log_debug = MagicMock() preview_renderer._text_fits_on_slide = MagicMock(side_effect=lambda a: a == '') preview_renderer.force_page = False # WHEN: format_slide is run formatted_slides = preview_renderer.format_slide(lyrics, None) # THEN: The formatted slides should have all the text and no blank slides assert formatted_slides == ['hello {st}test{/st}', 'line two', 'line after optional split'] def test_format_slide_no_split(settings): """ Test that the format_slide function doesn't split a slide that fits """ # GIVEN: Renderer where no text fits on screen (force one line per slide) with patch('openlp.core.display.render.ThemePreviewRenderer.__init__') as init_fn: init_fn.return_value = None preview_renderer = ThemePreviewRenderer() lyrics = 'line one\n[---]\nline two' preview_renderer._is_initialised = True preview_renderer.log_debug = MagicMock() preview_renderer._text_fits_on_slide = MagicMock(return_value=True) preview_renderer.force_page = False # WHEN: format_slide is run formatted_slides = preview_renderer.format_slide(lyrics, None) # THEN: The formatted slides should have all the text and no blank slides assert formatted_slides == ['line one
line two']