Spaces:
Sleeping
Sleeping
| from unittest.mock import Mock, patch | |
| import numpy as np | |
| import pytest | |
| from improvisation_lab.application.interval_practice.web_interval_app import \ | |
| WebIntervalPracticeApp | |
| from improvisation_lab.config import Config | |
| from improvisation_lab.domain.music_theory import Notes | |
| from improvisation_lab.infrastructure.audio import WebAudioProcessor | |
| from improvisation_lab.presentation.interval_practice.web_interval_view import \ | |
| WebIntervalPracticeView | |
| from improvisation_lab.service import IntervalPracticeService | |
| class TestWebIntervalPracticeApp: | |
| def init_module(self): | |
| """Initialize WebIntervalPracticeApp for testing.""" | |
| config = Config() | |
| service = IntervalPracticeService(config) | |
| self.app = WebIntervalPracticeApp(service, config) | |
| self.app.ui = Mock(spec=WebIntervalPracticeView) | |
| self.app.audio_processor = Mock(spec=WebAudioProcessor) | |
| def test_launch(self): | |
| """Test launching the application.""" | |
| with patch.object(self.app.ui, "launch", return_value=None) as mock_launch: | |
| self.app.launch() | |
| mock_launch.assert_called_once() | |
| def test_process_audio_callback(self): | |
| """Test processing audio callback.""" | |
| audio_data = np.array([0.0]) | |
| self.app.is_running = True | |
| self.app.phrases = [ | |
| [Notes.C, Notes.C_SHARP, Notes.C], | |
| [Notes.D, Notes.D_SHARP, Notes.D], | |
| ] | |
| self.app.current_phrase_idx = 0 | |
| self.app.current_note_idx = 1 | |
| mock_result = Mock() | |
| mock_result.target_note = "C#" | |
| mock_result.current_base_note = "C#" | |
| mock_result.remaining_time = 0.0 | |
| with patch.object( | |
| self.app.service, "process_audio", return_value=mock_result | |
| ) as mock_process_audio: | |
| self.app._process_audio_callback(audio_data) | |
| mock_process_audio.assert_called_once_with(audio_data, "C#") | |
| assert ( | |
| self.app.text_manager.result_text | |
| == "Target: C# | Your note: C# | Remaining: 0.0s" | |
| ) | |
| def test_handle_audio(self): | |
| """Test handling audio input.""" | |
| audio_data = (48000, np.array([0.0])) | |
| self.app.is_running = True | |
| with patch.object( | |
| self.app.audio_processor, "process_audio", return_value=None | |
| ) as mock_process_audio: | |
| base_note, phrase_text, result_text, results_table = self.app.handle_audio( | |
| audio_data | |
| ) | |
| mock_process_audio.assert_called_once_with(audio_data) | |
| assert base_note == self.app.base_note | |
| assert phrase_text == self.app.text_manager.phrase_text | |
| assert result_text == self.app.text_manager.result_text | |
| assert results_table == self.app.results_table | |
| def test_start(self): | |
| """Test starting the application.""" | |
| self.app.audio_processor.is_recording = False | |
| with patch.object( | |
| self.app.audio_processor, "start_recording", return_value=None | |
| ) as mock_start_recording: | |
| base_note, phrase_text, result_text, results_table = self.app.start( | |
| "minor 2nd", "Up", 10, True, 1.5 | |
| ) | |
| mock_start_recording.assert_called_once() | |
| assert self.app.is_running | |
| assert base_note == self.app.base_note | |
| assert phrase_text == self.app.text_manager.phrase_text | |
| assert result_text == self.app.text_manager.result_text | |
| assert results_table == self.app.results_table | |
| def test_stop(self): | |
| """Test stopping the application.""" | |
| self.app.audio_processor.is_recording = True | |
| with patch.object( | |
| self.app.audio_processor, "stop_recording", return_value=None | |
| ) as mock_stop_recording: | |
| base_note, phrase_text, result_text = self.app.stop() | |
| mock_stop_recording.assert_called_once() | |
| assert not self.app.is_running | |
| assert base_note == "-" | |
| assert phrase_text == self.app.text_manager.phrase_text | |
| assert result_text == self.app.text_manager.result_text | |
| def test_update_results_table(self, detected_note, expected_result): | |
| """Test updating the results table with correct and incorrect results.""" | |
| self.app.phrases = [[Notes.C, Notes.C_SHARP, Notes.C]] | |
| self.app.current_phrase_idx = 0 | |
| self.app.current_note_idx = 1 | |
| self.app.base_note = "C" | |
| self.app.text_manager.result_text = f"Target: C# | Your note: {detected_note}" | |
| self.app.is_auto_advance = True | |
| self.app.update_results_table() | |
| expected_entry = [1, "C", "C#", detected_note, expected_result] | |
| assert self.app.results_table[-1] == expected_entry | |