""" Tests for the Visualization Module — ActionVisualizer. """ import numpy as np import pytest from src.visualization.visualizer import ActionVisualizer class TestActionVisualizer: """Tests for ActionVisualizer methods.""" @pytest.fixture def visualizer(self) -> ActionVisualizer: return ActionVisualizer() @pytest.fixture def test_image(self) -> np.ndarray: """A 480x640 synthetic test image.""" return np.zeros((480, 640, 3), dtype=np.uint8) @pytest.fixture 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]}, ] @pytest.fixture def sample_action_plan(self) -> dict: return { "action": "move", "steps": [ "Step 1: Locate 'bottle'", "Step 2: Locate 'box'", "Step 3: Move 'bottle' → 'box'", "Step 4: Verify action completion", ], "source_bbox": [100, 150, 200, 350], "dest_bbox": [400, 300, 550, 500], "status": "success", } def test_draw_detections_returns_image( self, visualizer, test_image, sample_detections ): """draw_detections should return an image of the same shape.""" result = visualizer.draw_detections(test_image, sample_detections) assert isinstance(result, np.ndarray) assert result.shape == test_image.shape def test_draw_detections_modifies_image( self, visualizer, test_image, sample_detections ): """draw_detections should modify the image (not return a blank copy).""" result = visualizer.draw_detections(test_image, sample_detections) # The annotated image should differ from the original assert not np.array_equal(result, test_image) def test_draw_detections_empty_list(self, visualizer, test_image): """draw_detections with empty list should still return an image.""" result = visualizer.draw_detections(test_image, []) assert isinstance(result, np.ndarray) assert result.shape == test_image.shape def test_visualize_returns_image( self, visualizer, test_image, sample_action_plan ): """visualize should return an image of the same shape.""" result = visualizer.visualize(test_image, sample_action_plan) assert isinstance(result, np.ndarray) assert result.shape == test_image.shape def test_visualize_modifies_image( self, visualizer, test_image, sample_action_plan ): """visualize should modify the image.""" result = visualizer.visualize(test_image, sample_action_plan) assert not np.array_equal(result, test_image) def test_visualize_with_no_bboxes(self, visualizer, test_image): """visualize should handle missing bounding boxes gracefully.""" plan = { "action": "inspect", "steps": ["Step 1: Inspect object"], "source_bbox": None, "dest_bbox": None, "status": "failed", } result = visualizer.visualize(test_image, plan) assert isinstance(result, np.ndarray) assert result.shape == test_image.shape def test_draw_detections_invalid_image(self, visualizer): """draw_detections with None should return a fallback image.""" result = visualizer.draw_detections(None, []) assert isinstance(result, np.ndarray)