Add inn_listen/tests/test_core.py
This commit is contained in:
parent
46000a3036
commit
0ce9aaa39a
1 changed files with 82 additions and 0 deletions
82
inn_listen/tests/test_core.py
Normal file
82
inn_listen/tests/test_core.py
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
import pytest
|
||||||
|
import numpy as np
|
||||||
|
from unittest.mock import patch, MagicMock
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
import json
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# Importiere das zu testende Modul
|
||||||
|
import inn_listen.core as core
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def synthetic_signal():
|
||||||
|
# Erzeugt ein synthetisches 50Hz-Signal mit Rauschen
|
||||||
|
fs = 1000
|
||||||
|
t = np.linspace(0, 1, fs, endpoint=False)
|
||||||
|
signal = np.sin(2 * np.pi * 50 * t) + 0.01 * np.random.randn(fs)
|
||||||
|
return signal
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_audio_data(tmp_path):
|
||||||
|
return {
|
||||||
|
"timestamp": datetime.utcnow().isoformat(),
|
||||||
|
"frequency": 123.4,
|
||||||
|
"amplitude": 0.56,
|
||||||
|
"pattern": "harmonic"
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_start_stream_nominal(monkeypatch):
|
||||||
|
# Mock sounddevice.Stream
|
||||||
|
mock_stream = MagicMock()
|
||||||
|
monkeypatch.setattr(core, "sd", MagicMock(Stream=MagicMock(return_value=mock_stream)))
|
||||||
|
|
||||||
|
log_output = core.start_stream("contact", -12.0, 1024)
|
||||||
|
assert isinstance(log_output, str)
|
||||||
|
assert "contact" in log_output or "Audio" in log_output
|
||||||
|
|
||||||
|
|
||||||
|
def test_start_stream_invalid_types():
|
||||||
|
# Überprüft Typvalidierung
|
||||||
|
with pytest.raises((TypeError, ValueError)):
|
||||||
|
core.start_stream(123, "invalid", "fft")
|
||||||
|
|
||||||
|
|
||||||
|
def test_notch_filter_removes_frequency(synthetic_signal):
|
||||||
|
# Führt den Filter aus und überprüft, dass nicht identisch
|
||||||
|
filtered = core.notch_filter(synthetic_signal, freq=50.0, Q=30.0)
|
||||||
|
assert isinstance(filtered, np.ndarray)
|
||||||
|
assert filtered.shape == synthetic_signal.shape
|
||||||
|
diff_energy = np.sum(np.abs(filtered - synthetic_signal))
|
||||||
|
assert diff_energy > 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def test_notch_filter_invalid_inputs():
|
||||||
|
with pytest.raises((TypeError, ValueError)):
|
||||||
|
core.notch_filter("not-an-array", 50.0, 30.0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_audio_data_json_serialization(mock_audio_data, tmp_path):
|
||||||
|
output_file = tmp_path / "analysis.json"
|
||||||
|
with open(output_file, "w", encoding="utf-8") as fp:
|
||||||
|
json.dump(mock_audio_data, fp)
|
||||||
|
# Validate structure
|
||||||
|
with open(output_file, "r", encoding="utf-8") as fp:
|
||||||
|
restored = json.load(fp)
|
||||||
|
for field in ["timestamp", "frequency", "amplitude", "pattern"]:
|
||||||
|
assert field in restored
|
||||||
|
assert isinstance(restored["pattern"], str)
|
||||||
|
|
||||||
|
|
||||||
|
def test_cli_invocation(monkeypatch):
|
||||||
|
mock_start_stream = MagicMock(return_value="Stream started")
|
||||||
|
monkeypatch.setattr(core, "start_stream", mock_start_stream)
|
||||||
|
|
||||||
|
test_args = ["prog", "--mic", "contact", "--gain", "-12.0", "--fft", "2048"]
|
||||||
|
monkeypatch.setattr(sys, "argv", test_args)
|
||||||
|
with patch("builtins.print") as mock_print:
|
||||||
|
core.main()
|
||||||
|
mock_start_stream.assert_called_once()
|
||||||
|
mock_print.assert_called()
|
||||||
Loading…
Reference in a new issue