face_detection / tests /test_behavior.py
Boopathy Sivakumar
Initial commit without binary files
9e89884
Raw
History Blame Contribute Delete
1.86 kB
"""Tests for the expression -> movement planner.
The planner is pure logic (no robot SDK), so it is fully unit-testable. We
inject a seeded RNG to make the "random" movement selection deterministic.
"""
import random
import pytest
from face_detection.behavior import Movement, MovementPlanner
def test_known_expressions_have_movements():
planner = MovementPlanner()
for expression in ("happy", "neutral"):
move = planner.plan(expression)
assert isinstance(move, Movement)
assert move.duration > 0
def test_unknown_expression_falls_back_to_neutral():
planner = MovementPlanner(rng=random.Random(0))
fallback = planner.plan("does-not-exist")
assert fallback in planner.movements_for("neutral")
def test_selection_is_deterministic_with_seeded_rng():
a = MovementPlanner(rng=random.Random(42)).plan("happy")
b = MovementPlanner(rng=random.Random(42)).plan("happy")
assert a == b
def test_selection_varies_across_seeds_for_multi_option_expression():
planner = MovementPlanner(rng=random.Random(123))
picks = {planner.plan("happy").description for _ in range(50)}
# "happy" defines more than one movement, so we expect variety.
assert len(picks) > 1
def test_idle_movement_available():
planner = MovementPlanner()
idle = planner.idle()
assert isinstance(idle, Movement)
def test_movement_fields_are_within_safe_ranges():
planner = MovementPlanner()
for expression in planner.expressions:
for move in planner.movements_for(expression):
if move.antennas is not None:
left, right = move.antennas
assert -1.5 <= left <= 1.5
assert -1.5 <= right <= 1.5
if move.body_yaw is not None:
assert -1.0 <= move.body_yaw <= 1.0
assert 0.1 <= move.duration <= 5.0