McRogueFace/tests/unit/animation_test.py
2026-02-06 16:15:07 -05:00

159 lines
5.1 KiB
Python

# animation_test.py - Unit tests for Entity3D skeletal animation
import mcrfpy
import sys
def test_entity3d_animation_defaults():
"""Test Entity3D animation property defaults"""
entity = mcrfpy.Entity3D()
# Default animation state
assert entity.anim_clip == "", f"Expected empty anim_clip, got '{entity.anim_clip}'"
assert entity.anim_time == 0.0, f"Expected anim_time=0.0, got {entity.anim_time}"
assert entity.anim_speed == 1.0, f"Expected anim_speed=1.0, got {entity.anim_speed}"
assert entity.anim_loop == True, f"Expected anim_loop=True, got {entity.anim_loop}"
assert entity.anim_paused == False, f"Expected anim_paused=False, got {entity.anim_paused}"
assert entity.anim_frame == 0, f"Expected anim_frame=0, got {entity.anim_frame}"
# Auto-animate defaults
assert entity.auto_animate == True, f"Expected auto_animate=True, got {entity.auto_animate}"
assert entity.walk_clip == "walk", f"Expected walk_clip='walk', got '{entity.walk_clip}'"
assert entity.idle_clip == "idle", f"Expected idle_clip='idle', got '{entity.idle_clip}'"
print("[PASS] test_entity3d_animation_defaults")
def test_entity3d_animation_properties():
"""Test setting Entity3D animation properties"""
entity = mcrfpy.Entity3D()
# Set animation clip
entity.anim_clip = "test_anim"
assert entity.anim_clip == "test_anim", f"Expected 'test_anim', got '{entity.anim_clip}'"
# Set animation time
entity.anim_time = 1.5
assert abs(entity.anim_time - 1.5) < 0.001, f"Expected anim_time~=1.5, got {entity.anim_time}"
# Set animation speed
entity.anim_speed = 2.0
assert abs(entity.anim_speed - 2.0) < 0.001, f"Expected anim_speed~=2.0, got {entity.anim_speed}"
# Set loop
entity.anim_loop = False
assert entity.anim_loop == False, f"Expected anim_loop=False, got {entity.anim_loop}"
# Set paused
entity.anim_paused = True
assert entity.anim_paused == True, f"Expected anim_paused=True, got {entity.anim_paused}"
print("[PASS] test_entity3d_animation_properties")
def test_entity3d_auto_animate():
"""Test Entity3D auto-animate settings"""
entity = mcrfpy.Entity3D()
# Disable auto-animate
entity.auto_animate = False
assert entity.auto_animate == False
# Set custom clip names
entity.walk_clip = "run"
entity.idle_clip = "stand"
assert entity.walk_clip == "run"
assert entity.idle_clip == "stand"
print("[PASS] test_entity3d_auto_animate")
def test_entity3d_animation_callback():
"""Test Entity3D animation complete callback"""
entity = mcrfpy.Entity3D()
callback_called = [False]
callback_args = [None, None]
def on_complete(ent, clip_name):
callback_called[0] = True
callback_args[0] = ent
callback_args[1] = clip_name
# Set callback
entity.on_anim_complete = on_complete
assert entity.on_anim_complete is not None
# Clear callback
entity.on_anim_complete = None
# Should not raise error even though callback is None
print("[PASS] test_entity3d_animation_callback")
def test_entity3d_animation_callback_invalid():
"""Test that non-callable is rejected for animation callback"""
entity = mcrfpy.Entity3D()
try:
entity.on_anim_complete = "not a function"
assert False, "Should have raised TypeError"
except TypeError:
pass
print("[PASS] test_entity3d_animation_callback_invalid")
def test_entity3d_with_model():
"""Test Entity3D animation with a non-skeletal model"""
entity = mcrfpy.Entity3D()
cube = mcrfpy.Model3D.cube()
entity.model = cube
# Setting animation clip on non-skeletal model should not crash
entity.anim_clip = "walk" # Should just do nothing gracefully
assert entity.anim_clip == "walk" # The property is set even if model has no animation
# Frame should be 0 since there's no skeleton
assert entity.anim_frame == 0
print("[PASS] test_entity3d_with_model")
def test_entity3d_animation_negative_speed():
"""Test that animation speed can be negative (reverse playback)"""
entity = mcrfpy.Entity3D()
entity.anim_speed = -1.0
assert abs(entity.anim_speed - (-1.0)) < 0.001
entity.anim_speed = 0.0
assert entity.anim_speed == 0.0
print("[PASS] test_entity3d_animation_negative_speed")
def run_all_tests():
"""Run all animation tests"""
tests = [
test_entity3d_animation_defaults,
test_entity3d_animation_properties,
test_entity3d_auto_animate,
test_entity3d_animation_callback,
test_entity3d_animation_callback_invalid,
test_entity3d_with_model,
test_entity3d_animation_negative_speed,
]
passed = 0
failed = 0
for test in tests:
try:
test()
passed += 1
except AssertionError as e:
print(f"[FAIL] {test.__name__}: {e}")
failed += 1
except Exception as e:
print(f"[ERROR] {test.__name__}: {e}")
failed += 1
print(f"\n=== Results: {passed} passed, {failed} failed ===")
return failed == 0
if __name__ == "__main__":
success = run_all_tests()
sys.exit(0 if success else 1)