248 lines · 7.3 KB · Python
RawDownload
import numpy as npimport pytest from manim.mobject.text.code_mobject import Codefrom manim.utils.color.core import ManimColor  def test_code_initialization_from_string():    code_string = """from manim import Scene, Square class FadeInSquare(Scene):    def construct(self):        s = Square()        self.play(FadeIn(s))        self.play(s.animate.scale(2))        self.wait()"""    rendered_code = Code(        code_string=code_string,        language="python",    )    num_lines = len(code_string.split("\n"))    assert len(rendered_code.code_lines) == num_lines    assert len(rendered_code.line_numbers) == num_lines  @pytest.mark.parametrize(    ("code_string", "num_lines"),    [("pass", 1), ("   ", 1), (" \n ", 2)],)def test_code_initialization_without_line_numbers(code_string, num_lines):    rendered_code = Code(        code_string=code_string,        language="python",        add_line_numbers=False,    )     assert len(rendered_code.code_lines) == num_lines    assert not hasattr(rendered_code, "line_numbers")  def test_code_initialization_from_file():    rendered_code = Code(        code_file="example_scenes/basic.py",        language="python",        background="window",        background_config={"fill_color": "#101010"},        paragraph_config={"font_size": 14},    )    assert len(rendered_code.code_lines) == len(rendered_code.line_numbers)    assert rendered_code.background.fill_color == ManimColor("#101010")  @pytest.mark.parametrize(    ("formatter_style", "background_color", "text_color"),    [        ("xcode", "#ffffff", "#000000"),        ("vim", "#000000", "#cccccc"),    ],)def test_code_uses_formatter_style_colors(    formatter_style, background_color, text_color):    rendered_code = Code(        code_string="plain text",        language="text",        formatter_style=formatter_style,        add_line_numbers=False,    )     assert rendered_code.background.fill_color == ManimColor(background_color)    assert rendered_code.code_lines[0][0].get_color() == ManimColor(text_color)  def test_code_ignores_paragraph_color():    rendered_code = Code(        code_string="plain text",        language="text",        formatter_style="vim",        paragraph_config={"color": "#ff0000"},    )     assert rendered_code.code_lines[0][0].get_color() == ManimColor("#cccccc")    assert rendered_code.line_numbers[0][0].get_color() == ManimColor("#cccccc")  def test_code_ignores_default_paragraph_color(monkeypatch):    monkeypatch.setitem(Code.default_paragraph_config, "color", "#ff0000")     rendered_code = Code(        code_string="plain text",        language="text",        formatter_style="vim",    )     assert rendered_code.code_lines[0][0].get_color() == ManimColor("#cccccc")    assert rendered_code.line_numbers[0][0].get_color() == ManimColor("#cccccc")  def test_code_accepts_custom_pygments_style():    class CustomStyle(Code.get_pygments_style("xcode")):        background_color = "#123456"        line_number_color = "#abcdef"     rendered_code = Code(        code_string="plain text",        language="text",        formatter_style=CustomStyle,    )     assert rendered_code.background.fill_color == ManimColor("#123456")    assert rendered_code.code_lines[0][0].get_color() == ManimColor("#000000")    assert rendered_code.line_numbers[0][0].get_color() == ManimColor("#abcdef")  @pytest.mark.parametrize(    ("formatter_style", "line_number_color"),    [        ("solarized-light", ManimColor("#93a1a1")),        ("vim", ManimColor("#cccccc")),        ("xcode", ManimColor("#000000")),    ],)def test_code_line_numbers_use_formatter_style_color(    formatter_style, line_number_color):    rendered_code = Code(        code_string="plain text",        language="text",        formatter_style=formatter_style,    )     assert rendered_code.line_numbers[0][0].get_color() == line_number_color  def test_line_heights_initial_whitespace():    rendered_code = Code(        code_string="""print('Hello, World!')for _ in range(42):    print('Hello, World!')""",        language="python",    )    np.testing.assert_almost_equal(        rendered_code.code_lines[0].height,        rendered_code.code_lines[2].height,    )  @pytest.mark.parametrize("line_numbers_from", [1, 10, -2])def test_code_baseline_alignment(line_numbers_from):    baseline_offsets = []    for code_string in ("pass", "pass b"):        rendered_code = Code(            code_string=code_string,            language="python",            line_numbers_from=line_numbers_from,        )        baseline_offsets.append(            rendered_code.code_lines[0].get_bottom()[1]            - rendered_code.line_numbers[0].get_bottom()[1]        )     np.testing.assert_allclose(baseline_offsets[0], baseline_offsets[1], atol=1e-6)  @pytest.mark.parametrize("background", ["rectangle", "window"])@pytest.mark.parametrize("add_line_numbers", [True, False])def test_code_height_is_independent_of_boundary_glyphs(    background,    add_line_numbers,):    code_strings = (        "AAA\nppp",        "ppp\nAAA",        "AAA\nAAA",        "ppp\nppp",        "---\n---",    )    background_heights = [        Code(            code_string=code_string,            language="python",            background=background,            add_line_numbers=add_line_numbers,        ).background.height        for code_string in code_strings    ]     np.testing.assert_allclose(background_heights, background_heights[0], atol=1e-6)  @pytest.mark.parametrize("disable_ligatures", [True, False])@pytest.mark.parametrize("add_line_numbers", [True, False])def test_code_line_mobject_is_independent_of_ordinality(    disable_ligatures, add_line_numbers):    """Test that the (sub)mobject structure and width of a line of code does not depend    on the line's order in the block.    """    code_strings = ("Hello World!",) * 5    code_mobject = Code(        code_string="\n".join(code_strings),        add_line_numbers=add_line_numbers,        paragraph_config={"disable_ligatures": disable_ligatures},    )    lines = code_mobject.code_lines    reference_line = lines[len(lines) // 2]    for boundary_line in (lines[0], lines[-1]):        assert len(boundary_line) == len(reference_line)        np.testing.assert_allclose(            boundary_line.width,            reference_line.width,            atol=1e-6,        )  def test_code_syntax_highlighting_colors():    code_string = "pass\n# comment"    rendered_code = Code(        code_string=code_string,        language="python",        formatter_style="vim",    )     assert {char.color for char in rendered_code.code_lines[0]} == {        ManimColor("#CDCD00")    }    assert {char.color for char in rendered_code.code_lines[1]} == {        ManimColor("#000080")    }    assert [len(line) for line in rendered_code.code_lines] == [        sum(not char.isspace() for char in line) for line in code_string.splitlines()    ]    assert len(rendered_code.code_lines) == len(rendered_code.code_lines.chars)  def test_code_initialization_style_correct_color():    for style in Code.get_styles_list():        try:            Code(                code_string="""# This is a comment.var = 3print(var)""",                formatter_style=style,            )        except ValueError as e:            pytest.fail(f"Code initialization failed for style {style} with error: {e}")