manim/tests/test_vectorized_mobject.py
Ryan McCauley 1aba7c73f9
Update VGroup to support item assignment (#1530) (#1559)
Co-authored-by: Naveen M K <naveen@syrusdark.website>
2021-05-23 21:32:15 +05:30

206 lines
5.9 KiB
Python

import numpy as np
import pytest
from manim import Circle, Line, Mobject, Square, VDict, VGroup, VMobject
def test_vmobject_point_from_propotion():
obj = VMobject()
# One long line, one short line
obj.set_points_as_corners(
[
np.array([0, 0, 0]),
np.array([4, 0, 0]),
np.array([4, 2, 0]),
]
)
# Total length of 6, so halfway along the object
# would be at length 3, which lands in the first, long line.
assert np.all(obj.point_from_proportion(0.5) == np.array([3, 0, 0]))
with pytest.raises(ValueError, match="between 0 and 1"):
obj.point_from_proportion(2)
obj.clear_points()
with pytest.raises(Exception, match="with no points"):
obj.point_from_proportion(0)
def test_vgroup_init():
"""Test the VGroup instantiation."""
VGroup()
VGroup(VMobject())
VGroup(VMobject(), VMobject())
with pytest.raises(TypeError):
VGroup(Mobject())
with pytest.raises(TypeError):
VGroup(Mobject(), Mobject())
def test_vgroup_add():
"""Test the VGroup add method."""
obj = VGroup()
assert len(obj.submobjects) == 0
obj.add(VMobject())
assert len(obj.submobjects) == 1
with pytest.raises(TypeError):
obj.add(Mobject())
assert len(obj.submobjects) == 1
with pytest.raises(TypeError):
# If only one of the added object is not an instance of VMobject, none of them should be added
obj.add(VMobject(), Mobject())
assert len(obj.submobjects) == 1
with pytest.raises(Exception): # TODO change this to ValueError once #307 is merged
# a Mobject cannot contain itself
obj.add(obj)
def test_vgroup_add_dunder():
"""Test the VGroup __add__ magic method."""
obj = VGroup()
assert len(obj.submobjects) == 0
obj + VMobject()
assert len(obj.submobjects) == 0
obj += VMobject()
assert len(obj.submobjects) == 1
with pytest.raises(TypeError):
obj += Mobject()
assert len(obj.submobjects) == 1
with pytest.raises(TypeError):
# If only one of the added object is not an instance of VMobject, none of them should be added
obj += (VMobject(), Mobject())
assert len(obj.submobjects) == 1
with pytest.raises(Exception): # TODO change this to ValueError once #307 is merged
# a Mobject cannot contain itself
obj += obj
def test_vgroup_remove():
"""Test the VGroup remove method."""
a = VMobject()
c = VMobject()
b = VGroup(c)
obj = VGroup(a, b)
assert len(obj.submobjects) == 2
assert len(b.submobjects) == 1
obj.remove(a)
b.remove(c)
assert len(obj.submobjects) == 1
assert len(b.submobjects) == 0
obj.remove(b)
assert len(obj.submobjects) == 0
def test_vgroup_remove_dunder():
"""Test the VGroup __sub__ magic method."""
a = VMobject()
c = VMobject()
b = VGroup(c)
obj = VGroup(a, b)
assert len(obj.submobjects) == 2
assert len(b.submobjects) == 1
assert len((obj - a)) == 1
assert len(obj.submobjects) == 2
obj -= a
b -= c
assert len(obj.submobjects) == 1
assert len(b.submobjects) == 0
obj -= b
assert len(obj.submobjects) == 0
def test_vmob_add_to_back():
"""Test the Mobject add_to_back method."""
a = VMobject()
b = Line()
c = "text"
with pytest.raises(ValueError):
# Mobject cannot contain self
a.add_to_back(a)
with pytest.raises(TypeError):
# All submobjects must be of type Mobject
a.add_to_back(c)
# No submobject gets added twice
a.add_to_back(b)
a.add_to_back(b, b)
assert len(a.submobjects) == 1
a.submobjects.clear()
a.add_to_back(b, b, b)
a.add_to_back(b, b)
assert len(a.submobjects) == 1
a.submobjects.clear()
# Make sure the ordering has not changed
o1, o2, o3 = Square(), Line(), Circle()
a.add_to_back(o1, o2, o3)
assert a.submobjects.pop() == o3
assert a.submobjects.pop() == o2
assert a.submobjects.pop() == o1
def test_vdict_init():
"""Test the VDict instantiation."""
# Test empty VDict
VDict()
# Test VDict made from list of pairs
VDict([("a", VMobject()), ("b", VMobject()), ("c", VMobject())])
# Test VDict made from a python dict
VDict({"a": VMobject(), "b": VMobject(), "c": VMobject()})
# Test VDict made using zip
VDict(zip(["a", "b", "c"], [VMobject(), VMobject(), VMobject()]))
# If the value is of type Mobject, must raise a TypeError
with pytest.raises(TypeError):
VDict({"a": Mobject()})
def test_vdict_add():
"""Test the VDict add method."""
obj = VDict()
assert len(obj.submob_dict) == 0
obj.add([("a", VMobject())])
assert len(obj.submob_dict) == 1
with pytest.raises(TypeError):
obj.add([("b", Mobject())])
def test_vdict_remove():
"""Test the VDict remove method."""
obj = VDict([("a", VMobject())])
assert len(obj.submob_dict) == 1
obj.remove("a")
assert len(obj.submob_dict) == 0
with pytest.raises(KeyError):
obj.remove("a")
def test_vgroup_supports_item_assigment():
"""Test VGroup supports array-like assignment for VMObjects"""
a = VMobject()
b = VMobject()
vgroup = VGroup(a)
assert vgroup[0] == a
vgroup[0] = b
assert vgroup[0] == b
assert len(vgroup) == 1
def test_vgroup_item_assignment_at_correct_position():
"""Test VGroup item-assignment adds to correct position for VMObjects"""
n_items = 10
vgroup = VGroup()
for i in range(n_items):
vgroup.add(VMobject())
new_obj = VMobject()
vgroup[6] = new_obj
assert vgroup[6] == new_obj
assert len(vgroup) == n_items
def test_vgroup_item_assignment_only_allows_vmobjects():
"""Test VGroup item-assignment raises TypeError when invalid type is passed"""
vgroup = VGroup(VMobject())
with pytest.raises(TypeError, match="All submobjects must be of type VMobject"):
vgroup[0] = "invalid object"