diff --git a/tests/__init__.py b/tests/__init__.py index e09142a4..45c17aec 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -31,3 +31,7 @@ def delete_media_dir(): delete_media_dir() CASES_DIR = Path(Path(__file__).parent, "cases").absolute() FONT_DIR = Path(__file__).parent / "fonts" + +# avoid fail due to env vars. +os.environ["PANGOCAIRO_BACKEND"] = "" +os.environ["FONTCONFIG_PATH"] = "" diff --git a/tests/_manim.py b/tests/_manim.py deleted file mode 100644 index 3ea4676c..00000000 --- a/tests/_manim.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- -"""This file contains helpers for the tests copied and modified -from Manim. -""" - -import os -from pathlib import Path - -from manimpango import Alignment, MarkupUtils - - -class MarkupText: - def __init__( - self, - text: str, - *, - size: int = 1, - line_spacing: int = None, - font: str = None, - slant: str = "NORMAL", - weight: str = "NORMAL", - tab_width: int = 4, - disable_ligatures: bool = False, - justify: bool = None, - indent: float = None, - alignment: Alignment = None, - # for the tests - filename: str = "test.svg", - wrap_text: bool = True, - **kwargs, - ): - self.text = text - self.size = size - self.line_spacing = line_spacing - self.font = font - self.slant = slant - self.weight = weight - self.tab_width = tab_width - self.filename = filename - self.original_text = text - self.disable_ligatures = disable_ligatures - - self.justify = justify - self.indent = indent - self.alignment = alignment - self.wrap_text = wrap_text - if MarkupUtils.validate(self.text): - raise ValueError( - f"Pango cannot parse your markup in {self.text}. " - "Please check for typos, unmatched tags or unescaped " - "special chars like < and &." - ) - self.text2svg() - - def text2svg(self): - """Convert the text to SVG using Pango.""" - size = self.size * 10 - dir_name = Path(self.filename).parent - disable_liga = self.disable_ligatures - if not os.path.exists(dir_name): - os.makedirs(dir_name) - file_name = self.filename - if self.wrap_text: - return MarkupUtils.text2svg( - f"{self.text}", - self.font, - self.slant, - self.weight, - size, - True, # stray positional argument - disable_liga, - file_name, - 20, - 20, - 600, # width - 400, # height - justify=self.justify, - indent=self.indent, - line_spacing=self.line_spacing, - alignment=self.alignment, - ) - else: - return MarkupUtils.text2svg( - f"{self.text}", - self.font, - self.slant, - self.weight, - size, - True, # stray positional argument - disable_liga, - file_name, - 20, - 20, - 600, # width - 400, # height - justify=self.justify, - indent=self.indent, - line_spacing=self.line_spacing, - alignment=self.alignment, - pango_width=-1, - ) - # -1 for no wrapping - # default is full width and then wrap. - - def __repr__(self): - return f"MarkupText({repr(self.original_text)})" diff --git a/tests/test_font_description.py b/tests/test_font_description.py new file mode 100644 index 00000000..a6dae97b --- /dev/null +++ b/tests/test_font_description.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from manimpango import FontProperties + + +def test_init(): + FontProperties() + + +def test_family_property(): + desc = FontProperties() + assert desc.family is None + desc.family = "Roboto" + assert desc.family == "Roboto" + + +def test_size_property(): + desc = FontProperties() + assert desc.size is None + desc.size = 20 + assert desc.size == 20 diff --git a/tests/test_font_manager.py b/tests/test_font_manager.py new file mode 100644 index 00000000..e23c9fcb --- /dev/null +++ b/tests/test_font_manager.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +import sys +from pathlib import Path + +import pytest +from attr.exceptions import FrozenInstanceError + +from manimpango import FontProperties, RegisterFont, Style, Variant, Weight, list_fonts + +from .test_fonts import font_lists + + +def test_invalid_size(): + with pytest.raises(ValueError): + FontProperties(size=0) + + +def test_font_properties_attributes(): + fp = FontProperties( + family="Hello", + size=10, + style=Style.ITALIC, + variant=Variant.NORMAL, + weight=Weight.BOLD, + ) + assert fp.family == "Hello" + assert fp.size == 10 + assert fp.style == Style.ITALIC + assert fp.variant == Variant.NORMAL + assert fp.weight == Weight.BOLD + + +def test_Register_Font_wrapper_frozen(): + a = RegisterFont(list(font_lists.keys())[0]) + with pytest.raises(FrozenInstanceError): + a.family = "" + a.unregister() + + +def test_Register_Font(): + a = RegisterFont(list(font_lists.keys())[1]) + fonts = list_fonts() + assert a.family[0] in fonts + assert isinstance(a.family, list) + a.unregister() + # below one fails due to caching in Pango. + # Maybe we can disable it? + # assert a.family[0] not in fonts + + +@pytest.mark.skipif(sys.platform.startswith("linux"), reason="uses fc by default.") +def test_fc_in_Register_Font(): + a = RegisterFont(list(font_lists.keys())[1], use_fontconfig=True) + fonts = list_fonts() + assert a.family is not None + assert list(font_lists.values())[1] not in fonts + assert a.family[0] not in fonts + a.unregister() + + +def test_fc_in_Register_Font_with_rendering(setup_fontconfig): + a = RegisterFont(list(font_lists.keys())[1], use_fontconfig=True) + fonts = list_fonts() + assert a.family is not None + assert a.family[0] in fonts + a.unregister() + + +def test_Register_Font_without_calculating_family(): + a = RegisterFont(list(font_lists.keys())[1], calculate_family=False) + assert a.family is None + a.unregister() + + +@pytest.mark.parametrize("fontconfig", [True, False]) +def test_Register_Font_invalid_font_raise(tmpdir, fontconfig): + tmpfile = Path(tmpdir) / "nice.ttf" + with tmpfile.open("w") as f: + f.write("test font") + with pytest.raises(RuntimeError): + RegisterFont(tmpfile, use_fontconfig=fontconfig) + + +def test_Register_Font_file_not_found(tmpdir): + with pytest.raises(FileNotFoundError): + RegisterFont(Path(tmpdir) / "test") + with pytest.raises(FileNotFoundError): + RegisterFont(Path(tmpdir)) diff --git a/tests/test_fonts.py b/tests/test_fonts.py index 51e7eb43..3196828b 100644 --- a/tests/test_fonts.py +++ b/tests/test_fonts.py @@ -3,13 +3,17 @@ from pathlib import Path from shutil import copyfile -import manim import pytest import manimpango +from manimpango.font_manager._register_font import ( + fc_register_font, + fc_unregister_font, + register_font, + unregister_font, +) from . import FONT_DIR -from ._manim import MarkupText font_lists = { (FONT_DIR / "AdobeVFPrototype.ttf").absolute(): "Adobe Variable Font Prototype", @@ -23,24 +27,25 @@ def test_unicode_font_name(tmpdir): final_font = str(Path(tmpdir, "庞门正.ttf").absolute()) copyfile(FONT_DIR / "AdobeVFPrototype.ttf", final_font) - assert manimpango.register_font(final_font) - assert manimpango.unregister_font(final_font) + assert register_font(final_font) + assert unregister_font(final_font) @pytest.mark.parametrize("font_name", font_lists) def test_register_font(font_name): intial = manimpango.list_fonts() - assert manimpango.register_font(str(font_name)), "Invalid Font possibly." + assert register_font(str(font_name)), "Invalid Font possibly." final = manimpango.list_fonts() assert intial != final -@pytest.mark.parametrize("font_name", font_lists.values()) -def test_warning(capfd, font_name): - print(font_name) - manim.Text("Testing", font=font_name) - captured = capfd.readouterr() - assert "Pango-WARNING **" not in captured.err, "Looks like pango raised a warning?" +# @pytest.mark.parametrize("font_name", font_lists.values()) +# def test_warning(capfd, font_name): +# print(font_name) +# manim.Text("Testing", font=font_name) +# captured = capfd.readouterr() +# assert "Pango-WARNING **" not in captured.err, +# "Looks like pango raised a warning?" @pytest.mark.skipif( @@ -49,7 +54,7 @@ def test_warning(capfd, font_name): @pytest.mark.parametrize("font_name", font_lists) def test_unregister_font(font_name): intial = manimpango.list_fonts() - assert manimpango.unregister_font(str(font_name)), "Failed to unregister the font" + assert unregister_font(str(font_name)), "Failed to unregister the font" final = manimpango.list_fonts() assert intial != final @@ -59,8 +64,8 @@ def test_unregister_font(font_name): ) @pytest.mark.parametrize("font_name", font_lists) def test_register_and_unregister_font(font_name): - assert manimpango.register_font(str(font_name)), "Invalid Font possibly." - assert manimpango.unregister_font(str(font_name)), "Failed to unregister the font" + assert register_font(str(font_name)), "Invalid Font possibly." + assert unregister_font(str(font_name)), "Failed to unregister the font" @pytest.mark.skipif( @@ -69,9 +74,7 @@ def test_register_and_unregister_font(font_name): @pytest.mark.parametrize("font_name", font_lists) @pytest.mark.skipif(sys.platform.startswith("darwin"), reason="always returns true") def test_fail_just_unregister(font_name): - assert not manimpango.unregister_font( - str(font_name) - ), "Failed to unregister the font" + assert not unregister_font(str(font_name)), "Failed to unregister the font" @pytest.mark.skipif( @@ -79,7 +82,7 @@ def test_fail_just_unregister(font_name): ) @pytest.mark.skipif(sys.platform.startswith("darwin"), reason="unsupported api for mac") def test_unregister_linux(): - assert manimpango.unregister_font("random") + assert unregister_font("random") @pytest.mark.skipif( @@ -89,27 +92,27 @@ def test_adding_dummy_font(tmpdir): dummy = tmpdir / "font.ttf" with open(dummy, "wb") as f: f.write(b"dummy") - assert not manimpango.register_font(str(dummy)), "Registered a dummy font?" + assert not register_font(str(dummy)), "Registered a dummy font?" -def test_simple_fonts_render(tmpdir): - filename = str(Path(tmpdir) / "hello.svg") - MarkupText("Hello World", filename=filename) - assert Path(filename).exists() +# def test_simple_fonts_render(tmpdir): +# filename = str(Path(tmpdir) / "hello.svg") +# MarkupText("Hello World", filename=filename) +# assert Path(filename).exists() @pytest.mark.skipif( not sys.platform.startswith("linux"), reason="unsupported api other than linux" ) def test_both_fc_and_register_font_are_same(): - assert manimpango.fc_register_font == manimpango.register_font - assert manimpango.fc_unregister_font == manimpango.unregister_font + assert fc_register_font == register_font + assert fc_unregister_font == unregister_font @pytest.mark.parametrize("font_file", font_lists) def test_fc_font_register(setup_fontconfig, font_file): intial = manimpango.list_fonts() - assert manimpango.fc_register_font(str(font_file)), "Invalid Font possibly." + assert fc_register_font(str(font_file)), "Invalid Font possibly." final = manimpango.list_fonts() assert intial != final @@ -117,6 +120,6 @@ def test_fc_font_register(setup_fontconfig, font_file): def test_fc_font_unregister(setup_fontconfig): # it will remove everything intial = manimpango.list_fonts() - manimpango.fc_unregister_font("clear") + fc_unregister_font("clear") final = manimpango.list_fonts() assert intial != final diff --git a/tests/test_list_fonts.py b/tests/test_list_fonts.py index 370fb42d..22e832f3 100644 --- a/tests/test_list_fonts.py +++ b/tests/test_list_fonts.py @@ -4,6 +4,7 @@ import pytest import manimpango +from manimpango.font_manager._register_font import register_font, unregister_font from .test_fonts import font_lists @@ -20,7 +21,7 @@ def test_whether_list(): ) @pytest.mark.parametrize("font_file", font_lists) def test_resgister_font_with_list(font_file): - manimpango.register_font(str(font_file)) + register_font(str(font_file)) a = manimpango.list_fonts() assert font_lists[font_file] in a - manimpango.unregister_font(str(font_file)) + unregister_font(str(font_file)) diff --git a/tests/test_markup.py b/tests/test_markup.py index abb82bbc..6e3ed5c5 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -1,122 +1,106 @@ # -*- coding: utf-8 -*- -from pathlib import Path + import pytest import manimpango -from . import CASES_DIR -from ._manim import MarkupText -from .svg_tester import SVGStyleTester +# from .svg_tester import SVGStyleTester -ipsum_text = ( - "Lorem ipsum dolor sit amet, consectetur adipiscing elit," - "sed do eiusmod tempor incididunt ut labore et dolore" - "magna aliqua. Ut enim ad minim veniam, quis nostrud" - "exercitation ullamco laboris nisi ut aliquip" - "ex ea commodo consequat. Duis aute irure dolor" - "in reprehenderit in voluptate velit esse cillum" - "dolore eu fugiat nulla pariatur. Excepteur sint" - "occaecat cupidatat non proident, sunt in culpa qui" - "officia deserunt mollit anim id est laborum." -) +# ipsum_text = ( +# "Lorem ipsum dolor sit amet, consectetur adipiscing elit," +# "sed do eiusmod tempor incididunt ut labore et dolore" +# "magna aliqua. Ut enim ad minim veniam, quis nostrud" +# "exercitation ullamco laboris nisi ut aliquip" +# "ex ea commodo consequat. Duis aute irure dolor" +# "in reprehenderit in voluptate velit esse cillum" +# "dolore eu fugiat nulla pariatur. Excepteur sint" +# "occaecat cupidatat non proident, sunt in culpa qui" +# "officia deserunt mollit anim id est laborum." +# ) @pytest.mark.parametrize("text", ["foo", "bar", "வணக்கம்"]) def test_good_markup(text): - assert not manimpango.MarkupUtils.validate( - text, + assert ( + manimpango.layout.utils.validate_markup( + text, + ) + == "" ), f"{text} should not fail validation" @pytest.mark.parametrize("text", ["foo", "foo"]) def test_bad_markup(text): - assert manimpango.MarkupUtils.validate( - text + assert ( + manimpango.layout.utils.validate_markup(text) != "" ), f"{text} should fail validation (unbalanced tags)" -@pytest.mark.parametrize( - "text,error", - [ - ( - "foo", - "Error on line 1 char 23: Element “markup” was closed, " - "but the currently open element is “b”", - ), - ( - "foo", - "Unknown tag 'xyz' on line 1 char 14", - ), - ], -) -def test_bad_markup_error_message(text, error): - assert manimpango.MarkupUtils.validate(text) == error - - -def test_markup_text(tmpdir): - loc = Path(tmpdir, "test.svg") - assert not loc.exists() - MarkupText( - 'Hello Manim', filename=str(loc) - ) - assert loc.exists() - - -def test_markup_justify(tmpdir): - # don't know how to verify this correctly - # it varies upon diffent system so, we are - # just check whether it runs - loc = Path(tmpdir, "test.svg") - assert not loc.exists() - MarkupText(ipsum_text, justify=True, filename=str(loc)) - assert loc.exists() - - -def test_markup_indent(tmpdir): - # don't know how to verify this correctly - # it varies upon diffent system so, we are - # just check whether it runs - loc = Path(tmpdir, "test.svg") - assert not loc.exists() - MarkupText(ipsum_text, indent=10, filename=str(loc)) - assert loc.exists() - - -def test_markup_alignment(tmpdir): - # don't know how to verify this correctly - # it varies upon diffent system so, we are - # just check whether it runs - loc = Path(tmpdir, "test.svg") - assert not loc.exists() - MarkupText( - ipsum_text, - alignment=manimpango.Alignment.CENTER, - filename=str(loc), - ) - assert loc.exists() - - -def test_markup_style(tmpdir): - test_case = CASES_DIR / "hello_blue_world_green.svg" - expected = tmpdir / "expected.svg" - text = "Hello\nWorld" - MarkupText( - text, - filename=str(expected), - ) - s = SVGStyleTester(gotSVG=expected, expectedSVG=test_case) - assert len(s.got_svg_style) == len(s.expected_svg_style) - assert s.got_svg_style == s.expected_svg_style - - -def test_wrap_text(tmpdir): - tmpdir = Path(tmpdir) - wrapped = tmpdir / "wrap.svg" - nowrap = tmpdir / "nowarap.svg" - - MarkupText(ipsum_text, wrap_text=False, filename=str(nowrap)) - MarkupText(ipsum_text, filename=str(wrapped)) - - assert wrapped.read_text() != nowrap.read_text() +# def test_markup_text(tmpdir): +# loc = Path(tmpdir, "test.svg") +# assert not loc.exists() +# MarkupText( +# 'Hello Manim', filename=str(loc) +# ) +# assert loc.exists() + + +# def test_markup_justify(tmpdir): +# # don't know how to verify this correctly +# # it varies upon diffent system so, we are +# # just check whether it runs +# loc = Path(tmpdir, "test.svg") +# assert not loc.exists() +# MarkupText(ipsum_text, justify=True, filename=str(loc)) +# assert loc.exists() + + +# def test_markup_indent(tmpdir): +# # don't know how to verify this correctly +# # it varies upon diffent system so, we are +# # just check whether it runs +# loc = Path(tmpdir, "test.svg") +# assert not loc.exists() +# MarkupText(ipsum_text, indent=10, filename=str(loc)) +# assert loc.exists() + + +# def test_markup_alignment(tmpdir): +# # don't know how to verify this correctly +# # it varies upon diffent system so, we are +# # just check whether it runs +# loc = Path(tmpdir, "test.svg") +# assert not loc.exists() +# MarkupText( +# ipsum_text, +# alignment=manimpango.Alignment.CENTER, +# filename=str(loc), +# ) +# assert loc.exists() + + +# def test_markup_style(tmpdir): +# test_case = CASES_DIR / "hello_blue_world_green.svg" +# expected = tmpdir / "expected.svg" +# text = ("Hello" +# "\nWorld") +# MarkupText( +# text, +# filename=str(expected), +# ) +# s = SVGStyleTester(gotSVG=expected, expectedSVG=test_case) +# assert len(s.got_svg_style) == len(s.expected_svg_style) +# assert s.got_svg_style == s.expected_svg_style + + +# def test_wrap_text(tmpdir): +# tmpdir = Path(tmpdir) +# wrapped = tmpdir / "wrap.svg" +# nowrap = tmpdir / "nowarap.svg" + +# MarkupText(ipsum_text, wrap_text=False, filename=str(nowrap)) +# MarkupText(ipsum_text, filename=str(wrapped)) + +# assert wrapped.read_text() != nowrap.read_text() diff --git a/tests/test_utils.py b/tests/test_utils.py index 39189f89..a2bcf053 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- import pytest -from manimpango.enums import Style, Weight -from manimpango.utils import PangoUtils +from manimpango.utils import PangoUtils, Style, Weight def test_str2style():