Add acoustic_recorder/tests/test_core.py
This commit is contained in:
parent
f52877a8e3
commit
1aa4c0c352
1 changed files with 80 additions and 0 deletions
80
acoustic_recorder/tests/test_core.py
Normal file
80
acoustic_recorder/tests/test_core.py
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import wave
|
||||||
|
import tempfile
|
||||||
|
from pathlib import Path
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import acoustic_recorder.core as core
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_wav_file(tmp_path):
|
||||||
|
path = tmp_path / "test_output.wav"
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_recording(monkeypatch):
|
||||||
|
def fake_rec(duration, samplerate, channels):
|
||||||
|
assert duration > 0
|
||||||
|
t = np.linspace(0, duration, int(samplerate * duration), endpoint=False)
|
||||||
|
# Generate simple sine wave for deterministic output
|
||||||
|
data = np.sin(2 * np.pi * 440 * t)
|
||||||
|
return np.stack([data for _ in range(channels)], axis=1).astype(np.float32)
|
||||||
|
|
||||||
|
monkeypatch.setattr(core.sd, "rec", fake_rec)
|
||||||
|
monkeypatch.setattr(core.sd, "wait", lambda: None)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def test_record_audio_creates_wav(mock_recording, mock_wav_file, monkeypatch):
|
||||||
|
monkeypatch.setattr(core.Path, "cwd", lambda: mock_wav_file.parent)
|
||||||
|
|
||||||
|
result_path = core.record_audio(1)
|
||||||
|
|
||||||
|
assert isinstance(result_path, str)
|
||||||
|
path_obj = Path(result_path)
|
||||||
|
assert path_obj.suffix == ".wav"
|
||||||
|
assert path_obj.exists()
|
||||||
|
with wave.open(path_obj, 'rb') as wf:
|
||||||
|
frames = wf.getnframes()
|
||||||
|
channels = wf.getnchannels()
|
||||||
|
sampwidth = wf.getsampwidth()
|
||||||
|
|
||||||
|
assert channels == 1 or channels == 2
|
||||||
|
assert frames > 0
|
||||||
|
assert sampwidth > 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_record_audio_invalid_duration_raises(monkeypatch):
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
core.record_audio(0)
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
core.record_audio(-5)
|
||||||
|
|
||||||
|
|
||||||
|
def test_record_audio_path_uniqueness(mock_recording, tmp_path, monkeypatch):
|
||||||
|
monkeypatch.setattr(core.sd, "rec", lambda d, samplerate, channels: np.zeros((int(samplerate * d), channels)))
|
||||||
|
monkeypatch.setattr(core.sd, "wait", lambda: None)
|
||||||
|
monkeypatch.setattr(core.Path, "cwd", lambda: tmp_path)
|
||||||
|
|
||||||
|
path1 = Path(core.record_audio(1))
|
||||||
|
path2 = Path(core.record_audio(1))
|
||||||
|
|
||||||
|
assert path1 != path2
|
||||||
|
assert path1.exists()
|
||||||
|
assert path2.exists()
|
||||||
|
|
||||||
|
|
||||||
|
def test_record_audio_file_content_is_nonempty(mock_recording, tmp_path, monkeypatch):
|
||||||
|
monkeypatch.setattr(core.Path, "cwd", lambda: tmp_path)
|
||||||
|
|
||||||
|
file_path = core.record_audio(1)
|
||||||
|
with open(file_path, 'rb') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
assert len(content) > 44 # WAV header + data
|
||||||
Loading…
Reference in a new issue