Repository: ManimCommunity/manim
File: tests/test_texmobject.py (Python)

Code before:
    \end{align}
    """

    with pytest.raises(ValueError) as err:
        Tex(invalid_tex)

    stdout = str(capsys.readouterr().out)
    # validate useless context is not included
    assert r"\begin{frame}" not in stdout


# TODO: ValueError: max() arg is an empty sequence error for some reason

# def test_color_inheritance():
#     """Test that Text and MarkupText correctly inherit colour from
#     their parent class."""

#     VMobject.set_default(color=RED)
#     vmob = VMobject()
#     tex = Tex("test_color_inheritance")
#     mathtex = MathTex("test_color_inheritance")
#     VMobject.set_default()


#     assert tex.color == vmob.color
#     assert mathtex.color == vmob.color


Review comment (suggestion):
```suggestion
def test_color_inheritance():
     """Test that Text and MarkupText correctly inherit colour from
     their parent class."""

     VMobject.set_default(color=RED)
     vmob = VMobject()
     tex = Tex(r"test\_color\_inheritance")
     mathtex = MathTex("test_color_inheritance")
     VMobject.set_default()


     assert tex.color == vmob.color
     assert mathtex.color == vmob.color
```
Underscores are reserved for subscripts in LaTeX.

Code after:
from __future__ import annotations

from pathlib import Path

import pytest

from manim import MathTex, SingleStringMathTex, Tex, TexTemplate, config
from manim.mobject.types.vectorized_mobject import VMobject
from manim.utils.color import RED


def test_MathTex():
    MathTex("a^2 + b^2 = c^2")
    assert Path(config.media_dir, "Tex", "3879f6b03bc495cd.svg").exists()


def test_SingleStringMathTex():
    SingleStringMathTex("test")
    assert Path(config.media_dir, "Tex", "79822967f1fa1935.svg").exists()


@pytest.mark.parametrize(  # : PT006
    "text_input,length_sub",
    [("{{ a }} + {{ b }} = {{ c }}", 5), (r"\frac{1}{a+b\sqrt{2}}", 1)],
)
def test_double_braces_testing(text_input, length_sub):
    t1 = MathTex(text_input)
    assert len(t1.submobjects) == length_sub


def test_tex():
    Tex("The horse does not eat cucumber salad.")
    assert Path(config.media_dir, "Tex", "983949cac5bdd272.svg").exists()


def test_tex_whitespace_arg():
    """Check that correct number of submobjects are created per string with whitespace separator"""
    separator = "\t"
    str_part_1 = "Hello"
    str_part_2 = "world"
    str_part_3 = "It is"
    str_part_4 = "me!"
    tex = Tex(str_part_1, str_part_2, str_part_3, str_part_4, arg_separator=separator)
    assert len(tex) == 4
    assert len(tex[0]) == len("".join((str_part_1 + separator).split()))
    assert len(tex[1]) == len("".join((str_part_2 + separator).split()))
    assert len(tex[2]) == len("".join((str_part_3 + separator).split()))
    assert len(tex[3]) == len("".join(str_part_4.split()))


def test_tex_non_whitespace_arg():
    """Check that correct number of submobjects are created per string with non_whitespace characters"""
    separator = ","
    str_part_1 = "Hello"
    str_part_2 = "world"
    str_part_3 = "It is"
    str_part_4 = "me!"
    tex = Tex(str_part_1, str_part_2, str_part_3, str_part_4, arg_separator=separator)
    assert len(tex) == 4
    assert len(tex[0]) == len("".join((str_part_1 + separator).split()))
    assert len(tex[1]) == len("".join((str_part_2 + separator).split()))
    assert len(tex[2]) == len("".join((str_part_3 + separator).split()))
    assert len(tex[3]) == len("".join(str_part_4.split()))


def test_tex_white_space_and_non_whitespace_args():
    """Check that correct number of submobjects are created per string when mixing characters with whitespace"""
    separator = ", \n . \t\t"
    str_part_1 = "Hello"
    str_part_2 = "world"
    str_part_3 = "It is"
    str_part_4 = "me!"
    tex = Tex(str_part_1, str_part_2, str_part_3, str_part_4, arg_separator=separator)
    assert len(tex) == 4
    assert len(tex[0]) == len("".join((str_part_1 + separator).split()))
    assert len(tex[1]) == len("".join((str_part_2 + separator).split()))
    assert len(tex[2]) == len("".join((str_part_3 + separator).split()))
    assert len(tex[3]) == len("".join(str_part_4.split()))


def test_tex_size():
    """Check that the size of a :class:`Tex` string is not changed."""
    text = Tex("what").center()
    vertical = text.get_top() - text.get_bottom()
    horizontal = text.get_right() - text.get_left()
    assert round(vertical[1], 4) == 0.3512
    assert round(horizontal[0], 4) == 1.0420


def test_font_size():
    """Test that tex_mobject classes return
    the correct font_size value after being scaled."""
    string = MathTex(0).scale(0.3)

    assert round(string.font_size, 5) == 14.4


def test_font_size_vs_scale():
    """Test that scale produces the same results as .scale()"""
    num = MathTex(0, font_size=12)
    num_scale = MathTex(0).scale(1 / 4)

    assert num.height == num_scale.height


def test_changing_font_size():
    """Test that the font_size property properly scales tex_mobject.py classes."""
    num = Tex("0", font_size=12)
    num.font_size = 48

    assert num.height == Tex("0", font_size=48).height


def test_log_error_context(capsys):
    """Test that the environment context of an error is correctly logged if it exists"""
    invalid_tex = r"""
        some text that is fine

        \begin{unbalanced_braces}{
        not fine
        \end{not_even_the_right_env}
        """

    with pytest.raises(ValueError) as err:
        Tex(invalid_tex)

    # validate useful TeX error logged to user
    assert "unbalanced_braces" in str(capsys.readouterr().out)
    # validate useful error message raised
    assert "See log output above or the log file" in str(err.value)


def test_log_error_no_relevant_context(capsys):
    """Test that an error with no environment context contains no environment context"""
    failing_preamble = r"""\usepackage{fontspec}
    \setmainfont[Ligatures=TeX]{not_a_font}"""

    with pytest.raises(ValueError) as err:
        Tex(
            "The template uses a non-existent font",
            tex_template=TexTemplate(preamble=failing_preamble),
        )

    # validate useless TeX error not logged for user
    assert "Context" not in str(capsys.readouterr().out)
    # validate useful error message raised
    # this won't happen if an error is raised while formatting the message
    assert "See log output above or the log file" in str(err.value)


def test_error_in_nested_context(capsys):
    """Test that displayed error context is not excessively large"""
    invalid_tex = r"""
    \begin{align}
      \begin{tabular}{ c }
        no need to display \\
        this correct text \\
      \end{tabular}
      \notacontrolsequence
    \end{align}
    """

    with pytest.raises(ValueError) as err:
        Tex(invalid_tex)

    stdout = str(capsys.readouterr().out)
    # validate useless context is not included
    assert r"\begin{frame}" not in stdout