99from app .video_processors import OpenCVVideo
1010
1111
12+ @pytest .fixture
13+ def all_frames_extractor (extractor ):
14+ extractor ._config .all_frames = True
15+ yield extractor
16+ extractor ._config .all_frames = False
17+
18+
1219@pytest .fixture (scope = "function" )
1320def extractor (config ):
1421 extractor = BestFramesExtractor (config )
@@ -21,7 +28,6 @@ def test_process(extractor, caplog, config):
2128 extractor ._list_input_directory_files = MagicMock (return_value = test_videos )
2229 extractor ._get_image_evaluator = MagicMock ()
2330 extractor ._extract_best_frames = MagicMock (return_value = test_frames )
24- extractor ._save_images = MagicMock ()
2531 extractor ._add_prefix = MagicMock ()
2632 extractor ._signal_readiness_for_shutdown = MagicMock ()
2733
@@ -32,92 +38,101 @@ def test_process(extractor, caplog, config):
3238 config .video_extensions , config .processed_video_prefix )
3339 extractor ._get_image_evaluator .assert_called_once ()
3440 assert extractor ._extract_best_frames .call_count == len (test_videos )
35- assert extractor ._save_images .call_count == len (test_videos )
3641 assert extractor ._add_prefix .call_count == len (test_videos )
3742 extractor ._signal_readiness_for_shutdown .assert_called_once ()
3843 for video in test_videos :
3944 extractor ._add_prefix .assert_any_call (config .processed_video_prefix , video )
4045 extractor ._extract_best_frames .assert_any_call (video )
41- extractor ._save_images .assert_any_call (test_frames )
4246 assert f"Frames extraction has finished for video: { video } " in caplog .text
4347 assert f"Starting frames extraction process from '{ config .input_directory } '." in caplog .text
4448
4549
50+ def test_process_if_all_frames (extractor , caplog , config , all_frames_extractor ):
51+ test_videos = ["/fake/directory/video1.mp4" , "/fake/directory/video2.mp4" ]
52+ test_frames = ["frame1" , "frame2" ]
53+ extractor ._list_input_directory_files = MagicMock (return_value = test_videos )
54+ extractor ._get_image_evaluator = MagicMock ()
55+ extractor ._extract_best_frames = MagicMock (return_value = test_frames )
56+ extractor ._add_prefix = MagicMock ()
57+ extractor ._signal_readiness_for_shutdown = MagicMock ()
58+
59+ with caplog .at_level (logging .INFO ):
60+ extractor .process ()
61+
62+ extractor ._list_input_directory_files .assert_called_once_with (
63+ config .video_extensions , config .processed_video_prefix )
64+ extractor ._get_image_evaluator .assert_not_called ()
65+ assert not extractor ._image_evaluator
66+ assert extractor ._extract_best_frames .call_count == len (test_videos )
67+ assert extractor ._add_prefix .call_count == len (test_videos )
68+ extractor ._signal_readiness_for_shutdown .assert_called_once ()
69+ for video in test_videos :
70+ extractor ._add_prefix .assert_any_call (config .processed_video_prefix , video )
71+ extractor ._extract_best_frames .assert_any_call (video )
72+ assert f"Frames extraction has finished for video: { video } " in caplog .text
73+ assert f"Starting frames extraction process from '{ config .input_directory } '." in caplog .text
74+
75+
76+ @patch ("app.extractors.gc.collect" )
77+ @patch .object (BestFramesExtractor , "_get_best_frames" )
78+ @patch .object (BestFramesExtractor , "_save_images" )
4679@patch .object (OpenCVVideo , "get_next_frames" )
47- @patch .object (BestFramesExtractor , "_normalize_images" )
48- def test_extract_best_frames (mock_normalize , mock_get_next_frames , extractor , caplog ):
49- video_path = Path ("/fake/video.mp4" )
50- frames_batch = [MagicMock () for _ in range (10 )]
51- frames_batch_1 = frames_batch
52- frames_batch_2 = []
53- frames_batch_3 = frames_batch
54- mock_get_next_frames .return_value = iter ([frames_batch_1 , frames_batch_2 , frames_batch_3 ])
55- normalized_frames_1 = MagicMock (spec = np .ndarray )
56- normalized_frames_2 = MagicMock (spec = np .ndarray )
57- mock_normalize .side_effect = [normalized_frames_1 , normalized_frames_2 ]
58- test_ratings = [5 , 6 , 3 , 8 , 5 , 2 , 9 , 1 , 4 , 7 ]
59- extractor ._evaluate_images = MagicMock (return_value = test_ratings )
60- extractor ._get_best_frames = MagicMock (
61- side_effect = lambda frames , ratings , group_size : [frames [i ] for i in [3 , 6 ]])
62-
63- with caplog .at_level (logging .DEBUG ):
64- best_frames = extractor ._extract_best_frames (video_path )
65-
66- mock_get_next_frames .assert_called_once_with (video_path , extractor ._config .batch_size )
67- assert extractor ._evaluate_images .call_count == 2
68- assert extractor ._normalize_images .call_count == 2
69- assert extractor ._get_best_frames .call_count == 2
70- assert len (best_frames ) == 4
71- extractor ._evaluate_images .assert_any_call (normalized_frames_1 )
72- extractor ._evaluate_images .assert_any_call (normalized_frames_2 )
73- for batch in [frames_batch_1 , frames_batch_3 ]:
74- extractor ._get_best_frames .assert_any_call (
75- batch ,
76- test_ratings ,
77- extractor ._config .compering_group_size
78- )
79- assert caplog .text .count ("Frames batch generated." ) == 2
80+ def test_extract_best_frames (mock_generator , mock_save , mock_get , mock_collect , extractor ):
81+ video_path = MagicMock (spec = Path )
8082
83+ batch_1 = [f"frame{ i } " for i in range (5 )]
84+ batch_2 = []
85+ batch_3 = [f"frame{ i } " for i in range (5 )]
86+ mock_generator .return_value = iter ([batch_1 , batch_2 , batch_3 ])
8187
82- @pytest .fixture
83- def all_frames_extractor (extractor ):
84- extractor ._config .all_frames = True
85- yield extractor
86- extractor ._config .all_frames = False
88+ mock_get .side_effect = [batch_1 , batch_3 ]
8789
90+ extractor ._extract_best_frames (video_path )
8891
89- @patch .object (BestFramesExtractor , "_evaluate_images" )
92+ assert not extractor ._config .all_frames
93+ mock_generator .assert_called_once_with (video_path , extractor ._config .batch_size )
94+ assert mock_get .call_count == 2
95+ for batch in [batch_1 , batch_3 ]:
96+ mock_save .assert_called_with (batch )
97+ assert mock_collect .call_count == 2
98+
99+
100+ @patch ("app.extractors.gc.collect" )
90101@patch .object (BestFramesExtractor , "_get_best_frames" )
102+ @patch .object (BestFramesExtractor , "_save_images" )
91103@patch .object (OpenCVVideo , "get_next_frames" )
104+ def test_extract_all_frames (mock_generator , mock_save , mock_get , mock_collect , all_frames_extractor ):
105+ video_path = MagicMock (spec = Path )
106+
107+ batch_1 = [f"frame{ i } " for i in range (5 )]
108+ batch_2 = []
109+ batch_3 = [f"frame{ i } " for i in range (5 )]
110+ mock_generator .return_value = iter ([batch_1 , batch_2 , batch_3 ])
111+
112+ all_frames_extractor ._extract_best_frames (video_path )
113+
114+ assert all_frames_extractor ._config .all_frames
115+ mock_generator .assert_called_once_with (video_path , all_frames_extractor ._config .batch_size )
116+ assert mock_get .assert_not_called
117+ for batch in [batch_1 , batch_3 ]:
118+ mock_save .assert_called_with (batch )
119+ assert mock_collect .call_count == 2
120+
121+
92122@patch .object (BestFramesExtractor , "_normalize_images" )
93- def test_extract_all_frames (mock_normalize , mock_get_next_frames ,
94- mock_get , mock_evaluate , all_frames_extractor , caplog ):
95- video_path = Path ("/fake/video.mp4" )
96- frames_batch = [MagicMock () for _ in range (3 )]
97- frames_batch_1 = frames_batch
98- frames_batch_2 = []
99- frames_batch_3 = frames_batch
100- mock_get_next_frames .return_value = iter ([frames_batch_1 , frames_batch_2 , frames_batch_3 ])
101-
102- with caplog .at_level (logging .DEBUG ):
103- best_frames = all_frames_extractor ._extract_best_frames (video_path )
104-
105- mock_get_next_frames .assert_called_once_with (video_path , all_frames_extractor ._config .batch_size )
106- assert len (best_frames ) == 6
107- mock_evaluate .assert_not_called ()
108- mock_normalize .assert_not_called ()
109- mock_get .assert_not_called ()
110- assert caplog .text .count ("Frames batch generated." ) == 2
111-
112-
113- def test_get_best_frames (caplog , extractor ):
114- images = [MagicMock (spec = np .ndarray ) for _ in range (10 )]
115- ratings = np .array ([7 , 2 , 9 , 3 , 8 , 5 , 10 , 1 , 4 , 6 ])
116- batch_size = 3
117- expected_best_images = [images [2 ], images [4 ], images [6 ], images [9 ]]
123+ @patch .object (BestFramesExtractor , "_evaluate_images" )
124+ def test_get_best_frames (mock_evaluate , mock_normalize , caplog , extractor , config ):
125+ frames = [f"frames{ i } " for i in range (10 )]
126+ scores = np .array ([7 , 2 , 9 , 3 , 8 , 5 , 10 , 1 , 4 , 6 ])
127+ normalized_images = [MagicMock () for _ in range (10 )]
128+ mock_normalize .return_value = normalized_images
129+ mock_evaluate .return_value = scores
130+ expected_best_images = [frames [2 ], frames [6 ]]
118131
119132 with caplog .at_level (logging .INFO ):
120- best_images = extractor ._get_best_frames (images , ratings , batch_size )
133+ best_images = extractor ._get_best_frames (frames )
121134
135+ mock_evaluate .assert_called_once_with (normalized_images )
136+ mock_normalize .assert_called_once_with (frames , config .target_image_size )
122137 assert best_images == expected_best_images
123138 assert f"Best frames selected({ len (expected_best_images )} )." in caplog .text
0 commit comments