"""test_producers.py -- test the producers in the pipeline (eg ffmpeg, visualisation, json)""" import unittest import pipeline.producers as producers import test.mocks as mocks class TestFfmpegVideoProducer(unittest.TestCase): """Test FfmpegVideoProducer (produces videos using ffmpeg)""" def mock_run_no_output(self, cmd, cwd="."): """Mock out _run_no_output""" return None def test_init_empty(self): # test with no features -- should raise ValueError with self.assertRaises(ValueError): producers.FfmpegVideoProducer(features=None) def test_init(self): # test with features feature = mocks.MockFeature(interval="") features = [feature] vidprod = producers.FfmpegVideoProducer(features=features) self.assertEqual(vidprod.features, features) def test_ffmpeg_feature_to_clip(self): """Test without a feature and without output path -- unhappy path""" feature = mocks.MockFeature(interval=mocks.MockInterval(start=0, end=5), source=mocks.MockSource(path="test.mp4")) features = [feature] vidprod = producers.FfmpegVideoProducer(features=features) with self.assertRaises(ValueError): vidprod._ffmpeg_feature_to_clip(feature=None) with self.assertRaises(ValueError): vidprod._ffmpeg_feature_to_clip(feature=feature, output_filepath=None) def test_ffmpeg_concat_clips(self): """Test without clips and without output path -- unhappy path""" feature = mocks.MockFeature(interval="") features = [feature] vidprod = producers.FfmpegVideoProducer(features=features) with self.assertRaises(ValueError): vidprod._ffmpeg_concat_clips(clips=None) with self.assertRaises(ValueError): vidprod._ffmpeg_concat_clips(clips=features, output_filepath=None) # happy path def test_produce(self): """Test we can call produce without error""" feature = mocks.MockFeature(interval=mocks.MockInterval(start=0, end=5), source=mocks.MockSource(path="test.mp4")) features = [feature] vidprod = producers.FfmpegVideoProducer(features=features) vidprod.produce() class TestVisualisationProducer(unittest.TestCase): """Test VisualisationProducer (produces matplotlib visualisations)""" def test_init_empty(self): # test with no features -- should raise ValueError with self.assertRaises(ValueError): producers.VisualisationProducer(features=None) def test_init(self): # test with features feature = mocks.MockFeature(interval="") features = [feature] visprod = producers.VisualisationProducer(features=features) self.assertEqual(visprod.features, features) def test_produce(self): """Test we can call produce without error""" # to do this, we need to mock out plt.savefig(path) feature = mocks.MockFeature(interval=mocks.MockInterval(start=0, end=5), source=mocks.MockSource(path="test.mp4")) features = [feature] visprod = producers.VisualisationProducer(features=features) with unittest.mock.patch("matplotlib.pyplot.savefig") as mock_savefig: visprod.produce() mock_savefig.assert_called() # TODO: more more granular test coverage of produce behaviour def test_fe_colour(self): """test that colour picker returns the right colours# laughter=red, loudness=blue, video activity=green, words=yellow """ # this is a pretty poor test really expected = {"laughter": "red", "loudness": "blue", "videoactivity": "green", "words": "purple"} feature = mocks.MockFeature(interval="") features = [feature] visprod = producers.VisualisationProducer(features=features) for given, expected in expected.items(): feature.feature_extractor = given self.assertEqual(visprod._fe_colour(feature), expected) class TestJSONProducer(unittest.TestCase): def test_init_empty(self): # test with no features -- should raise ValueError with self.assertRaises(ValueError): producers.JSONProducer(features=None) def test_init(self): # test with features feature = mocks.MockFeature(interval="") features = [feature] jsonprod = producers.JSONProducer(features=features) self.assertEqual(jsonprod.features, features) def test_produce(self): """Test we can call produce without error""" feature = mocks.MockFeature(interval="") features = [feature] jsonprod = producers.JSONProducer(features=features) jsonprod.produce() class TestPipelineJSONEncoder(unittest.TestCase): """Test PipelineJSONEncoder""" # unhappy path def test_default_unserializable(self): pje = producers.PipelineJSONEncoder() with self.assertRaises(TypeError): pje.default(object())