import os import unittest from unittest.mock import patch from scripts.utils.analysis import run_analysis from scripts.utils.classes import ParseFileName from tests.helpers import TESTDATA, Settings from scripts.utils.analysis import filter_humans class TestRunAnalysis(unittest.TestCase): @patch('scripts.utils.helpers._load_settings') @patch('scripts.utils.analysis.loadCustomSpeciesList') def test_run_analysis(self, mock_loadCustomSpeciesList, mock_load_settings): # Mock the settings and species list mock_load_settings.return_value = Settings.with_defaults() mock_loadCustomSpeciesList.return_value = [] # Test file test_file = ParseFileName(os.path.join(TESTDATA, '2024-02-24-birdnet-16:19:37.wav')) # Expected results expected_results = [ {"confidence": 0.912, 'sci_name': 'Pica pica'}, {"confidence": 0.9316, 'sci_name': 'Pica pica'}, {"confidence": 0.8857, 'sci_name': 'Pica pica'} ] # Run the analysis detections = run_analysis(test_file) # Assertions self.assertEqual(len(detections), len(expected_results)) for det, expected in zip(detections, expected_results): self.assertAlmostEqual(det.confidence, expected['confidence'], delta=1e-4) self.assertEqual(det.scientific_name, expected['sci_name']) class TestFilterHumans(unittest.TestCase): @patch('scripts.utils.helpers._load_settings') def test_filter_humans_no_human(self, mock_load_settings): mock_load_settings.return_value = Settings.with_defaults() # Input detections without humans detections = [ [('Bird_A', 0.9), ('Bird_B', 0.8)], [('Bird_C', 0.7), ('Bird_D', 0.6)] ] # Expected output expected = [ [('Bird_A', 0.9), ('Bird_B', 0.8)], [('Bird_C', 0.7), ('Bird_D', 0.6)] ] # Run filter_humans result = filter_humans(detections) # Assertions self.assertEqual(result, expected) @patch('scripts.utils.helpers._load_settings') def test_filter_empty(self, mock_load_settings): mock_load_settings.return_value = Settings.with_defaults() # Input detections without humans detections = [] # Expected output expected = [] # Run filter_humans result = filter_humans(detections) # Assertions self.assertEqual(result, expected) @patch('scripts.utils.helpers._load_settings') def test_filter_humans_with_human(self, mock_load_settings): mock_load_settings.return_value = Settings.with_defaults() # Input detections with humans detections = [ [('Human_Human', 0.95), ('Bird_A', 0.8)], [('Bird_A', 0.9), ('Bird_B', 0.8)], [('Bird_C', 0.9), ('Bird_D', 0.8)], [('Bird_B', 0.7), ('Human vocal_Human vocal', 0.9)] ] # Expected output expected = [ [('Human_Human', 0.0)], [('Human_Human', 0.0)], [('Human_Human', 0.0)], [('Human_Human', 0.0)] ] # Run filter_humans result = filter_humans(detections) # Assertions self.assertEqual(result, expected) @patch('scripts.utils.helpers._load_settings') def test_filter_humans_with_human_neighbour(self, mock_load_settings): mock_load_settings.return_value = Settings.with_defaults() # Input detections with human neighbours detections = [ [('Bird_A', 0.9), ('Bird_B', 0.8)], [('Bird_D', 0.9), ('Bird_E', 0.8)], [('Human_Human', 0.95), ('Bird_C', 0.7)], [('Bird_F', 0.6), ('Bird_G', 0.5)] ] # Expected output expected = [ [('Bird_A', 0.9), ('Bird_B', 0.8)], [('Human_Human', 0.0)], [('Human_Human', 0.0)], [('Human_Human', 0.0)] ] # Run filter_humans result = filter_humans(detections) # Assertions self.assertEqual(result, expected) @patch('scripts.utils.helpers._load_settings') def test_filter_humans_with_deep_human(self, mock_load_settings): mock_load_settings.return_value = Settings.with_defaults() # Input detections with human neighbours detections = [ [('Bird_A', 0.9), ('Bird_B', 0.8)], [('Bird_D', 0.9), ('Bird_E', 0.8)], [('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.5), ('Bird_C', 0.7), ('Human_Human', 0.95)], [('Bird_F', 0.6), ('Bird_G', 0.5)] ] # Expected output expected = [ [('Bird_A', 0.9), ('Bird_B', 0.8)], [('Bird_D', 0.9), ('Bird_E', 0.8)], [('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.5)], [('Bird_F', 0.6), ('Bird_G', 0.5)] ] # Run filter_humans result = filter_humans(detections) # Assertions self.assertEqual(result, expected) @patch('scripts.utils.helpers._load_settings') def test_filter_humans_with_human_deep(self, mock_load_settings): settings = Settings.with_defaults() settings['PRIVACY_THRESHOLD'] = 1 mock_load_settings.return_value = settings # Input detections with human neighbours detections = [ [('Bird_A', 0.9), ('Bird_B', 0.8)], [('Bird_D', 0.9), ('Bird_E', 0.8)], [('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.7), ('Bird_C', 0.5), ('Bird_C', 0.7), ('Human_Human', 0.95)], [('Bird_F', 0.6), ('Bird_G', 0.5)] ] # Expected output expected = [ [('Bird_A', 0.9), ('Bird_B', 0.8)], [('Human_Human', 0.0)], [('Human_Human', 0.0)], [('Human_Human', 0.0)] ] # Run filter_humans result = filter_humans(detections) # Assertions self.assertEqual(result, expected) if __name__ == '__main__': unittest.main()