|
2 | 2 |
|
3 | 3 | import os |
4 | 4 | import wave |
5 | | -from unittest.mock import patch |
| 5 | +from unittest.mock import Mock, patch |
6 | 6 |
|
7 | 7 | import numpy as np |
8 | 8 | import pytest |
@@ -631,3 +631,93 @@ def test_load_video_file_not_found(): |
631 | 631 | with patch("cv2.VideoCapture", return_value=mock_cap): |
632 | 632 | with pytest.raises(FileNotFoundError): |
633 | 633 | multivox.load_video("fake_path.mp4") |
| 634 | + |
| 635 | + |
| 636 | +def test_load_video_basic(): |
| 637 | + """Test basic video loading without resizing or fps changes.""" |
| 638 | + # Create mock frames (5 frames, 480x640 BGR) |
| 639 | + mock_frames = [ |
| 640 | + np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8) for _ in range(5) |
| 641 | + ] |
| 642 | + |
| 643 | + mock_cap = Mock() |
| 644 | + mock_cap.isOpened.return_value = True |
| 645 | + mock_cap.read.side_effect = [(True, f.copy()) for f in mock_frames] + [ |
| 646 | + (False, None) |
| 647 | + ] |
| 648 | + mock_cap.get.return_value = 30.0 |
| 649 | + |
| 650 | + with patch("cv2.VideoCapture", return_value=mock_cap): |
| 651 | + with patch("cv2.cvtColor", side_effect=lambda f, c: f): |
| 652 | + result = multivox.load_video("fake_path.mp4") |
| 653 | + |
| 654 | + assert result.shape == (5, 480, 640, 3) |
| 655 | + mock_cap.release.assert_called_once() |
| 656 | + |
| 657 | + |
| 658 | +def test_load_video_with_frame_resize(): |
| 659 | + """Test video loading with frame resizing.""" |
| 660 | + mock_frames = [ |
| 661 | + np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8) for _ in range(3) |
| 662 | + ] |
| 663 | + resized_frame = np.random.randint(0, 255, (240, 320, 3), dtype=np.uint8) |
| 664 | + |
| 665 | + mock_cap = Mock() |
| 666 | + mock_cap.isOpened.return_value = True |
| 667 | + mock_cap.read.side_effect = [(True, f.copy()) for f in mock_frames] + [ |
| 668 | + (False, None) |
| 669 | + ] |
| 670 | + mock_cap.get.return_value = 30.0 |
| 671 | + |
| 672 | + with patch("cv2.VideoCapture", return_value=mock_cap): |
| 673 | + with patch("cv2.resize", return_value=resized_frame) as mock_resize: |
| 674 | + with patch("cv2.cvtColor", side_effect=lambda f, c: f): |
| 675 | + result = multivox.load_video("fake.mp4", frame_size=(240, 320)) |
| 676 | + |
| 677 | + assert result.shape == (3, 240, 320, 3) |
| 678 | + assert mock_resize.call_count == 3 |
| 679 | + # Check resize called with (width, height) format |
| 680 | + assert mock_resize.call_args_list[0][0][1] == (320, 240) |
| 681 | + |
| 682 | + |
| 683 | +def test_load_video_with_fps_resample(): |
| 684 | + """Test video loading with FPS resampling.""" |
| 685 | + # 10 frames at 30 fps, resample to 15 fps should give ~5 frames |
| 686 | + mock_frames = [ |
| 687 | + np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8) for _ in range(10) |
| 688 | + ] |
| 689 | + |
| 690 | + mock_cap = Mock() |
| 691 | + mock_cap.isOpened.return_value = True |
| 692 | + mock_cap.read.side_effect = [(True, f.copy()) for f in mock_frames] + [ |
| 693 | + (False, None) |
| 694 | + ] |
| 695 | + mock_cap.get.return_value = 30.0 |
| 696 | + |
| 697 | + with patch("cv2.VideoCapture", return_value=mock_cap): |
| 698 | + with patch("cv2.cvtColor", side_effect=lambda f, c: f): |
| 699 | + result = multivox.load_video("fake.mp4", target_fps=15) |
| 700 | + |
| 701 | + assert result.shape[0] == 5 |
| 702 | + assert result.shape[1:] == (100, 100, 3) |
| 703 | + |
| 704 | + |
| 705 | +def test_load_video_fps_fallback(): |
| 706 | + """Test that load_video handles invalid FPS with fallback.""" |
| 707 | + mock_frames = [ |
| 708 | + np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8) for _ in range(10) |
| 709 | + ] |
| 710 | + |
| 711 | + mock_cap = Mock() |
| 712 | + mock_cap.isOpened.return_value = True |
| 713 | + mock_cap.read.side_effect = [(True, f.copy()) for f in mock_frames] + [ |
| 714 | + (False, None) |
| 715 | + ] |
| 716 | + mock_cap.get.return_value = 0.0 # Invalid FPS |
| 717 | + |
| 718 | + with patch("cv2.VideoCapture", return_value=mock_cap): |
| 719 | + with patch("cv2.cvtColor", side_effect=lambda f, c: f): |
| 720 | + result = multivox.load_video("fake.mp4", target_fps=15) |
| 721 | + |
| 722 | + # Should use fallback fps of 30.0 |
| 723 | + assert result.shape[0] == 5 |
0 commit comments