diff --git a/fft_analysis/tests/test_io_utils.py b/fft_analysis/tests/test_io_utils.py new file mode 100644 index 0000000..159c8d8 --- /dev/null +++ b/fft_analysis/tests/test_io_utils.py @@ -0,0 +1,76 @@ +import json +import os +import tempfile +import numpy as np +import pytest +from pathlib import Path + +from fft_analysis import io_utils + + +def test_load_audio_file_wav(monkeypatch): + # Mock scipy.io.wavfile.read to return synthetic data + import scipy.io.wavfile as wavfile + + sample_rate = 44100 + data = np.array([0, 32767, -32768], dtype=np.int16) + + def mock_read(file_path): + assert isinstance(file_path, (str, Path)) + return sample_rate, data + + monkeypatch.setattr(wavfile, 'read', mock_read) + + arr, sr = io_utils.load_audio_file("dummy.wav") + assert isinstance(arr, np.ndarray) + assert sr == sample_rate + assert np.allclose(arr, data.astype(np.float32) / np.max(np.abs(data))) + + +def test_load_audio_file_invalid_path(): + with pytest.raises(FileNotFoundError): + io_utils.load_audio_file("nonexistent_path.wav") + + +def test_save_spectrum_to_json_and_verify(tmp_path): + spectrum = np.array([0.1, 0.5, 0.9, 0.2]) + output_file = tmp_path / "spectrum.json" + + io_utils.save_spectrum_to_json(spectrum, str(output_file)) + + assert output_file.exists() + + with open(output_file, "r", encoding="utf-8") as f: + data = json.load(f) + + assert isinstance(data, dict) + assert 'frequencies' in data and 'magnitudes' in data + assert isinstance(data['frequencies'], list) + assert isinstance(data['magnitudes'], list) + assert len(data['frequencies']) == len(data['magnitudes']) == len(spectrum) + + +def test_save_spectrum_to_json_invalid_path(): + spectrum = np.array([0.1, 0.2, 0.3]) + invalid_path = "/invalid_directory/output.json" + + with pytest.raises((OSError, IOError)): + io_utils.save_spectrum_to_json(spectrum, invalid_path) + + +def test_load_audio_file_normalization(monkeypatch): + import scipy.io.wavfile as wavfile + + sample_rate = 48000 + data = np.array([0, 1000, -1000], dtype=np.int16) + + def mock_read(file_path): + return sample_rate, data + + monkeypatch.setattr(wavfile, 'read', mock_read) + + arr, sr = io_utils.load_audio_file("file.wav") + + assert sr == sample_rate + assert np.isclose(np.max(arr), 1.0, atol=0.01) or np.isclose(np.max(arr), 0.0) + assert np.isclose(np.min(arr), -1.0, atol=0.01) or np.isclose(np.min(arr), 0.0)