mirror of
https://github.com/ManimCommunity/manim.git
synced 2026-06-22 10:01:47 +00:00
212 lines
7 KiB
Python
212 lines
7 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
import numpy as np
|
|
|
|
from manim import WHITE, Scene, Square, Tex, Text, config, tempconfig
|
|
from tests.assert_utils import assert_dir_exists, assert_dir_filled, assert_file_exists
|
|
|
|
|
|
def test_tempconfig():
|
|
"""Test the tempconfig context manager."""
|
|
original = config.copy()
|
|
|
|
with tempconfig({"frame_width": 100, "frame_height": 42}):
|
|
# check that config was modified correctly
|
|
assert config["frame_width"] == 100
|
|
assert config["frame_height"] == 42
|
|
|
|
# check that no keys are missing and no new keys were added
|
|
assert set(original.keys()) == set(config.keys())
|
|
|
|
# check that the keys are still untouched
|
|
assert set(original.keys()) == set(config.keys())
|
|
|
|
# check that config is correctly restored
|
|
for k, v in original.items():
|
|
if isinstance(v, np.ndarray):
|
|
assert np.allclose(config[k], v)
|
|
else:
|
|
assert config[k] == v
|
|
|
|
|
|
class MyScene(Scene):
|
|
def construct(self):
|
|
self.add(Square())
|
|
self.add(Text("Prepare for unforeseen consequencesλ"))
|
|
self.add(Tex(r"$\lambda$"))
|
|
self.wait(1)
|
|
|
|
|
|
def test_transparent():
|
|
"""Test the 'transparent' config option."""
|
|
orig_verbosity = config["verbosity"]
|
|
config["verbosity"] = "ERROR"
|
|
|
|
with tempconfig({"dry_run": True}):
|
|
scene = MyScene()
|
|
scene.render()
|
|
frame = scene.renderer.get_frame()
|
|
assert np.allclose(frame[0, 0], [0, 0, 0, 255])
|
|
|
|
with tempconfig({"transparent": True, "dry_run": True}):
|
|
scene = MyScene()
|
|
scene.render()
|
|
frame = scene.renderer.get_frame()
|
|
assert np.allclose(frame[0, 0], [0, 0, 0, 0])
|
|
|
|
config["verbosity"] = orig_verbosity
|
|
|
|
|
|
def test_background_color():
|
|
"""Test the 'background_color' config option."""
|
|
with tempconfig({"background_color": WHITE, "verbosity": "ERROR", "dry_run": True}):
|
|
scene = MyScene()
|
|
scene.render()
|
|
frame = scene.renderer.get_frame()
|
|
assert np.allclose(frame[0, 0], [255, 255, 255, 255])
|
|
|
|
|
|
def test_digest_file(tmp_path):
|
|
"""Test that a config file can be digested programmatically."""
|
|
with tempconfig({}):
|
|
tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False)
|
|
tmp_cfg.write(
|
|
"""
|
|
[CLI]
|
|
media_dir = this_is_my_favorite_path
|
|
video_dir = {media_dir}/videos
|
|
sections_dir = {media_dir}/{scene_name}/prepare_for_unforeseen_consequences
|
|
frame_height = 10
|
|
""",
|
|
)
|
|
tmp_cfg.close()
|
|
config.digest_file(tmp_cfg.name)
|
|
|
|
assert config.get_dir("media_dir") == Path("this_is_my_favorite_path")
|
|
assert config.get_dir("video_dir") == Path("this_is_my_favorite_path/videos")
|
|
assert config.get_dir("sections_dir", scene_name="test") == Path(
|
|
"this_is_my_favorite_path/test/prepare_for_unforeseen_consequences"
|
|
)
|
|
|
|
|
|
def test_custom_dirs(tmp_path):
|
|
with tempconfig(
|
|
{
|
|
"media_dir": tmp_path,
|
|
"save_sections": True,
|
|
"log_to_file": True,
|
|
"frame_rate": 15,
|
|
"pixel_height": 854,
|
|
"pixel_width": 480,
|
|
"save_sections": True,
|
|
"sections_dir": "{media_dir}/test_sections",
|
|
"video_dir": "{media_dir}/test_video",
|
|
"partial_movie_dir": "{media_dir}/test_partial_movie_dir",
|
|
"images_dir": "{media_dir}/test_images",
|
|
"text_dir": "{media_dir}/test_text",
|
|
"tex_dir": "{media_dir}/test_tex",
|
|
"log_dir": "{media_dir}/test_log",
|
|
}
|
|
):
|
|
scene = MyScene()
|
|
scene.render()
|
|
|
|
assert_dir_filled(os.path.join(tmp_path, "test_sections"))
|
|
assert_file_exists(os.path.join(tmp_path, "test_sections", "MyScene.json"))
|
|
|
|
assert_dir_filled(os.path.join(tmp_path, "test_video"))
|
|
assert_file_exists(os.path.join(tmp_path, "test_video", "MyScene.mp4"))
|
|
|
|
assert_dir_filled(os.path.join(tmp_path, "test_partial_movie_dir"))
|
|
assert_file_exists(
|
|
os.path.join(
|
|
tmp_path, "test_partial_movie_dir", "partial_movie_file_list.txt"
|
|
)
|
|
)
|
|
|
|
# TODO: another example with image output would be nice
|
|
assert_dir_exists(os.path.join(tmp_path, "test_images"))
|
|
|
|
assert_dir_filled(os.path.join(tmp_path, "test_text"))
|
|
assert_dir_filled(os.path.join(tmp_path, "test_tex"))
|
|
assert_dir_filled(os.path.join(tmp_path, "test_log"))
|
|
|
|
|
|
def test_frame_size(tmp_path):
|
|
"""Test that the frame size can be set via config file."""
|
|
assert np.allclose(config.aspect_ratio, config.pixel_width / config.pixel_height)
|
|
assert np.allclose(config.frame_height, 8.0)
|
|
|
|
with tempconfig({}):
|
|
tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False)
|
|
tmp_cfg.write(
|
|
"""
|
|
[CLI]
|
|
pixel_height = 10
|
|
pixel_width = 10
|
|
""",
|
|
)
|
|
tmp_cfg.close()
|
|
config.digest_file(tmp_cfg.name)
|
|
|
|
# aspect ratio is set using pixel measurements
|
|
assert np.allclose(config.aspect_ratio, 1.0)
|
|
# if not specified in the cfg file, frame_width is set using the aspect ratio
|
|
assert np.allclose(config.frame_height, 8.0)
|
|
assert np.allclose(config.frame_width, 8.0)
|
|
|
|
with tempconfig({}):
|
|
tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False)
|
|
tmp_cfg.write(
|
|
"""
|
|
[CLI]
|
|
pixel_height = 10
|
|
pixel_width = 10
|
|
frame_height = 10
|
|
frame_width = 10
|
|
""",
|
|
)
|
|
tmp_cfg.close()
|
|
config.digest_file(tmp_cfg.name)
|
|
|
|
assert np.allclose(config.aspect_ratio, 1.0)
|
|
# if both are specified in the cfg file, the aspect ratio is ignored
|
|
assert np.allclose(config.frame_height, 10.0)
|
|
assert np.allclose(config.frame_width, 10.0)
|
|
|
|
|
|
def test_temporary_dry_run():
|
|
"""Test that tempconfig correctly restores after setting dry_run."""
|
|
assert config["write_to_movie"]
|
|
assert not config["save_last_frame"]
|
|
|
|
with tempconfig({"dry_run": True}):
|
|
assert not config["write_to_movie"]
|
|
assert not config["save_last_frame"]
|
|
|
|
assert config["write_to_movie"]
|
|
assert not config["save_last_frame"]
|
|
|
|
|
|
def test_dry_run_with_png_format():
|
|
"""Test that there are no exceptions when running a png without output"""
|
|
with tempconfig(
|
|
{"dry_run": True, "write_to_movie": False, "disable_caching": True}
|
|
):
|
|
assert config["dry_run"] is True
|
|
scene = MyScene()
|
|
scene.render()
|
|
|
|
|
|
def test_dry_run_with_png_format_skipped_animations():
|
|
"""Test that there are no exceptions when running a png without output and skipped animations"""
|
|
with tempconfig(
|
|
{"dry_run": True, "write_to_movie": False, "disable_caching": True}
|
|
):
|
|
assert config["dry_run"] is True
|
|
scene = MyScene(skip_animations=True)
|
|
scene.render()
|