McRogueFace/tests/unit/animate_method_test.py

248 lines
6.8 KiB
Python

#!/usr/bin/env python3
"""Test the new .animate() shorthand method on UIDrawable and UIEntity.
This tests issue #177 - ergonomic animation API.
"""
import mcrfpy
import sys
def test_frame_animate():
"""Test animate() on Frame"""
frame = mcrfpy.Frame(pos=(100, 100), size=(200, 200))
# Basic float property animation
anim = frame.animate("x", 300.0, 1.0)
assert anim is not None, "animate() should return an Animation object"
# Color property animation
anim2 = frame.animate("fill_color", (255, 0, 0, 255), 0.5)
assert anim2 is not None
# Vector property animation
anim3 = frame.animate("position", (400.0, 400.0), 0.5)
assert anim3 is not None
print(" Frame animate() - PASS")
def test_caption_animate():
"""Test animate() on Caption"""
caption = mcrfpy.Caption(text="Hello", pos=(50, 50))
# Position animation
anim = caption.animate("y", 200.0, 1.0)
assert anim is not None
# Font size animation
anim2 = caption.animate("font_size", 24.0, 0.5)
assert anim2 is not None
print(" Caption animate() - PASS")
def test_sprite_animate():
"""Test animate() on Sprite"""
# Create with default texture
sprite = mcrfpy.Sprite(pos=(100, 100))
# Scale animation
anim = sprite.animate("scale", 2.0, 1.0)
assert anim is not None
# Sprite index animation
anim2 = sprite.animate("sprite_index", 5, 0.5)
assert anim2 is not None
print(" Sprite animate() - PASS")
def test_grid_animate():
"""Test animate() on Grid"""
grid = mcrfpy.Grid(grid_size=(10, 10), pos=(50, 50), size=(300, 300))
# Zoom animation
anim = grid.animate("zoom", 2.0, 1.0)
assert anim is not None
# Center animation
anim2 = grid.animate("center", (100.0, 100.0), 0.5)
assert anim2 is not None
print(" Grid animate() - PASS")
def test_entity_animate():
"""Test animate() on Entity"""
grid = mcrfpy.Grid(grid_size=(20, 20))
entity = mcrfpy.Entity(grid_pos=(5, 5), grid=grid)
# Position animation
anim = entity.animate("x", 10.0, 1.0)
assert anim is not None
anim2 = entity.animate("y", 15.0, 1.0)
assert anim2 is not None
# Sprite index animation
anim3 = entity.animate("sprite_index", 3, 0.5)
assert anim3 is not None
print(" Entity animate() - PASS")
def test_invalid_property_raises():
"""Test that invalid property names raise ValueError"""
frame = mcrfpy.Frame()
try:
frame.animate("invalid_property", 100.0, 1.0)
print(" ERROR: Should have raised ValueError for invalid property")
return False
except ValueError as e:
# Should contain the property name in the error message
if "invalid_property" in str(e):
print(" Invalid property detection - PASS")
return True
else:
print(f" ERROR: ValueError message doesn't mention property: {e}")
return False
except Exception as e:
print(f" ERROR: Wrong exception type: {type(e).__name__}: {e}")
return False
def test_entity_invalid_property():
"""Test that invalid property names raise ValueError for Entity"""
grid = mcrfpy.Grid(grid_size=(10, 10))
entity = mcrfpy.Entity(grid=grid)
try:
entity.animate("invalid_property", 100.0, 1.0)
print(" ERROR: Should have raised ValueError for invalid Entity property")
return False
except ValueError as e:
if "invalid_property" in str(e):
print(" Entity invalid property detection - PASS")
return True
else:
print(f" ERROR: ValueError message doesn't mention property: {e}")
return False
except Exception as e:
print(f" ERROR: Wrong exception type: {type(e).__name__}: {e}")
return False
def test_easing_options():
"""Test various easing parameter formats"""
frame = mcrfpy.Frame()
# String easing
anim1 = frame.animate("x", 100.0, 1.0, "easeInOut")
assert anim1 is not None, "String easing should work"
# Easing enum (if available)
try:
anim2 = frame.animate("x", 100.0, 1.0, mcrfpy.Easing.EaseIn)
assert anim2 is not None, "Enum easing should work"
except AttributeError:
pass # Easing enum might not exist
# None for linear
anim3 = frame.animate("x", 100.0, 1.0, None)
assert anim3 is not None, "None easing (linear) should work"
print(" Easing options - PASS")
def test_delta_mode():
"""Test delta=True for relative animations"""
frame = mcrfpy.Frame(pos=(100, 100))
# Absolute animation (default)
anim1 = frame.animate("x", 200.0, 1.0, delta=False)
assert anim1 is not None
# Relative animation
anim2 = frame.animate("x", 50.0, 1.0, delta=True)
assert anim2 is not None
print(" Delta mode - PASS")
def test_callback():
"""Test callback parameter"""
frame = mcrfpy.Frame()
callback_called = [False] # Use list for mutability in closure
def my_callback():
callback_called[0] = True
anim = frame.animate("x", 100.0, 0.01, callback=my_callback)
assert anim is not None, "Animation with callback should be created"
print(" Callback parameter - PASS")
def run_tests():
"""Run all tests"""
print("Testing .animate() shorthand method:")
all_passed = True
# Test UIDrawable types
try:
test_frame_animate()
except Exception as e:
print(f" Frame animate() - FAIL: {e}")
all_passed = False
try:
test_caption_animate()
except Exception as e:
print(f" Caption animate() - FAIL: {e}")
all_passed = False
try:
test_sprite_animate()
except Exception as e:
print(f" Sprite animate() - FAIL: {e}")
all_passed = False
try:
test_grid_animate()
except Exception as e:
print(f" Grid animate() - FAIL: {e}")
all_passed = False
try:
test_entity_animate()
except Exception as e:
print(f" Entity animate() - FAIL: {e}")
all_passed = False
# Test property validation
if not test_invalid_property_raises():
all_passed = False
if not test_entity_invalid_property():
all_passed = False
# Test optional parameters
try:
test_easing_options()
except Exception as e:
print(f" Easing options - FAIL: {e}")
all_passed = False
try:
test_delta_mode()
except Exception as e:
print(f" Delta mode - FAIL: {e}")
all_passed = False
try:
test_callback()
except Exception as e:
print(f" Callback parameter - FAIL: {e}")
all_passed = False
if all_passed:
print("\nAll tests PASSED!")
sys.exit(0)
else:
print("\nSome tests FAILED!")
sys.exit(1)
# Run tests immediately (no timer needed for this test)
run_tests()