BladeSzaSza's picture
fix: define REPO_NAME in hf_upload.sh (ensure_blade_space referenced it)
4948993 verified
Raw
History Blame Contribute Delete
4.71 kB
"""Tests for Pose2DAgent β€” model-dependent, skips if YOLO unavailable."""
import inspect
import unittest.mock as mock
import numpy as np
import pytest
from formscout.types import IngestResult, Pose2DResult
def _blank_ingest(n_frames=5, w=640, h=480):
frames = [np.zeros((h, w, 3), dtype=np.uint8) for _ in range(n_frames)]
return IngestResult(
frames=frames, fps=30.0, duration=n_frames / 30.0,
n_people=1, width=w, height=h,
)
@pytest.fixture
def pose2d_agent():
"""Create Pose2DAgent, skip if model unavailable."""
try:
from formscout.agents.pose2d import Pose2DAgent
agent = Pose2DAgent()
return agent
except Exception as e:
pytest.skip(f"Pose2D model unavailable: {e}")
class TestPose2DAgent:
def test_returns_typed_result(self, pose2d_agent):
result = pose2d_agent.run(_blank_ingest())
assert isinstance(result, Pose2DResult)
assert isinstance(result.keypoints, list)
assert result.fps == pytest.approx(30.0)
def test_keypoints_per_frame(self, pose2d_agent):
ingest = _blank_ingest(n_frames=3)
result = pose2d_agent.run(ingest)
assert len(result.keypoints) == 3
for frame_kps in result.keypoints:
assert isinstance(frame_kps, dict)
def test_graceful_on_empty_frames(self, pose2d_agent):
empty = IngestResult(
frames=[], fps=30.0, duration=0.0,
n_people=0, width=640, height=480,
)
result = pose2d_agent.run(empty)
assert result.confidence == 0.0
assert "no frames" in result.notes.lower()
def test_run_accepts_model_key(self, pose2d_agent):
sig = inspect.signature(pose2d_agent.run)
assert "model_key" in sig.parameters
assert "model_path" not in sig.parameters
def _blank_ingest_3():
frames = [np.zeros((480, 640, 3), dtype=np.uint8) for _ in range(3)]
return IngestResult(frames=frames, fps=30.0, duration=0.1, n_people=1, width=640, height=480)
class TestPose2DBackendsMocked:
"""Backend dispatch tests β€” no real model downloads."""
def test_yolo_backend_dispatches(self):
from formscout.agents.pose2d import Pose2DAgent
fake_kps = [{0: {"x": 10.0, "y": 20.0, "conf": 0.9}} for _ in range(3)]
with mock.patch("formscout.agents.pose2d._run_yolo", return_value=fake_kps) as m:
result = Pose2DAgent().run(_blank_ingest_3(), model_key="YOLO26n β€” nano (0.7M, fastest)")
m.assert_called_once()
assert isinstance(result, Pose2DResult)
assert len(result.keypoints) == 3
assert result.confidence > 0.0
def test_mediapipe_backend_dispatches(self):
from formscout.agents.pose2d import Pose2DAgent
fake_kps = [{i: {"x": float(i), "y": float(i), "conf": 0.8} for i in range(17)} for _ in range(3)]
with mock.patch("formscout.agents.pose2d._run_mediapipe", return_value=fake_kps) as m:
result = Pose2DAgent().run(_blank_ingest_3(), model_key="MediaPipe-Pose β€” full (~9 MB, CPU-friendly)")
m.assert_called_once()
assert isinstance(result, Pose2DResult)
assert len(result.keypoints) == 3
assert all(len(f) == 17 for f in result.keypoints)
def test_sapiens2_backend_dispatches(self):
from formscout.agents.pose2d import Pose2DAgent
fake_kps = [{i: {"x": float(i), "y": float(i), "conf": 0.85} for i in range(17)} for _ in range(3)]
with mock.patch("formscout.agents.pose2d._run_sapiens2", return_value=fake_kps) as m:
result = Pose2DAgent().run(_blank_ingest_3(), model_key="Sapiens2-0.4B [Phase 3, ~1.6 GB]")
m.assert_called_once()
assert isinstance(result, Pose2DResult)
assert len(result.keypoints) == 3
def test_unknown_model_key_falls_back(self):
from formscout.agents.pose2d import Pose2DAgent
fake_kps = [{0: {"x": 1.0, "y": 2.0, "conf": 0.7}} for _ in range(3)]
with mock.patch("formscout.agents.pose2d._run_yolo", return_value=fake_kps):
result = Pose2DAgent().run(_blank_ingest_3(), model_key="nonexistent-model-xyz")
assert isinstance(result, Pose2DResult)
def test_confidence_zero_on_empty_keypoints(self):
from formscout.agents.pose2d import Pose2DAgent
with mock.patch("formscout.agents.pose2d._run_yolo", return_value=[{}, {}, {}]):
result = Pose2DAgent().run(_blank_ingest_3(), model_key="YOLO26n β€” nano (0.7M, fastest)")
assert result.confidence == 0.0
assert "no person" in result.notes.lower()