Download tests/test_action_planner.py from SahilCodevally/codevally-vision-language-action: direct link, hf CLI and curl.
- Browser
- Download file 4.31 kB
-
https://huggingface.co/spaces/SahilCodevally/codevally-vision-language-action/resolve/main/tests/test_action_planner.py
- Command line
-
hf download hf://spaces/SahilCodevally/codevally-vision-language-action/tests/test_action_planner.py
-
curl -L -o test_action_planner.py https://huggingface.co/spaces/SahilCodevally/codevally-vision-language-action/resolve/main/tests/test_action_planner.py
4.31 kB
| """ | |
| Tests for the Action Planning Module — ActionPlanner. | |
| """ | |
| import pytest | |
| from src.planner.action_planner import ActionPlanner | |
| class TestActionPlanner: | |
| """Tests for ActionPlanner.plan() method.""" | |
| def planner(self) -> ActionPlanner: | |
| return ActionPlanner() | |
| def sample_detections(self) -> list[dict]: | |
| return [ | |
| {"label": "bottle", "confidence": 0.92, "bbox": [100, 150, 200, 350]}, | |
| {"label": "box", "confidence": 0.85, "bbox": [400, 300, 550, 500]}, | |
| {"label": "cup", "confidence": 0.78, "bbox": [250, 200, 320, 300]}, | |
| ] | |
| def test_plan_returns_required_keys(self, planner, sample_detections): | |
| """Plan output must have all required keys.""" | |
| interpretation = { | |
| "action": "move", | |
| "source": "bottle", | |
| "destination": "box", | |
| } | |
| result = planner.plan(sample_detections, interpretation) | |
| assert "steps" in result | |
| assert "source_bbox" in result | |
| assert "dest_bbox" in result | |
| assert "status" in result | |
| assert "action" in result | |
| def test_plan_success_status(self, planner, sample_detections): | |
| """Plan should succeed when both source and destination match.""" | |
| interpretation = { | |
| "action": "move", | |
| "source": "bottle", | |
| "destination": "box", | |
| } | |
| result = planner.plan(sample_detections, interpretation) | |
| assert result["status"] == "success" | |
| assert result["source_bbox"] == [100, 150, 200, 350] | |
| assert result["dest_bbox"] == [400, 300, 550, 500] | |
| def test_plan_partial_status(self, planner, sample_detections): | |
| """Plan should be partial when destination doesn't match.""" | |
| interpretation = { | |
| "action": "move", | |
| "source": "bottle", | |
| "destination": "nonexistent_object", | |
| } | |
| result = planner.plan(sample_detections, interpretation) | |
| assert result["status"] == "partial" | |
| assert result["source_bbox"] is not None | |
| assert result["dest_bbox"] is None | |
| def test_plan_failed_status(self, planner, sample_detections): | |
| """Plan should fail when source doesn't match.""" | |
| interpretation = { | |
| "action": "move", | |
| "source": "nonexistent_object", | |
| "destination": "box", | |
| } | |
| result = planner.plan(sample_detections, interpretation) | |
| assert result["status"] == "failed" | |
| def test_plan_generates_steps(self, planner, sample_detections): | |
| """Plan should generate meaningful steps.""" | |
| interpretation = { | |
| "action": "move", | |
| "source": "bottle", | |
| "destination": "box", | |
| } | |
| result = planner.plan(sample_detections, interpretation) | |
| assert len(result["steps"]) >= 3 | |
| assert any("bottle" in step.lower() for step in result["steps"]) | |
| assert any("box" in step.lower() for step in result["steps"]) | |
| def test_plan_no_destination(self, planner, sample_detections): | |
| """Plan should work when destination is None (e.g. 'inspect').""" | |
| interpretation = { | |
| "action": "inspect", | |
| "source": "cup", | |
| "destination": None, | |
| } | |
| result = planner.plan(sample_detections, interpretation) | |
| assert result["status"] == "success" | |
| assert result["dest_bbox"] is None | |
| def test_plan_empty_detections(self, planner): | |
| """Plan should fail gracefully with no detections.""" | |
| interpretation = { | |
| "action": "move", | |
| "source": "bottle", | |
| "destination": "box", | |
| } | |
| result = planner.plan([], interpretation) | |
| assert result["status"] == "failed" | |
| def test_plan_with_synonym(self, planner, sample_detections): | |
| """Plan should resolve synonyms via ObjectMapper (mug → cup).""" | |
| interpretation = { | |
| "action": "pick_up", | |
| "source": "mug", | |
| "destination": None, | |
| } | |
| result = planner.plan(sample_detections, interpretation) | |
| # "mug" should map to "cup" via the synonym mapper | |
| assert result["status"] == "success" | |
| assert result["source_bbox"] == [250, 200, 320, 300] | |